参考: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$ 的预测输出$$egin{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 维的