主要内容

使用深度学习的语言翻译

这个例子展示了如何使用循环序列到序列编码器-解码器模型训练一个德语到英语的翻译。

循环编码器-解码器模型在抽象文本摘要和神经机器翻译等任务中已被证明是成功的。这些模型由编码器,通常使用循环层(如LSTM层)和译码器它将编码的输入映射到所需的输出,通常也带有循环层。包含的模型注意机制在模型中,解码器可以专注于编码输入的部分,同时每次生成一个时间步的翻译。这个例子实现了Bahdanau关注[1]使用自定义层attentionLayer,作为支持文件附在本例中。金宝app要访问此层,请将此示例作为活动脚本打开。

该图显示了语言翻译模型的结构。指定为单词序列的输入文本通过编码器传递,编码器输出输入序列的编码版本和用于初始化解码器状态的隐藏状态。解码器使用之前的预测作为输入,一次预测一个单词,并输出更新状态和上下文值。

有关本例中使用的编码器和解码器网络的更多信息和详细信息,请参见定义编码器和解码器网络部分的示例。

为序列中的每一步预测最有可能的单词可能会导致次优结果。任何不正确的预测都可能在以后的时间步骤中导致更不正确的预测。例如,对于目标文本“一只鹰飞过。”,如果解码器预测翻译的第一个单词为“一个”,那么在下一个单词中预测“eagle”的概率就变得不太可能了,因为短语“a eagle”出现在英语文本中的概率很低。翻译生成过程因训练和预测而不同。这个例子使用了不同的方法来稳定训练和预测:

  • 为了稳定训练,可以随机使用目标值作为解码器的输入。特别是,您可以随着训练的进行调整用于注入目标值的概率。例如,你可以在训练开始时以更高的速率使用目标值进行训练,然后衰减概率,以便在训练结束时模型只使用以前的预测。这种技术被称为安排抽样[2].有关更多信息,请参见解码器预测函数部分的示例。

  • 为了提高翻译时的预测,对于每个时间步骤,您可以考虑顶部 K 对某个正整数的预测 K 并探索不同的预测序列,以确定最佳组合。这种技术被称为定向搜索.有关更多信息,请参见波束搜索函数部分的示例。

这个例子展示了如何加载和预处理文本数据来训练德语到英语的翻译,定义编码器和解码器网络,使用自定义训练循环训练模型,以及使用波束搜索生成翻译。

注意:语言翻译是一项计算密集型的任务。在本例中使用的完整数据集上进行训练可能需要花费许多小时。为了使示例运行得更快,您可以通过丢弃一部分训练数据来减少使用以前未见过的数据进行预测的准确性,从而减少训练时间。删除观测值可以加快训练速度,因为它减少了在一个纪元中要处理的数据量,并减少了训练数据的词汇量。

为了缩短运行示例所需的时间,丢弃70%的数据。请注意,丢弃大量数据会对学习模型的准确性产生负面影响。为了获得更准确的结果,请减少丢弃的数据量。为了加快示例的速度,可以增加丢弃的数据量。

discardProp = 0.70;

负荷训练数据

下载并提取英-德tab分隔的双语句子对数据集。数据来自http://www.manythings.org/anki而且https://tatoeba.org,并在Tatoeba使用条款CC-BY许可证

downloadFolder = tempdir;url =“http://www.manythings.org/anki/deu-eng.zip”;文件名= fullfile(下载文件夹,“deu-eng.zip”);dataFolder = fullfile(下载文件夹,“deu-eng”);如果~存在(dataFolder“dir”)流(下载以英德表符分隔的双语句子对数据集(7.6 MB)…) websave(文件名,url);解压缩(文件名,dataFolder);流(“完成。\ n”)结束

创建一个包含以字符串形式指定的句子对的表。阅读用制表符分隔的句子对readtable.指定德语文本作为源,英语文本作为目标。

文件名= fullfile(数据文件夹,“deu.txt”);opts = delimitedTextImportOptions(...分隔符=“t \”...VariableNames = [“目标”“源”“许可证”),...SelectedVariableNames = [“源”“目标”),...VariableTypes = [“字符串”“字符串”“字符串”),...编码=“utf - 8”);

查看数据中的前几对句子。

数据= readtable(文件名,opts);头(数据)
ans =8×2表来源目标_______________ _______“Geh。”“走吧。”“喂!”“嗨。”“格勒乌ß神!”“嗨。”“Lauf !”“快跑!”“Lauf !”“运行”。 "Potzdonner!" "Wow!" "Donnerwetter!" "Wow!" "Feuer!" "Fire!"

在完整数据集上的训练可能需要很长时间才能运行。为了以准确性为代价减少训练时间,可以丢弃一部分训练数据。删除观测值可以加快训练速度,因为它减少了在一个纪元中要处理的数据量,并减少了训练数据的词汇量。

方法丢弃部分数据discardProp在示例开始时定义的变量。请注意,丢弃大量数据会对学习模型的准确性产生负面影响。为了获得更准确的结果,可以通过设置减少丢弃的数据量discardProp到一个更低的值。

idx = size(data,1) - floor(discardProp*size(data,1)) + 1;Data (idx:end,:) = [];

查看剩余观测数。

大小(数据,1)
Ans = 68124

将数据分成训练分区和测试分区,分别包含90%和10%的数据。

trainingProp = 0.9;idx = randperm(size(data,1),floor(trainingProp*size(data,1)));dataTrain = data(idx,:);dataTest =数据;dataTest(idx,:) = [];

查看训练数据的前几行。

头(dataTrain)
ans =8×2表源目标  ___________________________________ _________________________ " 汤姆erschoss玛丽。”“汤姆枪杀了玛丽。”“Ruf michigan bitte an。”“请给我打电话。”“Kann das einer nachprüfen?”“有人能检查一下吗?”“Das lasse ich mir niht gefallen!”“我不能容忍。”“我晚上要英语。”“我不喜欢英语。” "Er ist auf dem Laufenden." "He is up to date." "Sie sieht glücklich aus." "She seems happy." "Wo wurden sie geboren?" "Where were they born?"

查看训练观察数。

numObservationsTrain = size(dataTrain,1)
numObservationsTrain = 61311

数据进行预处理

属性预处理文本数据preprocessText函数,在示例末尾列出。的preprocessText函数通过将文本分解为单词并添加开始和停止标记来对输入文本进行预处理和标记,以进行翻译。

documentsGerman = preprocessText(dataTrain.Source);

创建一个wordEncoding对象,该对象使用词汇表将标记映射到数值索引,反之亦然。

encGerman = worddencoding (documentsGerman);

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

documentsEnglish = preprocessText(dataTrain.Target);encEnglish = worddencoding (documentsEnglish);

查看源编码和目标编码的词汇表大小。

numWordsGerman = encGerman。NumWords
numWordsGerman = 12117
numWordsEnglish = encEnglish。NumWords
numWordsEnglish = 7226

定义编码器和解码器网络

该图显示了语言翻译模型的结构。指定为单词序列的输入文本通过编码器传递,编码器输出输入序列的编码版本和用于初始化解码器状态的隐藏状态。解码器使用之前的预测作为输入,一次进行一个单词的预测,并输出更新的状态和上下文值。

控件创建编码器和解码器网络languageTranslationLayers函数,作为支持文件附加到本示例中。金宝app要访问此函数,请将示例作为活动脚本打开。

对于编码器网络,使用languageTranslationLayers函数定义了一个简单的网络,由嵌入层和LSTM层组成。嵌入操作将分类标记转换为数字向量,其中数字向量由网络学习。

对于解码器网络,使用languageTranslationLayers函数定义了一个网络,该网络通过LSTM层传递与输入上下文连接的输入数据,并获得更新的隐藏状态和编码器输出,并将其通过注意机制来确定上下文向量。然后将LSTM输出和上下文向量连接起来,并通过全连接层和softmax层进行分类。

控件创建编码器和解码器网络languageTranslationLayers函数,作为支持文件附加到本示例中。金宝app要访问此函数,请将示例作为活动脚本打开。指定嵌入维度为128,并在LSTM层中指定128个隐藏单元。

embeddingDimension = 128;numHiddenUnits = 128;[lgraphEncoder,lgraphDecoder] = languageTranslationLayers(embeddingDimension,numHiddenUnits,numWordsGerman,numWordsEnglish);

要在自定义训练循环中训练网络,请将编码器和解码器网络转换为dlnetwork对象。

dlnetEncoder = dlnetwork(lgraphEncoder);dlnetDecoder = dlnetwork(lgraphDecoder);

解码器有多个输出,包括注意层的上下文输出,它也被传递到另一层。属性指定网络输出OutputNames解码器的属性dlnetwork对象。

dlnetDecoder。OutputNames=[“softmax”“背景”“lstm2 /隐藏”“lstm2 /细胞”];

定义模型梯度函数

创建函数modelGradients,列于模型梯度函数将编码器和解码器模型参数、一小批输入数据和与输入数据对应的填充掩码以及退出概率作为输入,并返回相对于模型中可学习参数的损失和相应损失的梯度。

指定培训项目

在15个epoch中使用64的小批大小进行训练,学习率为0.005。

miniBatchSize = 64;numEpochs = 15;learnRate = 0.005;

初始化Adam优化的选项。

gradientDecayFactor = 0.9;squaredGradientDecayFactor = 0.999;

训练使用逐渐衰减的值 ϵ 用于计划抽样。从值开始 ϵ 0 5 线性衰减到值 ϵ 0 .有关计划抽样的更多信息,请参见解码器预测函数部分的示例。

epsilonStart = 0.5;epsilonEnd = 0;

使用SortaGrad进行训练[3],这是一种改进粗糙序列训练的策略,先训练一个epoch,按序列排序,然后每个epoch洗牌一次。

按序列长度对训练序列进行排序。

sequenceLengths =文档长度(documentsGerman);[~,idx] = sort(sequenceLengths);documentsGerman = documentsGerman(idx);documentsEnglish = documentsEnglish(idx);

火车模型

使用自定义训练循环训练模型。

方法为源数据和目标数据创建数组数据存储arrayDatastore函数。方法组合数据存储结合函数。

adsSource = arrayDatastore(documentsGerman);adsTarget = arrayDatastore(documentsEnglish);cd = combine(adsSource,adsTarget);

创建一个小批队列以自动为培训准备小批。

  • 对训练数据进行预处理preprocessMiniBatch函数,该函数返回一个小批量的源序列、目标序列、相应的掩码和初始开始令牌。

  • 输出dlarray格式为“施”(通道,时间,批次)。

  • 丢弃任何部分小批量。

MBQ = minibatchqueue(cd,4,...MiniBatchSize = MiniBatchSize,...MiniBatchFcn = @ (X, Y) preprocessMiniBatch (X, Y, encGerman encEnglish),...MiniBatchFormat = [“施”“施”“施”“施”),...PartialMiniBatch =“丢弃”);

初始化培训进度图。

图C = colororder;lineLossTrain = animatedline(Color=C(2,:));包含(“迭代”) ylabel (“损失”) ylim([0 inf])网格

对于编码器和解码器网络,初始化Adam优化的值。

trailingAvgEncoder = [];trailingAvgSqEncoder = [];trailingAvgDecder = [];trailingAvgSqDecoder = [];

创建一个数组 ϵ 计划抽样的值。

numIterationsPerEpoch = floor(numObservationsTrain/miniBatchSize);numIterations = numIterationsPerEpoch * nummepochs;epsilon = linspace(epsilonStart,epsilonEnd,numIterations);

训练模型。对于每个迭代:

  • 从小批队列中读取一个小批数据。

  • 计算模型梯度和损失。

  • 方法更新编码器和解码器网络adamupdate函数。

  • 方法更新训练进度图并显示示例翻译ind2str函数,作为支持文件附加到本示例中。金宝app要访问此函数,请将此示例作为活动脚本打开。

  • 如果迭代产生的训练损失最小,则保存网络。

在每个纪元结束时,对迷你批处理队列进行洗牌。

对于大型数据集,训练可能需要花费数小时。

迭代= 0;开始= tic;lossMin = inf;重置(兆贝可)%遍历epoch。epoch = 1:numEpochs在小批上循环。Hasdata (mbq)迭代=迭代+ 1;读取小批数据。[dlX,dlT,maskT,decoderInput] = next(mbq);计算损失和梯度。[gradientsEncoder,gradientsDecoder,loss,dlYPred] = dlfeval(@modelGradients,dlnetEncoder,dlnetDecoder,dlX,dlT,maskT,decoderInput,epsilon(迭代));使用adamupdate更新网络可学习参数。[dlnetEncoder, trailingAvgEncoder,trailingAvgSqEncoder] = adamupdate(dlnetEncoder,gradientsEncoder,trailingAvgEncoder,trailingAvgSqEncoder,...迭代,learnRate、gradientDecayFactor squaredGradientDecayFactor);[dlnetDecoder, trailingAvgDecder,trailingAvgSqDecoder] = adamupdate(dlnetDecoder,gradientsDecoder,trailingAvgDecder,trailingAvgSqDecoder,...迭代,learnRate、gradientDecayFactor squaredGradientDecayFactor);为绘图生成翻译。如果迭代== 1 || mod(迭代,10)== 0 strGerman = ind2str(dlX(:,1,:),encGerman);str = ind2str(dlT(:,1,:),encEnglish,Mask=maskT);strTranslated = ind2str(dlYPred(:,1,:),encEnglish);结束显示培训进度。D = duration(0,0,toc(start),Format=“hh: mm: ss”);损失= double(gather(extractdata(Loss)));addpoints (lineLossTrain、迭代、失去)标题(...”时代:“+ epoch +,消失:"+字符串(D) +换行符+...“来源:”+ strGerman +换行符+...目标:“+ strength +换行符+...培训翻译:现在绘制保存最好的网络。如果loss < lossMin lossMin = loss;netBest。dlnetEncoder = dlnetEncoder;netBest。dlnetDecoder = dlnetDecoder;netBest。损失=损失;netBest。迭代=迭代;netBest。D = D;结束结束%洗牌。洗牌(兆贝可);结束

图中显示了原文的两种译本。目标是网络试图重现的训练数据提供的目标翻译。训练翻译是预测翻译,它通过预定的抽样机制使用来自目标文本的信息。

将单词编码添加到netBest结构并将结构保存在一个MAT文件中。

netBest。encGerman = encGerman;netBest。encEnglish = encEnglish;D = datestr(现在,“yyyy_mm_dd__HH_MM_SS”);文件名=“dlnet_best__”+ d +“.mat”;保存(文件名,“netBest”);

从中提取最佳网络netBest

dlnetEncoder = netBest.dlnetEncoder;dlnetDecoder = netBest.dlnetDecoder;

测试模型

为了评估翻译的质量,请使用双语评估替补(BLEU)评分算法[4]

类转换测试数据translateText示例末尾列出的函数。

strTranslatedTest = translateText(dlnetEncoder,dlnetDecoder,encGerman,encEnglish,dataTest.Source);

在表格中查看随机选择的测试源文本、目标文本和预测翻译。

numObservationsTest = size(dataTest,1);idx = randperm(numObservationsTest,8);TBL =表;资源描述。Source = dataTest.Source(idx);资源描述。目标= dataTest.Target(idx);资源描述。翻译= strTranslatedTest(idx)
台=8×3表源目标翻译  _____________________________________ __________________________ _________________________________ " Er sieht克兰克来自。”“他好像病了。”"他看起来病了" "我也不知道"“我去拿书。”“我去拿那本书。”它……”“Ruhst du dich jemals aus?”“你休息过吗?”“你往外看吗?”?? ?" "Was willst du?" "What are you after?" "what do you want want ? ? ? ?" "Du hast keinen Beweis." "You have no proof." "you have no proof . . . . ." "Macht es, wann immer ihr wollt." "Do it whenever you want." "do it you like it . . it ." "Tom ist gerade nach Hause gekommen." "Tom has just come home." "tom just came home home . . . ." "Er lügt nie." "He never tells a lie." "he never lie lies . . . . ."

为了使用BLEU相似度评分评估翻译的质量,首先使用与训练相同的步骤对文本数据进行预处理。指定空的开始和停止标记,因为在转换中不使用这些标记。

候选人= preprocessText(strTranslatedTest,StartToken=""StopToken ="");references = preprocessText(dataTest。目标,StartToken =""StopToken ="");

bleuEvaluationScore函数在默认情况下,通过比较长度为1到4的n-gram(包含四个或更少单词的多词短语或单个单词)来评估相似度得分。如果候选或参考文档的令牌少于4个,则结果BLEU评估得分为零。为了确保bleuEvaluationScore返回这些短候选文档的非零分数,将n-gram权重设置为元素少于其中字数的向量候选人

确定最短候选文档的长度。

minLength = min([doclth (candidate);doclength(引用)])
minLength = 2

如果最短文档的令牌少于4个,则将n-gram权重设置为一个向量,其长度与具有相同权重的最短文档匹配,且和为1。否则,指定的n-gram权重[0.25 0.25 0.25 0.25].注意,如果最小长度1(因此n-gram的权重也是1),然后bleuEvaluationScore函数可能返回意义较小的结果,因为它只比较单个单词(字母),而不比较任何n-gram(多词短语)。

如果minLength < 4 ngramWeights = ones(1,minLength) / minLength;其他的ngramWeights = [0.25 0.25 0.25 0.25];结束

计算BLEU评估分数,方法是迭代翻译并使用bleuEvaluationScore函数。

i = 1:numObservationsTest分数(i) = bleuEvaluationScore(候选人(i),引用(i),NgramWeights= NgramWeights);结束

在直方图中可视化BLEU评估分数。

图直方图(分数);标题(《BLEU评价分数》)包含(“分数”) ylabel (“频率”)

查看一些最好的翻译表格。

[~,idxSorted] = sort(分数,“下”);idx = idxSorted(1:8);TBL =表;资源描述。Source = dataTest.Source(idx);资源描述。目标= dataTest.Target(idx);资源描述。翻译= strTranslatedTest(idx)
台=8×3表源目标翻译  ________________________ ____________ _____________ " Legen您西奇欣!”“低调”。“低调”“我gähnte。”“我打了个哈欠。”“Küsse汤姆!”“吻汤姆。”“亲汤姆。”“Küssen你汤姆!”“吻汤姆。”"吻汤姆" "尼姆汤姆"“带汤姆。” "take tom ." "Komm bald." "Come soon." "come soon ." "Ich habe es geschafft." "I made it." "i made it ." "Ich sehe Tom." "I see Tom." "i see tom ."

查看一些最差翻译的表格。

idx = idxSorted(end-7:end);TBL =表;资源描述。Source = dataTest.Source(idx);资源描述。目标= dataTest.Target(idx);资源描述。翻译= strTranslatedTest(idx)
台=8×3表源目标翻译  _______________________________________________________________ __________________________ ____________________________ " 这田螺萤石埃森人。”“这些蜗牛可以吃。”"这个可以吃" "Sie stehen noch zu Verfügung "“它们仍然可用。”"还在. . . . . ." "Diese Schraube past zu dieser Mutter "“这个螺栓适合这个螺母。”“这一生太. . . . .”“Diese Puppe gehört mir。”“这个娃娃是我的。”"这是我的" "Das eine japanische Puppe "“这是一个日本娃娃。” "that's a old trick ." "Das ist eine Kreuzung, an der alle Fahrzeuge anhalten müssen." "This is a four-way stop." "that's a to to to . . . ." "Diese Sendung ist eine Wiederholung." "This program is a rerun." "this is is quiet ." "Die heutige Folge ist eine Wiederholung." "Today's show is a rerun." "uranus is care ."

生成翻译

方法生成新数据的转换translateText函数。

strGermanNew = [“Wie geht es Dir heute?”“Wie heien Sie?”“Das Wetter ist heute gut。”];

方法翻译文本translateText,示例末尾列出的函数。

strTranslatedNew = translateText(dlnetEncoder,dlnetDecoder,encGerman,encEnglish,strGermanNew)
strTranslatedNew =3×1的字符串“你今天感觉怎么样?”“你叫什么名字?”???“就是今天。”今天……”

预测功能

波束搜索函数

波束搜索是一种探索时间步预测的不同组合,以帮助找到最佳预测序列的技术。波束搜索的前提是对每一个时间步进行预测,识别顶部 K 对某个正整数的预测 K (也称为梁指数或者是波束宽度),并保持顶部 K 在每个时间步中预测到目前为止的序列。

该图显示了一个带波束索引的示例波束搜索的结构 K 3. .对于每个预测,保持前三个序列。

beamSearch函数将输入数据作为输入dlX,编码器和解码器网络和目标词编码,并使用波束索引为3,最大序列长度为10的波束搜索算法返回预测的翻译词。你也可以使用名称-值参数指定可选参数:

  • BeamIndex-光束索引。默认值是3。

  • MaxNumWords—最大序列长度。默认值是10。

函数str = beamSearch(dlX,dlnetEncoder,dlnetDecoder,encEnglish,args)解析输入参数。参数dlX dlnetEncoder dlnetDecoder encEnglish args。BeamIndex = 3;arg游戏。MaxNumWords = 10;结束beamIndex = args.BeamIndex;maxNumWords = args.MaxNumWords;startToken =“<开始>”;stopToken =“<停止>”编码器预测。[dlZ, hiddenState, cellState] = predict(dlnetEncoder,dlX);初始化上下文。miniBatchSize = size(dlX,2);numHiddenUnits = size(dlZ,1);context = 0 ([numHiddenUnits miniBatchSize],“喜欢”, dlZ);Context = dlarray(Context,“CB”);初始化候选。候选人= struct;候选人。单词= startToken;候选人。得分= 0;候选人。StopFlag=false; candidates.HiddenState = hiddenState; candidates.CellState = cellState;循环单词。T = 0;t < maxNumWords t = t + 1;candidatesNew = [];遍历候选对象。I = 1:数字(候选人)当预测到停止令牌时停止生成。如果候选人(i)。StopFlag继续结束%候选人详细信息。words =考生(i).Words;分数=考生(i).分数;hiddenState = candidate (i).HiddenState;cellState = candidate (i).CellState;预测下一个令牌。decoderInput = word2ind(encEnglish,words(end));decoderInput = darray (decoderInput,“认知行为治疗”);[dlYPred,context,hiddenState,cellState] = predict(dlnetDecoder,decoderInput,hiddenState,cellState,context,dlZ,...输出= [“softmax”“背景”“lstm2 /隐藏”“lstm2 /细胞”]);找到最佳预测。[scoresTop,idxTop] = maxk(extractdata(dlYPred),beamIndex);idxTop = gather(idxTop);循环顶部的预测。j = 1:beamIndex candidate = struct;确定候选词和分数。candidateWord = ind2word(encEnglish,idxTop(j));candidateScore = scoresTop(j);设置停止翻译标志。如果candidateWord == stopToken候选。StopFlag = true;其他的候选人。StopFlag=false;结束更新候选人详细信息。候选人。Words = [Words candidateWord];候选人。分数=分数+日志(candidateScore);候选人。HiddenState = HiddenState;候选人。CellState = CellState;添加到新的候选。candidatesNew = [candidatesNew候选人];结束结束找到最优秀的候选人。[~,idx] = maxk([candidatesNew.Score],beamIndex);候选人=候选人新(idx);当所有候选对象都有停止令牌时停止预测。如果([candidates.StopFlag])打破结束结束雇佣最优秀的候选人。单词=考生(1).单词;转换为字符串标量。words(ismember(words,[startToken stopToken])) = [];STR = join(words);结束

翻译文本功能

translateText函数将编码器和解码器网络、输入字符串以及源和目标单词编码作为输入,并返回翻译后的文本。

函数strTranslated = translateText(dlnetEncoder,dlnetDecoder,encGerman,encEnglish,strGerman,args)解析输入参数。参数dlnetEncoder dlnetDecoder encGerman encEnglish strGerman args。BeamIndex = 3;结束beamIndex = args.BeamIndex;预处理文本。documentsGerman = preprocessText(strGerman);dlX = preprocespredictors (documentsGerman,encGerman);dlX = dlarray(dlX,“施”);%循环观察。numObservations = numel(strGerman);strTranslated = strings(numObservations,1);n = 1:numObservations翻译文本。strTranslated(n) = beamSearch(dlX(:,n,:),dlnetEncoder,dlnetDecoder,encEnglish,BeamIndex= BeamIndex);结束结束

模型函数

模型梯度函数

modelGradients函数以编码器网络、解码器网络、小批量预测器作为输入dlX、目标dlT,对应于目标的填充蒙版maskT, ϵ 计划抽样的值。该函数返回相对于网络中可学习参数的损失梯度gradientsE而且gradientsD,相应的损耗,以及解码器的预测dlYPred编码为单热向量的序列。

函数[gradientsE,gradientsD,loss,dlYPred] = modelGradients(dlnetEncoder,dlnetDecoder,dlX,dlT,maskT,decoderInput,epsilon)%通过编码器转发。[dlZ, hiddenState, cellState] = forward(dlnetEncoder,dlX);%解码器输出。dlY = decoderPredictions(dlnetDecoder,dlZ,dlT,hiddenState,cellState,decoderInput,epsilon);稀疏交叉熵损失。loss = sparseCrossEntropy(dlY,dlT,maskT);%更新渐变。[gradientsE,gradientsD] = dlgradient(loss, dlnetencode . learnables,dlnetDecoder.Learnables);用于绘图,按序列长度归一化的返回损失。sequenceLength = size(dlT,3);loss = loss ./ sequenclength;对于绘制示例翻译,返回解码器输出。dlYPred = onehotdecode(dlY,1:size(dlY,1),1,“单身”);结束

解码器预测函数

decoderPredictions函数以输入,解码器网络,编码器输出dlZ,目标dlT,解码器输入隐藏和单元格状态值,以及 ϵ 计划抽样的值。

为了稳定训练,可以随机使用目标值作为解码器的输入。特别是,您可以随着训练的进行调整用于注入目标值的概率。例如,你可以在训练开始时以更高的速率使用目标值进行训练,然后衰减概率,以便在训练结束时模型只使用以前的预测。这种技术被称为安排抽样[2].该图显示了包含在解码器预测的一个时间步骤中的采样机制。

解码器一次一步地进行预测。在每一个时间步,输入是随机选择根据 ϵ 计划抽样的值。特别地,该函数使用目标值作为概率输入 ϵ 并使用之前的预测。

函数dlY = decoderprediction (dlnetDecoder,dlZ,dlT,hiddenState,cellState,decoderInput,epsilon)初始化上下文。numHiddenUnits = size(dlZ,1);miniBatchSize = size(dlZ,2);context = 0 ([numHiddenUnits miniBatchSize],“喜欢”, dlZ);Context = dlarray(Context,“CB”);初始化输出。idx = (dlnetDecoder.Learnables.)层= =“俱乐部”& dlnetDecoder.Learnables.Parameter = =“偏见”);numClasses = numel(dlnetDecoder.Learnables.Value{idx});sequenceLength = size(dlT,3);dlY = 0 ([numClasses miniBatchSize sequencelth],“喜欢”, dlZ);ly = darray (ly,“认知行为治疗”);通过解码器转发开始令牌。[dlY(:,:,1),context,hiddenState,cellState] = forward(dlnetDecoder,decoderInput,hiddenState,cellState,context,dlZ);%在剩余时间步骤上循环。t = 2:sequenceLength%计划抽样。随机选择以前的目标或以前%的预测。如果Rand <%使用目标值。decoderInput = dlT(:,:,t-1);其他的%使用以前的预测。[~,dlYhat] = max(dlY(:,:,t-1),[],1);decoderInput = dlYhat;结束%通过解码器转发。[dlY(:,:,t),context,hiddenState,cellState] = forward(dlnetDecoder,decoderInput,hiddenState,cellState,context,dlZ);结束结束

稀疏交叉熵损失

sparseCrossEntropy函数计算预测之间的交叉熵损失海底和目标dlT使用目标蒙版maskT,在那里海底是概率和的数组吗dlT编码为整数值序列。

函数loss = sparseCrossEntropy(dlY,dlT,maskT)初始化损失。[~,miniBatchSize, sequenclength] = size(dlY);损失= 0 ([miniBatchSize sequenclength],“喜欢”、海底);避免计算log为0,远离0。precision =底层类型(dlY);dlY(dlY < eps(精度))= eps(精度);%遍历时间步骤。n = 1:miniBatchSize序列长度idx = dlT(1,n,t);loss(n,t) = -log(dlY(idx,n,t));结束结束%应用屏蔽。maskT =挤压(maskT);* maskT;计算和并归一化。损失=总和(损失,“所有”);loss = loss / miniBatchSize;结束

预处理功能

文本预处理功能

preprocessText函数通过将文本转换为小写、添加开始和停止标记以及标记化来对输入文本进行预处理以进行翻译。

函数documents = preprocessText(str,args)参数str参数。StartToken =“<开始>”;arg游戏。StopToken =“<停止>”结束startToken = args.StartToken;stopToken = args.StopToken;STR = lower(STR);str = startToken + str + stopToken;documents = tokenizedDocument(str,CustomTokens=[startToken stopToken]);结束

小批量预处理功能

preprocessMiniBatch函数对标记化的文档进行预处理以进行训练。该函数将文档的小批量编码为数字索引序列,并将序列填充为具有相同的长度。

函数[XSource,XTarget,mask,decoderInput] = preprocessMiniBatch(dataSource,dataTarget,encGerman,encEnglish) documentsGerman = cat(1,dataSource{:});XSource = preprocespredictors (documentsGerman,encGerman);documentsenglish = cat(1,dataTarget{:});sequencesTarget = doc2sequence(encEnglish, documentsenglish,PaddingDirection=“没有”);[XTarget,mask] = padsequences(sequencesTarget,2,PaddingValue=1);decoderInput = XTarget(:,1,:);XTarget(:,1,:) = [];掩码(:,1,:)= [];结束

预测器预处理函数

preprocessPredictors函数对源文档进行预处理,用于训练或预测。该函数将标记文档数组编码为数字索引序列。

函数XSource = preprocespredictors (documentsGerman,encGerman) sequencesSource = doc2sequence(encGerman,documentsGerman,PaddingDirection=“没有”);XSource = padsequences(sequencesSource,2);结束

参考书目

  1. Chorowski, Jan, Dzmitry Bahdanau, Dmitriy Serdyuk, Kyunghyun Cho和Yoshua Bengio。“基于注意力的语音识别模型”预印本,提交于2015年6月24日。https://arxiv.org/abs/1506.07503。

  2. Bengio, Samy, Oriol Vinyals, Navdeep Jaitly和Noam Shazeer。用循环神经网络进行序列预测的计划采样预印本,2015年9月23日提交。https://arxiv.org/abs/1506.03099。

  3. Amodei, Dario, Sundaram Ananthanarayanan, Rishita Anubhai,白敬良,Eric Battenberg, Carl Case, Jared Casper等。“深度语音2:英语和普通话的端到端语音识别”在<引用>机器学习研究的进程 48(2016):173-182。

  4. Papineni, Kishore, Salim Roukos, Todd Ward和Wei-Jing Zhu。《BLEU:机器翻译的自动评价方法》在计算语言学协会第40届年会论文集(2002): 311 - 318。

另请参阅

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

相关的话题