torch中的张量处理

  这篇博文是持续更新博文,记录tensor各种操作的爱恨情仇。

  每天学一点,十天学十点,亿天学亿点!

目录

1.torch.stack

2.torch.cat

3.repeat_interleave

4.softmax与sum中指定维度dim的问题

5.sort

6.repeat

7.transpose

8.unsqueeze与squeeze


1.torch.stack

  stack命令表示输出的东西扩展成一个维度相加

K = torch.tensor([[[0.0, 1.0], [2.0, 3.0]], [[1.0, 2.0], [3.0, 4.0]]])
K.shape

'''
torch.Size([2, 2, 2])
'''

  将张量K与K+1(K中每个元素加1)和K+2连接起来,构成一个具有3个输出通道的卷积核,扩维。如果指定的维度维1,则尺寸维(2,3,2,2),所以这个指定的维度是进行叠加后扩展的维度数,使用stack叠加的东西总会扩维。

K = torch.stack((K, K + 1, K + 2), 0)
K.shape, K

'''
(torch.Size([3, 2, 2, 2]),
 tensor([[[[0., 1.],
           [2., 3.]],
 
          [[1., 2.],
           [3., 4.]]],
 
 
         [[[1., 2.],
           [3., 4.]],
 
          [[2., 3.],
           [4., 5.]]],
 
 
         [[[2., 3.],
           [4., 5.]],
 
          [[3., 4.],
           [5., 6.]]]]))
'''

2.torch.cat

不会扩维,会在原有的维度上指定拼接

X = torch.arange(16, dtype=torch.float32).reshape((1, 1, 4, 4))
X, X.shape

'''
(tensor([[[[ 0.,  1.,  2.,  3.],
           [ 4.,  5.,  6.,  7.],
           [ 8.,  9., 10., 11.],
           [12., 13., 14., 15.]]]]),
 torch.Size([1, 1, 4, 4]))
'''
X = torch.cat((X, X + 1), 1)
X, X.shape

'''
(tensor([[[[ 0.,  1.,  2.,  3.],
           [ 4.,  5.,  6.,  7.],
           [ 8.,  9., 10., 11.],
           [12., 13., 14., 15.]],
 
          [[ 1.,  2.,  3.,  4.],
           [ 5.,  6.,  7.,  8.],
           [ 9., 10., 11., 12.],
           [13., 14., 15., 16.]]]]),
 torch.Size([1, 2, 4, 4]))
​'''

注意:cat操作,注意只有除了指定的拼接维度之外,其他维度必须一致才能运行!

3.repeat_interleave

  repeat_interleave就是将原来的x_test中的每一个元素赋值n_train次,得到一个一维tensor,再使用reshape操作使复制的相同元素都在同一行中。

X_repeat = x_test.repeat_interleave(n_train).reshape((-1, n_train))

见下图:原x_text为:x_test = torch.arange(0, 5, 0.1)

4.softmax与sum中指定维度dim的问题

dim=1表示的是沿着列增的方向操作,本质是对每一行操作!!!

且sun(1)也表示沿着列增的方向操作,本质是对每一行的元素进行相加!!!

attention_weights = nn.functional.softmax(-(X_repeat - x_train)**2 / 2, dim=1)

5.sort

sort返回两个值,第一个是拍好了从小到大的顺序后的values,另一个是对应原数据的indices

6.repeat

  state的尺寸为(bs,h),X为(T,bs,emb)

context = state[-1].repeat(X.shape[0], 1, 1)

  改成(T,1),结果返回的是(T×bs,h);改成(T,1,1,1),返回的是(T,1,bs,h);改成(1,T,1),返回的(1,bs×T,h)。也就是说,原tensor为二维的(bs,h),repeat的最后两个数表示对这两个维度的操作,如果最后两个是(1,1),则原tensor保持不变,如果最后两个维度数字发生了变化,则表示原对应维度的数字×变化数字。如上述的(bs×T,h)或(bs, T×h)

 在这里,X表示tgt的input,形状为(T,bs,emb),广播后的state为(T,bs,h),拼接后为(T,bs,emb+h),对应decoder里面的GRU输入维度为dmb+h。

  cat操作只有除了指定的拼接维度之外,其他维度必须一致才能运行!

7.transpose

Numpy用于交换数组的维度。可指定维度。

scores = torch.bmm(queries, keys.transpose(1,2))

queries与keys两个tensor进行bmm矩阵乘法,对keys进行维度交换,从(bs,k-v,d)--(bs,d.k-v),这样bmm后得到的是(bs,q,k-v)。方便与后面的values的(bs,k-v,values)做bmm。

8.unsqueeze与squeeze

unsequeeze(i)再指定第i个维度上添加1维度;squeeze(i)减去原tensor中的第i维度,且第i维度必须是1才行,否则没用。

欣赏沐神加性注意力源码:forward部分

def forward(self, queries, keys, values, valid_lens):
        queries, keys = self.W_q(queries), self.W_k(keys)
        # 在维度扩展后,
        # queries的形状:(batch_size,查询的个数,1,num_hidden)
        # key的形状:(batch_size,1,“键-值”对的个数,num_hiddens)
        # 使⽤⼴播⽅式进⾏求和
        features = queries.unsqueeze(2) + keys.unsqueeze(1)
        features = torch.tanh(features)
        # self.w_v仅有⼀个输出,因此从形状中移除最后那个维度。
        # scores的形状:(batch_size,查询的个数,“键-值”对的个数)
        scores = self.w_v(features).squeeze(-1)
        self.attention_weights = masked_softmax(scores, valid_lens)
        # values的形状:(batch_size,“键-值”对的个数,值的维度)
        return torch.bmm(self.dropout(self.attention_weights), values)

对于query(bs,q,h)与key(bs,k-v,h),将两个扩充为(bs,q,1,h)与(bs,1,k-v,h),再通过广播相加,最后再激活,通过最后Linear变成(bs,q,k-v,1)。注意,最后维度为1,所以可以压缩掉最后的维度。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值