PicklingError: Can‘t pickle <function <lambda>...attribute lookup <lambda> on __main__ failed
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函数。
三、其他
- 由于spawn()的存在,linux下不会报错的代码在windows下可能会报错,所以在windows下使用多进程加载数据的时候要注意:
(1)python脚本的主代码应该放在if __name__ == '__main__':
内,这样它们就不会在worker子进程启动的时候再次运行,而DataLoader的构造是不需要被重复执行的,所以这部分代码也应该放在这里(比如cell4)
(2)任何自定义的内容,包括参数collate_fn, worker_init_fn或dataset的具体代码(通常是函数的形式)则要放在__main__
外面(比如cell3)。在pickle序列化的过程中对于函数传递的是引用而非二进制代码,所以要使worker子进程正常工作,这一步是必须的。 - torchvision.transforms.ToTensor,把读入的图片转为tensor
- 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相关推荐
- _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 ...
- 报错:PicklingError: Can‘t pickle <type ‘function‘>: attribute lookup __builtin__.function failed
python2.7在使用的多进程执行一个函数时出现错误[PicklingError: Can't pickle <type 'function'>: attribute lookup bu ...
- pytorch报错:PicklingError: Can’t pickle <function at 0x000001EA6923EAF0>: attribute lookup on main fai
PicklingError: Can't pickle : attribute lookup on main faied 报错显示 任务背景 解决方案 报错显示 PicklingError: Can' ...
- Python2 PicklingError: Can‘t pickle <type ‘instancemethod‘>: attribute lookup __builtin__.instanceme
PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup builtin.instancemethod f ...
- _pickle.PicklingError: Can‘t pickle <class ‘__main__.MLPmodel‘>: attribute lookup MLPmodel on __main
报错信息:_pickle.PicklingError: Can't pickle <class '__main__.MLPmodel'>: attribute lookup MLPmode ...
- [报错解决]_pickle.PicklingError: Can‘t pickle <class ‘__main__.Net‘>: attribute lookup Net on __main__ f
今天在Windows操作系统跑完模型之后想保存模型,无奈遇到如下报错: 真的是挺纳闷啊! 这是关于pickle的报错,于是上网查找了关于pickle的信息: pickle提供了一个简单的持久化功能,可 ...
- _pickle.PicklingError: Can‘t pickle <class ‘__main__.XXXX‘>: attribute lookup XXXX on __main的解决方法
这是之前报错的代码.在这个代码中,我把对网络的定义和对数据的train和test都写在了同一个文件(demo_reg.py)内.源码如下所示: import re # 引入正则表达式import nu ...
- 使用 Multiprocessing.Pool.map_async 报错 attribute lookup <lambda> on __main__ failed 的解决
使用 Multiprocessing.Pool.map_async 报错 attribute lookup on __main__ failed 的解决 创作背景 问题再现 解决方法 十六 char ...
- _pickle.PicklingError: Can‘t pickle <function <lambda> at 0x000001C172C848C8
_pickle.PicklingError: Can't pickle <function at 0x000001C172C848C8 百度看到很多都是用第三方库dill来解决的,但是我另外一个 ...
最新文章
- 与股权投资有关的抵消分录的编制
- Python练习 | Python 可迭代对象 迭代器
- 黄聪:Microsoft Enterprise Library 5.0 系列教程(四) Logging Application Block
- 登录代码,程序不是作文
- 打印Activity任务栈脚本:adb shell dumpsys activity
- [COLING18]两种成分句法分析的局部特征模型
- 基于图像识别的火灾检测系统设计思路流程
- HTML5小试 双人贪吃蛇
- c语言头文件下载微盘,c语言头文件下载 C语言头文件大全.doc
- C# 快递单批量打印
- 【web前端面试题整理07】我不理解表现与数据分离
- Win11如何设置默认浏览器 win11设置默认浏览器的步骤方法
- 怎么把半角引号替换成全角_巧妙批量互换全角与半角双引号
- 心电信号系统GUI系统
- 华三模拟器中的remote实现简单组网
- 元器件封装标准IPC-7351及电子开发论坛集合
- 行业品牌监测报告|《中国汽车产业舆情报告2022(上半年)》
- 转变思维,寒冬中的一把“创业火” ——猿团CEO受邀做主题演讲
- UVa11400 Lighting System Design
- 【产品】OEM、ODM、OBM是什么?