深度学习用于文本和序列
用于处理序列的两种基本的深度学习算法分别是循环神经网络和一维卷积神经网络。
循环神经网络,遍历所有序列元素,并保存一个状态,其中包含与已查看内容相关的信息。实际上,RNN是一类具有内部环恶神经网络。在处理两个不同的独立序列(比如两条不同的评论)之间,RNN的状态会被重置,因此仍可以将一个序列看作单个数据点,即网络的单个输入。真正改变的是,数据点不再是单个步骤中进行处理,相反,网络内部会对所有序列元素进行遍历。
一个简单的RNN传递过程:输入是一个张量序列,编码成(timesteps, input_features)。它对时间步(timesteps)进行遍历,在每个时间步,它考虑t时刻的当前状态和t时刻的输入(形状为input_features),对二者进行计算得到t时刻的输出。然后将下一个时间步的状态设置为上一个时间步的输出。对于第一个时间步,上一个时间步的输出没有定义,所以它没有当前状态,需要初始化为全零向量。
图1 一个简单的RNN结构
增强版的RNN——长短时记忆网络(LSTM):增加了一种携带信息跨越多个时间步的方法。假设有一条传送带,其运行方向平行于你所处理的序列。序列中的信息可以在任意位置跳上传送带,然后被传送到更晚的时间步,并在需要时原封不动地跳回来。这就是LSTM的原理:它保存信息以便后面使用,从而防止早期的信号在处理过程中逐渐消失。
图2 从simpleRNN到LSTM结构
我们向这张图像中添加额外的数据流,其中携带着跨越时间步的信息。它在不同的时间步的值叫作 Ct,其中 C 表示携带( carry)。这些信息将会对单元产生以下影响:它将与输入连接和循环连接进行运算(通过一个密集变换,即与权重矩阵作点积,然后加上一个偏置,再应用一个**函数),从而影响传递到下一个时间步的状态(通过一个**函数和一个乘法运算)。从概念上来看,携带数据流是一种调节下一个输出和下一个状态的方法(见图 2)。
下面来看这一方法的精妙之处,即携带数据流下一个值的计算方法。它涉及三个不同的变换,这三个变换的形式都和 SimpleRNN 单元相同。但这三个变换都具有各自的权重矩阵,我们分别用字母 i、 j 和 k 作为下标。
i_t = activation(dot(state_t, Ui) + dot(input_t, Wi) + bi)
f_t = activation(dot(state_t, Uf) + dot(input_t, Wf) + bf)
k_t = activation(dot(state_t, Uk) + dot(input_t, Wk) + bk)
对 i_t、 f_t 和 k_t 进行组合,可以得到新的携带状态(下一个 c_t)。
c_t+1 = i_t * k_t + c_t * f_t也许看起来有点复杂,但你不需要理解关于 LSTM 单元具体架构的任何内容。你只需要记住 LSTM 单元的作用:允许过去的信息稍后重新进入,从而解决梯度消失问题。
另外,还有一种新的结构——门控循环单元(GRU),工作原理与LSTM相同,但它做了一些简化,因此计算代价更低(虽然表示能力可能不如LSTM)。有兴趣的可以自行了解。
循环神经网络的三个高级技巧:
1.循环dropout:这是一种特征的内置方法,在循环层中使用dropout来降低过拟合。
2.堆叠循环层:这会提高网络的表示能力(代价是更高的计算负荷)。
3.双向循环层:将相同的信息以不同的方式呈现给循环网络,可以提高精度并缓解遗忘问题。
对于某些序列处理任务,一维卷积神经网络的效果可以媲美RNN,而且计算代价通常要小很多。(如音频生成,机器翻译,文本分类,时间序列预测等)
这种一维卷积层可以识别序列中的局部模式。因为对每个序列段执行相同的输入变换,所以在句子中某个位置学到的模式稍后可以在其他位置被识别,这使得一维卷积神经网络具有平移不变性(对于时间平移而言)。举个例子,使用大小为 5 的卷积窗口处理字符序列的一维卷积神经网络,应该能够学习长度 不大于 5 的单词或单词片段,并且应该能够在输入句子中的任何位置识别这些单词或单词段。因此,字符级的一维卷积神经网络能够学会单词构词法。
图3 一维卷积工作原理
你已经学过二维池化运算,比如二维平均池化和二维最大池化,在卷积神经网络中用于对图像张量进行空间下采样。一维也可以做相同的池化运算:从输入中提取一维序列段(即子序列),然后输出其最大值(最大池化)或平均值(平均池化)。与二维卷积神经网络一样,该运算也是用于降低一维输入的长度( 子采样)。
一维卷积神经网络的架构与二维卷积神经网络相同,它是 Conv1D 层和 MaxPooling1D层的堆叠,最后是一个全局池化层或 Flatten 层,将三维输出转换为二维输出,让你可以向模型中添加一个或多个 Dense 层,用于分类或回归。
不过二者有一点不同:一维卷积神经网络可以使用更大的卷积窗口。对于二维卷积层,3× 3 的卷积窗口包含 3× 3=9 个特征向量;但对于一位卷积层,大小为 3 的卷积窗口只包含 3个卷积向量。因此,你可以轻松使用大小等于 7 或 9 的一维卷积窗口。
结合RNN和CNN来处理序列:
一维卷积神经网络分别处理每个输入序列段,所以它对时间步的顺序不敏感(这里所说顺序的范围要大于局部尺度,即大于卷积窗口的大小),这一点与 RNN 不同。当然,为了识别更长期的模式,你可以将许多卷积层和池化层堆叠在一起,这样上面的层能够观察到原始输入中更长的序列段,但这仍然不是一种引入顺序敏感性的好方法。因为卷积神经网络在输入时间序列的所有位置寻找模式,它并不知道所看到某个模式的时间位置(距开始多长时间,距结束多长时间等)。
要想结合卷积神经网络的速度和轻量与 RNN 的顺序敏感性,一种方法是在 RNN 前面使用一维卷积神经网络作为预处理步骤(见图 6-30)。对于那些非常长,以至于 RNN 无法处理的序列比如包含上千个时间步的序列),这种方法尤其有用。卷积神经网络可以将长的输入序列转换为高级特征组成的更短序列(下采样)。然后,提取的特征组成的这些序列成为网络中 RNN 的输入。
图4 结合一维CNN和RNN来处理长序列