65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 TensorFlow 和 Keras 构建 AI 语言翻译

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2021 年 4 月 16 日

CPOL

4分钟阅读

viewsIcon

12002

downloadIcon

168

在本文中,我们将构建我们的 AI 语言翻译系统。

引言

谷歌翻译的效果非常好,它常常看起来像魔术。但它不是魔术——它是深度学习!

在本系列文章中,我们将向您展示如何使用深度学习来创建一个自动翻译系统。本系列可以被视为一个逐步教程,帮助您理解和构建神经机器翻译。

本系列假定您熟悉机器学习的概念:模型训练、监督学习、神经网络,以及人工神经元、层和反向传播。

上一篇文章中,我们安装了开发自动翻译系统所需的所有工具,并定义了开发流程。 在本文中,我们将继续构建我们的 AI 语言翻译系统。

我们需要编写非常少的代码,因为对于大多数逻辑,我们将使用基于 Keras 的预格式化模板。

如果您想查看我们最终得到的最终代码,可以在这个 Python notebook中找到。

导入库

首先,我们需要加载所需的库

import warnings
warnings.filterwarnings("ignore")
import tensorflow as tf
import numpy as np
import string
from numpy import array, argmax, random, take
#for processing imported data
import pandas as pd
#the RNN routines
from keras.models import Sequential
from keras.layers import Dense, LSTM, Embedding, RepeatVector
#we will need the tokenizer for BERT
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 层添加到我们的模型中。 该层获取前一层的全部输出神经元。 我们需要密集层是因为我们要进行预测。 我们希望获得与输入的英语句子对应的得分最高的俄语句子。 本质上,密集层计算每个 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 Embedding 层。

我们可以使用 gensim 包来自动获取嵌入层

from gensim.models import Word2Vec

然后,我们创建我们的 Word2Vec 嵌入层

model_w2v = Word2Vec(common_texts, size=100, window=5, min_count=1, workers=4)

然后可以按如下方式检索嵌入层

model_w2v.wv.get_keras_embedding(train_embeddings=False)

我们可以调用 model.summary() 函数来获得我们模型的概览

_________________________________________________________________
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
_________________________________________________________________
lstm_2 (LSTM)                (None, 512)               2099200
_________________________________________________________________
dense_1 (Dense)              (None, 512)               262656
=================================================================
Total params: 3,618,480
Trainable params: 3,617,280
Non-trainable params: 1,200
_________________________________________________________________

添加注意力机制

现在我们要添加一个注意力机制。 我们可以从头开始编写它,但更简单的解决方案是使用现有的 Keras 模块,例如 Keras self-attention

让我们导入这个模块

from keras_self_attention import SeqSelfAttention

现在我们将导入的模块添加到两个 LSTM 块之间

model.add(SeqSelfAttention(attention_activation='sigmoid'))

我们的模型现在完成了。

将模型放在一起

这是我们的 NN 的最终代码,用 Keras 编写

import warnings
warnings.filterwarnings("ignore")
import numpy as np
import string
from numpy import array, argmax, random, take
#for processing imported data
import tensorflow as tf
import pandas as pd
#the RNN routines
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
#optional if you want to generate statistical graphs of the DMT
#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

虽然我们的模型代码按原样工作良好,但考虑将模型创建代码包含在一个函数中将使其更易于重用。 你不必须这样做 - 但要了解它可能是什么样子,请参阅我们在notebook中提到的最终翻译器代码。

后续步骤

现在我们的模型已准备就绪。 在下一篇文章中,我们将训练和测试这个模型。 敬请关注!

© . All rights reserved.