Keras 模型中使用预训练的 gensim 词向量和可视化

2021-04-01 11:53:00 浏览数 (1)

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
代码语言:javascript复制
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.

代码语言:javascript复制
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.

0 人点赞