深度学习算法(第24期)----自然语言处理中的Word Embedding
上期我们一起学习了RNN的GRU模块,
深度学习算法(第23期)----RNN中的GRU模块
今天我们一起简单学习下自然语言处理中的Word Embedding.
遇到了什么问题?
我们知道,在前面的RNN或者CNN中,我们在训练网络的时候,不管输入还是输出,都是数值型的数据参与数学矩阵就算,然而面对自然语言中的单词,是没办法进行矩阵运算的,那么单词该怎么输入到网络中呢?
怎么解决?
其实Word Embedding就是解决上面的问题的,也就是对单词的转换表述。我们在之前的分类中常用的标签标示方法为one-hot向量,那么这里能不能也用one-hot向量呢?假如我们的词汇有5000个词,那么一个词用one-hot的方法标示的话,将会是一个5000维度的向量,这种稀疏的标示方法效率是及其低下的。
理想情况下,我们希望相似的词有相似的标示方法,这样模型就比较容易从一个词推断出和它相似的词有相同的用法。比如说,如果我们告诉模型“I drink milk”是一个有效的句子,并且如果模型知道“milk”和“water”比较接近,跟“shoes”相差比较远的话,那么模型将知道句子“I drink milk”比“I drink shoes”靠谱的多。
标示词汇中的一个词最常用的方法就是用一个相对小的,稠密(非稀疏)的向量(比如150维),称为一个embedding。那么接下来的任务就是让神经网络对每一个词训练出一个比较好的embedding。在训练的初期,embeddings基本上是随机选择的,但是经过网络的前后传输之后,最终相似的词将会聚类到一起,甚至会以某种更有意义的方式聚集到一起,比如性别,单复数,动名词等等。
在tensorflow中,我们应该首先为词汇中的每一个词创建一个embedding(随机初始化),如下:
vocabulary_size = 50000
embedding_size = 150
embeddings = tf.Variable(
tf.random_uniform([vocabulary_size, embedding_size], -1.0, 1.0))
现在,假如我们想将“I drink milk”输入到网络中,那么我们首先需要对句子做预处理,比如将句子拆分成已知的词,移除不必要的字符,替换未知字符。例如用[unk]代替未知的词,用[num]代替数字,用[url]代替网址等等。一旦我们有了已知单词的列表,那么我们就可以从词汇表中查找到相应单词的整数索引(0~4999),比如说“I drink milk”转换之后为[72, 3335, 288]。
train_inputs = tf.placeholder(tf.int32, shape=[None]) # from ids...
embed = tf.nn.embedding_lookup(embeddings, train_inputs) # ...to embeddings
如上,这个时候,我们就可以用一个placeholder来将这个句子输入到网络中了,并且用函数embedding_lookup()来获取相应的embedding。
一旦我们的模型学到了比较好的embeddings,那么这些embeddings也可以用在其他NLP的应用中,毕竟,“milk”基本上在任何应用中都和“water”相近,而和“shoes”相远。事实上,一般情况下,我们都会去down一个别人训练好的embeddings,而不是自己去重新训练一个。就和之前学的复用训练好的层一样,复用别人训练好的embeddings。
好了,至此,今天我们简单学习了自然语言处理的word embedding的简单知识,希望有些收获,下期我们将一起学习下机器翻译中的编码解码器,欢迎留言或进社区共同交流,喜欢的话,就点个“在看”吧,您也可以置顶公众号,第一时间接收最新内容。