提交 a81772b0 编写于 作者: W wizardforcel

2021-01-08 21:01:59

上级 e9fb3bb8
...@@ -26,11 +26,11 @@ ...@@ -26,11 +26,11 @@
如上图所示,来自先前时间点的数据进入了当前时间点的训练。 循环架构使模型可以很好地与时间序列(例如产品销售,股票价格)或顺序输入(例如文章中的单词-DNA 序列)配合使用。 如上图所示,来自先前时间点的数据进入了当前时间点的训练。 循环架构使模型可以很好地与时间序列(例如产品销售,股票价格)或顺序输入(例如文章中的单词-DNA 序列)配合使用。
假设我们在传统的神经网络中有一些输入![](img/89abe3fc-669d-415f-b6be-dc388be531b0.png)(其中`t`代表时间步长或顺序顺序),如下图所示。 假设不同`t`处的输入彼此独立。 可以将任何时间的网络输出写为![](img/ab8c4ddc-5802-427a-b1ba-688f8c0f8fa0.png),如下所示: 假设我们在传统的神经网络中有一些输入`x[t]`(其中`t`代表时间步长或顺序顺序),如下图所示。 假设不同`t`处的输入彼此独立。 可以将任何时间的网络输出写为`h[t] = f(x[t])`,如下所示:
![](img/b84d3a24-c102-4c42-ad72-7ad5a000340f.png) ![](img/b84d3a24-c102-4c42-ad72-7ad5a000340f.png)
在 RNN 中,反馈回路将当前状态的信息传递到下一个状态,如下图的网络展开版本所示。 RNN 网络在任何时间的输出都可以写成![](img/c1fb0b1b-45bd-4f39-910f-5f24a490db48.png)。 对序列的每个元素执行相同的任务![](img/0bd9ccf4-cf74-4a99-aaa9-14a3d576b8f4.png),并且输出![](img/374e5ca2-4893-4ccd-a1c6-088c6160a0b8.png)取决于先前计算的输出![](img/b0cecbb7-a627-4b43-bab8-b08f97d15ede.png)。 得益于这种类似链的架构,或到目前为止所计算出的额外的*存储器*捕获,在将 RNN 应用于时间序列和序列数据方面取得了巨大的成功。 在将 RNN 的变体应用于各种问题之前,首先,我们将了解 RNN 的历史及其演变路径: 在 RNN 中,反馈回路将当前状态的信息传递到下一个状态,如下图的网络展开版本所示。 RNN 网络在任何时间的输出都可以写成`h[t] = f(h[t-1], x[t])`。 对序列的每个元素执行相同的任`f`,并且输出`h[t]`取决于先前计算的输出`h[t-1]`。 得益于这种类似链的架构,或到目前为止所计算出的额外的*存储器*捕获,在将 RNN 应用于时间序列和序列数据方面取得了巨大的成功。 在将 RNN 的变体应用于各种问题之前,首先,我们将了解 RNN 的历史及其演变路径:
![](img/1c4993f9-b13d-411a-a330-9c7a332bf4e3.png) ![](img/1c4993f9-b13d-411a-a330-9c7a332bf4e3.png)
...@@ -92,16 +92,16 @@ RNN 可以分为*多对一*,*一对多*,*多对多*(同步)和*多对多 ...@@ -92,16 +92,16 @@ RNN 可以分为*多对一*,*一对多*,*多对多*(同步)和*多对多
![](img/0c393218-eae9-42f3-a09e-bf404ddf0682.png) ![](img/0c393218-eae9-42f3-a09e-bf404ddf0682.png)
这里,`U`是连接输入层和隐藏层的权重,`V`是隐藏层和输出层之间的权重,`W`是循环层,即反馈层的权重; ![](img/0629c3d2-74ed-49e2-96bb-1520132d63dc.png)是时间步`t`的隐藏状态,![](img/659a5e6b-9562-4e50-b27a-6e9328a9f71b.png)和![](img/37ae4f9d-2015-4f14-8ab2-ab9ad5089969.png)分别是时间步`t`的输入和输出。 这里,`U`是连接输入层和隐藏层的权重,`V`是隐藏层和输出层之间的权重,`W`是循环层,即反馈层的权重; `s[t]`是时间步`t`的隐藏状态,`x[t]``h[t]`分别是时间步`t`的输入和输出。
请注意,为简便起见,我们从现在开始仅使用一个循环层,但是我们可以将多个循环层堆叠在一起,我们将很快看到。 请注意,为简便起见,我们从现在开始仅使用一个循环层,但是我们可以将多个循环层堆叠在一起,我们将很快看到。
层之间的关系可以描述如下: 层之间的关系可以描述如下:
* 基于当前输入![](img/2040af3e-d1dc-44dc-92dc-a3f919bd1eaa.png)和通过![](img/562308e5-cbaa-4ff7-9b79-bd683a4011bd.png)的先前隐藏状态![](img/383bc003-23ee-43db-9fa1-59937dbe7657.png)计算时间步长`t`和![](img/54984d48-521b-41b9-9685-b73dce04345f.png)的隐藏状态,其中`a`是激活函数。 RNN 中隐藏层的激活函数的典型选择包括 tanh 和 ReLU。 * 基于当前输入`x[t]`和通过`s[t] = a(U x[t] + W s[t-1])`的先前隐藏状态`s[t-1]`计算时间步长`t``s[t]`的隐藏状态,其中`a`是激活函数。 RNN 中隐藏层的激活函数的典型选择包括 tanh 和 ReLU。
* 同样,![](img/70c19fab-defe-4e68-909f-f6211104a2c7.png)取决于![](img/c9869f70-3cd8-4f6e-93bc-550caa70f200.png),依此类推。 ![](img/024ed476-77bb-45bd-9b60-8608e00ad27e.png)也依赖于![](img/c9307527-4369-491f-a419-a486f8f49795.png),按照惯例,该![](img/c9307527-4369-491f-a419-a486f8f49795.png)设置为全零。 * 同样,`s[t-1]`取决于`s[t-2]: s[t-1] = a(U x[t] + W s[t-2])`,依此类推。 `s[1]`也依赖于`s[0]`,按照惯例,该`s[0]`设置为全零。
* 由于对时间步长具有这种依赖性,因此可以将隐藏状态视为网络的内存,从以前的时间步长中捕获信息。 * 由于对时间步长具有这种依赖性,因此可以将隐藏状态视为网络的内存,从以前的时间步长中捕获信息。
* 将时间步长`t`的输出计算为![](img/450661ff-68a5-4ba1-a496-4311c409ad7e.png),其中`g`是激活函数。 根据执行的任务,它可以是用于二进制分类的 Sigmoid 函数,用于多类分类的 softmax 函数以及用于回归的简单线性函数。 * 将时间步长`t`的输出计算为`h[t] = g(V s[t])`,其中`g`是激活函数。 根据执行的任务,它可以是用于二进制分类的 Sigmoid 函数,用于多类分类的 softmax 函数以及用于回归的简单线性函数。
与传统的神经网络类似,所有的权重`U``V``W`均使用反向传播算法进行训练。 但是不同之处在于,在当前时间`t`上,我们需要计算除当前时间之外的所有先前`t-1`个时间步的损耗。 这是因为权重由所有时间步共享,并且一个时间步的输出间接依赖于所有先前的时间步,例如权重的梯度。 例如,如果要计算时间步`t = 5`的梯度,则需要向后传播前四个时间步,并对五个时间步的梯度求和。 这种特殊的反向传播算法称为**时间上的反向传播(BPTT)** 与传统的神经网络类似,所有的权重`U``V``W`均使用反向传播算法进行训练。 但是不同之处在于,在当前时间`t`上,我们需要计算除当前时间之外的所有先前`t-1`个时间步的损耗。 这是因为权重由所有时间步共享,并且一个时间步的输出间接依赖于所有先前的时间步,例如权重的梯度。 例如,如果要计算时间步`t = 5`的梯度,则需要向后传播前四个时间步,并对五个时间步的梯度求和。 这种特殊的反向传播算法称为**时间上的反向传播(BPTT)**
...@@ -431,20 +431,20 @@ LSTM 的架构的神奇之处在于:在普通循环单元的顶部,增加了 ...@@ -431,20 +431,20 @@ LSTM 的架构的神奇之处在于:在普通循环单元的顶部,增加了
在上图中从左到右,主要组成部分说明如下: 在上图中从左到右,主要组成部分说明如下:
* ![](img/d2eddb1c-c3ef-49c6-810f-28dc26e845eb.png)**存储单元**,它从输入序列的最开始就存储上下文。 * `c[t]`**存储单元**,它从输入序列的最开始就存储上下文。
* `f`表示**遗忘门**,它控制来自前一存储状态![](img/ae610622-83d8-4566-a185-a21c8466adb2.png)的多少信息可以向前传递。 与遗忘门相关的权重包括`W[f]`,它与先前的隐藏状态`S[t-1]`连接,和`u[f]`,它与当前输入`x[t]`连接。 * `f`表示**遗忘门**,它控制来自前一存储状态`c[t-1]`的多少信息可以向前传递。 与遗忘门相关的权重包括`W[f]`,它与先前的隐藏状态`S[t-1]`连接,和`u[f]`,它与当前输入`x[t]`连接。
* `i`代表**输入门**,它确定当前输入可以通过多少信息。 权重![](img/8cd433d7-2c2f-4642-a2e8-7ddf1183a5dc.png)和![](img/148eead3-586f-48da-aa64-d1a420cf60a2.png)分别将其与先前的隐藏状态和当前输入相连。 * `i`代表**输入门**,它确定当前输入可以通过多少信息。 权重`W[i]``U[i]`分别将其与先前的隐藏状态和当前输入相连。
* **tanh** 只是隐藏状态的激活函数,并且基于当前输入![](img/a1163f30-f030-4a68-bef6-f1dc1e0af040.png)和先前的隐藏状态![](img/c3fdb075-55bf-414d-87a6-7ab49d707585.png)及其相应的权重![](img/385579ed-f3c0-4acd-9235-470929e0ad56.png)和![](img/55810aa2-f8f7-4e8f-a33a-ed7b829e01c1.png)进行计算。 它与原始 RNN 中的`a`完全相同。 * **tanh** 只是隐藏状态的激活函数,并且基于当前输入`x[t]`和先前的隐藏状态`s[t-1]`及其相应的权重`W[c]``U[c]`进行计算。 它与原始 RNN 中的`a`完全相同。
* `o`用作**输出门**,它定义了将内部存储器中的多少信息用作整个循环单元的输出。 同样,![](img/6f080896-cb2d-48a6-8b99-1f850b583c7f.png)和![](img/9c6a729e-ea1c-44e8-b39d-4a42a525aa43.png)是关联的权重。 * `o`用作**输出门**,它定义了将内部存储器中的多少信息用作整个循环单元的输出。 同样,`W[o]``U[o]`是关联的权重。
因此,这些组件之间的关系可以概括如下: 因此,这些组件之间的关系可以概括如下:
* 在时间步`t`处的遗忘门`f`的输出被计算为![](img/dfc4bb4b-8495-41d9-a584-5ace7802685f.png) * 在时间步`t`处的遗忘门`f`的输出被计算为`f = sigmoid(U[f] x[t] + W[f] s[t-1])`
* 将在时间步`t`处输入门`i`的输出计算为![](img/02cc7c8f-f9cc-4bbd-9829-51537291a0f0.png) * 将在时间步`t`处输入门`i`的输出计算为`i = sigmoid(U[i] x[t] + W[i] s[t-1])`
* 将在时间步`t`处的 tanh 激活`c'`的输出计算为![](img/438dd210-3f36-4e25-a625-a95ab8da7b02.png) * 将在时间步`t`处的 tanh 激活`c'`的输出计算为`c' = sigmoid(U[c] x[t] + W[c] s[t-1])`
* 在时间步`t`处的输出门`o`的输出被计算为![](img/57472460-64d3-48e7-8fb8-af2371057ee6.png) * 在时间步`t`处的输出门`o`的输出被计算为`o = sigmoid(U[o] x[t] + W[o] s[t-1])`
* 在时间步`t`处的存储单元![](img/1fb2797f-7135-4aba-beb0-9fcea0fe85fb.png)由![](img/01cf9cf7-8de2-40fc-960e-ce2e0d9d4936.png)更新,其中`.*`表示逐元素乘法。 值得注意的是,`f``i`中的 Sigmoid 函数将其输出转换为从`0``1`的范围,从而控制分别通过的先前存储器`c[t - 1]`和当前存储器输入`c'`的数据比例。 * 在时间步`t`处的存储单元`c[t]``c[t] = f .* c[t-1] + i .* c'`更新,其中`.*`表示逐元素乘法。 值得注意的是,`f``i`中的 Sigmoid 函数将其输出转换为从`0``1`的范围,从而控制分别通过的先前存储器`c[t - 1]`和当前存储器输入`c'`的数据比例。
* 最后,在时间步`t`的隐藏状态![](img/c4c7aecc-d631-4158-82cd-b718759d5e5d.png)被更新为![](img/4f00cc4c-ed31-48a5-932b-9590c070e0dd.png)。 同样,`o`确定用作整个单元输出的更新存储单元![](img/8a8220aa-1249-47c5-a5a9-481a95a274e2.png)的比例。 * 最后,在时间步`t`的隐藏状态`s[t]`被更新为`s[t] = o .* c[t]`。 同样,`o`确定用作整个单元输出的更新存储单元`c[t]`的比例。
使用随时间的反向传播训练所有四组权重`U``W`,这与原始 RNN 相同。 通过学习三个信息门的权重,网络显式地对长期依赖关系进行建模。 接下来,我们将利用 LSTM 架构并发明更强大的文本生成器。 使用随时间的反向传播训练所有四组权重`U``W`,这与原始 RNN 相同。 通过学习三个信息门的权重,网络显式地对长期依赖关系进行建模。 接下来,我们将利用 LSTM 架构并发明更强大的文本生成器。
...@@ -567,10 +567,10 @@ Epoch 251/300 ...@@ -567,10 +567,10 @@ Epoch 251/300
上图中从左到右的关键组件说明如下: 上图中从左到右的关键组件说明如下:
* `r`表示**复位门**,它控制要忘记前一存储器![](img/a21e1deb-e75d-4193-9432-501b4a6ec3a9.png)的多少信息。 给定连接到先前隐藏状态![](img/bd1fb43d-b4d5-4f34-91f4-6b4bcba74e2d.png)的权重![](img/26a4ccef-544d-4862-823a-597620a237f3.png)和连接到当前输入![](img/6ef9bee8-6dd8-4dfe-be58-2199ae86baf9.png)的![](img/94f32772-c2dd-4f7f-881e-859d4af214ae.png),复位门`r`的输出在时间步`t`计算为![](img/6339bc02-8da3-4c8a-8d9e-be8188fa7ef3.png) * `r`表示**复位门**,它控制要忘记前一存储器`s[t-1]`的多少信息。 给定连接到先前隐藏状态`s[t-1]`的权重`W[r]`和连接到当前输入`x[t]``U[r]`,复位门`r`的输出在时间步`t`计算为`r = sigmoid(U[r] x[t] + W[r] s[t-1])`
* `p`代表**更新门**,它确定可以从前一个内存中传递多少信息。 将权重![](img/9b065883-35f9-4d94-877e-cd880c60465d.png)和![](img/b6998aa5-8213-474f-a37e-b7289e045be0.png)分别连接到先前的存储状态和当前输入,将时间`t`的更新门`p`的输出计算为![](img/db52d7e2-4126-479e-b98e-70cdada21c9a.png) * `p`代表**更新门**,它确定可以从前一个内存中传递多少信息。 将权重`W[p]``U[p]`分别连接到先前的存储状态和当前输入,将时间`t`的更新门`p`的输出计算为`p = sigmoid(U[p] x[t] + W[p] s[t-1])`
* **tanh** 是隐藏状态的激活函数,并基于当前输入![](img/654ee17e-32b3-4327-b956-ff22ebd8ef7b.png)和先前存储状态的重置进行计算。 给定它们的相应权重![](img/d5bc4167-0b59-4e20-9a17-fff19fd23de5.png)和![](img/747037b6-52b8-420d-b26f-50c3cc5b641a.png),将当前存储器`c'`在时间步`t`的输出计算为![](img/f44dabd4-8d26-47eb-b5ae-a4e899b10a11.png) * **tanh** 是隐藏状态的激活函数,并基于当前输入`x[t]`和先前存储状态的重置进行计算。 给定它们的相应权重`W[c]``U[c]`,将当前存储器`c'`在时间步`t`的输出计算为`c = tanh(U[c] x[t] + W[c] (r .* s[t-1]))`
* 最后,在时间步`t`的隐藏状态![](img/4aa12099-9314-411a-a919-5af2beae170e.png)被更新为![](img/d105d076-6e63-4124-aa61-3318d267a0f0.png)。 同样,`p`决定用于更新当前内存的先前内存的比例–越接近`1`,则保留的内存就越多; 距离`0`越近,发生的当前存储器越多。 * 最后,在时间步`t`的隐藏状态`s[t]`被更新为`s[t] = (1 - p) .* c' + p .* s[t-1]`。 同样,`p`决定用于更新当前内存的先前内存的比例–越接近`1`,则保留的内存就越多; 距离`0`越近,发生的当前存储器越多。
* 有趣的是,如果`p`是全零向量,而`r`是全一向量(例如我们没有明确保留任何先前的内存),则该网络只是一个普通的 RNN。 * 有趣的是,如果`p`是全零向量,而`r`是全一向量(例如我们没有明确保留任何先前的内存),则该网络只是一个普通的 RNN。
总体而言,GRU 与 LSTM 非常相似。 它们都使用光栅机制进行长期建模,并且与门相关的参数通过 BPTT 进行训练。 但是,有一些区别值得注意: 总体而言,GRU 与 LSTM 非常相似。 它们都使用光栅机制进行长期建模,并且与门相关的参数通过 BPTT 进行训练。 但是,有一些区别值得注意:
...@@ -578,7 +578,7 @@ Epoch 251/300 ...@@ -578,7 +578,7 @@ Epoch 251/300
* LSTM 中有三个信息门,而 GRU 中只有两个。 * LSTM 中有三个信息门,而 GRU 中只有两个。
* GRU 中的更新门负责输入门和 LSTM 中的遗忘门。 * GRU 中的更新门负责输入门和 LSTM 中的遗忘门。
* GRU 中的重置门直接应用于先前的隐藏状态。 * GRU 中的重置门直接应用于先前的隐藏状态。
* LSTM 显式地对存储单元![](img/61f52a9f-668d-4147-b035-94fa2cade1fb.png)进行建模,而 GRU 则不。 * LSTM 显式地对存储单元`c[t]`进行建模,而 GRU 则不。
* 附加的非线性将应用于 LSTM 中更新的隐藏状态。 * 附加的非线性将应用于 LSTM 中更新的隐藏状态。
* LSTM 于 1997 年推出,近年来已得到研究和广泛使用。 GRU 于 2014 年发明,至今尚未得到充分的探索。 这就是为什么 LSTM 比 GRU 更受欢迎的原因,即使不能保证一个 LSTM 胜过另一个。 * LSTM 于 1997 年推出,近年来已得到研究和广泛使用。 GRU 于 2014 年发明,至今尚未得到充分的探索。 这就是为什么 LSTM 比 GRU 更受欢迎的原因,即使不能保证一个 LSTM 胜过另一个。
* 通常认为,与 GSTM 相比,训练 GRU RNN 相对更快并且需要更少的数据,因为 GRU RNN 具有较少的参数。 因此,有人认为 GRU 在训练量较小的情况下效果更好。 * 通常认为,与 GSTM 相比,训练 GRU RNN 相对更快并且需要更少的数据,因为 GRU RNN 具有较少的参数。 因此,有人认为 GRU 在训练量较小的情况下效果更好。
...@@ -659,7 +659,7 @@ DJIA 由 30 只大型和重要股票(例如 Apple,IBM,GE 和 Goldman Sachs ...@@ -659,7 +659,7 @@ DJIA 由 30 只大型和重要股票(例如 Apple,IBM,GE 和 Goldman Sachs
>>> Y_test = Y[train_n:] >>> Y_test = Y[train_n:]
``` ```
我们现在可以开始对训练数据进行建模吗? 当然不需要-需要数据缩放或预处理。 从上图可以看出,测试数据与训练数据不成比例,更不用说将来的数据了。 回归模型无法预测超出范围的值。 为了解决这个问题,我们通常使用最大最小缩放 ![](img/59f9afb3-b83d-4d93-9481-eb6595fafe7d.png)将数据缩放到给定范围,例如 0 到 1。 但是,没有可靠的方法来预测股票的![](img/c83a79f1-f415-4cce-9ff7-dfb8ea639122.png)(或![](img/07311e70-4ece-4170-8c85-d492a7815b82.png)。 这与已知最小值和最大值(例如,图像预测中的 0 和 255)的情况不同。 为了解决这个问题,我们将每个窗口内的价格标准化。 我们只需将时间窗口中的每个价格除以最近的已知价格即可。 再次使用前面的`T = 5`示例,我们可以如下预处理训练样本: 我们现在可以开始对训练数据进行建模吗? 当然不需要-需要数据缩放或预处理。 从上图可以看出,测试数据与训练数据不成比例,更不用说将来的数据了。 回归模型无法预测超出范围的值。 为了解决这个问题,我们通常使用最大最小缩放`x_scaled = (x - x_min) / (x_max / x_min)`将数据缩放到给定范围,例如 0 到 1。 但是,没有可靠的方法来预测股票的`x_max`(或`x_min`。 这与已知最小值和最大值(例如,图像预测中的 0 和 255)的情况不同。 为了解决这个问题,我们将每个窗口内的价格标准化。 我们只需将时间窗口中的每个价格除以最近的已知价格即可。 再次使用前面的`T = 5`示例,我们可以如下预处理训练样本:
| **输入** | **输出** | | **输入** | **输出** |
| --- | --- | | --- | --- |
...@@ -822,7 +822,7 @@ He said, "Machine __ combines computer science and statistics." ...@@ -822,7 +822,7 @@ He said, "Machine __ combines computer science and statistics."
![](img/4ee06bf0-c7d5-426e-a033-fff39a4b4629.png) ![](img/4ee06bf0-c7d5-426e-a033-fff39a4b4629.png)
在此,![](img/08f9b1f1-40af-48d3-88e3-6f77d257ca5f.png)和![](img/d14717c4-cbb8-4ab1-91b8-b580f9d7d6b4.png)分别表示正向和反向递归层。 它们连接在一起,形成隐藏层![](img/6272d6fe-ea90-4f70-92aa-d45bc73040c0.png),并保留来自过去和将来状态的信息。 在此,`f ->``f <-`分别表示正向和反向递归层。 它们连接在一起,形成隐藏层`f`,并保留来自过去和将来状态的信息。
当需要并提供完整的上下文(包括过去和将来的信息)时,BRNN 特别有用。 例如,在词性标记,实体识别或手写识别中,可以通过了解当前单词或字母之后的单词或字母来提高性能。 其他出色的用例包括语音识别,机器翻译和图像字幕。 当需要并提供完整的上下文(包括过去和将来的信息)时,BRNN 特别有用。 例如,在词性标记,实体识别或手写识别中,可以通过了解当前单词或字母之后的单词或字母来提高性能。 其他出色的用例包括语音识别,机器翻译和图像字幕。
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册