PyTorch | 张量Tensor变形记

文章通过一个古诗字符预测的例子,解释了在LSTM模型中,如何处理输入张量并进行reshape以适应全连接层。关键在于理解PyTorch张量的连续存储特性,reshape操作并不改变元素顺序,只是改变了观察数据的方式。通过示例证明了这一过程,并强调了在指定张量形状时,-1参数的灵活运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

01 | LSTM中的张量变形记

最近在学习PyTorch与LSTM的时候,发现当张量输入到LSTM的隐藏层后,所得输出需要进行变形(reshape)后才可以连接全连接层(线性Linear)。

基本原理是清楚的,为了说明的方便,我们可以尝试从下述示例中理清张量维度的变化,从而把握数据流:

1)假定对于一个古诗(七言绝句)样本,每首诗歌总共32个字符(含标点);

2)当我们一次训练五首古诗,且每个中文字符的嵌入向量为128维度时,便可以得到5×31×128的输入张量(因为用前一个字符预测后一个字符,因而输入31个字符而非32个字符);

3)假定LSTM中设置隐藏层单元数量hidden_num=64,那么意味着LSTM的ANN接受单个字符(128维度)后,输出64维度张量;

4)考虑到LSTM最后需要拼接一个线性全连接层,以将结果转变为所有可能字符的概率,因而需要将三维度张量5×31×64转变为155×64,直观上理解就是将单个字符的128嵌入向量转变为64,且输出一个包含5首古诗所有字符样本新嵌入向量的矩阵

5)将得到的155×64张量与线性系数矩阵(待训练)64×3542(假定3542是字库中不重复字符数量),恰好可以得到155×3542的输出,其含义为155个字符的预测结果恰好是一个涵盖3542字库待选对象的概率向量;

6)最终针对每个字符的概率选择最高的一个(同等最高可以随机选)作为预测输出,得到了155×1(列为索引数值)

7)将预测的155×1与实际的155×1比较计算交叉熵损失,进行梯度后向传播算法更新LSTM中的参数

在这里插入图片描述

02 | 张量的变与不变

尽管自己熟悉了示例LSTM的全程数据流形状,但是依旧会存有疑问:为何Flatten阶段可以将5×31×64的张量变形为155×64呢?各个张量元素的位置不会打乱吗?

经过查阅《Deep Learning with PyTorch》,自己得到了答案:

PyTorch中的数据类型张量连续存储与内存中,而非像Python的list一样分散存储;因而当使用torch.tensor.view()或reshape()时,仅仅是从不同的角度去投影同一块内存区域而已。

在这里插入图片描述

03 | 验证

事实上,可以通过指定“-1”参数的形式,提请PyTorch根据张量大小(形状或元素个数)实际确定张量各方向大小。

下例中使用标准正态分布初始化了一个2×3×4的张量(共有24个元素),PyTorch将其按顺序连续存储在内存块中。当我们指定第二个维度大小为4时,即要求PyTorch将其按照“4个一组”进行自动划分。

可见结果中元素顺序、位置依旧不变,变化的只有所属的张量层次:过去的2×3直接变成了现在的6,可见PyTorch也是基于已有的张量形状进行划分确定大小的。

import torch
a_tsr = torch.randn(2,3,4)
print(a_tsr)
b = a_tsr.view(-1,4)
print(b)

在这里插入图片描述

当然,我们也可以将“-1”基于后列,有PyTorch自动确定每组的元素个数:

d = a_tsr.view(8,-1)
print(d)
print(a_tsr)

在这里插入图片描述

04 | 结论

可见,当PyTorch操作时,改变的是投影的形状而非实际存储位置和顺序。

因而将一个5×31×64的张量通过设置为.reshape(-1, 64)的形式,即可得到155×64的新张量,其每行(组)恰好可看作新字符的64维度嵌入向量表示。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值