关于UserWarning: non-inplace resize is deprecated warnings.warn("non-inplace resize is deprecated")
view与reshape
reshape方法会尝试创建一个新的张量,其元素与原始张量共享内存空间。如果原始张量在内存中是连续的,reshape将返回一个指向相同数据的新张量视图;如果原始张量在内存中不连续,reshape可能会先将其复制为连续的张量,然后再返回新形状的张量。这意味着,在某些情况下,reshape可能会导致额外的内存开销。
view方法则不会创建一个新的张量,而是直接返回一个与原始张量共享数据存储的新视图。如果原始张量和新的视图张量上的元素被修改,它们会互相影响,因为它们共享相同的数据。
注意:上述话的的意思其实就是,reshape方法会创建一个新张量,而view方法不会,他们两个返回的数据都是和原始张量在同一片空间,这一点我们可以使用resize_()方法进行验证,然后reshape会依据原始张量是否连续来进行相应的操作,但是view不行,如果原始数据不连续的话他就没办法操作里,(就会报错)。
这里提到了张量的连续性,那么这个连续性究竟是什么?
关于连续
如果原始张量是连续的,那么它的一维展开顺序与按行优先存储的顺序一致。
举个例子:
首先我们要知道:在PyTorch中,张量(Tensor)的实际数据以一维数组(storage)的形式存储于连续的内存中,通常采用“行优先”的存储方式。这意味着,当张量被视为多维数组时,其元素在内存中的排列顺序是按照行(或称为“外层维度”)来确定的。
而转置(transpose)操作会改变张量的维度顺序,但不会改变其底层数据的物理位置。例如,一个形状为(m, n)的二维张量在转置后,其形状变为(n, m),但转置前后的张量共享同一个底层存储(storage)
例如:
假设有一个形状为(2, 3)的二维张量a,其内容为[[1, 2, 3], [4, 5, 6]]。在内存中,这个张量的一维展开顺序是[1, 2, 3, 4, 5, 6]。当对a进行转置操作得到张量b(形状为(3, 2))时,虽然b的内容仍然是[1, 2, 3, 4, 5, 6],但按照(3, 2)的形状来访问时,其元素在内存中的排列顺序就不再是[1, 2, 3, 4, 5, 6]了(实际上,由于共享同一个storage,物理上的排列顺序并未改变,但逻辑上的访问顺序变了)。因此,b被视为非连续张量。
所以我们就说,如果一个连续的数据转置后,他一维展开顺序发生变化,但是他在物理存储顺序还是和之前一样,所以就不连续。
判断是否连续的方法:.is_contiguous()
reshape和view区别的验证
import torch
a=[[1,2,3],[1,2,3]]
b1=torch.tensor(a)
b2=torch.tensor(a)
b3=torch.tensor(a)
print('b1是否连续:',b1.is_contiguous())
print('b2是否连续:',b2.is_contiguous())
print('b3是否连续:',b2.is_contiguous())
print('b1.shape:',b1.shape)
print('b2.shape:',b1.shape)
print('b3.shape:',b2.shape)
print('*---------------------------*')
c1=b1.reshape(3,2)
c2=b2.view(3,2)
print('c1:',c1)
print('c1的地址:',id(c1))
c1.resize_(2,3)
print('c1',c1)
print('b1:',b1)
print('c1的地址:',id(c1))
print('c1是否连续:',c1.is_contiguous())
print('*---------------------------*')
print('c2:',c2)
print('c2的地址:',id(c2))
c2.resize_(2,3)
print('c2',c2)
print('b2:',b2)
print('c2的地址:',id(c2))
print('c2是否连续:',c2.is_contiguous())
print('*---------------------*')
b3=torch.t(b3)
print('b3:',b3)
print('b3是否连续:',b3.is_contiguous())
print('对b3使用view方法:')
print(b3.view(2,3))

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



