6.维度变换和Broadcasting

维度变换

一. .view()

必须满足物理意义
适合于全连接层,使用打平后的数据
view的新的tensor的size要和原来的保持一致。

a=torch.rand(4,1,28,28)
print(a.shape)
b=a.view(4,28*28)
c=a.view(4*1,28*28)
d=a.view(4*1*28,28)
print(b)
print(b.shape)
print(c.shape)
print(d.shape)

在这里插入图片描述

致命问题

原来的维度信息丢失,[b,c,h,w]->[b,a],无法再直接反向恢复,也无法从后者直接得出原先的维度信息,需要额外的存储原本的维度信息。

b=a.view(4,28*28)
print(b.view(4,28,28,1))

我们可以把b进行view操作成(4,28,28,1),但是在不知道a的前提下,无法回到a。
在这里插入图片描述

二. .suqeeze()/.unsqueeze()

1.squeeze减少维度

可理解为减少维度
范围[-a.dim()-1,a.dim()+1),可接受正索引和负索引,正负数相当于在该索引处的减少维度1。维度不是1的不能挤压,不会报错,返回不变的。

给参数
a=torch.rand([1,32,1,1])
print(a.shape)
b=a.squeeze(0)
c=a.squeeze(-1)
d=a.squeeze(1)
print(b.shape)
print(c.shape)
print(d.shape)

维度不是1的不能挤压,不会报错,返回不变的。
在这里插入图片描述

不给参数

不给参数,能挤压的全部挤压,即dim=1。

a=torch.rand([1,32,1,1])
print(a.shape)
b=a.squeeze()
print(b.shape)

在这里插入图片描述

2.unsqueeze增加维度

理解为增加维度,增加一个组别,不增加数据,组别意义由自己决定
范围[-a.dim()-1,a.dim()+1),可接受正索引和负索引,正数相当于在索引处的前面插入维度1,负数相当于在索引处的后面插入维度1。
多出的1可以理解为一个batch,一个组,没有增加数据,概念增加了。
后面的1可以理解为,凭空捏造的,可以随意赋予其意义。
正数可以包含所有功能,不建议负数。

参数范围内
a=torch.rand(4,1,28,28)
print(a.shape)
print(a.unsqueeze(0).shape)
print(a.unsqueeze(1).shape)
print(a.unsqueeze(4).shape)
print(a.unsqueeze(-1).shape)
print(a.unsqueeze(-4).shape)
print(a.unsqueeze(-5).shape)

对于该案例,(4,1,28,28),可写索引范围为[-5,5),正索引分别为0,1,2,3,负索引分别为-4,-3,-2,-1,当输入索引为4时,与输入索引为-1,两者效果一样,都是在最后面插入一个维度1。
在这里插入图片描述

a=torch.tensor([1.2,3.2])
print(a.shape)
print(a)
b=a.unsqueeze(0)
c=a.unsqueeze(-1)
print(b.shape)
print(b)
print(c.shape)
print(c)

在这里插入图片描述

超出范围
print(a.unsqueeze(5).shape)

在这里插入图片描述

三. .expand()/.repeat()

1.expand扩张(推荐)

只是改变理解方式,没有增加数据
参数表示扩张后的tensor
expand和repeat两种最终效果等效,第一种不会主动复制数据,在有需要的时候,否则省略掉复制数据的过程。

a=torch.rand([1,32,1,1])
b=a.expand(4,32,14,14)

前提是扩张前后的shape一致,原来是1的维度可以扩张为n,原来是x的,不会扩张成y。
在这里插入图片描述

a=torch.rand([1,32,1,1])
c=a.expand(-1,32,-1,-1)
print(c.shape)
print(a.expand(-1,32,-1,-4).shape)

-1表示保持不变。-4变为-4这是一个bug,这个在最新的facebook被修复。
在这里插入图片描述

2.repeat重复

也是一种扩展,但是实实在在的增加数据。会更改掉存储。
参数表示要拷贝的次数。

a=torch.rand([1,32,1,1])
b=a.repeat(4,1,4,4)
print(b.shape)

存储变大。

在这里插入图片描述

四. .transpose()/.t()/.permute()

1. .t 转置

转置,只能适用于2d的tensor,即矩阵

a=torch.rand(2,3)
print(a)
print(a.t())

在这里插入图片描述

只适应于二维矩阵。

a=torch.rand(2,3,3)
print(a)
print(a.t())

在这里插入图片描述

2.transpose

交换某个维度,transpose[1,3]:[b,c,h,w]->[b,w,h,c]。相当于把后面连在一起再展开。
tips:数据的维度顺序必须和存储顺序一致。

a=torch.rand(1,2,3,4)
b=a.transpose(1,2)
print(b.shape)

在这里插入图片描述

contiguous变成连续
all所有内容一致才返回true

3.permute

这里放的数是原来tensor的tensor索引。相当于任意多的transpose。
tip:[b,h,w,c]是numpy存储图片的一种格式,需要这一步才能导出numpy

a=torch.rand(1,2,3,4)
b=a.transpose(1,2)
c=a.permute(0,2,1,3)
print(b.shape)
print(c.shape)

在这里插入图片描述

Broadcasting自动扩展

expand,且是自动实施
不需要复制数据
可以理解为一个插入维度使用了一个unsqueaze,再使用一个expand来复制数据(逻辑上复制)
关键点:第一,前面没有维度在前面插入一个新的维度,shape为1,第二,把dim为1的扩张为与A相同的大小
feature maps:A【4,32,14,14】
B【 32,1,1】在前面插入一个维度为1
B【 1, 32,1,1】
bias:【32,1,1】后面两个1是手动插入,

why broadcasting

1.实际需求

[班级,学生,得分]
现为每个学生加5分,即bias=5
5:的维度是[1]:unsqueaze(0).unsqueazse(0).expand_as(A)
可得到【1,1,1】->【4,32,8】
自动扩展使得我们不需要手动这部分的代码,更重要的是,现实中不使用expand而是repeate,大大增加了所需要的存储空间。

2.存储消耗

对一个5的存储,进行repeate后可能需要【4,32,8】->1024
什么时候使用

例子

小维度指定,大维度随意,从最后一个维度开始,
大 小
A【 信 息 】
B 无 【按照规则 】
前面若没有则前面插入1,然后再扩张成相同的大小,其他不行
例如:【4,32,8】
加分信息:(0,0,0,5)长度为4,维度为1,但是共有8门课,只给了4门的成绩,无法扩张。
例如【4,32,14,14】
给了【2,32,14,14】
需要手动

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值