(三)NumPy 共享、切片与独立副本
# 项目文件:demos/shared_memory.py
import numpy as np
import torch
array = np.array([1, 2, 3], dtype=np.float32)
shared = torch.from_numpy(array) # CPU 张量与这个 NumPy 数组共用数据。
copied = torch.tensor(array) # tensor 构造一份独立数据。
shared[0] = 9
print("数组", array.tolist(), "副本", copied.tolist())
view = shared[1:]
view[0] = 8
print("切片修改", shared.tolist())
independent = shared.clone()
independent[0] = -1
print("clone 后原值", shared.tolist())
print("numpy 仍共享", np.shares_memory(array, shared.numpy()))torch.from_numpy(array) 让 CPU 张量与原数组共用数据,所以通过张量把首项改为 9,数组也读到 9。torch.tensor(array) 则构造独立数据,仍保留 [1, 2, 3]。
基本切片 shared[1:] 是视图,通过它修改第二项后,原张量变为 [9, 8, 3]。clone() 复制数据,再改副本不会改回原张量。最后的 .numpy() 也可共享这份 CPU 数据,图中用同一个数据块表示这种联系。
数据副本与求导关系是两件事:clone 复制数据,后面仍可以沿计算过程求导;detach 切断求导联系,但会共用原数据。读到(九)时继续核对这两个动作。