主要内容

基于深度学习的语言翻译

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

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

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

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

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

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

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

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

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

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

discardProp = 0.70;

负荷训练数据

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

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

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

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

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

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

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

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

idx = size(data,1) - floor(discardProp*size(data,1)) + 1;数据(idx:最终,)= [];

查看剩余观察数。

大小(数据,1)
ans = 68124

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

trainingProp = 0.9;idx = randperm(大小(数据,1),地板(trainingProp *大小(数据,1)));dataTrain =数据(idx:);人数(=数据;人数((idx:) = [];

查看训练数据的前几行。

头(dataTrain)
ans =8×2表源目标  ___________________________________ _________________________ " 汤姆erschoss玛丽。”“汤姆玛丽。”“Ruf mich bite an。”“请给我打电话。”“Kann das einer nachprüfen?”“谁能检查一下这个吗?”“Das lasse ich mir nicht 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 =大小(dataTrain, 1)
numObservationsTrain = 61311

数据进行预处理

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

documentsGerman = preprocessText (dataTrain.Source);

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

encGerman = wordEncoding (documentsGerman);

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

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

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

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

定义编码器和解码器网络

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

方法创建编码器和解码器网络languageTranslationLayers函数,作为支持文件附加到本示例中。要访问此函数,请将示例作为实时脚本打开。

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

2021 - 04 - 12 _15 - 00 - 44. png

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

2021 - 04 - 12 _15 - 17 - 24. png

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

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

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

netEncoder = dlnetwork (lgraphEncoder);netDecoder = dlnetwork (lgraphDecoder);

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

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

定义模型损失函数

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

指定培训选项

用64个小批次训练15个课时,学习率为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],这是一种改进粗糙序列训练的策略,先训练一个历元,然后按序列排序,之后每个历元洗牌一次。

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

sequenceLengths = doclength (documentsGerman);[~, idx] = (sequenceLengths)进行排序;documentsGerman = documentsGerman (idx);documentsEnglish = documentsEnglish (idx);

火车模型

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

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

adsSource = arrayDatastore (documentsGerman);adsTarget = arrayDatastore (documentsEnglish);cd =结合(adsSource adsTarget);

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

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

  • 输出dlarray具有以下格式的“施”(通道、时间、批次)。

  • 丢弃任何部分小批量。

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

初始化训练进度图。

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

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

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

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

numIterationsPerEpoch =地板(numObservationsTrain / miniBatchSize);numIterations = numIterationsPerEpoch * numEpochs;ε= linspace (epsilonStart epsilonEnd numIterations);

火车模型。每一次迭代:

  • 从小批队列读取小批数据。

  • 计算模型损失和梯度。

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

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

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

在每个历元结束时,洗牌小批处理队列。

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

迭代= 0;开始=抽搐;lossMin =正;重置(兆贝可)循环遍历各个时代。时代= 1:numEpochs在小批量上循环。Hasdata (mbq)迭代=迭代+ 1;读取小批数据。[X, T, maskT decoderInput] =下一个(兆贝可);%计算损失和梯度。(损失、gradientsEncoder gradientsDecoder YPred] = dlfeval (@modelLoss, netEncoder netDecoder X T maskT, decoderInput,ε(迭代));使用adamupdate更新网络可学习参数。[netEncoder, trailingAvgEncoder,trailingAvgSqEncoder] = adamupdate(netEncoder,gradientsEncoder,trailingAvgEncoder,trailingAvgSqEncoder,...迭代,learnRate、gradientDecayFactor squaredGradientDecayFactor);[netDecoder, trailingAvgDecder,trailingAvgSqDecoder] = adamupdate(netDecoder,gradientsDecoder,trailingAvgDecder,trailingAvgSqDecoder,...迭代,learnRate、gradientDecayFactor squaredGradientDecayFactor);为情节生成翻译。如果迭代== 1 || mod(迭代,10)== 0 strGerman = ind2str(X(:,1,:),encGerman);strEnglish = ind2str (T (: 1:), encEnglish,面具= maskT);strTranslated = ind2str (YPred (: 1:), encEnglish);结束%显示训练进度。D =持续时间(0,0,toc(开始),格式=“hh: mm: ss”);损失=双(收集(extractdata(损失)));addpoints (lineLossTrain、迭代、失去)标题(...”时代:“+时代+”,过去:“字符串(D) +换行符+...“来源:”+ strGerman + newline +...目标:“+ english +换行符+...“训练翻译:“+ strTranslated) drawnow%保存最好的网络。如果loss < lossMin;netBest.netEncoder = netEncoder;netBest.netDecoder = netDecoder;netBest。损失=损失;netBest。迭代=迭代;netBest。D = D;结束结束%洗牌。洗牌(兆贝可);结束

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

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

netBest。encGerman = encGerman;netBest。encEnglish = encEnglish;D = datetime (“现在”格式=“yyyy_MM_dd__HH_mm_ss”);文件名=“net_best__”字符串(D) + +“.mat”;保存(文件名,“netBest”);

提取最好的网络netBest

netEncoder = netBest.netEncoder;netDecoder = netBest.netDecoder;

测试模型

为了评估译文的质量,可以使用双语评价替角(BLEU)评分算法[4]

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

strTranslatedTest = translateText (netEncoder netDecoder、encGerman encEnglish, dataTest.Source);

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

numObservationsTest =规模(人数(1);idx = randperm (numObservationsTest 8);台=表;资源描述。源= dataTest.Source (idx);资源描述。Target = dataTest.Target(idx); tbl.Translated = 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 ="");= preprocessText(人数(引用。目标,StartToken =""StopToken ="");

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

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

最小长度= min ([doclength(候选人);doclength(引用)])
最小长度= 2

如果最短文档的标记少于4个,则将n-gram权重设置为长度与最短文档匹配的向量,其权重之和为1。否则,指定的n克权重[0.25 0.25 0.25 0.25].注意,如果最小长度1(因此n克权重也是1),那么bleuEvaluationScore函数可能返回意义较低的结果,因为它只比较单个单词(unigrams),而不比较任何n-gram(多词短语)。

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

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

i = 1:numObservationsTest score(i) = bluevaluationscore (candidate (i),references(i),NgramWeights= NgramWeights);结束

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

图直方图(分数);标题(“蓝色的评估分数”)包含(“分数”) ylabel (“频率”

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

[~, idxSorted] =排序(得分,“下”);idx = idxSorted (1:8);台=表;资源描述。源= dataTest.Source (idx);资源描述。Target = dataTest.Target(idx); tbl.Translated = 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:结束);台=表;资源描述。源= dataTest.Source (idx);资源描述。Target = dataTest.Target(idx); tbl.Translated = strTranslatedTest(idx)
台=8×3表源目标翻译  _______________________________________________________________ __________________________ ____________________________ " 这田螺萤石埃森人。”“这些蜗牛是可以吃的。”“这个可以吃”“Sie stehen noch zu Verfügung”“他们仍然可用。”"它还在. . . . . ." "Diese Schraube past zu dieser Mutter "“这个螺栓适合这个螺母。”“这人生太. . . . .”“Diese Puppe gehört mir。”“这个娃娃是我的。”“这个是我的。”“Das ist 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?”“你叫黑ßen您?”“Das Wetter ist heute gut。”];

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

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

预测功能

束搜索功能

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

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

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

  • BeamIndex——梁指数。默认值为3。

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

函数str = beamSearch (X, netEncoder netDecoder encEnglish, args)解析输入参数。参数X netEncoder netDecoder encEnglish args。BeamIndex = 3;arg游戏。MaxNumWords = 10;结束beamIndex = args.BeamIndex;maxNumWords = args.MaxNumWords;startToken =“<开始>”;stopToken =“<停止>”%编码器预测。[Z, hiddenState, cellState] = predict(netEncoder,X);%初始化上下文。miniBatchSize =大小(X, 2);numHiddenUnits =大小(Z, 1);context = zero ([numHiddenUnits miniBatchSize],“喜欢”, Z);上下文= dlarray(上下文,“CB”);%初始化的候选人。候选人=结构;候选人。话说= startToken;候选人。分数= 0;候选人。StopFlag=false; candidates.HiddenState = hiddenState; candidates.CellState = cellState;循环单词。t = 0;t < maxNumWords t = t + 1;candidatesNew = [];循环遍历候选者。i = 1:元素个数(候选人)%当预测到停止令牌时停止生成。如果候选人(i)。StopFlag继续结束%的候选人的细节。话说=候选人(我).Words;得分=(我).Score候选人;.HiddenState hiddenState =候选人(我);.CellState cellState =候选人(我);%预测下一个令牌。decoderInput = word2ind (encEnglish,言语(结束));decoderInput = dlarray (decoderInput,“认知行为治疗”);[YPred、上下文hiddenState, cellState] =预测(netDecoder、decoderInput hiddenState, cellState,上下文,Z,...输出= [“softmax”“背景”“lstm2 /隐藏”“lstm2 /细胞”]);找出最热门的预测。[scoresTop, idxTop] = maxk (extractdata (YPred) beamIndex);idxTop =收集(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 candidate];结束结束找最好的候选人。[~, idx] = maxk ([candidatesNew.Score], beamIndex);候选人= candidatesNew (idx);当所有候选者都有停止令牌时停止预测。如果([candidates.StopFlag])打破结束结束找最好的候选人。话说= (1).Words候选人;%转换为字符串标量。words(ismember(words,[startToken stopToken])) = [];str =加入(单词);结束

翻译文本功能

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

函数strTranslated = translateText (netEncoder netDecoder、encGerman encEnglish, strGerman, args)解析输入参数。参数netEncoder netDecoder encGerman encEnglish strGerman args。BeamIndex = 3;结束beamIndex = args.BeamIndex;%预处理文本。documentsGerman = preprocessText (strGerman);X = preprocessPredictors (documentsGerman encGerman);X = dlarray (X,“施”);循环观察。numObservations =元素个数(strGerman);strTranslated =字符串(numObservations, 1);n = 1: numObservations%翻译文本。strTranslated (n) = beamSearch (X (n,::), netEncoder, netDecoder, encEnglish, BeamIndex = BeamIndex);结束结束

模型函数

损失函数模型

modelLoss函数以编码器网络、解码器网络、小批量预测器作为输入X、目标T,对应于目标的填充掩码maskT, ϵ 计划采样的值。函数返回损失,损失相对于网络中可学习参数的梯度gradientsE而且gradientsD,解码器预测YPred编码为单热向量的序列。

函数(损失、gradientsE gradientsD YPred] = modelLoss (netEncoder netDecoder X T maskT, decoderInput,ε)%通过编码器前进。[Z, hiddenState, cellState] = forward(netEncoder,X);%解码器输出。Y = decoderPredictions (netDecoder, Z, T, hiddenState cellState, decoderInput,ε);稀疏交叉熵损失。损失= sparseCrossEntropy (Y, T, maskT);%更新梯度。[gradientsE, gradientsD] = dlgradient(损失,netEncoder.Learnables netDecoder.Learnables);对于绘图,按序列长度归一化的返回损失。sequenceLength =大小(T, 3);loss = loss ./ sequenceLength;要绘制示例翻译,返回解码器输出。YPred = onehotdecode (Y, 1:尺寸(Y, 1), 1,“单身”);结束

译码器的预测功能

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

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

2021 - 04 - 12 _15 - 35 - 48. png

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

函数Y = decoderPredictions (netDecoder, Z, T, hiddenState cellState, decoderInput,ε)%初始化上下文。numHiddenUnits =大小(Z, 1);miniBatchSize =大小(Z, 2);context = zero ([numHiddenUnits miniBatchSize],“喜欢”, Z);上下文= dlarray(上下文,“CB”);%初始化输出。idx = (netDecoder.Learnables。层= =“俱乐部”& netDecoder.Learnables.Parameter = =“偏见”);numClasses =元素个数(netDecoder.Learnables.Value {idx});sequenceLength =大小(T, 3);Y = 0 ([numClasses miniBatchSize sequenceLength],“喜欢”, Z);Y = dlarray (Y,“认知行为治疗”);%通过解码器转发开始令牌。[Y(:: 1),上下文,hiddenState, cellState] =前进(netDecoder、decoderInput hiddenState, cellState,上下文,Z);%循环剩余的时间步骤。t = 2: sequenceLength%定期采样。随机选择前一个目标或前一个%的预测。如果兰德<ε%使用目标值。decoderInput = T (:,:, T - 1);其他的使用先前的预测。[~, Yhat] = max (Y (:,:, t - 1), [], 1);decoderInput = Yhat;结束%通过解码器转发。[Y (:,:, t)背景下,hiddenState, cellState] =前进(netDecoder、decoderInput hiddenState, cellState,上下文,Z);结束结束

稀疏的熵损失

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

函数损失= sparseCrossEntropy (Y, T, maskT)%初始化损失。[~, miniBatchSize sequenceLength] =大小(Y);损失= 0 ([miniBatchSize sequenceLength],“喜欢”, Y);防止计算log为0,远离0。精度= underlyingType (Y);Y(Y < eps(精度))= eps(精度);%循环时间步骤。n = 1: miniBatchSizet = 1:sequence elength idx = t (1,n,t);损失(n, t) =日志(Y (idx n t));结束结束%应用屏蔽。maskT =挤压(maskT);loss = loss .* maskT;计算和并规范化。损失=总和(损失,“所有”);loss = loss / miniBatchSize;结束

预处理功能

文本预处理功能

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

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

Mini-Batch预处理功能

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

函数[XSource,XTarget,mask,decoderInput] = preprocessMiniBatch(dataSource,dataTarget,encGerman,encEnglish) documentsGerman = cat(1,dataSource{:});XSource = preprocessPredictors (documentsGerman encGerman);documentsEngligh =猫(1,dataTarget {:});sequencesTarget = doc2sequence (encEnglish documentsEngligh PaddingDirection =“没有”);[XTarget,面具]= 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, riishita Anubhai, Jingliang Bai, 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。

另请参阅

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

相关的话题

Baidu
map