在自然语言处理时,会经常涉及到对输入进行Embedding,训练神经网络有两种Embedding方式,一种是直接调用tensorflow自带的Emdedding层,另一种就是自己建立一个Embedding层,加载自己的预训练词向量。
1.预训练词向量哪里来
一般来说由于标注数据和为标注数据的比列差距太大,所以会考虑利用未标注数据训练一个领域的特征词向量。这样可以最大程度的利用语料,训练词向量一般选择google的word2vec工具进行训练。实验结果也表示,使用自己训练的词向量的模型效果要优于模型的训练词向量。
2.如何在模型中加载自己的词向量
一般而言,我们需要将原来的Embedding层去掉,加入我们自己的Embedding层,也就是需要自定义层,下面是一个简单的Embedding层写法,我是基于tensorflow1.x
"""Embedding Layer"""
import tensorflow as tf
from keras.layers import Layer
import pickle
from tensorflow.python.ops import embedding_ops
from tensorflow.python.ops import math_ops
class SelfEmbedding(Layer):
"""EMBEDDING"""
def __init__(self, dim, **kwargs):
self.mask_zero = False
self.supports_masking = self.mask_zero
self.dim = dim
super(SelfEmbedding, self).__init__(**kwargs)
def build(self, input_shape):
"""bulid"""
self.kernel = self.add_weight(name='weight', shape=(2, self.dim), initializer='glorot_uniform')
with open('vocab_vec_tk.pkl', 'rb') as fr:
self.embeddings = pickle.load(fr)
self.embeddings = tf.convert_to_tensor(self.embeddings, dtype=tf.float32)
self.embeddings = tf.concat((self.kernel, self.embeddings), axis=0)
self.built = True
def call(self, inputs, **kwargs):
"""call"""
out = embedding_ops.embedding_lookup(self.embeddings, inputs)
return out
def compute_mask(self, inputs, mask=None):
"""is mask"""
if not self.mask_zero:
return None
return math_ops.not_equal(inputs, 0)
def compute_output_shape(self, input_shape):
""":return shape"""
output_shape = (input_shape[0], input_shape[1], self.dim)
return output_shape
def get_config(self):
"""get_config"""
base_config = super(SelfEmbedding, self).get_config()
base_config['dim'] = self.dim
return base_config
3.SelfEmbedding层详解
首先你需要将你预训练词向量提取出来,按照顺序构建一个np数组,并使用pkl保存。然后在SelfEmdedding层中的bulid函数中初始化你的词向量数据。这里可以看到我在词向量数据之前加了两个变量,这里是因为考虑了pad和unknown两个词向量。