# NLP中各框架对变长序列的处理全解

PyTorch

def pack_padded_sequence(input, lengths, batch_first=False, enforce_sorted=True):
...
if enforce_sorted:
sorted_indices = None
else:
lengths, sorted_indices = torch.sort(lengths, descending=True)
sorted_indices = sorted_indices.to(input.device)
batch_dim = 0 if batch_first else 1
input = input.index_select(batch_dim, sorted_indices)
...


# input_tensor shape：batch_size=2,time_step=3,dim=1
input_tensor = torch.FloatTensor([[4, 0, 0], [5, 6, 0]]).resize_(2, 3, 1)
seq_lens = torch.IntTensor([1, 2])
x_packed = nn_utils.rnn.pack_padded_sequence(input_tensor, seq_lens, batch_first=True, enforce_sorted=False)


PackedSequence(data=tensor([[5.],
[4.],
[6.]]), batch_sizes=tensor([2, 1]), sorted_indices=tensor([1, 0]), unsorted_indices=tensor([1, 0]))


[[5, 6, 0],
[4, 0, 0]]


PackedSequence 中的 data 是按照 time_step 这个维度，也就是按列来记录数据的，但是不包括 padding 位

https://www.cnblogs.com/lindaxin/p/8052043.html

batch_sizes 记录的每列有几个数据是有效的，也就是每列有效的 batch_size 长度，但是不包括为 0 的长度，因此上面例子中，x_packed 的 batch_sizes=tensor([2, 1])，因此，每个 time_step 只需要传入对应 batch_size 个数据即可，可以减少计算量。

def pad_packed_sequence(sequence, batch_first=False, padding_value=0.0, total_length=None):
max_seq_length = sequence.batch_sizes.size(0)
if total_length is not None:
max_seq_length = total_length
...


1.3 使用方式

class MaskedLSTM(Module):
def __init__(self, input_size, hidden_size, num_layers=1, bias=True, batch_first=False, dropout=0., bidirectional=False):
self.batch_first = batch_first
self.lstm = LSTM(input_size, hidden_size, num_layers=num_layers, bias=bias,
batch_first=batch_first, dropout=dropout, bidirectional=bidirectional)

def forward(self, input_tensor, seq_lens):
# input_tensor shape: batch_size*time_step*dim , seq_lens: (batch_size,)  when batch_first = True
total_length = input_tensor.size(1) if self.batch_first else input_tensor.size(0)
x_packed = pack_padded_sequence(input_tensor, seq_lens, batch_first=self.batch_first, enforce_sorted=False)
y_lstm, hidden = self.lstm(x_packed)


Keras

Masking(mask_value=0.,input_shape=(time_step,feature_size))


# Embedding 层中的mask计算函数
return None


2.1 使用方式

input = keras.layers.Input((time_step,feature_size))
model = Model(input, lstm_output)


input = keras.layers.Input((time_step,))
lstm_output = keras.layers.LSTM(hidden_size, return_sequences=True)(emd)
model = Model(input, lstm_output)


TensorFlow

https://www.zhihu.com/question/52200883

3.1 使用方式

# 静态图定义部分
basic_cell = tf.nn.rnn_cell.LSTMCell(hidden_size)
X = tf.placeholder(tf.float32, shape=[None, time_step, dim])
seq_length = tf.placeholder(tf.int32, [None])
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32, sequence_length=seq_length)


#### 参考文献

[1]https://blog.csdn.net/u012526436/article/details/98206560

# 投 稿 通 道 #

#### 让你的论文被更多人看到

PaperWeekly 鼓励高校实验室或个人，在我们的平台上分享各类优质内容，可以是 最新论文解读 ，也可以是 学习心得技术干货 。我们的目的只有一个，让知识真正流动起来。

:memo:  来稿标准：

• 稿件确系个人 原创作品 ，来稿需注明作者个人信息（姓名+学校/工作单位+学历/职位+研究方向）

• 如果文章并非首发，请在投稿时提醒并附上所有已发布链接

• PaperWeekly 默认每篇文章都是首发，均会添加“原创”标志

:mailbox_with_mail:  投稿邮箱：

• 投稿邮箱： hr@paperweekly.site

• 所有文章配图，请单独在附件中发送

• 请留下即时联系方式（微信或手机），以便我们在编辑发布时和作者沟通

:mag:

PaperWeekly 是一个推荐、解读、讨论、报道人工智能前沿论文成果的学术平台。如果你研究或从事 AI 领域，欢迎在公众号后台点击 「交流群」 ，小助手将把你带入 PaperWeekly 的交流群里。