在本系列文章中,将向您展示如何利用深度学习技术创建一个自动翻译系统。可以将其视为一个分步骤的教程,帮助您理解并构建一个神经机器翻译系统。 本系列假设您已经熟悉机器学习的概念:模型训练、监督学习、神经网络,以及人工神经元、层和反向传播。
首先,需要加载所需的库:
import warnings
warnings.filterwarnings("ignore")
import tensorflow as tf
import numpy as np
import string
from numpy import array, argmax, random, take
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense, LSTM, Embedding, RepeatVector
from keras.preprocessing.text import Tokenizer
from keras.callbacks import ModelCheckpoint
from keras.preprocessing.sequence import pad_sequences
from keras.models import load_model
from keras import optimizers
使用Keras构建模型非常简单。将从使用Keras提供的Sequential模型开始创建模型。
model = Sequential()
接下来,添加一个长短期记忆(LSTM)层。在Keras的LSTM类中,LSTM单元的大多数参数都有默认值,因此唯一需要明确定义的是输出的维度:为序列到序列递归神经网络(RNN)创建的LSTM单元的数量。 输入向量的大小是原始句子中的单词总数。因为使用的是嵌入,将得到标记化的单词。这意味着单词可以被分割成子标记,增加了输入句子中的单词数量。
为了保持模型大小可管理(从而确保能够在合理的时间内训练它),设置长度为512。添加了两个LSTM层:第一个是编码器,第二个是解码器。
model.add(LSTM(512))
model.add(RepeatVector(LEN_EN))
model.add(LSTM(512))
注意在中间添加了一个RepeatVector。这将是即将添加的注意力机制的一部分。
接下来,向模型添加一个Dense层。这一层接收前一层的所有输出神经元。需要Dense层是因为正在做预测。希望得到与输入的英语句子相对应的俄语句子,该句子具有最大的分数。本质上,Dense层计算每个LSTM单元输出的softmax。
model.add(Dense(LEN_RU, activation='softmax'))
LEN_RU是输出向量的大小(将在后面计算这些参数)。LEN_EN也是如此。
以下是到目前为止模型应该是什么样子:
model = Sequential()
model.add(LSTM(512))
model.add(LSTM(512))
model.add(Dense(LEN_RU, activation='softmax'))
rms = optimizers.RMSprop(lr=0.001)
model.compile(optimizer=rms, loss='sparse_categorical_crossentropy')
使用了一个名为RMSprop的Keras优化器。它优化了用于反向传播的梯度下降技术。
仍然需要添加嵌入层,以及在编码器和解码器之间包含一个注意力层。 嵌入层是用Word2Vec创建的。实际上,这是一个预训练的嵌入层。现在需要生成Word2Vec权重矩阵(层的神经元权重)并用该矩阵填充一个标准的Keras嵌入层。 可以使用gensim包自动获得嵌入层:
from gensim.models import Word2Vec
model_w2v = Word2Vec(common_texts, size=100, window=5, min_count=1, workers=4)
model.add(model_w2v.wv.get_keras_embedding(train_embeddings=False))
可以通过调用model.summary()函数来获得模型的概览:
model.summary()
现在想要添加一个注意力机制。可以从头开始编写,但一个更简单的解决方案是使用现有的Keras模块,例如Keras self-attention。 让导入这个模块:
from keras_self_attention import SeqSelfAttention
model.add(SeqSelfAttention(attention_activation='sigmoid'))
模型现在完成了。
以下是用Keras编写的NN的最终代码:
import warnings
warnings.filterwarnings("ignore")
import numpy as np
import string
from numpy import array, argmax, random, take
import pandas as pd
from keras.models import Sequential
from keras.layers import Dense, LSTM, Embedding, RepeatVector
from keras.preprocessing.text import Tokenizer
from keras.callbacks import ModelCheckpoint
from keras.preprocessing.sequence import pad_sequences
from keras.models import load_model
from keras import optimizers
import matplotlib.pyplot as plt
from keras.utils import plot_model
import pydot
from gensim.models import Word2Vec
from gensim.test.utils import common_texts
from keras_self_attention import SeqSelfAttention
model = Sequential()
model_w2v = Word2Vec(common_texts, size=100, window=5, min_count=1, workers=4)
model.add(model_w2v.wv.get_keras_embedding(train_embeddings=False))
model.add(LSTM(512))
model.add(RepeatVector(8))
model.add(SeqSelfAttention(attention_activation='sigmoid'))
model.add(LSTM(512))
model.add(Dense(LEN_RU, activation='softmax'))
rms = optimizers.RMSprop(lr=0.001)
model.compile(optimizer=rms, loss='sparse_categorical_crossentropy')
plot_model(model, to_file='model_plot4a.png', show_shapes=True, show_layer_names=True)
model.summary()
运行代码后,将得到以下输出:
[root@ids ~]# python3 NMT.py
Using TensorFlow backend.
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding_1 (Embedding) (None, None, 100) 1200
_________________________________________________________________
lstm_1 (LSTM) (None, 512) 1255424
_________________________________________________________________
repeat_vector_1 (RepeatVecto (None, 8, 512) 0
_________________________________________________________________
seq_self_attention_1 (SeqSel (None, 8, 512) 32833
_________________________________________________________________
lstm_2 (LSTM) (None, 512) 2099200
_________________________________________________________________
dense_1 (Dense) (None, 512) 262656
=================================================================
Total params: 3,651,313
Trainable params: 3,650,113
Non-trainable params: 1,200
_________________________________________________________________