pytorch中的pack和pad操作,PyTorch中的Pack和Pad操作详解

马肤

温馨提示:这篇文章已超过458天没有更新,请注意相关的内容是否还可用!

在PyTorch中,"pack"和"pad"操作是用于处理张量(tensor)的重要操作。"pack"操作通常用于将稀疏数据转换为紧凑格式,以减少存储空间和提高计算效率。"pad"操作则用于在数据中添加额外的维度或元素,以使其具有统一的形状或满足特定的计算需求。这两个操作在处理多维数据和深度学习模型时非常常见,有助于优化数据处理和计算性能。

背景

  进行训练和测试时,有时难以保证输入文本长度的一致性,因此常常需要截断操作(即将超过预设长度的文本截断)和pad操作(即对不足预设长度的文本进行补0)。

  在Pytorch中的torch.nn.utils.rnn,提供了pad和pack,pack_padded_sequence和pad_packed_sequence四种方法实现这一操作。

pad和pack

  举一个简单的例子:

from torch.nn.utils.rnn import pack_sequence, pad_sequence,pad_packed_sequence, pack_padded_sequence, 
text1 = torch.tensor([1,2,3,4])    # 可视为有4个文字的样本
text2 = torch.tensor([5,6,7])  # 可视为有3个文字的样本
text3 = torch.tensor([8,9])    # 可视为有2个文字的样本
sequences = [text1, text2, text3]  # 三个文本序列

  pack操作将原来的二维数据(batch*sequence)进行了压缩,但其排列是按照列(即sequence的顺序)进行排列,每个时间步一次性输出batch上的所有样本,即:

pytorch中的pack和pad操作,PyTorch中的Pack和Pad操作详解 第1张

  pack后的返回值包括两数据。一类为data,即压缩后的数据;而另一类batch_sizes表示每个时间步,batch中包含的样本量。

[Input]  pack_sequence(sequences)
[Output] PackedSequence(data=tensor([1, 5, 8, 2, 6, 9, 3, 7, 4]), batch_sizes=tensor([3, 3, 2, 1]))

  pad操作即是将不同长度的文本序列进行补0。需要注意的是,这个没有dim参数,替代的是batch_first参数,即第一个维度是否是batch,在默认情况下,参数batch_first=False,这是rnn网络的推荐用法。其返回值的第一个维度将变成sequence,而第二个维度才为batch。如果是仅仅使用这种方法对数据进行补齐或截断,可以通过设置batch_first=True,使得返回值的第一个维度为batch,从而保持与输入值的一致性。

pytorch中的pack和pad操作,PyTorch中的Pack和Pad操作详解 第2张

[Input]  pad_sequence(sequences)
[Output] tensor([[1, 5, 8],
        		[2, 6, 9],
        		[3, 7, 0],
        		[4, 0, 0]])
[Input]  pad_sequence(sequences, batch_first=True)
[Output] tensor([[1, 2, 3, 4],
        		[5, 6, 7, 0],
        		[8, 9, 0, 0]])

pack_padded_sequence和pad_packed_sequence

  因为pytorch中的RNN网络可以接受的是PackedSequence类型数据(通过pack操作实现),而pad操作又可以实现不等长文本的填充对齐,所以自然会想到将两个操作联合起来,这就是pytorch提供的pack_padded_sequence和pad_packed_sequence功能。

  pack_padded_sequence就是将经pad后的文本序列在做pack,从而实现对文本缺失位置的填0和维度压缩:

pytorch中的pack和pad操作,PyTorch中的Pack和Pad操作详解 第3张

[Input]  pack_padded_sequence(pad_sequence(sequences,batch_first=True),lengths=[4,3,3], batch_first=True)
[Output] PackedSequence(data=tensor([1, 5, 8, 2, 6, 9, 3, 7, 0, 4, 0]), batch_sizes=tensor([3, 3, 3, 2]))

  pack_padded_sequence函数接收一个padded_sequence数据;根据batch_first参数明确该数据的布局(默认为batch_first=False);根据lengths参数明确batch内各样本的时间步长,选择数据;将上述数据按照时间维度进行压缩,得到目标的PackedSequence类型数据。

  pad_packed_sequence函数即为pack_padded_sequence的逆操作,其在参数设定时也通过batch_first控制返回值的维度顺序,同时可通过设置total_lengths来控制pad后的总步长(该值必须不小于输入PackedSequence数据的步长数):

[Input] pad_packed_sequence(pack_sequence(sequences),total_length=5,batch_first=True)
[Output] (tensor([[1, 2, 3, 4, 0],
         [5, 6, 7, 0, 0],
         [8, 9, 0, 0, 0]]), tensor([4, 3, 2]))

0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码