You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中Multiprocessing freeze_support()错误求助(PyCharm运行深度学习代码)

问题

本人是深度学习新手,此前一直使用Google Colab运行深度学习模型。近期在PyCharm中运行项目名为model、文件名为model.py的代码时,出现Multiprocessing freeze_support()错误。代码未定义main函数,直接运行,相关代码及报错信息如下:

运行代码

from __future__ import print_function, division
import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import torch.backends.cudnn as cudnn
import numpy as np
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import os
import copy

cudnn.benchmark = True
plt.ion()   # interactive mode


data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}

data_dir = '.\hymenoptera_data'

image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
                                          data_transforms[x])
                  for x in ['train', 'val']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
                                             shuffle=True, num_workers=4)
              for x in ['train', 'val']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
class_names = image_datasets['train'].classes

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")


##visualize the model

def imshow(inp, title=None):
    """Imshow for Tensor."""
    inp = inp.numpy().transpose((1, 2, 0))
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    inp = std * inp + mean
    inp = np.clip(inp, 0, 1)
    plt.imshow(inp)
    if title is not None:
        plt.title(title)
    plt.pause(0.001)  # pause a bit so that plots are updated


inputs, classes = next(iter(dataloaders['train']))
 
out = torchvision.utils.make_grid(inputs)

imshow(out, title=[class_names[x] for x in classes])

报错信息

(venv) PS C:\Users\prasa\PycharmProjects\model> python model.py
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:\python 39\lib\multiprocessing\spawn.py", line 116, in spawn_main
    exitcode = _main(fd, parent_sentinel)
  File "C:\python 39\lib\multiprocessing\spawn.py", line 125, in _main
    prepare(preparation_data)
  File "C:\python 39\lib\multiprocessing\spawn.py", line 236, in prepare
    _fixup_main_from_path(data['init_main_from_path'])
  File "C:\python 39\lib\multiprocessing\spawn.py", line 287, in _fixup_main_from_path
    main_content = runpy.run_path(main_path,
  File "C:\python 39\lib\runpy.py", line 268, in run_path
    return _run_module_code(code, init_globals, run_name,
  File "C:\python 39\lib\runpy.py", line 97, in _run_module_code
                ...

        The "freeze_support()" line can be omitted if the program
        is not going to be frozen to produce an executable.

疑问

  1. 直接运行无main函数的Python代码是否合规?
  2. 该如何解决这个错误?

解答

1. 无main函数的Python代码是否合规?

完全合规。Python允许直接执行脚本里的顶层代码,不需要强制定义main函数。但这种写法在涉及多进程、模块导入等场景时容易出现问题,比如你遇到的多进程启动错误,因此推荐用if __name__ == '__main__':包裹顶层执行代码,这是Python社区的最佳实践,既能避免模块被导入时重复执行代码,也能解决多进程在Windows系统下的启动问题。

2. 解决Multiprocessing freeze_support()错误的方法

这个错误出现在Windows系统下,原因是Windows的多进程通过spawn方式创建子进程时,会重新导入主模块并执行所有顶层代码,导致重复初始化甚至死锁。有两种解决方法:

方法一:用if __name__ == '__main__':包裹执行代码

把所有需要直接运行的代码(除了导入、函数定义、变量初始化等不会触发执行的部分)放到这个判断里,同时可以加上freeze_support()(非打包场景可省略,但加上更稳妥)。修改后的代码如下:

from __future__ import print_function, division
import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import torch.backends.cudnn as cudnn
import numpy as np
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import os
import copy
from multiprocessing import freeze_support  # 导入freeze_support

cudnn.benchmark = True
plt.ion()   # interactive mode


data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}

def imshow(inp, title=None):
    """Imshow for Tensor."""
    inp = inp.numpy().transpose((1, 2, 0))
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    inp = std * inp + mean
    inp = np.clip(inp, 0, 1)
    plt.imshow(inp)
    if title is not None:
        plt.title(title)
    plt.pause(0.001)  # pause a bit so that plots are updated


if __name__ == '__main__':
    freeze_support()  # Windows下多进程必备
    
    data_dir = '.\hymenoptera_data'

    image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
                                              data_transforms[x])
                      for x in ['train', 'val']}
    dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
                                                 shuffle=True, num_workers=4)
                  for x in ['train', 'val']}
    dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
    class_names = image_datasets['train'].classes

    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

    # 可视化部分
    inputs, classes = next(iter(dataloaders['train']))
    out = torchvision.utils.make_grid(inputs)
    imshow(out, title=[class_names[x] for x in classes])

方法二:临时关闭多进程加载数据

如果不想修改代码结构,可以把DataLoader里的num_workers设为0,这样就不会启用多进程加载数据,自然不会触发这个错误:

dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
                                             shuffle=True, num_workers=0)  # num_workers改为0
              for x in ['train', 'val']}

但这种方法会降低数据加载速度,仅适合临时调试,不推荐在训练大模型时使用。


内容的提问来源于stack exchange,提问作者Prasanjeet Panda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 00:52:40