本文首發於我的博客,知乎排版可能有問題,建議直接看我的博客
起因
事情的起因是這樣的,我已經用tensorflow實現了一個帶attention的encoder-decoder(都是單層的RNN)的結構,代碼組織結構如下所示
encoder_cell = tf.nn.rnn_cell.LSTMCell(num_units=rnn_size)
decoder_cell = tf.nn.rnn_cell.LSTMCell(num_units=rnn_size)
def Encoder(cell, inputs):
根據輸入得到輸出
......
return outputs
# shape: (batch_size, max_seq_len, rnn_size)
encoder_outputs = Encoder(encoder_cell, inputs)
# 下面是attention
attn_mech = tf.contrib.seq2seq.LuongAttention(...)
decoder_cell = tf.contrib.seq2seq.AttentionWrapper(decoder_cell, attn_mech, attention_layer_size=attn_size,...)
# 下面的就不重要了
......
上面這段代碼在attn_size為任何值的時候都是可以正常執行的。這也很符合預期,因為上面這段代碼所乾的事情如下:
- 用encoder將input編碼成encoder_output(即attention的keys或者memory);
- 對於decode的每一個時刻t,將t-1時刻得到的attention context(shape[-1]為attn_size)和decoder的輸入合併在一起輸入到decoder;
......
可以看到attn_size確實是任何值都可以, 也即decoder的輸入維度(attn_size + input_x_size)為任何都可以。
注意TensorFlow中的RNN cell不需要顯式指定輸入的維度(而是自己推斷出來),這和pytorch不一樣:pytorch_rnn = torch.nn.LSTM(input_size = attn_size + input_x_size, hidden_size=rnn_size)
經過
後來我又想將decoder改成多層的RNN,decoder結構就像下面右邊這樣: