Python Dataloader 多进程报错 num_workers参数设置

报错内容:An attempt has been made to start a new process before the current process has finished

该报错一般发生在Windows系统中使用多进程。比如在Pycharm中执行如下代码:

import torch
import torch.utils.data as Data
import numpy as np
from sklearn.datasets import load_iris

iris_x, irisy = load_iris(return_X_y=True)
print("iris_x.dtype:", iris_x.dtype)
print("irisy:", irisy.dtype)

## 训练集X转化为张量,训练集y转化为张量
train_xt = torch.from_numpy(iris_x.astype(np.float32))
train_yt = torch.from_numpy(irisy.astype(np.int64))
print("train_xt.dtype:", train_xt.dtype)
print("train_yt.dtype:", train_yt.dtype)

## 将训练集转化为张量后,使用TensorDataset将X和Y整理到一起
train_data = Data.TensorDataset(train_xt, train_yt)
## 定义一个数据加载器,将训练数据集进行批量处理
train_loader = Data.DataLoader(
    dataset=train_data,  ## 使用的数据集
    batch_size=10,  # 批处理样本大小
    shuffle=True,  # 每次迭代前打乱数据
    num_workers=2,  # 【注意:这里使用2个进程】
)

##  检查训练数据集的一个batch的样本的维度是否正确
for step, (b_x, b_y) in enumerate(train_loader):
    if step > 0:
        break
## 输出训练图像的尺寸和标签的尺寸,和数据类型
print("b_x.shape:", b_x.shape)
print("b_y.shape:", b_y.shape)
print("b_x.dtype:", b_x.dtype)
print("b_y.dtype:", b_y.dtype)


## ——————————正确结果如下——————————
# iris_x.dtype: float64
# irisy: int32
# train_xt.dtype: torch.float32
# train_yt.dtype: torch.int64
# b_x.shape: torch.Size([10, 4])
# b_y.shape: torch.Size([10])
# b_x.dtype: torch.float32
# b_y.dtype: torch.int64

则会报如下的错。(在同样环境下的Jupyter Notebook中运行不会报错,目前不知道为何。。。)

RuntimeError: 
        An attempt has been made to start a new process before the
        current process has finished its bootstrapping phase.

        This probably means that you are not using fork to start your
        child processes and you have forgotten to use the proper idiom
        in the main module:

            if __name__ == '__main__':
                freeze_support()
                ...

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

 关于这里的freeze_support(),讲解可见:

讲解python中的 freeze_support()_欢迎关注,共同进步!-CSDN博客

其他例子见自己电脑 Pytorch\SYL_YBG\Test 路径下:

2_5_2_图像数据预处理.py

2_5_1_高维数组预处理.py

解决方法一:

把设置多进程的语句去掉,该例子中即把下面这行注释掉、删掉或者num_workers设为0。该语句表示调用 1+num_workers 个进程。Linux系统,该参数正常,不需担心。

num_workers=2,  # 【注意:这里使用2个进程】

解决方法二:

将当前位于脚本顶层的所有代码放在一个函数中,然后在【if __name__ == '__main__':】语句下调用。

import torch
import torch.utils.data as Data
import numpy as np
from sklearn.datasets import load_iris


def Func():
    iris_x, irisy = load_iris(return_X_y=True)
    print("iris_x.dtype:", iris_x.dtype)
    print("irisy:", irisy.dtype)

    ## 训练集X转化为张量,训练集y转化为张量
    train_xt = torch.from_numpy(iris_x.astype(np.float32))
    train_yt = torch.from_numpy(irisy.astype(np.int64))
    print("train_xt.dtype:", train_xt.dtype)
    print("train_yt.dtype:", train_yt.dtype)

    ## 将训练集转化为张量后,使用TensorDataset将X和Y整理到一起
    train_data = Data.TensorDataset(train_xt, train_yt)
    ## 定义一个数据加载器,将训练数据集进行批量处理
    train_loader = Data.DataLoader(
        dataset=train_data,  ## 使用的数据集
        batch_size=10,  # 批处理样本大小
        shuffle=True,  # 每次迭代前打乱数据
        num_workers=2,  # 【注意:这里使用2个进程】
    )

    ##  检查训练数据集的一个batch的样本的维度是否正确
    for step, (b_x, b_y) in enumerate(train_loader):
        if step > 0:
            break
    ## 输出训练图像的尺寸和标签的尺寸,和数据类型
    print("b_x.shape:", b_x.shape)
    print("b_y.shape:", b_y.shape)
    print("b_x.dtype:", b_x.dtype)
    print("b_y.dtype:", b_y.dtype)


if __name__ == '__main__': # 把上面所有内容都写到一个函数里,在该语句下调用函数,则只执行1遍!
    Func()
## ——————————Pycharm中运行结果如下——————————
iris_x.dtype: float64
irisy: int32
train_xt.dtype: torch.float32
train_yt.dtype: torch.int64
b_x.shape: torch.Size([10, 4])
b_y.shape: torch.Size([10])
b_x.dtype: torch.float32
b_y.dtype: torch.int64

——————————————

【注意】:如果只 把调用多进程的代码部分,移到【if __name__ == '__main__':下。

if __name__ == '__main__':
    ##  检查训练数据集的一个batch的样本的维度是否正确
    for step, (b_x, b_y) in enumerate(train_loader):
        if step > 0:
            break
        ## 输出训练图像的尺寸和标签的尺寸,和数据类型
    print("b_x.shape:", b_x.shape)
    print("b_y.shape:", b_y.shape)
    print("b_x.dtype:", b_x.dtype)
    print("b_y.dtype:", b_y.dtype)

在Pycharm中,会把【for step, (b_x, b_y) in enumerate(train_loader):】这行代码之前的部分执行3遍

## ——————————Pycharm中运行结果如下——————————
iris_x.dtype: float64
irisy: int32
train_xt.dtype: torch.float32
train_yt.dtype: torch.int64

iris_x.dtype: float64
irisy: int32
train_xt.dtype: torch.float32
train_yt.dtype: torch.int64

iris_x.dtype: float64
irisy: int32
train_xt.dtype: torch.float32
train_yt.dtype: torch.int64

b_x.shape: torch.Size([10, 4])
b_y.shape: torch.Size([10])
b_x.dtype: torch.float32
b_y.dtype: torch.int64
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值