torch.nn包下的Embedding,作為訓練的壹層,隨模型訓練得到適合的詞向量。
實際上,上面通過隨機初始化建立了詞向量層後,建立了壹個“二維表”,存儲了詞典中每個詞的詞向量。每個mini-batch的訓練,都要從詞向量表找到mini-batch對應的單詞的詞向量作為RNN的輸入放進網絡。那麽怎麽把mini-batch中的每個句子的所有單詞的詞向量找出來放進網絡呢, 輸入是什麽樣子,輸出是什麽樣子?
首先我們知道肯定先要建立壹個詞典,建立詞典的時候都會建立壹個dict:word2id:存儲單詞到詞典序號的映射。假設壹個mini-batch如下所示:
顯然,這個mini-batch有3個句子,即batch_size=3
第壹步首先要做的是:將句子標準化,所謂標準化,指的是:大寫轉小寫,標點分離,這部分很簡單就略過。經處理後,mini-batch變為:
可見,這個list的元素成了壹個個list。還要做壹步:將上面的三個list按單詞數從多到少排列。標點也算單詞。至於為什麽,後面會說到。
那就變成了:
可見,每個句子的長度,即每個內層list的元素數為:5,5,4。這個長度也要記錄。
之後,為了能夠處理,將batch的單詞表示轉為在詞典中的index序號,這就是word2id的作用。轉換過程很簡單,假設轉換之後的結果如下所示,當然這些序號是我編的。
同時,每個句子結尾要加EOS,假設EOS在詞典中的index是1。
那麽長度要更新:
很顯然,這個mini-batch中的句子長度不壹致。所以為了規整的處理,對長度不足的句子,進行填充。填充PAD假設序號是2,填充之後為:
這樣就可以直接取詞向量訓練了嗎?
不能。上面batch有3個樣例,RNN的每壹步要輸入每個樣例的壹個單詞,壹次輸入batch_size個樣例,所以batch要按list外層是時間步數(即序列長度),list內層是batch_size排列。即batch的維度應該是:
怎麽變換呢?
變換方法可以是:使用itertools模塊的zip_longest函數。而且,使用這個函數,連填充這壹步都可以省略,因為這個函數可以實現填充。
經變換,結果應該是:
batch還要轉成LongTensor:
這裏的batch就是詞向量層的輸入。
詞向量層的輸出是什麽樣的?
好了,現在使用建立了的embedding直接通過batch取詞向量了,如:
假設詞向量維度是6,結果是:
維度的前兩維和前面講的是壹致的。可見多了壹個第三維,這就是詞向量維度。所以,Embedding層的輸出是: