
本篇博客参考:
pytorch之数据:pack_padded_sequence()与pad_packed_sequence()
Pytorch学习笔记05---- pack_padded_sequence和pad_packed_sequence理解
首先,packed是包装好的的意思;padded是填充的意思;pack有包装、压紧的意思;pad有填充的意思。
pack_padded_sequence即压紧封装填充好的句子
pad_packed_sequence即填充被压紧封装好的句子
示意图:
pack_padded_sequence
pad_packed_sequence就是上边的那个过程反过来
pack_padded_sequence#官方函数torch.nn.utils.rnn.pack_padded_sequence(input, lengths, batch_first=False)#↓'返回'return PackedSequence #一个PackedSequence对象功能:将一个填充过的变长序列压紧。返回PackedSequence对象。
参数input:要压缩的数据。当batch_first是False时候,shape的输入格式是[B,S * ],其中B是batch_size,S是seq_len(该batch中最长序列的长度)* 可以是任何维度。如果batch_first是True时候,相应的的数据格式必须是[S,B,* ]。input必须按序列长度的长短排序,长的在前面,短的在后面,第一个时间步的数据必须是最长的数据。lengths:输入数据的每个序列的长度。batch_first:当为True,数据格式必须[B, S, * ],反之,默认是False。pad_packed_sequencetorch.nn.utils.rnn.pad_packed_sequence(sequence, batch_first=False) → tuple#↓'返回'return (sequence_pad , List) # 这个元组包含被填充后的序列 , 和batch中序列的长度列表。功能:上面提到的函数的功能是将一个填充后的变长序列压紧。这个 *** 作和pack_padded_sequence()是相反的。把压紧的序列再填充回来,默认按返回中List最大的数字填充。
参数sequence:将要被填充的batch,是一个PackedSequence对象。batch_first:作用同上pack_padded_sequence的batch_size,但是影响的是输出的数据格式。例子import torchbatch_size = 3 # 这个batch有3个序列max_len = 6 # 最长序列的长度是6embedding_size = 8 # 嵌入向量大小8hIDden_size = 16 # 隐藏向量大小16vocab_size = 20 # 词汇表大小20input_seq = [[3, 5, 12, 7, 2, ], [4, 11, 14, ], [18, 7, 3, 8, 5, 4]]lengths = [5, 3, 6] # batch中每个seq的有效长度。# embeddingembedding = torch.nn.Embedding(vocab_size, embedding_size, padding_IDx=0)# LSTM的RNN循环神经网络lstm = torch.nn.LSTM(embedding_size, hIDden_size)因为pack_padded_sequence中要求input必须按序列长度的长短排序,长的在前面,短的在后面,第一个时间步的数据必须是最长的数据。
所以先对数据进行排序。
zip放在补充
#由大到小排序input_seq = sorted(input_seq, key = lambda tp: len(tp), reverse=True)lengths = sorted(lengths, key = lambda tp: tp, reverse=True)print(input_seq)print(lengths)PAD_token = 0 # 填充下标是0def pad_seq(seq, seq_len, max_length): seq = seq seq += [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, j, max_len))print(pad_seqs)[[18, 7, 3, 8, 5, 4], [3, 5, 12, 7, 2], [4, 11, 14]][6, 5, 3][[18, 7, 3, 8, 5, 4], [3, 5, 12, 7, 2, 0], [4, 11, 14, 0, 0, 0]]pad过后的句子是如下格式
[[18, 7, 3, 8, 5, 4], [3, 5, 12, 7, 2, 0], [4, 11, 14, 0, 0, 0]]即[batch_size,seq_len,* ],所以pack_padded_sequence中的batch_first=True
LSTM的输出维度:
其中如果LSTM是双向则num_directions=2,否则num_directions=1
| 参数 | 维度1 | 维度2 | 维度3 |
|---|---|---|---|
| output | seq_len | batch | num_directions×hIDden_size |
pad_seqs = torch.tensor(pad_seqs)embeded = embedding(pad_seqs)# 压缩,设置batch_first为truepack = torch.nn.utils.rnn.pack_padded_sequence(embeded, lengths, batch_first=True)#这里如果不写batch_first,你的数据必须是[s,b,e],不然会报错lenghth错误# 利用lstm循环神经网络测试结果state = Nonepade_outputs, _ = lstm(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)print(others)torch.Size([3, 6, 16])tensor([6, 5, 3])补充python中zip()函数的用法
import numpy as npa=[1,2,3,4,5]b=(1,2,3,4,5)c=np.arange(5)d="zhang"zz=zip(a,b,c,d)print(List(zz))[(1, 1, 0, 'z'), (2, 2, 1, 'h'), (3, 3, 2, 'a'), (4, 4, 3, 'n'), (5, 5, 4, 'g')] 总结 以上是内存溢出为你收集整理的【python学习笔记】pytorch中的pack_padded_sequence()与pad_packed_sequence()使用全部内容,希望文章能够帮你解决【python学习笔记】pytorch中的pack_padded_sequence()与pad_packed_sequence()使用所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)