2018-summer-DL-training-program / Lab-2-Image-Captioning

Image Captioning
1 stars 1 forks source link

lstm 動態輸入長度處理方式 #9

Open favrei opened 6 years ago

favrei commented 6 years ago

Hello 同學還有助教們,

由於 caption 的長度有長有短,我在推資料進 lstm cell 的時候會遇到長度不定的問題。

用下面的例子解釋比較簡單: input = [ [f1, 'this', 'homework', 'is', 'soooo', 'hard',], [f2, 'help', 'needed', PAD, PAD, PAD], ]

input 是一個 2 6 emb_size 的 tensor, 先做 pack 以後,將它依序餵進 lstm 這段我可以理解。 所以它一開始是這樣: lstm( [f1, f2] ) lstm( ['this', 'help'] ) lstm( ['homework', 'needed'] )

接下來問題來了,我是直接將 pad 餵給 lstm 嗎? lstm( ['is', PAD])

還是說我需要依每一個 seq 該有的長度做裁剪?

a514514772 commented 6 years ago

Hi @killer9619 ,

告訴 pack_padded_sequence 你每句captions的length有多長,他會幫你處理。

unpack後你會得到一個資料的tensor與batch size list,以你的例子解釋:

data, batch_size = packed_seq data = [f1, f2, 'this', 'help', 'homework', 'needed', 'is', 'soooo', 'hard'] batch_size = [2, 2, 2, 1, 1, 1]

然後for loop,搞定。

Hope it becomes much easier. :(

TA

favrei commented 6 years ago

所以是這樣做嗎? lstm(f1) lstm(f2) lstm('this') ... lstm('hard') 可是這樣 lstm 怎麼會知道時間點(seq)已經切換了呢?

favrei commented 6 years ago

@a514514772 , 再麻煩救我一下~

a514514772 commented 6 years ago

@killer9619 ,

EDIT: 抱歉,我剛人在外面用手機回,我把他改得完整一點

一次forwarding就要全部做完lstm(all input) 在forwarding function裡面做For loop,每個iteration就是一個timestep

lstm實作的時候其實不在乎你是第幾個timestep, 只管hidden state

a514514772 commented 6 years ago

@killer9619 ,

補充一下,在一次forwarding裡面你需要maintain的是 (batch_size, hidden_size) 這麼大的hidden_state跟cell_state。timestep 0的時候你就用h0, c0 (可能沒有初始值,你需要自己初始化,可以全部是0),算出h1, c1;接著在timestep 1的時候以h1, c1算出h2, c2以此類推。

favrei commented 6 years ago

@a514514772 , 我稍作整理一下。

這樣的 h 長度會隨著 t 增長而縮小,因為它得配合 x 的長度。 剛好配上它後面的 pad_packed_sequence ,所以展開來以後又可以變回維度為 [ batch_size, max_batch_len, hidden_size] 。 請問上面的說法是正確的嗎?

a514514772 commented 6 years ago

@killer9619 ,

這樣的 h 長度會隨著 t 增長而縮小,因為它得配合 x 的長度。

這個是對的。

剛好配上它後面的 pad_packed_sequence ,所以展開來以後又可以變回維度為 [ batch_size, max_batch_len, hidden_size] 。

不太正確。舉個完整一點的例子:input 包含padding的shape: [batch size, max_len, embed_size],透過pad_packed_sequence後,再unpack,padding的字元會被去除,input shape變成: [batch_size*max_len-total_num_padding_words, hidden_size]

接著根據unpack時給你的每個timestep的batch size,算完forwarding後,你會把每個timestep的output (hidden_state)存起來,所以最後你的output size應該是 [batch_size*max_len-total_num_padding_words, hidden_state_size]

favrei commented 6 years ago

這樣搞可以動了,感謝回答。