主要内容

Sequence-to-Sequence翻译使用注意

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

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

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

译码器的模型,这个示例使用一个网络编码器,包含两个LSTMs非常相似。然而,一个重要的区别是译码器包含一个注意力机制。注意机制允许解码器参加编码器输出信号的特定部分。

负荷训练数据

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

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

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

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

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

头(dataTrain)
ans =8×2表源目标______月______“492”“CDXCII”“911”“965”“CMXI”“CMLXV”“951”“160”“CMLI”“CLX”“662”“102”“DCLXII”“人民共和国”“440”“CDXL”

数据进行预处理

预处理文本数据使用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年与200年两个LSTM层隐藏的单位,和辍学层与随机辍学概率0.05。

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

初始化编码器模型参数

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

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

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

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

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

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

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

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

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

深圳= [4 * numHiddenUnits numHiddenUnits];numOut = 4 * numHiddenUnits;numIn = numHiddenUnits;parameters.encoder.lstm2。InputWeights = initializeGlorot(深圳、numOut numIn);parameters.encoder.lstm2。RecurrentWeights = initializeOrthogonal ([4 * numHiddenUnits numHiddenUnits]);parameters.encoder.lstm2。偏见= 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.attn.Weights = initializeGlorot(深圳、numOut numIn);

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

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

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

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

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

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

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

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

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

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

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

深圳= [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更新状态,注重分数。

定义模型梯度函数

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

指定培训选项

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

miniBatchSize = 32;numEpochs = 75;learnRate = 0.002;

初始化选项从亚当。

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设备。金宝app支持设备的信息,请参阅GPU的支持。金宝app

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

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

初始化培训进展阴谋。

图lineLossTrain = animatedline (“颜色”[0.85 0.325 0.098]);ylim([0正])包含(“迭代”)ylabel (“损失”网格)

初始化的值adamupdate函数。

trailingAvg = [];trailingAvgSq = [];

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

  • 读了mini-batch填充序列。

  • 计算损失和梯度。

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

  • 更新培训进展阴谋。

迭代= 0;开始=抽搐;%循环时期。时代= 1:numEpochs重置(兆贝可);%在mini-batches循环。hasdata(兆贝可)迭代=迭代+ 1;[dlX T, sequenceLengthsSource maskSequenceTarget] =下一个(兆贝可);%计算损失和梯度。(渐变,亏损)= dlfeval (@modelGradients、参数dlX T sequenceLengthsSource,maskSequenceTarget,辍学);%更新使用adamupdate参数。(参数、trailingAvg trailingAvgSq) = adamupdate(参数、渐变trailingAvg trailingAvgSq,迭代,learnRate、gradientDecayFactor squaredGradientDecayFactor);%显示培训进展。D =持续时间(0,0,toc(开始),“格式”,“hh: mm: ss”);addpoints (lineLossTrain、迭代、双(收集(损失)))标题(”时代:“+时代+”,过去:“+ drawnow字符串(D))结束结束

生成翻译

为新数据生成翻译使用训练模型,将文本数据转换为数字序列训练时使用相同的步骤和输入序列到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表源目标翻译______ ___________ __________“108”“CVIII”“CVIIII”“651”“DCLI”“局长”“147”“CXLVII”“CCLXVII”“850”“DCCCL”“DCCCDCC”“468”“CDLXVIII”“CCLXVIII”“168”“CLXVIII”“CDLXVIII”“220”“CCXX”“CCC”“832”“DCCCXXXII”“DCCCXXII”“162”“CLXII”“CDXLII”“659”“DCLIX”“DCXIX”“224”“CCXXIV”“CCXXIV”“760”“DCCLX”“DCCLDC”“304”“CCCIV”“CCCIV”“65”“LXV”“DCLV”“647”“DCXLVII”“DCXLVII”“596”“DXCVI”“DCXVI⋮”

文本转换功能

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]);结束

模型梯度函数

modelGradients函数接受编码器和译码器模型参数,输入数据mini-batch和填充面具对应于输入数据,和辍学概率和回报的梯度损失对模型中的可学的参数和相应的损失。

函数(渐变,亏损)= modelGradients(参数、dlX T,sequenceLengthsSource maskTarget,辍学)%通过编码器。[dlZ, hiddenState] = modelEncoder (parameters.encoder、dlX sequenceLengthsSource);%解码器输出。doTeacherForcing =兰德< 0.5;sequenceLength =大小(T, 3);海底= decoderPredictions (hiddenState parameters.decoder, dlZ, T,辍学,doTeacherForcing sequenceLength);%掩盖损失。海底=海底(::1:end-1);T = extractdata(收集(T(:,:, 2:结束)));T = onehotencode (T, 1“类名”1:尺寸(海底,1));maskTarget = maskTarget(:,:, 2:结束);maskTarget = repmat (maskTarget,大小(海底,1),1,1]);损失= crossentropy(海底T“面具”maskTarget,“Dataformat”,“认知行为治疗”);%更新梯度。梯度= dlgradient(损失、参数);%绘制,回波损耗由序列长度归一化。= extractdata损失(损失)。/ sequenceLength;结束

编码器模型函数

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

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

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

译码器模型函数

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

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

注意函数

注意函数返回的关注分数据陈德良“将军”得分和更新的上下文向量。能量在每个时间步的点积是隐藏的状态和可学的关注权重乘以编码器输出信号。

函数[attentionScores、上下文]=注意(hiddenState encoderOutputs,重量)%初始化关注的能量。[miniBatchSize, sequenceLength] =大小(encoderOutputs 2:3);attentionEnergies = 0 ([sequenceLength miniBatchSize),“喜欢”,hiddenState);%注意能量。hWX = hiddenState。* pagemtimes(重量、encoderOutputs);tt = 1: sequenceLength attentionEnergies (tt:) =总和(hWX (:,:, tt), 1);结束%注意分数。attentionScores = softmax (attentionEnergies,“DataFormat”,“CB”);%的上下文。encoderOutputs =排列(encoderOutputs [1 3 2]);attentionScores =排列(attentionScores [1 3 2]);上下文= pagemtimes (encoderOutputs attentionScores);上下文=挤压(上下文);结束

译码器模型的预测函数

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

函数海底= decoderPredictions (hiddenState parametersDecoder, dlZ, T,辍学,doTeacherForcing sequenceLength)%转换为dlarray。dlT = dlarray (T);%初始化上下文。miniBatchSize =大小(dlT, 2);numHiddenUnits =大小(dlZ, 1);上下文= 0 ([numHiddenUnits miniBatchSize),“喜欢”,dlZ);如果doTeacherForcing%通过译码器。海底= modelDecoder (dlT parametersDecoder,上下文,hiddenState, dlZ辍学);其他的%获得译码器时间的第一步。decoderInput = dlT (:: 1);%初始化输出。numClasses =元素个数(parametersDecoder.fc.Bias);海底= 0 ([numClasses miniBatchSize sequenceLength),“喜欢”,decoderInput);随着时间的推移%循环步骤。t = 1: sequenceLength%通过译码器。(海底(:,:,t)背景下,hiddenState] = modelDecoder (parametersDecoder decoderInput,上下文,hiddenState, dlZ辍学);%更新译码器的输入。[~,decoderInput] = max(海底(:,:,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]);dlX = dlarray (X);%初始化输出。numObservations =元素个数(你要);strTranslated =字符串(numObservations, 1);%在mini-batches循环。numIterations =装天花板(numObservations / miniBatchSize);i = 1: numIterations idxMiniBatch =(张)* miniBatchSize + 1: min(我* miniBatchSize numObservations);miniBatchSize =元素个数(idxMiniBatch);%编码器编码使用模型。sequenceLengths = [];[dlZ, hiddenState] = modelEncoder(参数。编码器,dlX(:,idxMiniBatch,:), sequenceLengths);%解码器的预测。doTeacherForcing = false;辍学= 0;decoderInput = repmat (word2ind (encTarget startToken) [1 miniBatchSize]);decoderInput = dlarray (decoderInput);海底= decoderPredictions (parameters.decoder, dlZ、decoderInput hiddenState,辍学,doTeacherForcing maxSequenceLength);[~,idxPred] = max (extractdata(海底),[],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;结束结束结束

另请参阅

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

相关的话题