PyTorch张量内存共享机制:赋值后修改为何原张量有时不变
PyTorch变量绑定与原地操作的区别说明
核心原因是两组测试中对b的修改属于完全不同的操作类型,一个是原地修改共享内存的内容,一个是给变量重新绑定新对象。
第一组测试逻辑
你执行的b[b == 1] = 0是原地修改(in-place operation):
- 执行
b = a后,a和b两个变量名绑定到了同一个Tensor对象,二者指向同一块底层数据内存 - 原地修改操作直接改写该内存地址下存储的Tensor值,不会生成新的对象,因此两个变量同步感知到内容变化
你可以通过print(a.data_ptr() == b.data_ptr())验证,执行完赋值操作后二者的底层数据地址仍然一致。
第二组测试逻辑
你执行的b = b - 1不是原地操作:
b - 1属于算术运算,PyTorch会为运算结果分配新的内存,生成一个全新的Tensor对象- 赋值语句
b = 新的Tensor对象会把b这个变量名,从原来和a共享的旧Tensor上解绑,重新绑定到新生成的Tensor上 - 此时
a仍然绑定原来的旧Tensor对象,自然不会受到新对象的影响
同样可以用data_ptr验证:执行b = b - 1后,b.data_ptr()已经和a.data_ptr()不相等,二者已经指向不同的内存空间。
补充验证
如果你希望减法操作也能原地修改共享内存,可以使用PyTorch中带_后缀的原地方法,或者增量赋值语法:
a = torch.tensor([[1,0,1,0], [0,1,1,0]]) b = a b -= 1 # 等价于b.sub_(1),属于原地操作
执行上述代码后,a也会同步变化为减法后的结果。
内容的提问来源于stack exchange,提问作者Xxxxiehaofeng
相关产品推荐
相关产品推荐

