PicklingError: Can’t pickle <function at 0x000002AD125A6318>: attribute lookup on main failed

环境:win10, python3.7, jupyter notebook
报错来源:20天吃掉那只pytorch-DAY2
报错原因:cell3 + cell4 ⬅ torch.utils.data

一、cell3 + cell4

# cell3
def target_transform(t):return torch.tensor([t]).float()ds_train = datasets.ImageFolder("./dataset/cifar2/train/",transform = transform_train,target_transform= lambda t:torch.tensor([t]).float())
ds_valid = datasets.ImageFolder("./dataset/cifar2/test/",transform = transform_train,target_transform= lambda t:torch.tensor([t]).float())print(ds_train.class_to_idx)# cell4
dl_train = DataLoader(ds_train,batch_size = 50,shuffle = True,num_workers=3)
dl_valid = DataLoader(ds_valid,batch_size = 50,shuffle = True,num_workers=3)

cell3中datasets.ImageFolder使用了lambda函数,cell4中num_workers被设置为3,这两个因素共同作用导致报错。

二、torch.utils.data

torch.utils.data.DataLoader默认采用单进程(主进程)来加载数据,但可以通过num_workers设置同时使用几个子进程,num_workers=0表示只使用主进程。这里的workers由pytorch提供,其实现依赖于python的multiprocessing,其实现在windows下和unix下是不同的。

  • unix下默认采用fork(),子进程通过从父进程那里继承来的地址空间直接访问dataset和代码中其他带参数的函数
  • windows下默认采用spawn(),这时候会另起一个python解释器来执行主代码(main script),之后通过pickle序列化接收dataset, collate_fn以及其他参数来执行主代码内部需要由workers来执行的代码

采用spawn()的时候,worker_init_fn参数不能为unpicklable对象,例如lambda函数。

三、其他

  1. 由于spawn()的存在,linux下不会报错的代码在windows下可能会报错,所以在windows下使用多进程加载数据的时候要注意:
    (1)python脚本的主代码应该放在if __name__ == '__main__':内,这样它们就不会在worker子进程启动的时候再次运行,而DataLoader的构造是不需要被重复执行的,所以这部分代码也应该放在这里(比如cell4)
    (2)任何自定义的内容,包括参数collate_fn, worker_init_fn或dataset的具体代码(通常是函数的形式)则要放在__main__外面(比如cell3)。在pickle序列化的过程中对于函数传递的是引用而非二进制代码,所以要使worker子进程正常工作,这一步是必须的。
  2. torchvision.transforms.ToTensor,把读入的图片转为tensor
  3. torchvision.transforms.Compose,把对读入图片的各种处理组合起来

四、解决办法

方法一:依旧是在jupyter notebook环境中,把num_workers=3改为num_workers=0
方法二:由于cell3中lambda函数的存在,无论是notebook还是脚本中的__main__都不能实现子进程num_workers>0,所以把cell3改为:

ds_train = datasets.ImageFolder("./dataset/cifar2/train/",transform = transform_train)
ds_valid = datasets.ImageFolder("./dataset/cifar2/test/",transform = transform_train)print(ds_train.class_to_idx)
# 也就是把target_transform = lambda ...删掉
# 可以打印一下ds_train[0]和type(ds_train[0][1])看一下

再把cell5改为:

%matplotlib inline
%config InlineBackend.figure_format = 'svg'# 查看部分样本
from matplotlib import pyplot as plt plt.figure(figsize=(8,8))
for i in range(9):img,label = ds_train[i]img = img.permute(1,2,0)ax=plt.subplot(3,3,i+1)ax.imshow(img.numpy())ax.set_title("label = %d"%label)ax.set_xticks([])ax.set_yticks([])
plt.show()
# 也就是把label.item()改为label

这里要说一下target_transform,如果说错了敬请指正。这个参数网上资料比较少,官网的说明也不清楚,作用应该是对类别,也就是ds_train[0][1]作转换,如果没有这个,可以看到ds_train[0][1]的类型是int,那么cell5中会报“int 没有 item()”的错误,加上这个以后就变成了tensor,再取item()实际上就是得到int(或者按原文是float,因为原文在tensor([t])后面加了.float()),所以感觉这一步比较多余,不知道有没有人可以在评论里告诉我为什么要这么做?

PicklingError: Can‘t pickle <function <lambda>...attribute lookup <lambda> on __main__ failed相关推荐

  1. _pickle.PicklingError:Can‘t pickle <function <lambda> at 0>: attribute lookup <lambda> on xxx failed

    报错提示: _pickle.PicklingError: Can't pickle <function <lambda> at 0x0000016CEB6F0488>: att ...

  2. 报错:PicklingError: Can‘t pickle <type ‘function‘>: attribute lookup __builtin__.function failed

    python2.7在使用的多进程执行一个函数时出现错误[PicklingError: Can't pickle <type 'function'>: attribute lookup bu ...

  3. pytorch报错:PicklingError: Can’t pickle <function at 0x000001EA6923EAF0>: attribute lookup on main fai

    PicklingError: Can't pickle : attribute lookup on main faied 报错显示 任务背景 解决方案 报错显示 PicklingError: Can' ...

  4. Python2 PicklingError: Can‘t pickle <type ‘instancemethod‘>: attribute lookup __builtin__.instanceme

    PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup builtin.instancemethod f ...

  5. _pickle.PicklingError: Can‘t pickle <class ‘__main__.MLPmodel‘>: attribute lookup MLPmodel on __main

    报错信息:_pickle.PicklingError: Can't pickle <class '__main__.MLPmodel'>: attribute lookup MLPmode ...

  6. [报错解决]_pickle.PicklingError: Can‘t pickle <class ‘__main__.Net‘>: attribute lookup Net on __main__ f

    今天在Windows操作系统跑完模型之后想保存模型,无奈遇到如下报错: 真的是挺纳闷啊! 这是关于pickle的报错,于是上网查找了关于pickle的信息: pickle提供了一个简单的持久化功能,可 ...

  7. _pickle.PicklingError: Can‘t pickle <class ‘__main__.XXXX‘>: attribute lookup XXXX on __main的解决方法

    这是之前报错的代码.在这个代码中,我把对网络的定义和对数据的train和test都写在了同一个文件(demo_reg.py)内.源码如下所示: import re # 引入正则表达式import nu ...

  8. 使用 Multiprocessing.Pool.map_async 报错 attribute lookup <lambda> on __main__ failed 的解决

    使用 Multiprocessing.Pool.map_async 报错 attribute lookup on __main__ failed 的解决 创作背景 问题再现 解决方法 十六 char ...

  9. _pickle.PicklingError: Can‘t pickle <function <lambda> at 0x000001C172C848C8

    _pickle.PicklingError: Can't pickle <function at 0x000001C172C848C8 百度看到很多都是用第三方库dill来解决的,但是我另外一个 ...

最新文章

  1. 与股权投资有关的抵消分录的编制
  2. Python练习 | Python 可迭代对象 迭代器
  3. 黄聪:Microsoft Enterprise Library 5.0 系列教程(四) Logging Application Block
  4. 登录代码,程序不是作文
  5. 打印Activity任务栈脚本:adb shell dumpsys activity
  6. [COLING18]两种成分句法分析的局部特征模型
  7. 基于图像识别的火灾检测系统设计思路流程
  8. HTML5小试 双人贪吃蛇
  9. c语言头文件下载微盘,c语言头文件下载 C语言头文件大全.doc
  10. C# 快递单批量打印
  11. 【web前端面试题整理07】我不理解表现与数据分离
  12. Win11如何设置默认浏览器 win11设置默认浏览器的步骤方法
  13. 怎么把半角引号替换成全角_巧妙批量互换全角与半角双引号
  14. 心电信号系统GUI系统
  15. 华三模拟器中的remote实现简单组网
  16. 元器件封装标准IPC-7351及电子开发论坛集合
  17. 行业品牌监测报告|《中国汽车产业舆情报告2022(上半年)》
  18. 转变思维,寒冬中的一把“创业火” ——猿团CEO受邀做主题演讲
  19. UVa11400 Lighting System Design
  20. 【产品】OEM、ODM、OBM是什么?

热门文章

  1. FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比
  2. 为网站引暴流量的高级软文技巧!
  3. python连接mysql三种方式_用 Python 连接 MySQL 的几种方式详解
  4. 小鼠单克隆抗体分型试剂盒丨杂交瘤筛选鉴定及相关检测
  5. 仿招商银行载入loading效果
  6. 感恩有你,我们大会见?
  7. 史上最全的画册制作流程—画册设计价格
  8. CORESET#0与和Initial DL BWP
  9. 用笔记本改装智能家居服务器,让智能家居真正融入生活
  10. php中二数组,php数组合并的方法