主要内容

Sequence-to-Sequence翻译使用注意

这个例子展示了如何将十进制的字符串转换成罗马数字使用复发sequence-to-sequence encoder-decoder模型与关注。

复发encoder-decoder模型已被证明成功的任务如摘要式的文本摘要和神经机器翻译。模型包含一个编码器通常处理输入数据层如LSTM复发,和一个吗译码器这地图编码输入所需的输出,通常与第二次复发性层。模型,结合注意机制进入模型允许解码器的重点部分编码输入而产生的翻译。

编码器模型,这个示例使用一个简单的网络组成一个嵌入一个LSTM操作紧随其后。嵌入的方法是分类标记转换成数值向量。

译码器的模型,这个示例使用一个网络,其中包含一个LSTM操作和注意机制。注意机制允许解码器参加编码器输出信号的特定部分。

负荷训练数据

下载decimal-Roman数字配对“romanNumerals.csv”

文件名= fullfile (“romanNumerals.csv”);选择= detectImportOptions(文件名,TextType =“字符串”,ReadVariableNames = false);选项。VariableNames = [“源”“目标”];选项。VariableTypes = [“字符串”“字符串”];data = readtable(文件名,选择);

将数据分为训练集和测试每个分区包含50%的数据。

idx = randperm(大小(数据,1),500);dataTrain =数据(idx:);人数(=数据;人数((idx:) = [];

视图的一些decimal-Roman数字配对。

头(dataTrain)
源目标______ _______“437”“CDXXXVII”“431”“102”“CDXXXI”“人民共和国”“862”“738”“DCCCLXII”“DCCXXXVIII”“527”“401”“DXXVII”“CDI”“184”“CLXXXIV”

数据进行预处理

预处理文本数据使用transformText函数,列出的例子。的transformText函数进行预处理,将输入文本翻译的文本分割到人物和添加启动和停止令牌。文本通过把文本转化为单词而不是字符,跳过第一步。

startToken =“<开始>”;stopToken =“<停止>”;你要= dataTrain.Source;documentsSource = transformText(你要startToken stopToken);

创建一个wordEncoding对象地图标记数字索引使用词汇,反之亦然。

encSource = wordEncoding (documentsSource);

使用这个词编码,源文本数据转换为数字序列。

sequencesSource = doc2sequence (encSource documentsSource PaddingDirection =“没有”);

目标数据转换为使用相同的步骤序列。

strTarget = dataTrain.Target;documentsTarget = transformText (strTarget startToken stopToken);encTarget = wordEncoding (documentsTarget);sequencesTarget = doc2sequence (encTarget documentsTarget PaddingDirection =“没有”);

排序的序列长度。训练序列排序的序列长度增加导致批次和序列大约相同的序列长度,确保小序列批次用于时间序列批次之前更新模型。

sequenceLengths = cellfun(@(序列)大小(序列,2),sequencesSource);[~,idx] = (sequenceLengths)进行排序;sequencesSource = sequencesSource (idx);sequencesTarget = sequencesTarget (idx);

创建arrayDatastore对象包含源和目标数据和结合使用结合函数。

sequencesSourceDs = arrayDatastore (sequencesSource OutputType =“相同”);sequencesTargetDs = arrayDatastore (sequencesTarget OutputType =“相同”);sequencesDs =结合(sequencesSourceDs sequencesTargetDs);

初始化模型参数

初始化模型参数。编码器和解码器,指定一个嵌入维数128人,与100隐藏单位LSTM层,辍学层用随机辍学概率为0.05。

embeddingDimension = 128;numHiddenUnits = 100;辍学= 0.05;

初始化编码器模型参数

初始化权值的编码使用高斯使用嵌入initializeGaussian函数附加到这个例子作为支持文件。万博1manbetx指定一个意味着(0)和标准偏差为0.01。欲了解更多,请看高斯函数初始化(深度学习工具箱)

inputSize = encSource。NumWords + 1;深圳= [embeddingDimension inputSize];μ= 0;σ= 0.01;parameters.encoder.emb。重量= initializeGaussian (sz、μ、σ);

初始化可学的参数编码器LSTM操作:

  • 初始化输入权重Glorot初始化器使用initializeGlorot函数附加到这个例子作为支持文件。万博1manbetx欲了解更多,请看Glorot初始化(深度学习工具箱)

  • 初始化的权重与正交初始化器使用initializeOrthogonal函数附加到这个例子作为支持文件。万博1manbetx欲了解更多,请看正交初始化(深度学习工具箱)

  • 初始化倾向与单位大门忘记初始化使用initializeUnitForgetGate函数附加到这个例子作为支持文件。万博1manbetx欲了解更多,请看单位大门忘记初始化(深度学习工具箱)

初始化可学的参数编码器LSTM操作。

深圳= [4 * numHiddenUnits embeddingDimension];numOut = 4 * numHiddenUnits;numIn = embeddingDimension;parameters.encoder.lstm。InputWeights = initializeGlorot(深圳、numOut numIn);parameters.encoder.lstm。RecurrentWeights = initializeOrthogonal ([4 * numHiddenUnits numHiddenUnits]);parameters.encoder.lstm。偏见= initializeUnitForgetGate (numHiddenUnits);

译码器模型参数进行初始化

初始化权值的编码使用高斯使用嵌入initializeGaussian函数。指定一个意味着(0)和标准偏差为0.01。

outputSize = encTarget。NumWords + 1;深圳= [embeddingDimension outputSize];μ= 0;σ= 0.01;parameters.decoder.emb.Weights = initializeGaussian (sz、μ、σ);

初始化权重的注意机制使用Glorot初始化器使用initializeGlorot函数。

深圳= [numHiddenUnits numHiddenUnits];numOut = numHiddenUnits;numIn = numHiddenUnits;parameters.decoder.attention.Weights = initializeGlorot(深圳、numOut numIn);

初始化可学的参数解码器LSTM操作:

  • 初始化输入权重Glorot初始化器使用initializeGlorot函数。

  • 初始化的权重与正交初始化器使用initializeOrthogonal函数。

  • 初始化倾向与单位大门忘记初始化使用initializeUnitForgetGate函数。

初始化可学的解码器LSTM操作的参数。

深圳= [4 * numHiddenUnits embeddingDimension + numHiddenUnits];numOut = 4 * numHiddenUnits;numIn = embeddingDimension + numHiddenUnits;parameters.decoder.lstm.InputWeights = initializeGlorot(深圳、numOut numIn);parameters.decoder.lstm.RecurrentWeights = initializeOrthogonal ([4 * numHiddenUnits numHiddenUnits]);parameters.decoder.lstm.Bias = initializeUnitForgetGate (numHiddenUnits);

初始化可学的译码器的参数完全连接操作:

  • 初始化权重Glorot初始值设定项。

  • 使用零使用初始化偏差initializeZeros函数附加到这个例子作为支持文件。万博1manbetx欲了解更多,请看零初始化(深度学习工具箱)

深圳= [outputSize 2 * numHiddenUnits];numOut = outputSize;numIn = 2 * numHiddenUnits;parameters.decoder.fc.Weights = initializeGlorot(深圳、numOut numIn);parameters.decoder.fc.Bias = initializeZeros ([outputSize 1]);

定义模型函数

创建函数modelEncodermodelDecoder上市的例子,计算编码器和译码器的输出模型,分别。

modelEncoder函数,列出的编码器模型函数部分的示例中,需要输入数据,模型参数,可选的面具,确定正确的输出用于培训和返回模型输出和LSTM隐藏状态。

modelDecoder函数,列出的译码器模型函数部分的示例中,需要输入数据,模型参数,上下文向量,LSTM最初的隐藏状态,编码器的输出,以及辍学概率和输出译码器的输出,更新的上下文向量,LSTM更新状态,注重分数。

定义模型损失函数

创建函数modelLoss中列出,损失函数模型部分的示例中,这需要编码器和译码器模型参数,mini-batch输入数据和填充面具对应于输入数据,辍学并返回损失概率和损失的梯度模型中的可学的参数。

指定培训选项

列车与mini-batch大小为32 100时代学习速率为0.001。

miniBatchSize = 32;numEpochs = 100;learnRate = 0.001;

初始化选项从亚当。

gradientDecayFactor = 0.9;squaredGradientDecayFactor = 0.999;

火车模型

火车模型使用自定义训练循环。使用minibatchqueue在培训过程和管理mini-batches图像。为每个mini-batch:

  • 使用自定义mini-batch预处理功能preprocessMiniBatch(在这个例子中定义)找到mini-batch中所有序列的长度和垫一样的序列长度最长的序列,分别为源和目标序列。

  • 排列第二和第三维度的填充序列。

  • 无格式返回mini-batch变量dlarray与底层数据对象类型。所有其他的输出是数据类型的数组

  • 火车在GPU如果一个是可用的。返回所有mini-batch变量在GPU上如果有一个可用。使用GPU需要并行计算工具箱™和支持GPU设备。万博1manbetx支持设备的信息,请参阅GPU的支持。万博1manbetx

minibatchqueue对象返回四个输出参数为每个mini-batch:源序列,目标序列,mini-batch所有源序列的长度,和序列目标序列的面具。

numMiniBatchOutputs = 4;兆贝可= minibatchqueue (sequencesDs numMiniBatchOutputs,MiniBatchSize = MiniBatchSize,MiniBatchFcn = @ (x, t) preprocessMiniBatch (x, t, inputSize outputSize));

初始化的值adamupdate函数。

trailingAvg = [];trailingAvgSq = [];

计算迭代的总数的培训进度监控

numObservationsTrain =元素个数(sequencesSource);numIterationsPerEpoch =装天花板(numObservationsTrain / miniBatchSize);numIterations = numEpochs * numIterationsPerEpoch;

初始化培训进度监控。因为计时器开始创建监视器对象时,确保你创建对象接近的训练循环。

监控= trainingProgressMonitor (指标=“损失”,信息=“时代”,包含=“迭代”);

火车模型。为每个mini-batch:

  • 读了mini-batch填充序列。

  • 计算损失和梯度。

  • 更新编码器和解码器使用的模型参数adamupdate函数。

  • 更新培训进度监控。

  • 停止训练时停止房地产培训进度监控的真正的。的停止训练监控更改的属性1当你点击停止按钮。

时代= 0;迭代= 0;%循环时期。时代< numEpochs & & ~班长。停止时代=时代+ 1;重置(兆贝可);%在mini-batches循环。hasdata(兆贝可)& & ~班长。停止iteration = iteration + 1; [X,T,sequenceLengthsSource,maskSequenceTarget] = next(mbq);%计算损失和梯度。(损失,梯度)= dlfeval (@modelLoss、参数X, T, sequenceLengthsSource,maskSequenceTarget,辍学);%更新使用adamupdate参数。(参数、trailingAvg trailingAvgSq) = adamupdate(参数、渐变trailingAvg trailingAvgSq,迭代,learnRate、gradientDecayFactor squaredGradientDecayFactor);%正常化损失序列长度。损失=损失。/大小(T, 3);%更新培训进度监控。recordMetrics(监控、迭代损失=损失);updateInfo(监视、时代=时代+“的”+ numEpochs);班长。进步= 100 *迭代/ numIterations;结束结束

生成翻译

为新数据生成翻译使用训练模型,将文本数据转换为数字序列训练时使用相同的步骤和输入序列到encoder-decoder模型和转换生成的序列使用令牌回文本索引。

预处理文本数据训练时使用相同的步骤。使用transformText函数,列出的示例中,将文本分为字符并添加开始和结束标记。

你要= dataTest.Source;strTarget = dataTest.Target;

翻译文本使用modelPredictions函数。

maxSequenceLength = 10;分隔符=”“;strTranslated = translateText(参数、你要maxSequenceLength miniBatchSize,encSource、encTarget startToken stopToken,分隔符);

创建一个表包含测试源文本,目标文本和翻译。

台=表;资源描述。源=你要;资源描述。目标= strTarget;资源描述。翻译= strTranslated;

查看随机选择的翻译。

idx = randperm(规模(人数(1)miniBatchSize);台(idx:)
ans =32×3表源目标翻译______ ___________ _______“996”“CMXCVI”“CMMXCVI”“576”“DLXXVI”“DCLXXVI”“86”“LXXXVI”“DCCCLXV”“23”“二十三”“CCCCXIII”“99”“XCIX”“CMMXIX”“478”“CDLXXVIII”“DCCCLXXVII”“313”“CCCXIII”“CCCXIII”“60”“LX”“DLX”“864”“DCCCLXIV”“DCCCLIV”“280”“CCLXXX”“CCCCLX”“792”“DCCXCII”“DCCCIII”“959”“CMLIX”“CMLXI”“283”“CCLXXXIII”“CCCCLXXIII”“356”“CCCLVI”“CCCCVI”“534”“DXXXIV”“DCCXXIV”“721”“DCCXXI”“DCCCII⋮”

文本转换功能

transformText函数进行预处理,将输入文本翻译的文本分割到人物和添加启动和停止令牌。文本通过把文本转化为单词而不是字符,跳过第一步。

函数文件= transformText (str, startToken stopToken) str =地带(替换(str,”“,”“));str = startToken + str + stopToken;文件= tokenizedDocument (str, CustomTokens = [startToken stopToken]);结束

Mini-Batch预处理功能

preprocessMiniBatch函数,火车模型部分中描述的示例中,预处理数据进行训练。使用以下步骤:预处理数据功能

  1. 确定所有的长度在mini-batch源和目标序列

  2. 垫的序列长度相同mini-batch使用最长的序列padsequences函数。

  3. 排列的最后二维序列

函数[X, T, sequenceLengthsSource maskTarget] = preprocessMiniBatch (sequencesSource、sequencesTarget inputSize, outputSize) sequenceLengthsSource = cellfun (@ (X)大小(X, 2), sequencesSource);X = padsequences (sequencesSource 2 PaddingValue = inputSize);X =排列(X, [1 3 2]);[T, maskTarget] = padsequences (sequencesTarget 2 PaddingValue = outputSize);T =排列(T) [1 3 2]);maskTarget =排列(maskTarget [1 3 2]);结束

损失函数模型

modelLoss函数将编码器和译码器模型参数、输入数据mini-batch和填充面具对应于输入数据,辍学并返回损失概率和损失的梯度模型中的可学的参数。

函数(损失,梯度)= modelLoss(参数X, T,sequenceLengthsSource maskTarget,辍学)%通过编码器。[Z, hiddenState] = modelEncoder (parameters.encoder X, sequenceLengthsSource);%解码器输出。doTeacherForcing =兰德< 0.5;sequenceLength =大小(T, 3);Y = decoderPredictions (hiddenState parameters.decoder, Z, T,辍学,doTeacherForcing sequenceLength);%掩盖损失。Y = Y (:: 1: end-1);T = extractdata(收集(T(:,:, 2:结束)));T = onehotencode (T 1一会= 1:尺寸(Y, 1));maskTarget = maskTarget(:,:, 2:结束);maskTarget = repmat (maskTarget,大小(Y, 1), 1, 1]);损失= crossentropy (Y, T,面具= maskTarget Dataformat =“认知行为治疗”);%更新梯度。梯度= dlgradient(损失、参数);结束

编码器模型函数

这个函数modelEncoder需要输入数据,模型参数,可选的面具,确定正确的输出用于培训和返回模型输出和LSTM隐藏状态。

如果sequenceLengths是空的,那么函数不掩码输出。指定和空值sequenceLengths当使用modelEncoder函数的预测。

函数[Z, hiddenState] = modelEncoder(参数X, sequenceLengths)%嵌入。重量= parameters.emb.Weights;Z =嵌入(X,重量,DataFormat =“认知行为治疗”);% LSTM。inputWeights = parameters.lstm.InputWeights;recurrentWeights = parameters.lstm.RecurrentWeights;偏见= parameters.lstm.Bias;numHiddenUnits =大小(recurrentWeights, 2);initialHiddenState = dlarray (0 ([numHiddenUnits 1]));initialCellState = dlarray (0 ([numHiddenUnits 1]));[Z, hiddenState] = lstm (Z, initialHiddenState, initialCellState inputWeights,recurrentWeights,偏见,DataFormat =“认知行为治疗”);%屏蔽进行训练。如果~ isempty (sequenceLengths) miniBatchSize =大小(Z, 2);n = 1: miniBatchSize hiddenState (:, n) = Z (: n sequenceLengths (n));结束结束结束

译码器模型函数

这个函数modelDecoder需要输入数据,模型参数、上下文向量,LSTM最初的隐藏状态,编码器的输出,以及辍学概率和输出译码器的输出,更新的上下文向量,LSTM更新状态,关注分数。

函数[Y,上下文,hiddenState, attentionScores] = modelDecoder(参数X,上下文,hiddenState, Z,辍学)%嵌入。重量= parameters.emb.Weights;X =嵌入(X,重量,DataFormat =“认知行为治疗”);% RNN输入。sequenceLength =大小(X, 3);Y =猫(1 X repmat(上下文,[1 1 sequenceLength]));% LSTM。inputWeights = parameters.lstm.InputWeights;recurrentWeights = parameters.lstm.RecurrentWeights;偏见= parameters.lstm.Bias;initialCellState = dlarray(0(大小(hiddenState)));[Y, hiddenState] = lstm (Y, hiddenState initialCellState,inputWeights recurrentWeights,偏见,DataFormat =“认知行为治疗”);%的辍学生。掩码=兰德(大小(Y),“喜欢”,Y) >辍学;Y = Y *面具;%的注意。重量= parameters.attention.Weights;[背景下,attentionScores] = luongAttention (hiddenState Z、重量);%连接。Y =猫(1,Y, repmat(上下文,[1 1 sequenceLength]));%完全连接。重量= parameters.fc.Weights;偏见= parameters.fc.Bias;Y = fullyconnect (Y,重量、偏见、DataFormat =“认知行为治疗”);% Softmax。Y = softmax (Y, DataFormat =“认知行为治疗”);结束

陈德良关注功能

luongAttention函数返回上下文向量和关注分数据陈德良“通用”评分[1]。这相当于点积关注查询,键和值指定为隐藏状态,加权潜在的代表,和潜在的表示。

函数[背景下,attentionScores] = luongAttention (hiddenState Z、重量)numHeads = 1;查询= hiddenState;键= pagemtimes(重量、Z);值= Z;[背景下,attentionScores] =注意(查询、键值、numHeads规模= 1,DataFormat =“认知行为治疗”);结束

译码器模型的预测函数

decoderModelPredictions函数的作用是:返回预测序列Y给定的输入序列,目标序列,隐藏状态,辍学概率,国旗,让老师强迫,和序列长度。

函数Y = decoderPredictions(参数,Z, T, hiddenState,辍学,doTeacherForcing sequenceLength)%转换为dlarray。T = dlarray (T);%初始化上下文。miniBatchSize =大小(T, 2);numHiddenUnits =大小(Z, 1);上下文= 0 ([numHiddenUnits miniBatchSize),“喜欢”,Z);如果doTeacherForcing%通过译码器。Y = modelDecoder(参数、T、上下文、hiddenState Z,辍学);其他的%获得译码器时间的第一步。decoderInput = T (:,: 1);%初始化输出。numClasses =元素个数(parameters.fc.Bias);Y = 0 ([numClasses miniBatchSize sequenceLength),“喜欢”,decoderInput);随着时间的推移%循环步骤。t = 1: sequenceLength%通过译码器。[Y (:,:, t)背景下,hiddenState] = modelDecoder(参数、decoderInput上下文,hiddenState, Z,辍学);%更新译码器的输入。[~,decoderInput] = max (Y (:,:, t), [], 1);结束结束结束

文本翻译功能

translateText函数将一个数组遍历mini-batches文本。模型参数的函数作为输入,输入字符串数组,最大序列长度,mini-batch大小,源和目标词编码对象,启动和停止令牌,组装输出的分隔符。

函数strTranslated = translateText(参数、你要maxSequenceLength miniBatchSize,encSource、encTarget startToken stopToken,分隔符)%转换文本。documentsSource = transformText(你要startToken stopToken);sequencesSource = doc2sequence (encSource documentsSource,PaddingDirection =“正确”,PaddingValue = encSource。NumWords + 1);%转换为dlarray。X =猫(sequencesSource {:});X =排列(X, [1 3 2]);X = dlarray (X);%初始化输出。numObservations =元素个数(你要);strTranslated =字符串(numObservations, 1);%在mini-batches循环。numIterations =装天花板(numObservations / miniBatchSize);i = 1: numIterations idxMiniBatch =(张)* miniBatchSize + 1: min(我* miniBatchSize numObservations);miniBatchSize =元素个数(idxMiniBatch);%编码器编码使用模型。sequenceLengths = [];[Z, hiddenState] = modelEncoder (parameters.encoder X (:, idxMiniBatch:), sequenceLengths);%解码器的预测。doTeacherForcing = false;辍学= 0;decoderInput = repmat (word2ind (encTarget startToken) [1 miniBatchSize]);decoderInput = dlarray (decoderInput);Y = decoderPredictions (parameters.decoder, Z, decoderInput hiddenState,辍学,doTeacherForcing maxSequenceLength);[~,idxPred] = max (extractdata (Y), [], 1);%保持翻译国旗。idxStop = word2ind (encTarget stopToken);keepTranslating = idxPred ~ = idxStop;随着时间的推移%循环步骤。t = 1;任何(t < = maxSequenceLength & & keepTranslating (:,:, t))%更新输出。newWords = ind2word (encTarget idxPred (:,:, t) ';idxUpdate = idxMiniBatch (keepTranslating (:,:, t));strTranslated (idxUpdate) = strTranslated (idxUpdate) +分隔符+ newWords (keepTranslating (:,:, t));t = t + 1;结束结束结束

参考书目

[1]陈德良、Minh-Thang Hieu Pham,克里斯托弗·d·曼宁。“有效的机器翻译方法引起的神经。”arXiv预印本arXiv: 1508.04025(2015)。

另请参阅

|||(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)|(深度学习工具箱)|

相关的话题