因为专注于NLP的学习与研究,所以经常接触文本数据,文本数据有一个不好的地方是不同的文本的长度不同,而输入到模型中一个Batch的数据要求他们的长度是相同的,这就产生了要给文本加padding,使得一个Batch中所有的文本长度变成相同的,但pad不能参与到训练,这就给广大的炼丹师带来了麻烦,但幸好Pytorch给我们提供了两个函数pack_padded_sequence与pad_packed_sequence让我们很好的解决了这个问题。

import torch
from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence

为了方便演示这两个函数的作用,我们需要一个toydata来演示一下,数据如下:batch_size=3,max_seq_len=7,padding用0表示。

sample = torch.tensor([[1,2,3,4,5,6,7],[1,2,3,4,0,0,0],[1,2,3,4,5,0,0]]).T
sample
tensor([[1, 1, 1],[2, 2, 2],[3, 3, 3],[4, 4, 4],[5, 0, 5],[6, 0, 0],[7, 0, 0]])

我们用一个list来储存三个句子的长度:

lengths = (7,4,5)

pack_padded_sequence
这个函数用通俗的话来说是将pad好了的sequence解开,恢复为原来没有pad的样子。

pack_padded_sequence(inputs, lengths, batch_first=False, enforce_sorted=True)

输入:

inputs (Tensor): pad好了的sequence集,数据的size要求为[T, B, *],其中T表示的是所有句子中最长的句子的长度,B为Batch的大小,要求inputs至少是两维;
lengths (Tensor or list or tuple or …): 储存了每个句子没有pad之前的长度的集合
batch_first: 如果是True的话,就把B放在T前
enforce_sorted: 如果是True的话就说明输入的inputs已经按照句子长度递减排好了,False的话就要在函数里排。

pack_sample = pack_padded_sequence(sample, lengths, enforce_sorted=False)
print(f"pack_sample.data = {pack_sample.data}")
print(f"pack_sample.batch_sizes = {pack_sample.batch_sizes}")
print(f"pack_sample.sorted_indices = {pack_sample.sorted_indices}")
print(f"pack_sample.unsorted_indices = {pack_sample.unsorted_indices}")
pack_sample.data = tensor([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 6, 7])
pack_sample.batch_sizes = tensor([3, 3, 3, 3, 2, 1, 1])
pack_sample.sorted_indices = tensor([0, 2, 1])
pack_sample.unsorted_indices = tensor([0, 2, 1])

我们可以直接把pack_sample输入到RNN中进行运算了。

pad_packed_sequence
这个函数就是上一个函数的逆过程。


pad_pack_sample, lengths = pad_packed_sequence(pack_sample)
pad_pack_sample
tensor([[1, 1, 1],[2, 2, 2],[3, 3, 3],[4, 4, 4],[5, 0, 5],[6, 0, 0],[7, 0, 0]])

lengths

tensor([7, 4, 5])

再来一个例子
1、准备例子数据

import torchbatch_size = 3   # 这个batch有3个序列
max_len = 6       # 最长序列的长度是6
embedding_size = 8 # 嵌入向量大小8
hidden_size = 16   # 隐藏向量大小16
vocab_size = 20    # 词汇表大小20input_seq = [[3, 5, 12, 7, 2, ], [4, 11, 14, ], [18, 7, 3, 8, 5, 4]]
lengths = [5, 3, 6]   # batch中每个seq的有效长度。
# embedding
embedding = torch.nn.Embedding(vocab_size, embedding_size, padding_idx=0)
# GRU的RNN循环神经网络
gru = torch.nn.GRU(embedding_size, hidden_size)
2、排序数据```python
'由大到小排序'
input_seq = sorted(input_seq, key = lambda tp: len(tp), reverse=True)
lengths = sorted(lengths, key = lambda tp: tp, reverse=True)
'''
outputs:
input_seq: [[18, 7, 3, 8, 5, 4], [3, 5, 12, 7, 2], [4, 11, 14]]
lengths : [6, 5, 3]
'''

3、填充数据

PAD_token = 0 # 填充下标是0
def pad_seq(seq, seq_len, max_length):seq = seqseq += [PAD_token for _ in range(max_length - seq_len)]return seqpad_seqs = []  # 填充后的数据
for i,j in zip(input_seq, lengths):pad_seqs.append(pad_seq(i, len_i, max_len))
'''
填充后数据
pad_seqs : [[18, 7, 3, 8, 5, 4], [3, 5, 12, 7, 2, 0, 0], [4, 11, 14, 0, 0, 0, 0, 0, 0]]
'''

4、使用pack和pad函数

pad_seqs = torch.tensor(pad_seqs)
embeded = embedding(pad_seqs)# 压缩,设置batch_first为true
pack = torch.nn.utils.rnn.pack_padded_sequence(embeded, lengths, batch_first=True)
'这里如果不写batch_first,你的数据必须是[s,b,e],不然会报错lenghth错误'# 利用gru循环神经网络测试结果
state = None
pade_outputs, _ = gru(pack, state)
# 设置batch_first为true;你可以不设置为true,为false时候只影响结构不影响结果
pade_outputs, others = torch.nn.utils.rnn.pad_packed_sequence(pade_outputs, batch_first=True)# 查看输出的元祖
print(pade_outputs.shape) 'torch.Size([3, 6, 16])'
print(others) 'tensor([6, 5, 3])' 

Pytorch之pack_padded_sequence与pad_packed_sequence函数相关推荐

  1. pack_padded_sequence 和 pad_packed_sequence

    参考: pytorch中如何处理RNN输入变长序列padding pack_padded_sequence 和 pad_packed_sequence 大佬们写的都非常nice啊

  2. gather torch_浅谈Pytorch中的torch.gather函数的含义

    pytorch中的gather函数 pytorch比tensorflow更加编程友好,所以准备用pytorch试着做最近要做的一些实验. 立个flag开始学习pytorch,新开一个分类整理学习pyt ...

  3. python中squeeze函数_详解pytorch中squeeze()和unsqueeze()函数介绍

    squeeze的用法主要就是对数据的维度进行压缩或者解压. 先看torch.squeeze() 这个函数主要对数据的维度进行压缩,去掉维数为1的的维度,比如是一行或者一列这种,一个一行三列(1,3)的 ...

  4. pytorch 中 expand ()函数

    pytorch 中 expand ()函数 expand函数的功能就是 用来扩展张量中某维数据的尺寸,它返回输入张量在某维扩展为更大尺寸后的张量. 例如: x = torch.tensor([1, 2 ...

  5. 通过例子10分钟快速看懂pad_sequence、pack_padded_sequence以及pad_packed_sequence

    前言 import torch import torch.nn as nnfrom torch.nn.utils.rnn import pad_sequence from torch.nn.utils ...

  6. pack_padded_sequence和pad_packed_sequence详解

    先提供一个官网解读 https://pytorch.org/docs/1.0.1/nn.html#torch.nn.utils.rnn.pack_padded_sequence 在使用深度学习特别是L ...

  7. pytorch 1.9.0 backward函数解释以及报错(RuntimeError: grad can be implicitly created only for scalar outputs)

    文章目录 官方文档 简单示例 示例1 示例2(报错(RuntimeError: grad can be implicitly created only for scalar outputs)解决方法) ...

  8. [PyTorch] 深度学习框架PyTorch中的概念和函数

    Pytorch的概念 Pytorch最重要的概念是tensor,意为"张量". Variable是能够构建计算图的 tensor(对 tensor 的封装).借用Variable才 ...

  9. Pytorch中的torch.where函数

    首先我们看一下Pytorch中torch.where函数是怎样定义的: @overload def where(condition: Tensor) -> Union[Tuple[Tensor, ...

  10. opencv和pytorch中的warp操作函数:cv2.warpAffine, torch.nn.functional.grid_sample, cv2.warpPerspective

    关于图像的warp操作是指利用一个旋转缩放矩阵对图像进行操作. 常见的操作有,平移,绕某个点旋转,缩放. opencv中有getRotationMatrix2D,warpAffine, getAffi ...

最新文章

  1. 图神经网络(Graph Neural Networks,GNN)综述
  2. 设置ASP.NET中的TextBox控件不缓存上次输入的信息
  3. CTFshow 信息收集 web12
  4. PXE自动安装FreeBSD
  5. [NewLife.XCode]反向工程(自动建表建库大杀器)
  6. ioslabel阴影,UILabel的内阴影
  7. Unity3D动画面板编辑器状态属性对照表
  8. 爱奇艺回应遭做空;百度 App 部分频道停更;React Native 0.62 发布 | 极客头条
  9. 编译OpenCV:precomp.hpp:60:37: fatal error: dynlink_nvcuvid.h
  10. 冰点文库下载器v3.2.9
  11. 乾颐堂现任明教教主(2014年课程)TCPIP协议详解卷一 第六节课笔记
  12. 丹东dns服务器位置,各省主要DNS服务器对照表
  13. 饺子播放器使用IJKPlayer播放MP4文件
  14. 唐巧访谈: iOS大V的技术进阶之路
  15. HDUOJ 4513 吉哥系列故事——完美队形II
  16. excel ctrl shift+键盘方向键的使用
  17. 认识和选用常用的几种 GPRS 模块
  18. 代理加速 gradle 构建
  19. 网站被劫持 网站被劫持跳转到非法页面的解决办法
  20. python之用scapy分层解析pcap报文(Ethernet帧、IP数据包、TCP数据包、UDP数据包、Raw数据包)

热门文章

  1. 域控服务器导出证书,证书服务器(CA)的备份和还原
  2. php追加append,PHP ArrayObject append()用法及代码示例
  3. 【Processing】使用vscode编辑运行Processing
  4. 【ArcGIS|空间分析】选址分析(为学校选址)
  5. IntelliJ产品C盘瘦身
  6. 西方红玫瑰和辣条先生黑产组织深度分析报告
  7. 解析Linux商业应用现状
  8. Laravel框架中使用 Repository 模式
  9. 二叉树先序递归遍历,中序递归非递归遍历实验
  10. Excel Rate 函数的JavaScript 实现,等额本息计算反推利率