a = torch.rand(2, 1, 2, 2) # 共有 2 * 1 * 2 * 2 = 8 个元素
print(a.shape) # torch.Size([2, 1, 2, 2])
print(a.numel()) # 8
print(a)
'''
tensor([
[[[0.6904, 0.6917],[0.1554, 0.4077]]],
[[[0.7704, 0.3776],[0.5143, 0.8417]]]
])
'''
b = a.view(2, 2 * 2) # 表示把 1 2 3三个维度合并成 1 个维度,第 0 维度不动
print(b.shape) # torch.Size([2, 4])
print(b.numel()) # 8
print(b)
'''
tensor([[0.6904, 0.6917, 0.1554, 0.4077],
[0.7704, 0.3776, 0.5143, 0.8417]])
'''
c = b.view(8)
print(c.shape) # torch.Size([8])
print(c.numel()) # 8
print(c)
'''
tensor([0.6904, 0.6917, 0.1554, 0.4077, 0.7704, 0.3776, 0.5143, 0.8417])
'''
d = c.view(8, 1, 1, 1, 1, 1, 1, 1, 1, 1)
print(d.shape) # torch.Size([8, 1, 1, 1, 1, 1, 1, 1, 1, 1])
print(d)
'''
tensor([[[[[[[[[[0.6904]]]]]]]]],
[[[[[[[[[0.6917]]]]]]]]],
[[[[[[[[[0.1554]]]]]]]]],
[[[[[[[[[0.4077]]]]]]]]],
[[[[[[[[[0.7704]]]]]]]]],
[[[[[[[[[0.3776]]]]]]]]],
[[[[[[[[[0.5143]]]]]]]]],
[[[[[[[[[0.8417]]]]]]]]]])
'''
print(a.dim()) # 4维度
print(b.dim()) # 2维度
print(c.dim()) # 1维度
print(d.dim()) # 10w维度
a = torch.ones(2, 1, 2)
print(a.shape) # torch.Size([2, 1, 2, 2])
print(a.dim()) # 3
print(a.numel()) # 4
print(a)
'''
tensor([
[[1., 1.]],
[[1., 1.]]
])
'''
b = a.reshape(4)
print(b.shape) # torch.Size([2, 4])
print(b.dim()) # 1
print(b.numel()) # 4
print(b)
'''
tensor([1., 1., 1., 1.])
'''
def unsqueeze(dim) -> Tensor
参数dim正数范围: [ 0, 原 dimMax ],下面测试代码为 dim∈ [0, 4] ,如果在第 5 维度新增维度会报错
import torch
a = torch.ones(4, 3, 28, 28)
print(a.dim()) # 4
print(a.shape) # torch.Size([4, 3, 28, 28])
b = a.unsqueeze(0) # 在 0 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([1, 4, 3, 28, 28])
b = a.unsqueeze(1) # 在 1 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([4, 1, 3, 28, 28])
b = a.unsqueeze(2) # 在 2 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([4, 3, 1, 28, 28])
b = a.unsqueeze(3) # 在 3 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([4, 3, 28, 1, 28])
b = a.unsqueeze(4) # 在 4 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([4, 3, 28, 28, 1])
b = a.unsqueeze(5) # 在 5 维度处插入一个维度
print(b.dim())
print(b.shape)
# IndexError: Dimension out of range (expected to be in range of [-5, 4], but got 5)
参数dim负数范围: [ - ( 原 dimMax + 1 ), 0 ],下面测试代码为 dim∈ [ -5, 0 ]
import torch
a = torch.ones(4, 3, 28, 28)
print(a.dim()) # 4
print(a.shape) # torch.Size([4, 3, 28, 28])
b = a.unsqueeze(0) # 在 0 维度前面插入一个新维度
print(b.dim()) # 5
print(b.shape) # torch.Size([1, 4, 3, 28, 28])
b = a.unsqueeze(-1) # 在 4 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([4, 3, 28, 28, 1])
b = a.unsqueeze(-2) # 在 3 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([4, 3, 28, 1, 28])
b = a.unsqueeze(-3) # 在 2 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([4, 3, 1, 28, 28])
b = a.unsqueeze(-4) # 在 1 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([4, 1, 3, 28, 28])
b = a.unsqueeze(-5) # 在 0 维度处插入一个维度
print(b.dim()) # 5
print(b.shape) # torch.Size([1, 4, 3, 28, 28])
b = torch.rand(32)
f = torch.rand(4, 32, 14, 14)
b = b.unsqueeze(1).unsqueeze(2).unsqueeze(0)
print(b.shape) # torch.Size([1, 32, 1, 1])
def squeeze(dim=None) -> Tensor
参数dim正数范围:[1, 原 dimMax]
a = torch.ones(1, 1, 2, 2)
print(a.dim()) # 4
print(a.shape) # torch.Size([1, 1, 2, 2])
b = a.squeeze()
print(b.dim()) # 2
print(b.shape) # torch.Size([2, 2])
b = a.squeeze(0)
print(b.dim()) # 3
print(b.shape) # torch.Size([1, 2, 2])
b = a.squeeze(1)
print(b.dim()) # 3
print(b.shape) # torch.Size([1, 2, 2])
b = a.squeeze(2)
print(b.dim()) # 2
print(b.shape) # torch.Size([2, 2])
b = a.squeeze(3)
print(b.dim()) # 4
print(b.shape) # torch.Size([1, 1, 2, 2])
b = a.squeeze(4)
print(b.dim())
print(b.shape)
# IndexError: Dimension out of range (expected to be in range of [-4, 3], but got 4)
参数dim负数范围:[- 原 dimMax, -1]
a = torch.ones(1, 1, 2, 2)
print(a.dim()) # 4
print(a.shape) # torch.Size([4, 3, 28, 28])
b = a.squeeze()
print(b.dim()) # 2
print(b.shape) # torch.Size([2, 2])
b = a.squeeze(0)
print(b.dim()) # 3
print(b.shape) # torch.Size([1, 2, 2])
b = a.squeeze(-1)
print(b.dim()) # 4
print(b.shape) # torch.Size([1, 1, 2, 2])
b = a.squeeze(-2)
print(b.dim()) # 4
print(b.shape) # torch.Size([1, 1, 2, 2])
b = a.squeeze(-3)
print(b.dim()) # 3
print(b.shape) # torch.Size([1, 2, 2])
b = a.squeeze(-4)
print(b.dim()) # 3
print(b.shape) # torch.Size([1, 2, 2])
def expand(*sizes) -> Tensor
a = torch.rand(2, 1, 2, 2)
b = torch.rand(2, 1, 1, 1)
c = b.expand(a.shape)
print(c.shape) # torch.Size([2, 1, 2, 2])
print(a)
print(b)
print(c)
'''
tensor([[[[0.4356, 0.0878],
[0.3151, 0.1201]]],
[[[0.3978, 0.2646],
[0.0629, 0.9532]]]])
tensor([[[[0.9870]]],
[[[0.1181]]]])
tensor([[[[0.9870, 0.9870],
[0.9870, 0.9870]]],
[[[0.1181, 0.1181],
[0.1181, 0.1181]]]])
'''
def repeat(*sizes) -> Tensor
b = torch.rand(2, 1, 1, 1)
c = b.repeat(1, 2, 1, 2)
print(c.shape) # torch.Size([2, 2, 1, 2])
print(c)
'''
tensor([[[[0.2657, 0.2657]],
[[0.2657, 0.2657]]],
[[[0.8223, 0.8223]],
[[0.8223, 0.8223]]]])
'''
代码解释:
c = b.repeat(1, 2, 1, 2)
将 b 的 0 维度中的值复制 1 次,所以复制之后 0 维度中有 2 * 1 个值
将 b 的 1 维度中的值复制 2 次,所以复制之后 1 维度中有 1 * 2 个值
将 b 的 2 维度中的值复制 1 次,所以复制之后 2 维度中有 1 * 1 个值
将 b 的 3 维度中的值复制 2 次,所以复制之后 3 维度中有 1 * 2 个值
def t() -> Tensor
a = torch.randn(2, 2)
print(a)
b = a.t()
print(b)
'''
tensor([[-0.6856, 0.7479],
[ 0.7589, 0.6101]])
tensor([[-0.6856, 0.7589],
[ 0.7479, 0.6101]])
'''
def transpose(dim0, dim1) -> Tensor
a = torch.randn(4, 3, 28, 28)
print(a.shape) # torch.Size([4, 3, 28, 28])
a1 = a.transpose(0, 3)
print(a1.shape) # torch.Size([28, 3, 28, 4])
注意
:view 函数运行之后需要记住原维度及size才能恢复原状,要不然可能会产生数据污染,如下代码所示a = torch.randn(4, 3, 32, 32)
a1 = a.transpose(1, 3).contiguous().view(4, 3 * 32 * 32).view(4, 3, 32, 32)
a2 = a.transpose(1, 3).contiguous().view(4, 3 * 32 * 32).view(4, 32, 32, 3).transpose(1, 3)
# 比较是否完全一样
print(torch.all(torch.eq(a, a1))) # tensor(False)
print(torch.all(torch.eq(a, a2))) # tensor(True)
def permute(*dims) -> Tensor
a = torch.rand(4, 3, 28, 28)
b = a.permute(0, 2, 3, 1)
print(b.shape) # torch.Size([4, 28, 28, 3])
解释:
将原来的 0 维度放置在 0 维度处
将原来的 2 维度放置在 1 维度处
将原来的 3 维度放置在 2 维度处
将原来的 1 维度放置在 3 维度处
特点:
- 自动扩展维度并改变维度中的值:自动调用 expand 函数
- 没有数据拷贝:不需要拷贝数据
例如:Tensor A [4, 32, 14, 14] ; Tensor B [32, 1, 1]
将 B 转化为 A :先扩展维度,再扩展维度中的值
[32, 1, 1] -> [1, 32, 1, 1] -> [4, 32, 14, 14]