当前位置: 首页 > news >正文

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

问题阐述:
 

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()

 crop_center_bbox = data['search_anno'][0].clone()

 非常重要的事!!!

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

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

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

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

a = [1, 2, 3]
b = a.copy()

来避免这个问题。

看看大模型怎么说

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

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

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

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

  • ​对于不可变对象(如 intfloatstrtuple)​​:
    修改时会创建新对象,所以不会影响原对象。

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

​对于可变对象(如 listdictsetPyTorch Tensor)​​:
修改时会直接操作原对象,所以所有引用都会受影响

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 也会变。
  • 示例验证​

  • import torchb = 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()(推荐)​

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

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

    a = torch.clone(b)  # 等同于 b.clone()

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

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

  • ​深度学习中,Tensor 数据可能很大(如图像、视频)​​,如果每次赋值都复制,内存和计算开销会很大。
  • ​默认共享内存​​ 可以提高效率,但需要开发者 ​​显式调用 .clone()​ 来避免意外修改。
  •  
http://www.lqws.cn/news/460783.html

相关文章:

  • 博士,超28岁,出局!
  • 深入解析BERT:语言分类任务的革命性引擎
  • 3D Gaussian Splatting算法安装与实测
  • GO Gin Web框架面试题及参考答案
  • Android sdk 36沉浸式兼容性问题修复
  • 每天一个前端小知识 Day 7 - 现代前端工程化与构建工具体系
  • LeetCode 2942.查找包含给定字符的单词
  • P12894 [蓝桥杯 2025 国 Java B] 智能交通信号灯
  • 伸缩线充电宝推荐丨倍思灵动充45W突破移动界限!
  • 计算机——硬盘驱动器
  • 结构体解决冒泡排序
  • 多线程八股
  • 【Go语言基础】对齐边界与内存填充
  • 初学python的我开始Leetcode题10-2
  • Vuex(一) —— 集中式的状态管理仓库
  • AI 产品的“嵌点”(Embedded Touchpoints)
  • 如何落地你的AI创意
  • 一体三面:UEBA在数据分析、数据治理与数据安全中的应用洞察
  • 【Flink实战】 Flink SQL 中处理字符串 `‘NULL‘` 并转换为 `BIGINT`
  • 零基础入门PCB设计 一实践项目篇 第四章(STM32开发板PCB设计)
  • 破解数据可视化难题:带轴断裂的柱状图绘制全指南
  • Maven并行构建
  • IPv6 | 地址解析 / 地址管理 / 邻居发现协议(NDP)/ 无状态自动配置(SLAAC)
  • 智能群跃小助手发布说明
  • 还原自动驾驶的“前世今生”:用 Python 实现数据记录与回放系统
  • 二分查找----1.搜索插入位置
  • Java虚拟机解剖:从字节码到机器指令的终极之旅(七)
  • 端侧AI+OS垂直创新研究报告
  • 微软应用商店打不开怎么办2025,打开TLS1.3
  • shell脚本--变量及特殊变量,算术逻辑运算