https://www.cnblogs.com/jiangkejie/p/10683531.html
https://blog.csdn.net/qq_41131535/article/details/92842307
https://zhuanlan.zhihu.com/p/76255917
https://www.cnblogs.com/jiangkejie/p/10683531.html
随机张量创建
https://blog.csdn.net/manduner/article/details/87343269
一 张量维度变换
transpose()、permute()、squeeze()、unsqueeze()
1.1 维度交换:transpose()、permute()
transpose一次只能交换任意两个维度,permute一次可以交换任意个维度;
transpose()参数只能有两个,permute()参数个数必须和原tensor相同;
permute中不变的维度参数用-1表示;
对于二维张量,transpose、permute实现的就是转置操作
test_tensor=torch.randn(2,3,4)
print(test_tensor) # [1,2,3]
print(test_tensor.transpose(1,0)) # [2,1,3],第1维和第0维交换
print(test_tensor.permute(1,0,-1)) # [2,1,3],原第1维变到第0维,原第0维变到第1维,原第2维不变
print(test_tensor.permute(2,0,1)) # [3,1,2],原第2维变到第0维,原第0维变到第1维,原第1维变到第2维
tensor([[[0.7801, 0.1460, 1.2772],
[2.0538, 2.3125, 0.6436]]])
tensor([[[0.7801, 0.1460, 1.2772]],
[[2.0538, 2.3125, 0.6436]]])
tensor([[[0.7801, 0.1460, 1.2772]],
[[2.0538, 2.3125, 0.6436]]])
tensor([[[0.7801, 2.0538]],
[[0.1460, 2.3125]],
[[1.2772, 0.6436]]])
对变换的解释:
…
1.2 维度压缩:squeeze()、unsqueeze()
squeeze用于去掉tensor中长度为1的维度,如:1*2*3压缩为2*3,可以自动压缩所有长度为1的维度,也可以指定压缩某个维度,如果该维度的长度不为1,则不发生变化
unsqueeze用于添加一个长度为1的维度,如:2*3扩充为123,unsqueeze需要指定待扩充的维度
test_tensor=torch.randn(1,2,3)
print(test_tensor)
print(test_tensor.squeeze())
print(test_tensor.unsqueeze(0))
tensor([[[-0.4205, -0.0865, -0.3514],
[-0.1979, -1.3624, 1.4863]]])
tensor([[-0.4205, -0.0865, -0.3514],
[-0.1979, -1.3624, 1.4863]])
tensor([[[[-0.4205, -0.0865, -0.3514],
[-0.1979, -1.3624, 1.4863]]]])
对压缩的解释:
二 张量变形
https://blog.csdn.net/qq_39507748/article/details/105381089
https://blog.csdn.net/xpy870663266/article/details/101616286
view()、reshape()、resize_()
1 view与reshape的区别
view操作的张量必须要在内存中连续分布,而transpose、permute操作会使得张量在内存中不连续,此时需要先使用contiguous()把张量变得连续分布,在用view变换。reshape在pytorch0.4和transpose、permute一起加入,相当于,contiguous().view()
2 view/reshape与reszize_的区别
浅拷贝:
view、reshape是对原张量的浅拷贝,resize_是原张量的直接引用。
由于是浅拷贝,所以view、reshape的操作不会影响到原张量的形状,原张量形状之后的变化也不会再影响到view、reshape得到的张量;
由于是直接引用,所以resize_是直接改变原张量并返回原张量的引用;
由于只是浅拷贝,所以view、reshape、原张量三者中任意一个改变了张量元素的数值,会同时影响这三者。
view、reshape中的参数表示变形后的维度,参数的数值是维度的长度;参数的乘积表示张量中元素的个数,必须和原张量相等,也就是说view、reshape变形得到的张量,不能改变元素个数,只能改变形状(维度数量、各维度的长度);
resize_中参数的含义与view、reshape相同;但是,参数的乘积可以与必须和原张量中元素个数不相等,也就是说既可以改变形状、又可以改变元素个数。
验证:
test_tensor=torch.randn(1,2,3)
print(test_tensor)
new_tensor1=test_tensor.view(1,1,1,6)
new_tensor2=test_tensor.reshape(1,6,1,1)
new_tensor3=test_tensor.resize_(1,3,1,1)
print('第一组:-------------------------------')
print(test_tensor)
print(new_tensor1)
print(new_tensor2)
print(new_tensor3)
print('第二组:-------------------------------')
print(id(test_tensor))
print(id(new_tensor1))
print(id(new_tensor2))
print(id(new_tensor3))
print('第三组:-------------------------------')
print(id(test_tensor[0]))
print(id(new_tensor1[0]))
print(id(new_tensor2[0]))
print(id(new_tensor3[0]))
print('第四组:-------------------------------')
new_tensor1[0][0][0][0]=12345
print(test_tensor)
print(new_tensor1)
print(new_tensor2)
print(new_tensor3)
# 输出
tensor([[[-0.5990, 0.2711, 0.4092],
[-0.1552, -0.9530, -0.3696]]])
第一组:-------------------------------
tensor([[[[-0.5990]],
[[ 0.2711]],
[[ 0.4092]]]])
tensor([[[[-0.5990, 0.2711, 0.4092, -0.1552, -0.9530, -0.3696]]]])
tensor([[[[-0.5990]],
[[ 0.2711]],
[[ 0.4092]],
[[-0.1552]],
[[-0.9530]],
[[-0.3696]]]])
tensor([[[[-0.5990]],
[[ 0.2711]],
[[ 0.4092]]]])
第二组:-------------------------------
140620313335440
140620318192416
140620313465792
140620313335440
第三组:-------------------------------
140620313459040
140620313459040
140620313459040
140620313459040