引言
本篇介绍tensor的维度变化。
维度变化改变的是数据的理解方式!
view/reshape:大小不变的条件下,转变shape
squeeze/unsqueeze:减少/增加维度
transpose/t/permute:转置,单次/多次交换
expand/repeat:维度扩展
view reshape
在pytorch0.3的时候,默认是view .为了与numpy一致0.4以后增加了reshape。
损失维度信息,如果不额外存储/记忆的话,恢复时会出现问题。
执行view/reshape是有一定的物理意义的,不然不会这样做。
保证tensor的size不变即可/numel()一致/元素个数不变。
数据的存储/维度顺序非常非常非常重要
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
In[4]: a = torch.rand(4,1,28,28)
In[5]: a.shape
Out[5]: torch.Size([4, 1, 28, 28])
In[6]: a.view(4,28*28) # 4, 1*28*28 将后面的进行合并/合并通道,长宽,忽略了通道信息,上下左右的空间信息。适合全连接层。
Out[6]:
tensor([[0.1483, 0.6321, 0.8864, ..., 0.0646, 0.4791, 0.0892],
[0.5868, 0.5278, 0.8514, ..., 0.0682, 0.7815, 0.2724],
[0.4945, 0.4957, 0.0047, ..., 0.4253, 0.4135, 0.1234],
[0.0618, 0.4257, 0.1960, ..., 0.1377, 0.5776, 0.4071]])
In[7]: a.view(4,28*28).shape
Out[7]: torch.Size([4, 784])
In[8]: a.view(4*28, 28).shape # 合并batch,channel,行合并 放在一起为N [N,28] 每个N,刚好有28个像素点,只关心一行数据
Out[8]: torch.Size([112, 28])
In[9]: a.view(4*1,28,28).shape# 4张叠起来了
Out[9]: torch.Size([4, 28, 28])
In[10]: b = a.view(4,784) # a原来的维度信息是[b,c,h,w],但a这样赋值后,它是恢复不到原来的
In[11]: b.view(4,28,28,1) # logic Bug # 语法上没有问题,但逻辑上 [b h w c] 与以前是不对应的。
a.view(4,783)
RuntimeError: shape '[4, 783]' is invalid for input of size 3136
squeeze 与 unsqueeze
unsqueeze
unsqueeze(index) 拉伸(增加一个维度) (增加一个组别)
参数的范围是 [-a.dim()-1, a.dim()+1) 如下面例子中范围是[-5,5)
-5 –> 0 … -1 –> 4 这样的话,0表示在前面插入,-1表示在后面插入,正负会有些混乱,所以推荐用正数。
0与正数,就是在xxx前面插入。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21