解决使用copy.deepcopy()拷贝Tensor或model时报错只支持用户显式创建的Tensor问题

article/2025/1/18 17:07:24

模型训练过程中常需边训练边做validation或在训练完的模型需要做测试,通常的做法当然是先创建model实例然后掉用load_state_dict()装载训练出来的权重到model里再调用model.eval()把模型转为测试模式,这样写对于训练完专门做测试时当然是比较合适的,但是对于边训练边做validation使用这种方式就需要写一堆代码,如果能使用copy.deepcopy()直接深度拷贝训练中的model用来做validation显然是比较简洁的写法,但是由于copy.deepcopy()的限制,写model里代码时如果没注意,调用copy.deepcopy(model)时可能就会遇到这个错误:Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment,详细错误信息如下:

 File "/usr/local/lib/python3.6/site-packages/prc/framework/model/validation.py", line 147, in init_val_modelval_model = copy.deepcopy(model)File "/usr/lib64/python3.6/copy.py", line 180, in deepcopyy = _reconstruct(x, memo, *rv)File "/usr/lib64/python3.6/copy.py", line 280, in _reconstructstate = deepcopy(state, memo)File "/usr/lib64/python3.6/copy.py", line 150, in deepcopyy = copier(x, memo)File "/usr/lib64/python3.6/copy.py", line 240, in _deepcopy_dicty[deepcopy(key, memo)] = deepcopy(value, memo)File "/usr/lib64/python3.6/copy.py", line 180, in deepcopyy = _reconstruct(x, memo, *rv)File "/usr/lib64/python3.6/copy.py", line 306, in _reconstructvalue = deepcopy(value, memo)File "/usr/lib64/python3.6/copy.py", line 180, in deepcopyy = _reconstruct(x, memo, *rv)File "/usr/lib64/python3.6/copy.py", line 280, in _reconstructstate = deepcopy(state, memo)File "/usr/lib64/python3.6/copy.py", line 150, in deepcopyy = copier(x, memo)File "/usr/lib64/python3.6/copy.py", line 240, in _deepcopy_dicty[deepcopy(key, memo)] = deepcopy(value, memo)File "/usr/lib64/python3.6/copy.py", line 180, in deepcopyy = _reconstruct(x, memo, *rv)File "/usr/lib64/python3.6/copy.py", line 306, in _reconstructvalue = deepcopy(value, memo)File "/usr/lib64/python3.6/copy.py", line 180, in deepcopyy = _reconstruct(x, memo, *rv)File "/usr/lib64/python3.6/copy.py", line 280, in _reconstructstate = deepcopy(state, memo)File "/usr/lib64/python3.6/copy.py", line 150, in deepcopyy = copier(x, memo)File "/usr/lib64/python3.6/copy.py", line 240, in _deepcopy_dicty[deepcopy(key, memo)] = deepcopy(value, memo)File "/usr/lib64/python3.6/copy.py", line 161, in deepcopyy = copier(memo)File "/root/.local/lib/python3.6/site-packages/torch/_tensor.py", line 55, in __deepcopy__raise RuntimeError("Only Tensors created explicitly by the user "
RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment

这个错误简单地说就是copy.deepcopy()不支持拷贝requires_grad=True的Tensor(在网络中一般是非叶子结点Tensor, grad_fn不为None),开始以为真的哪个地方Tensor的requires_grad没有按要求设置,熬了几个夜去检查调试网络代码没发现什么线索很郁闷,后来想既然是copy.deepcopy()里报错的,源码也有那就去它里面debug看是拷贝网络的那部分时抛出的Exception吧,折腾了一阵发现里面这个地方加breakpoint比较合适:

   if dictiter is not None:if deep:for key, value in dictiter:key = deepcopy(key, memo)value = deepcopy(value, memo)y[key] = valueelse:for key, value in dictiter:y[key] = value

我这个网络的结构是使用的python dict方式定义的,运行时使用注册机制动态创建出来的,既然是dict,这里的key和value就是对应配置文件里的定义网络每层结构的dict的key和value,在这里加bp可以比较清楚地跟踪看到是在哪个地方导致的抛出Exception,结果发现原因是因为有个实现分割功能的head类的内部有个成员变量保存了这层的输出结果Tensor用于后面计算loss,模型每层的输出数据Tensor自然是requires_grad=True,把这个成员变量去掉,改成forward()输出结果,然后在网络的主类里接收它并传入计算Loss的函数,然后deepcopy(model)就不报上面的错了!

另外,显式创建一个Tensor时指定requires_grad=True(默认是False)并不会导致copy.deepcopy()报错,不管这个Tensor是在cpu上还是gpu上,关键是用户自己创建的Tensor是叶子结点Tensor,它的grad_fn是None,在这个Tensor上做切片或者加载到gpu上等操作得到的新的Tensor就不是叶子结点了,pytorch认为requires_grad=Trued的Tensor经过运算得到新的Tensor是需要求导的会自动加上grad_fn而不管这个Tensor是不是网络的一部分,这时再使用copy.deepcopy()深度拷贝新的Tensor时会抛出上面的错误,看完下面的示例就知道了:

>>> t = torch.tensor([1,2,3.5],dtype=torch.float32, requires_grad=True, device='cuda:0')
>>> t
tensor([1.0000, 2.0000, 3.5000], device='cuda:0', requires_grad=True)
>>> x = copy.deepcopy(t)
>>> x
tensor([1.0000, 2.0000, 3.5000], device='cuda:0', requires_grad=True)
>>> t1 = t[:2]
>>> t1
tensor([1., 2.], device='cuda:0', grad_fn=<SliceBackward0>)
>>> x = copy.deepcopy(t1)
Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/usr/local/python3.8/lib/python3.8/copy.py", line 153, in deepcopyy = copier(memo)File "/root/.local/lib/python3.8/site-packages/torch/_tensor.py", line 85, in __deepcopy__raise RuntimeError("Only Tensors created explicitly by the user "
RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment>>> t = torch.tensor([1,2,3.5],dtype=torch.float32, requires_grad=True)
>>> t1 = t.cuda()
>>> t1
tensor([1.0000, 2.0000, 3.5000], device='cuda:0', grad_fn=<ToCopyBackward0>)
>>> x = copy.deepcopy(t1)
Traceback (most recent call last):File "<stdin>", line 1, in <module>File "/usr/local/python3.8/lib/python3.8/copy.py", line 153, in deepcopyy = copier(memo)File "/root/.local/lib/python3.8/site-packages/torch/_tensor.py", line 85, in __deepcopy__raise RuntimeError("Only Tensors created explicitly by the user "
RuntimeError: Only Tensors created explicitly by the user (graph leaves) support the deepcopy protocol at the moment>>> t = torch.tensor([1,2,3.5],dtype=torch.float32, requires_grad=False)
>>> t
tensor([1.0000, 2.0000, 3.5000])
>>> x = copy.deepcopy(t)
>>> x
tensor([1.0000, 2.0000, 3.5000])
>>> t1 = t[:2]  
>>> t1
tensor([1., 2.])
>>> x = copy.deepcopy(t1)

为何deepcopy()不直接支持有梯度的Tensor,按理要支持复制一个当时的瞬间值应该也没问题,看到https://discuss.pytorch.org/t/copy-deepcopy-vs-clone/55022/10这里这个经常回答问题的胡子哥给了个猜测:


http://chatgpt.dhexx.cn/article/w5VRXPkP.shtml

相关文章

Python中copy()和deepcopy()的区别

同样是copy&#xff0c;二者有什么不同呢今天我们就一探究竟&#xff01;&#xff01;&#xff01; 关于copy()和deepcopy()的第一篇博客 初学编程的小伙伴都会对于深浅拷贝的用法有些疑问&#xff0c;今天我们就结合python变量存储的特性从内存的角度来谈一谈赋值和深浅拷贝~…

python deepcopy

1. copy.copy 浅拷贝 只拷贝父对象&#xff0c;不会拷贝对象的内部的子对象。 2. copy.deepcopy 深拷贝 拷贝对象及其子对象 一个很好的例子&#xff1a; import copya [ 1 , 2 , 3 , 4 , [ a , b ]] # 原始对象 b a # 赋值&#xff0c;传对象的引用 c copy.…

Python copy与deepcopy(深浅复制)

Python深浅复制 一般对象的复制复杂对象的复制 最近遇到了有关Python中的copy与deepcopy问题&#xff0c;之前再Java里面好像也遇到了深浅复制的问题&#xff0c;但是Python中的深浅复制还不是很熟&#xff0c;就简单了解了一下它们2个的差别&#xff0c;可以供大家参考&#x…

python copy()和deepcopy()解释(浅拷贝、深拷贝)

对于简单的 object&#xff0c;用 shallow copy 和 deep copy 没区别 复杂的 object&#xff0c; 如 list 中套着 list 的情况&#xff0c;shallow copy 中的 子list&#xff0c;并未从原 object 真的「独立」出来。也就是说&#xff0c;如果你改变原 object 的子 list 中的一…

python学习 - copy模块的浅复制(copy)与深复制(deepcopy)

python学习 - copy模块的浅复制&#xff08;copy&#xff09;与深复制&#xff08;deepcopy&#xff09; 简介copy.copy()详解copy.deepcopy()详解 简介 在使用列表或者字典进行传递参数的时候&#xff0c;可能会遇到函数改变了列表的值&#xff0c;但是不希望印象原来列表中的…

python中copy()和deepcopy()详解

参考文章 http://iaman.actor/blog/2016/04/17/copy-in-python **首先直接上结论&#xff1a; —–我们寻常意义的复制就是深复制&#xff0c;即将被复制对象完全再复制一遍作为独立的新个体单独存在。所以改变原有被复制对象不会对已经复制出来的新对象产生影响。 —–而浅…

不懂copy与deepcopy的区别?这一篇就够了

背景 在运用Python进行开发代码过程中&#xff0c;会遇到变量复制备份的场景&#xff0c;但并没有得到预期的结果&#xff0c;例如下面的例子&#xff1a; lista [a, b, [1, 2, 3]] listb lista.copy() lista[2].append(4)print(lista) # [a, b, [1, 2, 3, 4]] print(list…

浅拷贝(shallow copy)和深拷贝(deep copy)

浅拷贝&#xff08;shallow copy&#xff09;&#xff1a;只负责克隆按值传递的数据&#xff08;比如基本数据类型、String类型&#xff09; 深拷贝&#xff08;deep copy&#xff09;&#xff1a;除了shallow copy的值外&#xff0c;还负责克隆引用类型的数据&#xff0c;基本…

js深拷贝deepCopy教程:支持循环引用、类型不丢失、可扩展、可定制

目录 1. 背景2. 简介3. 安装方式 3.1. 方式1&#xff1a;通过 npm 安装3.2. 方式2&#xff1a;直接下载原代码3.3. 方式3&#xff1a;通过<script>标签引入 4. 教程 4.1. API简介4.2. 基本使用4.3. 拷贝函数4.4. 指定拷贝深度4.5. 循环引用4.6. 保持类型信息4.7. 拷贝不可…

深入理解Python深拷贝(deepcopy)、浅拷贝(copy)、等号拷贝----看了还不懂找我

编程中难免会遇到copy&#xff08;浅拷贝&#xff09;与deepcopy&#xff08;深拷贝&#xff09;问题&#xff0c;一不小心就会掉进坑中了&#xff0c;或许很多人只知道有深浅拷贝&#xff0c;但是你又知道copy和""拷贝有什么区别么&#xff1f;也许很少有人对二者的…

Python-copy()与deepcopy()区别

最近在实习&#xff0c;boss给布置了一个python的小任务&#xff0c;学习过程中发现copy&#xff08;&#xff09;和deepcopy&#xff08;&#xff09;这对好基友实在是有点过分&#xff0c;搞的博主就有点傻傻分不清啊&#xff0c;但是呢本着一探到底的精神&#xff0c;还是要…

三分钟入门大数据之什么是用户画像?

哈喽&#xff0c;大家好&#xff0c;我是汉斯老师。近几年来&#xff0c;互联网行业由于较高的薪资收入&#xff0c;受到许多人的追捧。很多年轻的学子&#xff0c;或是其他行业的有志青年&#xff0c;都想要投身到这个行业中来。然而一方面受到“互联网寒冬”的影响&#xff0…

什么是用户画像?金融行业大数据用户画像实践

金融消费者逐渐年轻化&#xff0c;80、90后成为客户主力&#xff0c;他们的消费意识和金融意识正在增强。金融服务正在从以产品为中心&#xff0c;转向以消费者为中心。所有金融行业面对的最大挑战是消费者的消费行为和消费需求的转变&#xff0c;金融企业迫切需要为产品寻找目…

银行用户画像简介

当我们讨论产品、需求、场景、用户体验时&#xff0c;往往需要将焦点聚集在某类人群上&#xff0c;用户画像便是一种抽象的方法&#xff0c;是目标用户的集合。本文作者对银行用户画像体系的建设进行了分析&#xff0c;希望能给你带来一些帮助。 用户画像的正式英文名称是User …

用户画像基础之用户画像是什么

目录 0. 相关文章链接 1. 用户画像是什么 2. 画像简介 3. 标签类型 注&#xff1a;此博文为根据 赵宏田 老师的 用户画像方法论与工程化解决方案 一书读后笔记而来&#xff0c;仅供学习使用 0. 相关文章链接 用户画像文章汇总 1. 用户画像是什么 在互联网步入大数据时代…

详解用户画像

01画像简介 用户画像&#xff0c;即用户信息标签化&#xff0c;通过收集用户的社会属性、消费习惯、偏好特征等各个维度的数据&#xff0c;进而对用户或者产品特征属性进行刻画&#xff0c;并对这些特征进行分析、统计&#xff0c;挖掘潜在价值信息&#xff0c;从而抽象出用户的…

用户画像——什么是用户画像?和用户画像的计算框架选型

用户画像——什么是用户画像&#xff1f;和用户画像的计算框架选型 1.什么是用户画像&#xff1f; 1.1 应用场景 1.1.1 精细化运营 1.1.2 推荐系统 1.2 概念定义 1.2.1 总结场景对数据的需求 1.2.2 实现这些场的数据结构 1.2.3 用户画像的概念 2.用户画像…

什么是用户画像,流程、方法是什么?

什么是用户画像&#xff0c;流程、方法是什么? 01 用户画像概述1. 什么是用户画像2. 为什么需要用户画像 02 用户画像流程1. 整体流程1&#xff09;目标分析2&#xff09;标签体系构建3&#xff09;画像构建 2. 标签体系1&#xff09;事实标签2&#xff09;模型标签3&#xff…

一文让你彻底明白,到底什么是用户画像?

写在前面&#xff1a; 博主是一名大数据的初学者&#xff0c;昵称来源于《爱丽丝梦游仙境》中的Alice和自己的昵称。作为一名互联网小白&#xff0c;写博客一方面是为了记录自己的学习历程&#xff0c;一方面是希望能够帮助到很多和自己一样处于起步阶段的萌新。由于水平有限&a…

什么是用户画像——从零开始搭建实时用户画像(一)

用户画像 简介 用户画像&#xff0c;作为一种勾画目标用户、联系用户诉求与设计方向的有效工具&#xff0c;用户画像在各领域得到了广泛的应用。 用户画像最初是在电商领域得到应用的&#xff0c;在大数据时代背景下&#xff0c;用户信息充斥在网络中&#xff0c;将用户的每…