參考:Word2Vec Tutorial - The Skip-Gram Model
參考:Word2Vec Tutorial Part 2 - Negative Sampling
參考:通俗理解word2vec
參考:一文搞懂word embeddding和keras中的embedding
參考:Docs » Layers » 嵌入層 Embedding
參考:詞嵌入 —— 簡書
詞嵌入(Word Embedding)是一種將文本中的詞轉換成數字向量的方法,為了使用標准機器學習算法來對它們進行分析,就需要把這些被轉換成數字的向量以數字形式作為輸入。詞嵌入過程就是把一個維數為所有詞數量的高維空間嵌入到一個維數低得多的連續向量空間中,每個單詞或詞組被映射為實數域上的向量,詞嵌入的結果就生成了詞向量。
One-hot編碼
One-hot編碼(被稱為獨熱碼或獨熱編碼)的詞向量。One-hot編碼是最基本的向量方法。One-hot編碼通過詞匯大小的向量表示文本中的詞,其中只有對應於該詞的項是1而所有其他的項都是0。
One-hot編碼的主要問題是不能表示詞之間的相似性。在任何給定的語料庫中,我們會期望諸如(貓、狗)之類的詞具有一些相似性,使用點積計算向量之間的相似性。點積是向量元素乘法的總和。在One-hot編碼中,語料庫中任何兩個詞之間的點積總是為0。
使用神經網絡學習詞嵌入
一旦數據是(輸入,輸出)格式,我們就可以使用神經網絡來學習詞嵌入。首先,讓我們確定學習詞嵌入所需的變量。為了存儲詞嵌入,我們需要一個
V*D 矩陣,其中
V 是詞匯量大小,
D 是詞嵌入的維度(即向量中表示單個單詞的元素數量)。
D 是用戶定義的超參數,
D 越大,學習到的詞嵌入表達力越強。該矩陣將稱為嵌入空間或嵌入層。輸入數據和輸出數據為維度為
V 的one-hot編碼向量。
接下來,我們有一個softmax層,其權重大小為 D*V,偏置大小為 V。
每個詞將被表示為大小為
V 的獨熱編碼向量,其中一個元素為1,所有其他元素為0。因此,輸入單詞和相應的輸出單詞各自的大小為
V,讓我們把第 $i$ 個輸入記為 $x_i$,$x_i$ 的對應嵌入記為 $z_i$ (向量維度為
D ),對應的輸出為 $y_i$。
此時,我們定義了所需的變量。接下來,對於每個輸入 $x_i$,我們將從對應於輸入的嵌入層中找到嵌入向量。該操作為我們提供 $z_i$(輸入向量為 1 的位置與權重矩陣相乘獲得的
D 維向量就是 $z_i$,隱藏層的節點),然后,我們做提下轉換以計算 $x_i$ 的預測輸出
$$\begin{ali
這里,$logit(x_i)$ 表示非標准化分數(即logits),$\hat y_i$ 是
V 大小的預測輸出(表示輸出是
V 大小的詞匯表的單詞的概率)。
W 是
D*V 權重矩陣,
b 是
V1 偏置矢量,softmax 是 softmax 激活。我們將可視化 skip-gram 模型的概念
- V 是詞匯量大小
- D 是嵌入層的維度
表示定 i 個輸入單詞,表示獨熱編碼向量
是與第 i 個輸入單詞對應的嵌入向量
是與
對應輸出單詞的獨熱編碼向量
表示
的預測輸出
輸入
的非標准化得分
- W 是 softmax 權重矩陣
- b 是 softmax 的偏置
Embedding 層是權重矩陣,相當於 (sequence_length, embedding_dimensionality),單詞個數,向量維度
權重矩陣,Embedding 層可以理解為一個字典,將整數索引(表示特定單詞)映射為密集向量。它接收整數作為輸入,並在內部字典中查找這些整數,然后返回相關聯的向量。Embedding 層實際上是一種字典查找。
keras.layers.Embedding(input_dim, output_dim, ... , input_length=None)
- input_dim: 這是文本數據中詞匯的大小(下圖中的10000)。對應最左邊的長度。例如,如果你的數據是整數編碼為0-10之間的值,則詞表的大小將為11個字。
- output_dim: 這是嵌入單詞的向量空間的大小(下圖中的300)。它為每個單詞定義了該層的輸出向量的大小。例如,它可以是32或100甚至更大。根據問題來定。
- input_length: 這是輸入序列的長度,正如你為Keras模型的任何輸入層定義的那樣。例如,如果你的所有輸入文檔包含1000個單詞,則為1000。(相當於文本的長度,或者截取多少字,例如tweets數據,可以截取前20個單詞,就是input_length=20)
- 輸入尺寸
尺寸為 (batch_size, sequence_length) 的 2D 張量。 - 輸出尺寸
尺寸為 (batch_size, sequence_length, output_dim) 的 3D 張量。 - batch_size: 樣本數,例如,100個tweets
- sequence_length: 每個樣本的長度,例如,每個tweet選擇20個單詞
- output_dim: 每個單詞的向量長度,例如,每個單詞的向量長度為1000
model = Sequential() model.add(Embedding(1000, 64, input_length=10)) # 模型將輸入一個大小為 (batch, input_length) 的整數矩陣。 # 輸入中最大的整數(即詞索引)不應該大於 999 (詞匯表大小) # 現在 model.output_shape == (None, 10, 64),其中 None 是 batch 的維度。 input_array = np.random.randint(1000, size=(32, 10)) model.compile('rmsprop', 'mse') output_array = model.predict(input_array) assert output_array.shape == (32, 10, 64)
參考:preprocessing/sequence/pad_sequences(將文本剪切或者填補成相同的長度,從后面截取)
from keras.layers import Embedding from keras.datasets import imdb from keras import preprocessing maxlen = 50 (x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features) #截取或者填充成20的長度 x_train = preprocessing.sequence.pad_sequences(x_train, maxlen=maxlen) x_test = preprocessing.sequence.pad_sequences(x_test, maxlen=maxlen) from keras.models import Sequential from keras.layers import Flatten, Dense, Embedding model = Sequential() #單詞為10000維 #單詞向量為8維 #文本長度為20 #輸出為 (samples, 20, 8) model.add(Embedding(10000, 8, input_length=maxlen)) #Flatten后變為 (samples, 20 * 8) #每個樣本都是一個 1維 向量 model.add(Flatten()) #Fully connected NN model.add(Dense(1, activation='sigmoid')) model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc']) model.summary() history = model.fit(x_train, y_train, epochs=10, batch_size=32, validation_split=0.2)
output
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= embedding_5 (Embedding) (None, 50, 8) 80000 _________________________________________________________________ flatten_4 (Flatten) (None, 400) 0 _________________________________________________________________ dense_4 (Dense) (None, 1) 401 ================================================================= Total params: 80,401 Trainable params: 80,401 Non-trainable params: 0 _________________________________________________________________ Train on 20000 samples, validate on 5000 samples Epoch 1/10 20000/20000 [==============================] - 2s 92us/step - loss: 0.6485 - acc: 0.6508 - val_loss: 0.5449 - val_acc: 0.7606 Epoch 2/10 20000/20000 [==============================] - 1s 61us/step - loss: 0.4492 - acc: 0.8058 - val_loss: 0.4284 - val_acc: 0.7992 Epoch 3/10 20000/20000 [==============================] - 1s 68us/step - loss: 0.3646 - acc: 0.8417 - val_loss: 0.4027 - val_acc: 0.8084 Epoch 4/10 20000/20000 [==============================] - 1s 62us/step - loss: 0.3277 - acc: 0.8588 - val_loss: 0.3973 - val_acc: 0.8156 Epoch 5/10 20000/20000 [==============================] - 1s 61us/step - loss: 0.3029 - acc: 0.8720 - val_loss: 0.3973 - val_acc: 0.8162 Epoch 6/10 20000/20000 [==============================] - 1s 62us/step - loss: 0.2831 - acc: 0.8833 - val_loss: 0.4014 - val_acc: 0.8188 Epoch 7/10 20000/20000 [==============================] - 1s 64us/step - loss: 0.2655 - acc: 0.8913 - val_loss: 0.4054 - val_acc: 0.8186 Epoch 8/10 20000/20000 [==============================] - 1s 63us/step - loss: 0.2483 - acc: 0.8995 - val_loss: 0.4111 - val_acc: 0.8178 Epoch 9/10 20000/20000 [==============================] - 2s 75us/step - loss: 0.2313 - acc: 0.9081 - val_loss: 0.4179 - val_acc: 0.8140 Epoch 10/10 20000/20000 [==============================] - 1s 70us/step - loss: 0.2141 - acc: 0.9170 - val_loss: 0.4270 - val_acc: 0.8104
以上提供了訓練數據
通過神經網絡來訓練數據
最終的文本向量是 300 維的