实验问题记录:PyTorch Tensor 也会出现 a = b 赋值后,修改 a 会影响 b 的情况

问题阐述:

python 复制代码
crop_center_bbox = data['search_anno'][0]
        # shape = crop_center_bbox.shape
crop_center_bbox[0], crop_center_bbox[1] = 0.5 - crop_center_bbox[2]/2, 0.5 - crop_center_bbox[3]/2
crop_center_bbox[2], crop_center_bbox[3] = 0.5 + crop_center_bbox[2]/2, 0.5 + crop_center_bbox[3]/2
data['crop_center_bbox'] = [crop_center_bbox]

执行上述代码前,

而执行后

咦?怎么search_anno 也同步变了呢

很奇怪Σ(っ °Д °;)っ

解决办法

tensor 利用 clone()

python 复制代码
 crop_center_bbox = data['search_anno'][0].clone()

非常重要的事!!!

因此,在根据预定算法 完成代码 的写作过程中,一定要注意这些细节。如果不注意,这种会影响 预设 的变量 的形式,会对算法的真实完整实现 造成很大的 干扰。

不仅如此,在模型网络中的 tensor 前向传播的过程中, 中间凭空生成的或者使用的 新tensor也要注意 clone() 的使用,避免对 数据造成影响。

此外,不仅tensor有这个机制, list等也有这个机制,注意 浅拷贝的使用

对于list等形式的数据,可通过

python 复制代码
a = [1, 2, 3]
b = a.copy()

来避免这个问题。

看看大模型怎么说

为什么 PyTorch Tensor 也会出现 a = b 赋值后,修改 a 会影响 b 的情况?​​

这和 ​​Python 的变量赋值机制​ ​ 以及 ​​PyTorch Tensor 的内存管理方式​​ 有关。下面详细解释:

1. Python 的变量赋值机制(所有对象通用)​​

在 Python 中,​​变量赋值(=)只是创建了一个新的引用(指针),而不是复制对象​​。

  • ​​对于不可变对象(如 int, float, str, tuple)​ ​:

    修改时会创建新对象,所以不会影响原对象。

python 复制代码
a = 10
b = a  # b 和 a 都指向 10
b = 20  # b 现在指向 20,a 仍然是 10(因为 int 不可变)
print(a)  # 10
print(b)  # 20

​​对于可变对象(如 list, dict, set, PyTorch Tensor)​ ​:

修改时会直接操作原对象,所以所有引用都会受影响

python 复制代码
a = [1, 2, 3]
b = a  # b 和 a 指向同一个列表
b[0] = 99  # 修改 b 也会影响 a
print(a)  # [99, 2, 3]
print(b)  # [99, 2, 3]

PyTorch Tensor 也是可变对象​ ​,所以 a = b 只是让 a 和 b 指向同一个 Tensor,修改 a 会影响 b。

2. PyTorch Tensor 的特殊之处​​

PyTorch Tensor 是 ​​存储在 GPU/CPU 内存中的多维数组​​,它的赋值行为和 Python 列表类似:

  • ​a = b​ :只是让 a 指向 b 的内存地址,​没有复制数据​。
  • ​修改 a​ :直接修改 b 的内存数据,所以 b 也会变。

示例验证​

python 复制代码
import torch

b = torch.tensor([1.0, 2.0, 3.0])  # 原始 Tensor
a = b  # a 和 b 指向同一个 Tensor
a[0] = 99.0  # 修改 a 也会影响 b
print(b)  # tensor([99.,  2.,  3.])

可以看到,b 被修改了,因为 a 和 b 是同一个 Tensor。

如何避免这个问题?​​

如果你希望 a 是 b 的 ​​独立副本​ ​(修改 a 不影响 b),必须 ​​显式复制 Tensor​​:

​​(1) 使用 .clone()(推荐)​

python 复制代码
a = b.clone()  # 创建独立副本
a[0] = 99.0  # 修改 a 不会影响 b
print(b)  # tensor([1., 2., 3.])

(2) 使用 torch.clone()(函数形式)​​

python 复制代码
a = torch.clone(b)  # 等同于 b.clone()

4. 为什么 PyTorch 不默认深拷贝?​​

PyTorch 的设计选择 ​​a = b 不复制数据​ ​,主要是为了 ​​性能优化​​:

  • ​深度学习中,Tensor 数据可能很大(如图像、视频)​,如果每次赋值都复制,内存和计算开销会很大。
  • ​默认共享内存​ 可以提高效率,但需要开发者 ​显式调用 .clone()​ 来避免意外修改。
复制代码
相关推荐
2601_967980115 分钟前
win10如何把python加入环境变量
python·win10·安装教程·命令行·环境变量
盼小辉丶16 分钟前
PyTorch强化学习实战(35)——多智能体强化学习
人工智能·pytorch·深度学习·强化学习
我就是全世界31 分钟前
【轻AI越影视觉开发板】local_voice_process 语音功能模块教程——从音频采集到本地语音识别、多模态视觉交互与 ESP32-S31 硬核对比
人工智能·语音识别
hpoenixf35 分钟前
Agent 测评的身份难题:一次任务换了模型,历史成绩还能算数吗?
人工智能
hpoenixf1 小时前
专家、Subagent、Review、Judge:都是另一个模型,为什么不是同一回事?
人工智能
深蓝AI2 小时前
26.1% 的 Agent 技能带漏洞:skills 霸榜 GitHub 当天,NVIDIA 和 OpenAI 同时掏出安检仪
人工智能·程序员
锋行天下8 小时前
langgraph 后端发自定义数据,前端接收方法概括
人工智能·python
泯泷9 小时前
单个 AI 再强,为什么也干不过一支 AI 团队?
人工智能·llm·agent
浪遏9 小时前
认识 wm:从多平台发布到可扩展 CLI 的架构设计
人工智能
benchmark_cc9 小时前
用 QuantDash 读取单只股票五档盘口:抽样、缺失值检查与复现记录
python·数据分析·pandas·量化交易·股票数据·quantdash