“”"Bi-LSTM Encoder
Args:
input_size: (int) vocab word2vec dim
hidden_size: (int) hidden size in Bi-LSTM
num_layers: (int) num_layers in Bi-LSTM
bi: (boolean) Bi-direction
"""
self.input_size = input_size
self.hidden_size = hidden_size
self.num_layers = num_layers
self.bi = bi
nn.LSTM(self.input_size,
self.hidden_size,
num_layers=self.num_layers,
batch_first=True,
bidirectional=self.bi)
def forward(self, *input):
self.rnn.flatten_parameters()
x_emb, x_len, return_type = input # (batch_size, max_len, word2vec_dim) (batch_size, )
# BiLSTM
total_length = x_len.max()
x_packed = nn.utils.rnn.pack_padded_sequence(x_emb, x_len.cpu(), batch_first=True, enforce_sorted=False)
out_lstm, hidden = self.rnn(x_packed)
out, _ = nn.utils.rnn.pad_packed_sequence(out_lstm, batch_first=True, total_length=total_length)
# vector represent
if return_type == 'mean_pooling':
out = out.sum(dim=1).div(x_len.float().unsqueeze(-1)) # (batch_size, num_directions * hidden_size)
elif return_type == 'all_return': # (batch_size, max_len, num_directions * hidden_size)
pass
return out
在使用pytorch处理数据时,一般是采用batch的形式同时处理多个样本序列,而每个batch中的样本序列是不等长的,导致rnn无法处理。所以,通常的做法是先将每个batch按照最长的序列进行padding处理等长的形式
(通常,将每个batch按照最长的序列进行padding处理等长的方式)
但padding操作会带来一个问题,那就是对于多数进行padding过的序列,会导致rnn对它的表示多了很多无用的字符,我们希望的是在最后一个有用的字符后就可以输出该序列的向量表示,而不是在很多padding字符后。
这时候,pack操作就派上场了,可以理解成,它是将一个经过padding后的变长序列压紧****,压缩后就不含padding的字符0了。具体操作就是:
if return_type == ‘mean_pooling’:
out = out.sum(dim=1).div(x_len.float().unsqueeze(-1)) # (batch_size, num_directions * hidden_size)
elif return_type == ‘all_return’: # (batch_size, max_len, num_directions * hidden_size)
pass
return out
慢慢的自己将其研究透彻,都行啦的回事与打算。
明天自己把双向LSTM也看一看,都行啦,自己将其研究透彻都行啦的回事与打算。
把模型看看,然后自己对比以下代码,经模型经过给其搞透彻。
全部要学会掌握,都行啦的样子与打算。慢慢的自己整理都行啦的回事与打算。