神经网络的序列学习和 NLP

序列学习指的是神经网络可以培训执行的各种相关任务. 所有这些任务的相同之处是网络的输入是某种序列. 输入通常是可变长度,这意味着网络可以同等运作于短或长序列.
区别各种序列学习任务的是网络输出的格式. 这里,有各种各样的技术对应于输出的格式:
在本教程中,给出大部分技术的简单范例.
序列回归

整数相加

在该范例中,网络被培训成相加两个二位数的整数. 问题的困难所在是输入是字符串而不是数值,而输出是数值. 例如,网络接受输入 "25+33" 且需要返回接近 58 的实数. 注意,输入是可变长度,培训数据包括长度 3 ("5+5")、长度 4 ("5+10") 和长度 5 ("10+10") 的范例.
基于描述两位数相加的字符串和对应的数值结果创建培训数据:
创建一个由循环层链组成的网络来读取输入字符串并预测数字结果:
培训网络:
把培训网络应用于输入列表:
序列分类

情绪分析

培训分类器,分类电影评论片段为 "positive""negative".
首先,获取培训和测试数据:
定义网络,接受单词字符串作为输入并返回 "positive""negative"
培训两轮培训的网络:
根据测试集的范例计算已培训的网络,获取概率:
序列到序列学习
序列到序列是一个学习任务,其中输入和预测的输出是序列. 任务,诸如:把德语翻成英文,从音频文件中转录演讲,排序数字列表等是该任务的范例.

固定长度输出的整数相加

该范例演示如何培训网络接受变长度序列作为输入,预测固定长度序列作为输出. 我们接受一个字符串描述和,例如:"250+123",并产生输出字符串描述答案,例如:"373".
基于描述三位数相加的字符串和相应作为字符串的结果创建培训数据. 为了使输出为固定长度,所有输出被填充为最大长度 4(因为最大值为 999+999=1998):
定义一个网络,接受字符串作为输入并返回另一个长度为 4 的字符串:
培训 40 轮培训的网络:
把网络应用于某些范例:
获取测试集上网络的精确度:

带有变长度输出的整数相加

该范例演示了如何在序列上培训网络,其中,输入和输出是变长度序列,且不一样. 该任务的一个复杂范例是把英文翻成德文,但是,我们要演示的范例是一个更简单的问题:接受一个描述和的字符串,例如:"250+123",并产生一个输出字符串描述答案,例如,"373". 该方法是基于 2014 年的 I. Sutskever 等写的, "Sequence to Sequence Learning with Neural Networks".
基于描述三位数相加的字符串和对应的字符串结果创建培训数据:
创建一个 NetEncoder,为字符串的起始和结尾使用特殊代码,这将被用于表明输出序列的起始和结束:
计算输入字符串的编码器:
为输入创建类似的编码器,其中包含 "+":
定义一个网络,接受输入序列,返回大小为 150 的单个向量输出:
定义一个网络,接受输入向量大小为 150 以及向量序列输入,返回向量序列输出:
定义一个带有 CrossEntropyLossLayer 的网络,包含编码器和解码器网络:
培训网络(该过程一般称之为teacher forcing):
3 位数整数相加的情况,只有 1999 种可能的输出. 计算每个可能输出的损失并找到最小的损失是可行的:
预测输出,给定输入数字和已培训的网络:
给定输入,还可以可视化每个输出的损失:
获取预测更有效的方法是产生输出直到到达 EndOfString 可视化字符.
首先,从已培训的 NetGraph 提取培训的编码器解码器子网络,并附加合适的编码器和解码器:
使用 SequenceLastLayer 制作解码器,给定之前字符,只产生答案的最后字符的预测. 这里为概率向量附加字符解码器,使用同样的字母作为目标输入:
对部分答案应用解码器:
当解码器预测到目标字符串的末尾,会产生一个空字符串:
现在定义一个预测函数,接受编码器解码器网络和输入字符串. 函数会计算连续更长的结果直到解码器声称已经完成:
对输入数据计算该预测函数:
这是第一种方法的一个很好的近似,它找到了精确的最大似然性答案:
通过将每个部分答案传递给解码器网络以导出下一个字符而产生的幼稚技术具有 n2 的时间复杂度,其中 n 是输出序列的长度,因此不适合于生成更长的序列. NetStateObject 用于生成 n 的时间复杂度.
首先,创建一个解码器接受单个字符并预测下一个字符. GatedRecurrentLayer 的循环状态由 NetStateObject 在更晚的点处理.
根据培训网络,获取培训 GatedRecurrentLayerLinearLayer
定义一个 "Class" 编码器和解码器,编码和解码单独字符,以及特殊类,指明字符串的起始和结束:
定义一个网络,接受单个字符,运行 GatedRecurrentLayer 的一个步骤并产生单个 softmax 预测:
该预测器由内部循环状态,由 Information 显示:
创建一个使用 NetStateObject 的函数,记住内部循环状态,它是由训练过的编码器产生的代码播种的:
把函数应用于某些输入获取预测的序列:
获取测试集上培训网络的精确度:

整数排序

在该范例中,培训网络来排序整数列表. 例如,网络接受输入 {3,2,4} 并且需要返回 {2,3,4}. 该范例也演示了 AttentionLayer 的使用,它显著改善了神经网络在许多序列学习任务中的性能.
生成一个测试和培训集,包括介于 1 和 6 之间的整数列表:
显示来自于培训集的 3 个随机样本:
AttentionLayer 定义 NetGraph
培训网络:
使用网络排序整数列表:

玩具数据集上的光字符识别 (OCR)

光字符识别问题是接受包含字符序列的图像,返回字符列表. 一个简单的方法是预处理图像,产生只包含单个字符的图像并进行分类. 这是很脆弱的方法,对于像连体手写会完全失败,因为字符是连在一起.
首先,产生培训和测试数据,包含单词图像和对应的单词字符串:
把数据集分成测试集和培训集:
提取培训集的 RandomSample
使用的字符集:
解码器是光束搜索解码器,光束大小为 50:
定义一个网络,接受图像,把宽维度作为序列维度. 产生概率向量序列与宽维度:
定义带有字符 NetEncoder 附加在目标端口的 CTCLossLayer
使用 CTC 损失培训网络:
计算测试集上图像的培训网络:
获取图像的前 5 个解码,以及每个解码的负对数似然性:
问题回答

bAbI QA 数据集上简单的 RNN 培训

使用循环网络在 bAbI QA 数据集的首个任务(单一支持事实)上培训问题-回答网络.
首先,获取培训和验证数据:
获取用于问题和上下文的类和字典列表:
定义网络,定义问题字符串和上下文字符串并返回答案:
培训 3 轮培训的网络. 通过使用提供给解码器的同样的类,NetTrain 会自动附加 CrossEntropyLossLayer
使用培训的网络进行预测:
获取测试集上培训网络的精确度:

bAbI QA 数据集上的内存网络培训

在 bAbI QA 数据集上的第一个任务(单个支持事实)上培训问题-回答网络,使用的内存网络基于 2015 年的 Sukhbaatar 等的 "End-to-End Memory Networks".
首先,获取培训和验证数据:
内存网络有些不支持变长度序列的层(例如,TransposeLayer).
把所有字符串转换成令牌列表,使用左填充(该例中比右填充性能更好)确保这些列表有同样的长度:
"Context" 输入现在是用 Padding 符号填充的长度为 68 的列表:
获取用于问题和上下文的类和字典列表:
定义网络:
使用 "RMSProp" 优化方法培训网络,改善了该范例的学习性能:
获取测试数据上网络的精确度:
语言模型

字符级语言模型

培训英文字符级语言模型.
首先,从 2 部小说中 25 个字符,创建 300,000 培训范例:
数据又有分类格式的问题:给定字符序列,预测下一个. 数据样本:
获取文本中所有字符列表:
定义一个网络,接受字符字符串并返回下一字符的预测:
培训网络. 在 CPU 上大概需要 1 个小时,如果有 NVIDIA 图卡,就使用 TargetDevice->"GPU". 现代 GPU 大约 7 分钟就可以完成该范例:
给定字符序列,预测下一字符:
给定起始文本,产生 100 个文本字符. 注意,该方法使用 NetStateObject 高效产生文本的长序列:
通过采样预测的概率分布获取更有趣的文本:
该学习问题的其他等价公式只需要单个字符串作为输入,从网络内部剩余序列分离最后一个字符.
使用图中的 SequenceMostLayerSequenceLastLayer 从剩余部分分离最后字符:
根据原始培训数据在输入序列中培训该网络(从技术上讲,这意味着你最终会以略短的序列训练网络):
训练语言模型的更有效方法是 "teacher forcing",网络同时预测整个序列,而不只是最后字母.
首先,构建预测整个序列的网络. 这个与之前的预测网络不同,之前是映射 LinearLayer 并执行矩阵 softmax,而不是采集最后元素,进行常规向量 softmax:
现在构建强迫网络,接受目标句子,并以交错形式展现在网络上:对于长度为 26 的句子,对网络展现字符 1 到 25,为字符 2 到 26 产生预测,通过 CrossEntropyLossLayer 比较真实字符产生损失:
根据原始数据对输入序列培训网络. 对于典型 CPU,这个应该花 15 分钟,在现代 GPU 上大概 2 分钟. 既然 teacher forcing 是更有效的技术,你可以使用更少的培训轮回:
从结果中提取预测链:
构建单个字符预测链:
测试预测器:
给定起始文本,产生 100 个字符文本. 注意,该方法使用 NetStateObject 高效地产生长文本序列:
通过采样预测的概率分布可以获取更多有趣的文本: