你本來也不用自己手動進行詞向量更新啊,你搞這么一出最后收斂到0那不是必然的么? @霍華德 老師的答案已經給你推導出來了。
實際上你問的這個問題很簡單——只要把Embedding層本身也當成模型參數的一部分就可以了,一開始不使用外部詞向量,直接隨機初始化一個Embedding層,然后正常讀入訓練數據開始執行訓練就可以了。在訓練的過程中,如果指定Embedding層也是可訓練的參數(pytorch里設置requires_grad=True)的話,那么在訓練的時候Embedding層的參數也會被更新,就像更新LSTM的參數一樣,對損失函數求導,通過BP更新Embedding層的參數,然后就可以實現你說的“同時訓練詞向量”了。
但一般情況下我們不會這么做——即使是不考慮梯度從損失函數出發,穿透LSTM到達Embedding層之后還能剩下多少(LSTM顯然也不可能完全克服梯度消失問題),你這么一搞的話模型的參數總量就相當于你的LSTM的參數總量,加上Embedding層的參數總量。假設詞表長度是10W,詞向量維度是100的話,這種做法就意味著你的模型憑空多出了10W * 100 = 1000W的參數,顯然你那點標注數據根本就喂不飽這么多參數,真這么玩的話直接就過擬合到姥姥家了。
這也就是為什么我們要使用預訓練詞向量——訓練模型同時訓練詞向量,就意味著要使用寶貴的標注數據去填Embedding層這個大窟窿。而預訓練詞向量就完全不一樣了——主流的詞向量訓練方法,比如早年間的word2vec,GloVe,或者近年來的各種Context-aware Embedding,都可以通過自監督(Self-Supervised)方法進行訓練。也就是說,語料的詞與詞間共現關系(word2vec)或者上下文順序(ELMo和BERT等)本身就是給模型的標注信息——這就意味著我們可以輕而易舉地使用大量的無監督文本語料進行詞向量訓練。要知道,互聯網時代,無監督文本語料本身的獲取成本是很低的,基本上只要你往上堆算力堆模型就可以了。通過預訓練詞向量,不僅可以通過大量的文本獲得質量更高的詞向量,還可以在訓練的時候直接把Embedding層當成常數(requires_grad=False),這樣的話需要訓練的參數就只有LSTM本身的參數了,讓寶貴的標注數據可以好鋼用在刀刃上。