將訓練的句子人工分為兩派(數字派,字母派),雖然都是文字,但是期望模型能自動區分出在空間上,數字和字母是有差別的。因為數字總是和數字一同出現, 而字母總是和字母一同出現。臥底數字 9 的任務就是把字母那邊的情報向數字通風報信。 所以期望的樣子就是數字 9 不但靠近數字,而且也靠近字母。
上一節已經介紹了cbow的**,tf2.+的**結構雖然知道哪一步在幹嘛,但具體的內容不清楚。而且網路上單單查詢乙個函式,很難看得懂。如:with tf.gradienttape() as tape:還有class cbow(keras.model):的設計。該**把call函式看成普通的函式呼叫了。loss 的計算和反向傳遞在意義上和cbow不太一樣,不過在**實現上卻是一模一樣的。想要快速入門,應該多看不同的**,而不是乙份**糾結太細節的地方。
在計算loss的時候,為了避免詞彙量大,帶來的softmax計算複雜度高的問題,這個地方像cbow一樣,使用了nce技術,在計算loss和反向傳播的時候只考慮部分的負樣本, 節約計算量。
不足:為了簡化訓練過程,在skip-gram中,x資料只有1個詞,y也只有1個詞。使用同乙個x,對前後n個詞都**一遍。
原本應該是這樣:**類似,最後在給出,先討論更重要的。輸入:莫
輸出:[我,愛] + [煩,python]
對同一批訓練資料,你也可以這樣
輸入:莫 -> 輸出:我
輸入:莫 -> 輸出:愛
輸入:莫 -> 輸出:煩
輸入:莫 -> 輸出:python
經過這樣乙個處理,神經網路的訓練過程就簡單了。**量也少了,容易實現了,何樂而不為。
到此學習到了如何訓練詞向量模型,但它也有不足的地方。
遇到一詞多義這種情況,用skip-gram或者cbow訓練出來的詞向量能否解決這個問題? 答案是不行的,因為它們會針對每乙個詞生成唯一的詞向量,也就是這個詞有且只有一種解釋(向量表達)。
有什麼辦法讓模型表達出詞語的不同含義呢?當然我們還是站在向量的角度,只是這個詞向量的表示如果能考慮到句子上下文的資訊, 那麼這個詞向量就能表達詞語在不同句子中不同的含義了。在後面的elmo模型中,我們會**這一種做法。
不想佔篇幅的,主要是資料集大小變了,也沒有評價標準,執行一下看看效果就好。
只有這個類不一樣,這個類也只有一行不一樣。
class
skipgram
(keras.model)
:def
__init__
(self, v_dim, emb_dim)
:super()
.__init__(
) self.v_dim = v_dim
self.embeddings = keras.layers.embedding(
input_dim=v_dim, output_dim=emb_dim,
# [n_vocab, emb_dim]
embeddings_initializer=keras.initializers.randomnormal(0.
,0.1),
)# noise-contrastive estimation
self.nce_w = self.add_weight(
name=
"nce_w"
, shape=
[v_dim, emb_dim]
, initializer=keras.initializers.truncatednormal(0.
,0.1))
# [n_vocab, emb_dim]
self.nce_b = self.add_weight(
name=
"nce_b"
, shape=
(v_dim,),
initializer=keras.initializers.constant(
0.1)
)# [n_vocab, ]
self.opt = keras.optimizers.adam(
0.01
)def
call
(self, x, training=
none
, mask=
none):
# x.shape = [n, ]
o = self.embeddings(x)
# [n, emb_dim]
return o
# negative sampling: take one positive label and num_sampled negative labels to compute the loss
# in order to reduce the computation of full softmax
defloss
(self, x, y, training=
none):
embedded = self.call(x, training)
return tf.reduce_mean(
tf.nn.nce_loss(
weights=self.nce_w, biases=self.nce_b, labels=tf.expand_dims(y, axis=1)
, inputs=embedded, num_sampled=
5, num_classes=self.v_dim)
)def
step
(self, x, y)
:with tf.gradienttape(
)as tape:
loss = self.loss(x, y,
true
)#training引數沒用
grads = tape.gradient(loss, self.trainable_variables)
zip(grads, self.trainable_variables)
)return loss.numpy(
)
NLP(四)詞向量
關於word2vec的原理網上很詳細了 本文 共2種詞向量轉換方式 1 獨熱編碼 2 word2vec from sklearn.preprocessing import labelencoder one hot labelencoder 輸入為列表好像也可以 word vector one hot...
NLP 如何評估詞向量
目前詞向量的評估一般分為兩大類 extrinsic evaluation和 intrinsic evaluation。即內部評估和外部評估。內部評估直接衡量單詞之間的句法和語義關係。這些任務通常涉及一組預先選擇的查詢術語和語義相關的目標詞彙,我們將其稱為query inventory。當前絕大部分工...
nlp期末複習 詞向量
1 不能體現詞的含義進行編碼 one hot 2 單詞按照含義進行編碼成向量的方式稱為word embedding word embedding word2vec cbow skip gram glove 3 從word embedding到bert模型 無法解決詞的多義問題 缺點 word emb...