【DL】第15章 使用RNN 和 CNN处理序列

  大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流

个人主页-Sonhhxg_柒的博客_CSDN博客 

欢迎各位→点赞 + 收藏⭐️ + 留言​

系列专栏 - 机器学习【ML】 自然语言处理【NLP】  深度学习【DL】

 foreword

✔说明⇢本人讲解主要包括Python、机器学习(ML)、深度学习(DL)、自然语言处理(NLP)等内容。

如果你对这个系列感兴趣的话,可以关注订阅哟

这击球手击球。外野手立即开始奔跑,预测球的轨迹。他跟踪它,调整他的动作,最后抓住它(在雷鸣般的掌声中)。预测未来是你一直在做的事情,无论你是完成朋友的一句话,还是期待早餐时咖啡的味道。在本章中,我们将讨论循环神经网络(RNN),这是一类可以预测未来的网络(当然,在一定程度上)。他们可以分析股票价格等时间序列数据,告诉你何时买入或卖出。在自动驾驶系统,他们可以预测汽车轨迹并帮助避免事故。更一般地说,他们可以处理任意长度的序列,而不是像我们目前考虑的所有网络那样处理固定大小的输入。例如,他们可以将句子、文档或音频样本作为输入,使它们对于自然语言处理应用程序非常有用,例如自动翻译或语音到文本。

在本章中,我们将首先了解 RNN 的基本概念以及如何使用反向传播来训练它们,然后我们将使用它们来预测时间序列。之后,我们将探讨 RNN 面临的两个主要困难:

  • 不稳定的梯度(在第 11 章中讨论),可以使用各种技术来缓解,包括循环丢失和循环层归一化

  • 一个(非常)有限的短期记忆,可以使用 LSTM 和 GRU 单元进行扩展

RNN 并不是唯一能够处理序列数据的神经网络类型:对于小序列,常规密集网络可以解决问题;对于非常长的序列,例如音频样本或文本,卷积神经网络实际上也可以很好地工作。我们将讨论这两种可能性,我们将完成本章通过实现WaveNet:这是一种 CNN 架构,能够处理数万个时间步长的序列。在第 16 章中,我们将继续探索 RNN,并了解如何将它们用于自然语言处理,以及基于注意力机制的最新架构。让我们开始吧!

循环神经元和层

向上到目前为止,我们专注于前馈神经网络,其中激活仅在一个方向上流动,从输入层到输出层(附录 E中讨论了一些例外情况)。循环神经网络看起来很像前馈神经网络,除了它也有向后指向的连接。让我们看一下最简单的 RNN,它由一个神经元接收输入、产生输出并将输出发送回自身,如图 15-1(左)所示。在每个时间步 t(也称为),这个循环神经元接收输入t )以及它自己的前一个时间步的输出,t –1)。由于在第一个时间步没有之前的输出,所以一般设置为 0。我们可以对照时间轴来表示这个微小的网络,如图 15-1(右)所示。这个被称为随时间展开网络(它是每个时间步表示一次的相同循环神经元)。

【DL】第15章 使用RNN 和 CNN处理序列_第1张图片

图 15-1。一个循环神经元(左)随着时间展开(右)

您可以轻松创建一层循环神经元。在每个时间步t,每个神经元都接收输入向量t )和前一时间步t –1)的输出向量,如图 15-2所示。请注意,现在输入和输出都是向量(当只有一个神经元时,输出是标量)。

 

图 15-9。LSTM 单元

现在让我们打开盒子吧!关键思想是网络可以学习在长期状态下存储什么、丢弃什么以及从中读取什么。由于长期状态t –1)从左到右遍历网络,可以看到它首先经过一个遗忘门,删除一些记忆,然后通过加法操作添加一些新记忆(添加由输入门选择的记忆)。结果t )直接发送出去,没有任何进一步的转换。因此,在每个时间步,一些记忆被删除,一些记忆被添加。而且,加法运算后,将长期状态复制并通过tanh函数,然后将结果过滤输出门。这会产生短期状态t )(等于该时间步的单元输出t ))。现在让我们看看新的记忆是从哪里来的,以及这些门是如何工作的。

首先,当前输入向量t )和之前的短期状态t –1)被馈送到四个不同的全连接层。它们都有不同的用途:

  • 主层是输出t )的层。它具有分析当前输入t )和先前(短期)状态t –1)的通常作用。在一个基本单元中,除了这一层之外没有其他任何东西,它的输出直接输出到t )和t )。相比之下,在 LSTM 单元中,这一层的输出不会直接输出,而是将其最重要的部分存储在长期状态中(其余部分被丢弃)。

  • 其他三层是门控制器。由于它们使用逻辑激活函数,因此它们的输出范围从 0 到 1。如您所见,它们的输出被馈送到逐元素乘法运算,因此如果它们输出 0,则关闭门,如果输出 1,则打开门. 具体来说:

    • 遗忘门(由t )控制)控制应该擦除长期状态的哪些部分。

    • 输入门(由t )控制)控制应将t )的哪些部分添加到长期状态。

    • 最后,输出门(由t )控制)控制长期状态的哪些部分应该在这个时间步被读取并输出到t )和t )。

简而言之,一个 LSTM 单元可以学习识别一个重要的输入(这就是输入门的作用),将其存储在长期状态中,只要需要就保存它(这就是遗忘门的作用) , 并在需要时提取它。这就解释了为什么这些细胞在捕捉时间序列、长文本、录音等中的长期模式方面取得了惊人的成功。

公式 15-3总结了如何计算单元的长期状态、短期状态以及单个实例在每个时间步的输出(整个小批量的公式非常相似)。

公式 15-3。LSTM 计算

【DL】第15章 使用RNN 和 CNN处理序列_第2张图片

在这个等式中:

  • xi , xf , xo , xg是四层中每一层与输入向量t )的连接的权重矩阵。

  • hihfWhohg是四层中每一层的权重矩阵,用于连接到先前的短期状态t –1)。

  • ifog是四层中每一层的偏置项。请注意,TensorFlow 将f初始化为一个满是 1 而不是 0 的向量。这可以防止在训练开始时忘记一切。

窥孔连接(Peephole connections

在常规 LSTM 单元中,门控制器只能查看输入t )和之前的短期状态t –1)。通过让他们窥视长期状态来给他们更多背景可能是个好主意。这个想法是由 Felix Gers 和 Jürgen Schmidhuber 在 2000 年提出的。10他们提出了一个 LSTM 变体额外的连接称为窥视孔连接:先前的长期状态t –1)作为输入添加到遗忘门和输入门的控制器,当前长期状态t )作为输入添加到输出门的控制器。这通常会提高性能,但并非总是如此,并且没有明确的模式可以确定哪些任务有或没有它们更好:你必须在你的任务上尝试它,看看它是否有帮助。

在 Keras 中,LSTM图层基于keras.layers.LSTMCell单元格,不支持窥视孔。但是,实验tf.keras.experimental.PeepholeLSTMCell确实如此,因此您可以创建一个keras.layers.RNN层并将 a 传递PeepholeLSTMCell给它的构造函数。

LSTM 单元还有许多其他变体。一个特别流行的变体是 GRU 单元,我们现在来看看。

GRU 细胞

控循环单元(GRU) 单元(见图 15-10)由 Kyunghyun Cho 等人提出。在2014 年的一篇论文11中,该论文还介绍了我们之前讨论的编码器-解码器网络。【DL】第15章 使用RNN 和 CNN处理序列_第3张图片

图 15-10。GRU细胞

GRU 单元是 LSTM 单元的简化版本,它的性能似乎和12一样好(这解释了它越来越受欢迎)。这些是主要的简化:

  • 两个状态向量合并为一个向量t )。

  • 单个门控制器t )控制遗忘门和输入门。如果门控制器输出 1,则忘记门打开 (= 1),输入门关闭 (1 – 1 = 0)。如果它输出 0,则相反。换句话说,每当必须存储内存时,首先将存储它的位置擦除。这实际上是 LSTM 单元本身的一个常见变体。

  • 没有输出门;在每个时间步输出完整的状态向量。但是,有一个新的门控制器t )控制先前状态的哪一部分将显示给主层 ( t ) )。

公式 15-4总结了如何计算单个实例在每个时间步的单元状态。

公式 15-4。GRU 计算

【DL】第15章 使用RNN 和 CNN处理序列_第4张图片

Keras 提供了一个keras.layers.GRU层(基于keras.layers.GRUCell内存单元);使用它只是替换SimpleRNNLSTMGRU.

LSTM 和 GRU 单元是 RNN 成功的主要原因之一。然而,虽然它们可以处理比简单 RNN 长得多的序列,但它们的短期记忆仍然相当有限,而且它们很难在 100 个时间步或更多时间步长的序列中学习长期模式,例如音频样本、长时间系列或长句。解决这个问题的一种方法是缩短输入序列,例如使用 1D 卷积层。

使用一维卷积层处理序列

在第 14 章中,我们看到 2D 卷积层通过在图像上滑动几个相当小的内核(或过滤器)来工作,产生多个 2D 特征图(每个内核一个)。类似地,一维卷积层在一个序列中滑动几个内核,每个内核生成一个一维特征图。每个内核将学习检测一个非常短的序列模式(不超过内核大小)。如果您使用 10 个内核,则该层的输出将由 10 个 1 维序列(长度相同)组成,或者等效地您可以将此输出视为单个 10 维序列。这意味着您可以构建一个由循环层和一维卷积层(甚至一维池化层)混合组成的神经网络。如果您使用步长为 1 的一维卷积层,并且"same"填充,则输出序列将与输入序列具有相同的长度。但是如果你使用"valid"填充或步幅大于 1,那么输出序列将比输入序列短,因此请确保相应地调整目标。例如,以下模型与之前的模型相同,不同之处在于它从一维卷积层开始,将输入序列下采样 2 倍,步幅为 2。内核大小大于步幅,因此所有输入将用于计算层的输出,因此模型可以学会保留有用的信息,只丢弃不重要的细节。通过缩短序列,卷积层可以帮助GRU层检测更长的模式。请注意,我们还必须裁剪目标中的前三个时间步长(由于内核的大小为 4,卷积层的第一个输出将基于输入时间步长 0 到 3),并将目标下采样一个因子2:

model = keras.models.Sequential([
    keras.layers.Conv1D(filters=20, kernel_size=4, strides=2, padding="valid",
                        input_shape=[None, 1]),
    keras.layers.GRU(20, return_sequences=True),
    keras.layers.GRU(20, return_sequences=True),
    keras.layers.TimeDistributed(keras.layers.Dense(10))
])

model.compile(loss="mse", optimizer="adam", metrics=[last_time_step_mse])
history = model.fit(X_train, Y_train[:, 3::2], epochs=20,
                    validation_data=(X_valid, Y_valid[:, 3::2]))

如果你训练和评估这个模型,你会发现它是迄今为止最好的模型。卷积层真的很有帮助。事实上,实际上可以只使用 1D 卷积层并完全放弃循环层!

WaveNet

在13 Aaron van den Oord 和其他 DeepMind 研究人员在 2016 年的一篇论文中介绍了一种名为WaveNet的架构。他们堆叠了 1D 卷积层,使每一层的扩张率(每个神经元输入的分散程度)加倍:第一个卷积层一次只能看到两个时间步长,而下一个卷积层看到四个时间步长(它的接受字段有四个时间步长),下一个看到八个时间步长,依此类推(见图 15-11)。这样,较低层学习短期模式,而较高层学习长期模式。由于双倍扩张率,网络可以非常有效地处理非常大的序列。【DL】第15章 使用RNN 和 CNN处理序列_第5张图片

图 15-11。WaveNet 架构

在 WaveNet 论文中,作者实际上堆叠了 10 个卷积层,膨胀率为 1、2、4、8、...、256、512,然后他们堆叠了另一组 10 个相同的层(膨胀率为 1、2、4、 8, ..., 256, 512),然后是另一个相同的 10 层组。他们通过指出具有这些膨胀率的 10 个卷积层的单个堆栈将充当具有大小为 1,024 的内核的超高效卷积层来证明这种架构的合理性(除了更快、更强大和使用更少的参数),这这就是为什么他们堆叠了 3 个这样的积木。他们还在每一层之前用与膨胀率相等的零数填充输入序列,以在整个网络中保持相同的序列长度。下面是如何实现一个简化的 WaveNet 来处理相同的序列较早:14

model = keras.models.Sequential()
model.add(keras.layers.InputLayer(input_shape=[None, 1]))
for rate in (1, 2, 4, 8) * 2:
    model.add(keras.layers.Conv1D(filters=20, kernel_size=2, padding="causal",
                                  activation="relu", dilation_rate=rate))
model.add(keras.layers.Conv1D(filters=10, kernel_size=1))
model.compile(loss="mse", optimizer="adam", metrics=[last_time_step_mse])
history = model.fit(X_train, Y_train, epochs=20,
                    validation_data=(X_valid, Y_valid))

Sequential模型从显式输入层开始(这比尝试input_shape仅在第一层上设置更简单),然后使用"causal"填充继续使用 1D 卷积层:这确保了卷积层在进行预测时不会窥视未来(它相当于在左侧用正确数量的零填充输入并使用"valid"填充)。然后我们添加类似的使用不断增长的膨胀率的层对:1、2、4、8,然后是 1、2、4、8。最后,我们添加输出层:具有 10 个大小为 1 的滤波器且没有任何激活函数的卷积层。由于填充层,每个卷积层都输出与输入序列长度相同的序列,因此我们在训练期间使用的目标可以是完整序列:无需裁剪或下采样。

最后两个模型在预测我们的时间序列方面提供了迄今为止最好的性能!在 WaveNet 论文中,作者在包括文本到语音的任务在内的各种音频任务(因此得名该架构)上实现了最先进的性能,在多种语言中产生了令人难以置信的逼真声音。他们还使用该模型生成音乐,一次一个音频样本。当您意识到一秒钟的音频可以包含数万个时间步长时,这一壮举就更加令人印象深刻了——即使 LSTM 和 GRU 也无法处理如此长的序列。

在第 16 章中,我们将继续探索 RNN,我们将了解它们如何处理各种 NLP 任务。

练习

  1. 你能想到序列到序列 RNN 的一些应用吗?那么序列到向量 RNN 和向量到序列 RNN 呢?

  2. RNN 层的输入必须有多少维?每个维度代表什么?它的输出呢?

  3. 如果你想构建一个深度序列到序列的 RNN,应该有哪些 RNN 层return_sequences=True?那么序列到向量 RNN 呢?

  4. 假设您有一个每日单变量时间序列,并且您想要预测接下来的 7 天。你应该使用哪种 RNN 架构?

  5. 训练 RNN 的主要困难是什么?你怎么能处理它们?

  6. 你能画出 LSTM 单元的架构吗?

  7. 为什么要在 RNN 中使用一维卷积层?

  8. 您可以使用哪种神经网络架构对视频进行分类?

  9. 为 TensorFlow 数据集中提供的 SketchRNN 数据集训练分类模型。

  10. 下载巴赫合唱数据集并解压缩。它由约翰·塞巴斯蒂安·巴赫创作的 382 首合唱曲组成。每个合唱的长度为 100 到 640 个时间步长,每个时间步包含 4 个整数,其中每个整数对应于钢琴上的音符索引(值 0 除外,表示不演奏音符)。训练一个模型——循环的、卷积的或两者兼有——它可以预测下一个时间步(四个音符),给定来自合唱的一系列时间步。然后使用这个模型生成类似巴赫的音乐,一次一个音符:你可以通过给模型一个合唱的开头并要求它预测下一个时间步长来做到这一点,然后将这些时间步长附加到输入序列和向模型询问下一个音符,依此类推。还要确保查看Google 的 Coconet 模型,它被用于一个关于巴赫的漂亮谷歌涂鸦。

附录 A中提供了这些练习的解决方案。

1请注意,许多研究人员更喜欢在 RNN 中使用双曲正切 (tanh) 激活函数,而不是 ReLU 激活函数。例如,看看 Vu Pham 等人 2013 年的论文“Dropout Improvements Recurrent Neural Networks for Handwriting Recognition”。基于 ReLU 的 RNN 也是可能的,如 Quoc V. Le 等人 2015 年的论文“A Simple Way to Initialize Recurrent Networks of Rectified Linear Units”所示。

2请注意,一个层相当于一个层。TimeDistributed(Dense(n))Conv1D(n, kernel_size=1)

3César Laurent 等人,“Batch Normalized Recurrent Neural Networks” ,IEEE 国际声学、语音和信号处理会议论文集(2016 年):2657-2661。

4Jimmy Lei Ba 等人,“Layer Normalization”,arXiv 预印本 arXiv:1607.06450 (2016)。

5相反,继承会更简单,SimpleRNNCell这样我们就不必创建内部SimpleRNNCell或处理state_sizeandoutput_size属性,但这里的目标是展示如何从头开始创建自定义单元格。

6动画电影《海底总动员》和《海底总动员》中出现短期记忆丧失的角色。

7Sepp Hochreiter 和 Jürgen Schmidhuber,“长期短期记忆”,神经计算9,第 8 期(1997 年):1735-1780。

8Haşim Sak 等人,“用于大词汇语音识别的基于长短期记忆的递归神经网络架构”,arXiv 预印本 arXiv:1402.1128 (2014)。

9Wojciech Zaremba 等人,“循环神经网络正则化”,arXiv 预印本 arXiv:1409.2329 (2014)。

10FA Gers 和 J. Schmidhuber,“Recurrent Nets That Time and Count” ,IEEE-INNS-ENNS 国际神经网络联合会议论文集(2000 年):189-194。

11Kyunghyun Cho 等人,“Learning Phrase Representations Using RNN Encoder-Decoder for Statistical Machine Translation” ,2014 年自然语言处理经验方法会议论文集(2014 年):1724-1734。

12Klaus Greff 等人在 2015 年发表的一篇论文“LSTM:A Search Space Odyssey”似乎表明所有 LSTM 变体的性能大致相同。

13Aaron van den Oord 等人,“WaveNet:原始音频的生成模型”,arXiv 预印本 arXiv:1609.03499 (2016)。

14完整的 WaveNet 使用了更多技巧,例如像 ResNet 中的跳过连接,以及类似于 GRU 单元中的门控激活单元。请参阅笔记本了解更多详细信息。

你可能感兴趣的