Keras 模型中使用预训练的词向量
Word2vec,为一群用来产生词嵌入的相关模型。这些模型为浅而双层的神经网络,用来训练以重新建构语言学之词文本。网络以词表现,并且需猜测相邻位置的输入词,在word2vec中词袋模型假设下,词的顺序是不重要的。训练完成之后,word2vec模型可用来映射每个词到一个向量,可用来表示词对词之间的关系。该向量为神经网络之隐藏层。 https://zh.wikipedia.org/wiki/Word2vec
在这篇 [在Keras模型中使用预训练的词向量](https://keras-cn.readthedocs.io/en/latest/blog/ word_embedding/) 讲述了如何利用预先训练好的 GloVe 模型,本文基本大同小异。只写一些不同的地方,更想的可以看这篇文章。
总体思路就是给 Embedding
层提供一个 [ word_token : word_vector]
的词典来初始化向量,并且标记为不可训练。
解析 word2vec 模型,其中:
word2idx
保存词语和 token 的对应关系,语料库 tokenize 时候需要。embeddings_matrix
存储所有 word2vec 中所有向量的数组,用于初始化模型Embedding
层
import numpy as np
from gensim.models import Word2Vec
model = Word2Vec.load(model_path)
word2idx = {"_PAD": 0} # 初始化 `[word : token]` 字典,后期 tokenize 语料库就是用该词典。
vocab_list = [(k, model.wv[k]) for k, v in model.wv.vocab.items()]
# 存储所有 word2vec 中所有向量的数组,留意其中多一位,词向量全为 0, 用于 padding
embeddings_matrix = np.zeros((len(model.wv.vocab.items()) 1, model.vector_size))
for i in range(len(vocab_list)):
word = vocab_list[i][0]
word2idx[word] = i 1
embeddings_matrix[i 1] = vocab_list[i][1]
使用方法:
代码语言:javascript复制from keras.layers import Embedding
EMBEDDING_DIM = 100 #词向量维度
embedding_layer = Embedding(len(embeddings_matrix),
EMBEDDING_DIM,
weights=[embeddings_matrix]
trainable=False)
Tensorboard 可视化 Keras 模型
Tensorflow 提供了超级棒的可视化工具 TensorBoard,详细的介绍请看 - TensorBoard: Visualizing Learning
Keras 模型记录训练进度到 Tensorboard 非常方便,直接使用 Keras 封装好的 Tensorboard 回调 即可。
不过这里有个小细节,如果想对比多次运行的效果,一定要每次记录在 log 目录下的不同的子目录。
代码语言:javascript复制logdir = "./logs/{}".format(run_name)
tensorBoard = TensorBoard(log_dir = logdir,
histogram_freq = 1,
write_graph = True,
write_images = False,
embeddings_freq = 1,
embeddings_layer_names = None,
embeddings_metadata = None)
self.model.fit(train_x, train_y,
batch_size = self.batch_size,
epochs = self.epochs,
verbose = 1,
callbacks = [tensorBoard])
然后运行 tensorboard --logdir='./logs/'
即可看到相应的运行记录。就能看到以下的记录:
然而当打开 Embeddings
看词向量可视化效果时候发现所有的节点全部用数字表示的,密密麻麻的数字根本看不懂…
这些数字是我们 tokenize 时候使用的 id,现在利用之前保存的 word2idx
字典来生成该 Embedding 的 metadata.
meta_file = "w2v_metadata.tsv"
# 按照 id 排序
word2idx_sorted = [(k, word2idx[k]) for k in sorted(word2idx, key = word2idx.get, reverse = False)]
# 按照 id 顺序写入文件
logdir = "./logs/{}".format(run_name)
with open(os.path.join(logdir, meta_file), 'w ') as file_metadata:
for word in word2idx_sorted:
if word[0] == '':
print("Emply Line, should replecaed by any thing else, or will cause a bug of tensorboard")
file_metadata.write('<Empty Line>' 'n')
else:
file_metadata.write(word[0] 'n')
tensorBoard = TensorBoard(log_dir = logdir,
histogram_freq = 1,
write_graph = True,
write_images = False,
embeddings_freq = 1,
embeddings_layer_names = None,
embeddings_metadata = meta_file) # 初始化 TensorBoard 时候带上 metadata
再次训练后运行 tensorboard --logdir='./logs/'
,然后可以看到带上中文标签的 Embedding 可视化效果。
直接可视化 word2vec 模型
上面的可视化方法需要在 keras 建模并且训练,如果想直接可视化,可以利用 w2v_visualizer.py 这个脚本,使用方法很简单
代码语言:javascript复制python3 w2v_visualizer.py <模型路径> <输出文件夹路径>
参考
- Vector Representations of Words
- 在Keras模型中使用预训练的词向量
- TensorBoard: Embedding Visualization
- how to convert/port gensim word2vec to tensorflow projector board.