PyTorch中torch.Tensor接收torch.Size对象的行为疑问
torch.Tensor(data.shape)与预期不符的原因 核心原因:两个构造函数的设计差异
PyTorch中torch.Tensor()(大写T类构造函数)和torch.tensor()(小写t工厂函数)的行为完全不同,这是导致问题的关键:
torch.Tensor()(类构造函数)
当传入的参数是序列类型(比如torch.Size,它本质是tuple的子类)时,该序列会被当作张量的形状参数,用于创建对应形状的未初始化张量。未初始化张量的内存是随机分配的,所以你会看到看似全0但实际包含非零元素的结果。
你的代码torch.Tensor(data.shape)中,data.shape返回的torch.Size([1, 2000, 3000])被识别为形状参数,因此生成了一个形状为(1,2000,3000)的未初始化张量。torch.tensor()(工厂函数)
这个函数的作用是将输入的数据转换为张量,不管输入是tuple、list还是torch.Size,都会把其中的数值作为张量的元素。因此torch.tensor(data.shape)会直接把data.shape中的1、2000、3000作为元素,生成一个形状为(3,)的张量。
为什么torch.Tensor(list(data.shape))能正常工作?
当你把data.shape转换为list后,list(data.shape)是一个包含尺寸数值的列表,此时传给torch.Tensor()时,构造函数会将其视为数据输入而非形状参数,因此生成存储这些数值的张量。这是因为torch.Tensor()对非tuple/Size类型的序列(比如list)的处理逻辑是当作数据。
结论
这个行为不是bug,是PyTorch构造函数的设计逻辑,长期以来保持稳定,未来版本也不会随意变更。如果要将张量的尺寸值转换为张量,推荐使用:
torch.tensor(data.shape)(最简洁)torch.Tensor(list(data.shape))
内容的提问来源于stack exchange,提问作者Profitus Maximus

