Full Update (#563)

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 03.1-均方差损失函数.md

* Update 03.1-均方差损失函数.md

* Update 03.2-交叉熵损失函数.md

* Update 03.0-损失函数.md

* Update 03.0-损失函数.md

* Update 04.0-单入单出单层-单变量线性回归.md

* Update 04.0-单入单出单层-单变量线性回归.md

* Update 04.0-单入单出单层-单变量线性回归.md

* Update 04.1-最小二乘法.md

* Update 04.1-最小二乘法.md

* Update 04.2-梯度下降法.md

* Update 04.0-单入单出单层-单变量线性回归.md

* Update 04.1-最小二乘法.md

* Update 04.2-梯度下降法.md

* Update 04.3-神经网络法.md

* Update 04.3-神经网络法.md

* Update 04.4-多样本计算.md

* Update 04.4-多样本计算.md

* Update 04.0-单入单出单层-单变量线性回归.md

* Update 04.5-梯度下降的三种形式.md

* Update 04.5-梯度下降的三种形式.md

* Update 04.5-梯度下降的三种形式.md

* Update 04.5-梯度下降的三种形式.md

* Update 04.5-梯度下降的三种形式.md

* Update 04.5-梯度下降的三种形式.md

* Update 05.0-多入单出单层-多变量线性回归.md

* Update 05.0-多入单出单层-多变量线性回归.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.2-神经网络法.md

* Update 05.2-神经网络法.md

* Update 05.2-神经网络法.md

* Update 05.2-神经网络法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 05.1-正规方程法.md

* Update 03.0-损失函数.md

* Update 03.1-均方差损失函数.md

* Update 03.2-交叉熵损失函数.md

* Update 02.0-反向传播与梯度下降.md

* Update 02.0-反向传播与梯度下降.md

* Update 02.1-线性反向传播.md

* Update 02.1-线性反向传播.md

* Update 02.2-非线性反向传播.md

* Update 02.3-梯度下降.md

* Update 02.0-反向传播与梯度下降.md

* Update 02.1-线性反向传播.md

* Update 05.2-神经网络法.md

* Update 05.2-神经网络法.md

* Update 05.2-神经网络法.md

* Update 05.3-样本特征数据标准化.md

* Update 05.3-样本特征数据标准化.md

* Update 05.3-样本特征数据标准化.md

* Update 05.4-还原参数值.md

* Update 05.5-正确的推理方法.md

* Update 05.6-标准化标签值.md

* Update 05.6-标准化标签值.md

* Update 01.2-范式的演化.md

* Update 01.2-范式的演化.md

* Update 01.3-神经网络的基本工作原理.md

* Update 01.3-神经网络的基本工作原理.md

* Update 06.1-二分类函数.md

* Update 06.1-二分类函数.md

* Update 06.1-二分类函数.md

* Update 06.1-二分类函数.md

* Update 06.2-线性二分类实现.md

* Update 06.2-线性二分类实现.md

* Update 06.2-线性二分类实现.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update 09.4-神经网络非线性回归的实现.md

* Update 06.3-线性二分类的工作原理.md

* Update 06.4-线性二分类结果可视化.md

* Update 06.0-多入单出单层神经网络-线性二分类.md

* Update 06.0-多入单出单层神经网络-线性二分类.md

* Update 06.0-多入单出单层神经网络-线性二分类.md

* Update 06.5-实现逻辑与或非门.md

* Update 06.6-用双曲正切函数分类.md

* Update 06.6-用双曲正切函数分类.md

* Update 07.0-多入多出单层神经网络-线性多分类.md

* Update 07.1-多分类函数.md

* Update 07.2-线性多分类实现.md

* Update 07.3-线性多分类的工作原理.md

* Update 07.3-线性多分类的工作原理.md

* Update 07.4-线性多分类结果可视化.md

* Update 08.0-激活函数.md

* Update 08.1-挤压型激活函数.md

* Update 08.1-挤压型激活函数.md

* Update 08.2-半线性激活函数.md

* Update 08.2-半线性激活函数.md

* Update 08.2-半线性激活函数.md

* Update 09.0-单入单出双层-非线性回归.md

* Update 09.1-多项式回归法拟合正弦曲线.md

* Update 09.2-多项式回归法拟合复合函数曲线.md

* Update 09.3-验证与测试.md

* Update 09.3-验证与测试.md

* Update 09.3-验证与测试.md

* Update 09.4-神经网络非线性回归的实现.md

* Update 09.5-曲线拟合.md

* Update 09.6-非线性回归的工作原理.md

* Update 09.7-参数调优初步.md

* 课程配套PPT

目前已完成Step 1-4共计九章课件内容的制作,后续内容正在更新中。

* Update 08 第四步 - 非线性回归.md

* Update 09.7-参数调优初步.md

* Update 09.7-参数调优初步.md

* Update 04.0-单入单出单层-单变量线性回归.md

* Update 05.0-多入单出单层-多变量线性回归.md

* Update 05.0-多入单出单层-多变量线性回归.md

* Update 16.1-偏差与方差.md

* Update 16.1-偏差与方差.md

* Update 16.1-偏差与方差.md

* Update 16.1-偏差与方差.md

* Update 16.1-偏差与方差.md

* Update 16.1-偏差与方差.md

* Update 16.1-偏差与方差.md

* Update 16.1-偏差与方差.md

* Update 16.1-偏差与方差.md

* Update 15.5-批量归一化的原理.md

* PPTs of first 7 steps

* Delete Chapter 04 单入单出的单层神经网络.pdf

* Delete Chapter 05 多入单出的单层神经网络.pdf

* Delete Chapter 06 线性二分类.pdf

* Delete Chapter 07 线性多分类.pdf

* Delete Chapter 09 单入单出的双层神经网络.pdf

* Update 10.0-多入单出双层-非线性二分类.md

* Update 10.1-为什么必须用双层神经网络.md

* Update 10.1-为什么必须用双层神经网络.md

* Update 10.2-非线性二分类实现.md

* Update 10.2-非线性二分类实现.md

* Update 10.2-非线性二分类实现.md

* Update 10.3-实现逻辑异或门.md

* Update 10.4-逻辑异或门的工作原理.md

* Update 10.5-实现双弧形二分类.md

* Update 10.5-实现双弧形二分类.md

* Update 10.6-双弧形二分类的工作原理.md

* Update 11.0-多入多出双层-非线性多分类.md

* Update 11.1-非线性多分类实现.md

* Update 11.2-非线性多分类的工作原理.md

* Update 12.1-三层神经网络的实现.md

* Update 12.1-三层神经网络的实现.md

* Update 12.2-梯度检查.md

* Update 12.3-学习率与批大小.md

* Update 13.0-手工测试训练效果.md

* Update 13.1-模型文件概述.md

* Update 13.2-ONNX模型文件.md

* Update 14.0-搭建深度神经网络框架.md

* Update 14.1-回归任务功能测试.md

* Update 14.2-回归任务真实案例.md

* Update 14.2-回归任务真实案例.md

* Update 14.4-二分类任务真实案例.md

* Update 14.4-二分类任务真实案例.md

* Update 14.5-多分类任务功能测试.md

* Update 14.6-多分类任务真实案例.md

* Update 15.1-权重矩阵初始化.md

* Update 15.2-梯度下降优化算法.md

* Update 15.3-自适应学习率算法.md

* Update 15.4-算法效果比较.md

* Update 15.5-批量归一化的原理.md

* Update 15.5-批量归一化的原理.md

* Update 15.6-批量归一化的实现.md

* Update 16.0-正则化.md

* Update 16.2-L2正则.md

* Update 16.2-L2正则.md

* Update 16.3-L1正则.md

* Update 16.3-L1正则.md

* Update 16.3-L1正则.md

* Update 16.4-早停法.md

* Update 16.5-丢弃法.md

* Update 16.6-数据扩展.md

* Update 16.6-数据扩展.md

* Update 16.7-集成学习.md

* Update 16.7-集成学习.md

* Update 04.0-单入单出单层-单变量线性回归.md

* Update 05.0-多入单出单层-多变量线性回归.md

* Update 06.0-多入单出单层神经网络-线性二分类.md

* Update 06.1-二分类函数.md

* Update 05.2-神经网络法.md

* Update 07.0-多入多出单层神经网络-线性多分类.md

* Update 07.0-多入多出单层神经网络-线性多分类.md

* Update 07.1-多分类函数.md

* Update 10.4-逻辑异或门的工作原理.md

* Delete Chapter 01 概论.pdf

* Delete Chapter 02 神经网络中的三个基本概念.pdf

* Delete Chapter 03 损失函数.pdf

* Delete Chapter 08 激活函数.pdf

* Add files via upload

PPTs of first 7 steps

* Delete Chapter 08 激活函数.pdf

* Images Modified

修改了图片链接地址

* Update 20.1-LSTM基本原理.md

* Update 20.1-LSTM基本原理.md

* Update 20.1-LSTM基本原理.md

* Update 20.1-LSTM基本原理.md

* Update 20.3-GRU基本原理.md

* Update 20.3-GRU基本原理.md

* Update 19.6-深度循环神经网络.md

* Update 20.4-序列到序列.md

* Update 19.7-双向循环神经网络.md

* Final PPTs

* Update 19.1-两个时间步的循环神经网络.md

* Update 19.1-两个时间步的循环神经网络.md

* Update 19.2-四个时间步的循环神经网络.md

* Update 19.3-通用的循环神经网络模型.md

* Update 17.1-卷积的前向计算原理.md

* Update 17.2-卷积前向计算代码实现.md

* Update 17.3-卷积的反向传播原理.md

* Update 17.3-卷积的反向传播原理.md

* Update 17.3-卷积的反向传播原理.md

* Update 17.3-卷积的反向传播原理.md

* Update 17.3-卷积的反向传播原理.md

* Update 17.3-卷积的反向传播原理.md

* Update 17.5-池化的前向计算与反向传播.md

* Update 17.5-池化的前向计算与反向传播.md

* Update 20.3-GRU基本原理.md

* Update 20.4-序列到序列.md

* Update 20.3-GRU基本原理.md

* Update 20.4-序列到序列.md

* Update README.md

* Update README.md

* DataDownload

* Update README.md

* Update DataDownload.py

* Update README.md

* Update README.md

* Update README.md

* Update README.md
This commit is contained in:
Double680
2020-09-23 11:12:13 +08:00
committed by GitHub
parent 4fc7dd78dd
commit b8e8ce80d2
18 changed files with 283 additions and 261 deletions
@@ -13,6 +13,8 @@
2. 也可以clone全部内容到本地,然后用VSCode浏览,但VSCode中需要安装能读取Markdown格式的扩展,比如Markdown AllInOne插件。
3. 本教程提供数据包:在"SourceCode"文件夹中下载"DataDownload.py"并运行,输入本地目录后即可开始下载数据包,并自动解压至当地。
## 写在前面,为什么要出这个系列的教程呢?
总的说来,我们现在有了很多非常厉害的深度学习框架,比如TensorflowCNTKPaddlePaddleCaffe2等等。然而,我们用这些框架在搭建我们自己的深度学习模型的时候,到底做了一些什么样的操作呢?我们试图去阅读框架的源码来理解框架到底帮助我们做了些什么,但是……很难!很难!很难!因为深度学习是需要加速啦,分布式计算啦,框架做了很多很多的优化,也让像我们这样的小白难以理解这些框架的源码。
@@ -48,22 +50,22 @@
|网络结构名称|网络结构图|应用领域|
|---|----|----|
|单入<br>单出<br>一层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/4/Setup.png"/>|一元线性回归|
|多入<br>单出<br>一层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/5/setup.png"/>|多元线性回归|
|多入<br>单出<br>一层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/6/BinaryClassifierNN.png"/>|线性二分类<br>|
|多入<br>多出<br>一层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/7/MultipleClassifierNN.png"/>|线性多分类<br>|
|单入<br>单出<br>两层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/9/nn.png"/>|一元非线性回归/拟合<br>可以拟合任意复杂函数|
|多入<br>单出<br>两层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/10/xor_nn.png"/>|非线性二分类|
|多入<br>多出<br>两层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/11/nn.png"/>|非线性多分类|
|多入<br>多出<br>三层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/12/nn3.png"/>|非线性多分类|
|多层全连接网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/14/mnist_net.png"/>|非线性多分类|
|带批归一化层的多层全连接网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/15/bn_mnist.png"/>|非线性多分类|
|带丢弃层的多层全连接网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/16/dropout_net.png"/>|非线性多分类|
|简单的卷积神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/17/conv_net.png"/>|非线性多分类|
|复杂的卷积神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/18/mnist_net.png"/>|非线性多分类|
|单向循环神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/19/bptt_simple.png"/>|非线性多分类|
|双向循环神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/19/bi_rnn_net_right.png"/>|非线性多分类|
|深度循环神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-imagesImages/19/deep_rnn_net.png"/>|非线性多分类|
|单入<br>单出<br>一层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/4/Setup.png"/>|一元线性回归|
|多入<br>单出<br>一层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/5/setup.png"/>|多元线性回归|
|多入<br>单出<br>一层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/6/BinaryClassifierNN.png"/>|线性二分类<br>|
|多入<br>多出<br>一层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/7/MultipleClassifierNN.png"/>|线性多分类<br>|
|单入<br>单出<br>两层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/9/nn.png"/>|一元非线性回归/拟合<br>可以拟合任意复杂函数|
|多入<br>单出<br>两层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/10/xor_nn.png"/>|非线性二分类|
|多入<br>多出<br>两层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/11/nn.png"/>|非线性多分类|
|多入<br>多出<br>三层|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/12/nn3.png"/>|非线性多分类|
|多层全连接网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/14/mnist_net.png"/>|非线性多分类|
|带批归一化层的多层全连接网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/15/bn_mnist.png"/>|非线性多分类|
|带丢弃层的多层全连接网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/16/dropout_net.png"/>|非线性多分类|
|简单的卷积神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/17/conv_net.png"/>|非线性多分类|
|复杂的卷积神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/18/mnist_net.png"/>|非线性多分类|
|单向循环神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/19/bptt_simple.png"/>|非线性多分类|
|双向循环神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/19/bi_rnn_net_right.png"/>|非线性多分类|
|深度循环神经网络|<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/19/deep_rnn_net.png"/>|非线性多分类|
## 写在后面
@@ -0,0 +1,29 @@
from urllib.request import urlretrieve
import time
import tarfile
URL_path = r"https://aiedugithub4a2.blob.core.windows.net/a2-data"
filename = r"Data.tar.gz"
print("Please input the local folder path:")
local = input()
from_path = URL_path + "/" + filename
to_path = local + "/" + filename
print("Downloading...")
try:
urlretrieve(from_path, to_path)
print("Done.")
print("Extracting...")
try:
with tarfile.open(to_path) as file:
file.extractall(path = local)
print("Done.")
print("All Work Finished!")
except:
print("Failed Extraction!")
except:
print("Invalid Path!")
print("Exit in 3 seconds...")
time.sleep(3)
@@ -41,7 +41,7 @@ $$h(x) = (f*g)(x) = \sum^{\infty}_{t=-\infty} f(t)g(x-t) \tag{2}$$
$$
\begin{aligned}
h(4) &= f(1)g(3)+f(2)g(2)+f(3)g(1) \\
h(4) &= f(1)g(3)+f(2)g(2)+f(3)g(1) \\\\
&=f(1)g(4-1) + f(2)g(4-2) + f(3)g(4-3)
\end{aligned}
$$
@@ -30,7 +30,7 @@ class ConvWeightsBias(WeightsBias_2_1):
- KernalCount=3,第二维,卷积核数量,对应输入通道数。两个Filter里面的Kernal数必须相同。
- KernalHeight=5KernalWidth=5,卷积核的尺寸,第三维和第四维。同一组WeightsBias里的卷积核尺寸必须相同。
在初始化函数中,会根据四个参数定义WBShape,然后在CreateNew函数中,创建相应形状的WeightsBias。
在初始化函数中,会根据四个参数定义`WBShape`,然后在`CreateNew`函数中,创建相应形状的`Weights``Bias`
### 17.2.2 卷积前向运算的实现 - 方法1
```Python
@@ -48,7 +48,7 @@ class ConvLayer(CLayer):
return self.z
```
上述代码中的conv_4d函数实现了17.1中定义的四维卷积运算:
上述代码中的`conv_4d()`函数实现了17.1中定义的四维卷积运算:
```Python
def conv_4d(x, weights, bias, out_h, out_w, stride=1):
@@ -74,13 +74,13 @@ def conv_4d(x, weights, bias, out_h, out_w, stride=1):
上面的函数包含以下几重循环:
1. 批量数据循环(第一维):bs in batch_size,对每个样本进行计算;
2. 输出通道循环(第二维):oc in output_channel。这里先把bias加上了,后加也可以;
3. 输入通道循环:ic in input_channel;
4. 输出图像纵坐标循环:i in out h;
5. 输出图像横坐标循环:j in out_w。循环4和5完成对输出图像的每个点的遍历,在下面的子循环中计算并填充值;
6. 卷积核纵向循环(第三维):fh in filter_height
7. 卷积核横向循环(第四维):fw in filter_width。循环6和7完成卷积核与输入图像的卷积计算,并保存到循环4和5指定的输出图像的点上。
1. 批量数据循环(第一维):`bs in batch_size`,对每个样本进行计算;
2. 输出通道循环(第二维):`oc in output_channel`。这里先把`bias`加上了,后加也可以;
3. 输入通道循环:`ic in input_channel`;
4. 输出图像纵坐标循环:`i in out h`
5. 输出图像横坐标循环:`j in out_w`。循环4和5完成对输出图像的每个点的遍历,在下面的子循环中计算并填充值;
6. 卷积核纵向循环(第三维):`fh in filter_height`
7. 卷积核横向循环(第四维):`fw in filter_width`。循环6和7完成卷积核与输入图像的卷积计算,并保存到循环4和5指定的输出图像的点上。
我们试着运行上面的代码并循环10次,看看它的执行效率如何:
@@ -90,15 +90,15 @@ Time used for Python: 38.057225465774536
出乎我们的预料,在足足等了30多秒后,才返回结果。
通过试验发现,其运行速度非常慢,如果这样的函数在神经网络训练中被调用几十万次,其性能是非常糟糕的,这也是Python做为动态语言的一个缺点。
通过试验发现,其运行速度非常慢,如果这样的函数在神经网络训练中被调用几十万次,其性能是非常糟糕的,这也是`Python`做为动态语言的一个缺点。
### 17.2.3 卷积前向运算的实现 - 方法2
既然动态语言速度慢,我们把它编译成静态方法,是不是会快一些呢?
很幸运,有这样一个开源项目:[numba](https://numba.pydata.org/),它可以在运行时把Python编译成C语言执行,代码是用C语言“风格”编写的Python代码,而且越像C的话,执行速度越快。
很幸运,有这样一个开源项目:[numba](https://numba.pydata.org/),它可以在运行时把`Python`编译成`C`语言执行,代码是用`C`语言“风格”编写的`Python`代码,而且越像`C`的话,执行速度越快。
我们先用pip安装numba包:
我们先用`pip`安装`numba`包:
```
pip install numba
@@ -112,15 +112,15 @@ def jit_conv_4d(x, weights, bias, out_h, out_w, stride=1):
...
```
为了明确起见,我们把conv_4d前面加上一个jit前缀,表明这个函数是经过numba加速的。然后运行循环10次的测试代码:
为了明确起见,我们把`conv_4d`前面加上一个`jit`前缀,表明这个函数是经过`numba`加速的。然后运行循环10次的测试代码:
```
Time used for Numba: 0.0727994441986084
```
又一次出乎我们的预料,这次只用了0.07秒,比纯Python代码快了500多倍!
又一次出乎我们的预料,这次只用了0.07秒,比纯`Python`代码快了500多倍!
但是不要急,我们还需要检查一下其正确性。方法1输出结果为output1,Numba编译后的方法输出结果为output2,二者都是四维矩阵,我们用np.allclose()函数来比较它们的差异:
但是不要急,我们还需要检查一下其正确性。方法1输出结果为`output1`Numba编译后的方法输出结果为`output2`,二者都是四维矩阵,我们用`np.allclose()`函数来比较它们的差异:
```Python
print("correctness:", np.allclose(output1, output2, atol=1e-7))
@@ -132,15 +132,15 @@ Time used for Numba: 0.0727994441986084
correctness: True
```
np.allclose方法逐元素检查两种方法的返回值的差异,如果绝对误差在1e-7之内,说明两个返回的四维数组相似度极高,运算结果可信。
`np.allclose`方法逐元素检查两种方法的返回值的差异,如果绝对误差在`1e-7`之内,说明两个返回的四维数组相似度极高,运算结果可信。
为什么不把所有的Python代码都编译成C代码呢?是因为numba的能力有限,并不支持numpy的所有函数,所以只能把关键的运算代码设计为独立的函数,然后用numba编译执行,函数的输入可以是数组、向量、标量,不能是复杂的自定义结构体或函数指针。
为什么不把所有的Python代码都编译成C代码呢?是因为`numba`的能力有限,并不支持`numpy`的所有函数,所以只能把关键的运算代码设计为独立的函数,然后用`numba`编译执行,函数的输入可以是数组、向量、标量,不能是复杂的自定义结构体或函数指针。
### 17.2.4 卷积前向运算的实现 - 方法3
由于卷积操作是原始图片数据与卷积核逐点相乘的结果,所以遍历每个点的运算速度非常慢。在全连接层中,由于是两个矩阵直接相乘,所以速度非常快。我们是否可以把卷积操作转换为矩阵操作呢?
在Caffe框架中,巧妙地把逐点相乘的运算转换成了矩阵运算,大大提升了程序运行速度。这就是著名的im2col函数(我们在代码中命名为img2col)。
在Caffe框架中,巧妙地把逐点相乘的运算转换成了矩阵运算,大大提升了程序运行速度。这就是著名的`im2col`函数(我们在代码中命名为`img2col`)。
```Python
def forward_img2col(self, x, train=True):
@@ -164,23 +164,23 @@ np.allclose方法逐元素检查两种方法的返回值的差异,如果绝对
图17-20 把卷积运算转换成矩阵运算
先看上半部分:绿色的3x3矩阵为输入,经过棕色的卷积核运算后,得到右侧的2x2的矩阵。
先看上半部分:绿色的$3\times 3$矩阵为输入,经过棕色的卷积核运算后,得到右侧的$2\times 2$的矩阵。
再看图的下半部分:
第一步,上半部分中蓝色的虚线圆内的四个元素排列成第1行,形成[0,1,3,4],红色虚线圆内的四个元素排列成第4行[4,5,7,8],中间两行可以从右上角的[1,2,4,5]和左下角的[3,4,6,7]得到。这样,一个3x3的矩阵,就转换成了一个4x4的矩阵。也就是把卷积核视野中的每个二维2x2的数组变成1x4的向量。
第一步,上半部分中蓝色的虚线圆内的四个元素排列成第1行,形成[0,1,3,4],红色虚线圆内的四个元素排列成第4行[4,5,7,8],中间两行可以从右上角的[1,2,4,5]和左下角的[3,4,6,7]得到。这样,一个$3\times 3$的矩阵,就转换成了一个$4\times 4$的矩阵。也就是把卷积核视野中的每个二维$2\times 2$的数组变成$1\times 4$的向量。
第二步,把棕色的权重矩阵变成4x1的向量[3,2,1,0]。
第二步,把棕色的权重矩阵变成$4\times 1$的向量[3,2,1,0]。
第三步,把4x4的矩阵与4x1的向量相乘,得到4x1的结果向量[5,11,23,29]。
第三步,把$4\times 4$的矩阵与$4\times 1$的向量相乘,得到$4\times 1$的结果向量[5,11,23,29]。
第四步:把4x1的结果变成2x2的矩阵,就得到了卷积运算的真实结果。
第四步:把$4\times 1$的结果变成$2\times 2$的矩阵,就得到了卷积运算的真实结果。
#### 四维数组的展开
前面只说明了二维数组的展开形式,四维数组可以用同样的方式展开。
我们假定有2个输入样本,每个样本含有3个通道,每个通道上是3x3的数据,则样本的原始形状和展开形状分别是:
我们假定有2个输入样本,每个样本含有3个通道,每个通道上是$3\times 3$的数据,则样本的原始形状和展开形状分别是:
```
x =
(样本1) [样本2]
@@ -209,7 +209,7 @@ col_x =
[31. 32. 34. 35.| 40. 41. 43. 44.| 49. 50. 52. 53.]]
```
从生成的8x12的矩阵中可以观察到:
从生成的$8\times 12$的矩阵中可以观察到:
- 前4行是样本1的数据,后4行是样本2的数据
- 前4列是通道1的数据,中间4列是通道2的数据,后4列是通道3的数据
@@ -249,7 +249,7 @@ col_w=
#### 结果数据的处理
原始数据展开成了8x12的矩阵,权重展开成了12x2的矩阵,所以最后的结果是8x2的矩阵:
原始数据展开成了$8\times 12$的矩阵,权重展开成了$12\times 2$的矩阵,所以最后的结果是$8\times 2$的矩阵:
```
[[1035.| 2619.]
[1101.| 2829.]
@@ -263,10 +263,10 @@ col_w=
```
这是两个样本的结果。如何把它拆开呢?是简单的左右分开就行了吗?这里要稍微动一下脑筋,推理一下:
1. 两个样本的原始数组x展开后的矩阵col_x是8x12,计算结果是8x2,如果原始数据只有一个样本,则展开矩阵col_x的形状是4x12,那么运算结果将会是4x2。所以,在上面这个8x2的矩阵中,前4行应该是第一个样本的卷积结果,后4行是第二个样本的卷积结果。
2. 如果输出通道只有一个,则权重矩阵w展开后的col_w只有一列,那么运算结果将会是8x1;两个输出通道的运算结果是8x2。所以第一列和第二列应该是两个通道的数据,而不是两个样本的数据。
1. 两个样本的原始数组x展开后的矩阵`col_x`是$8\times 12$,计算结果是$8\times 2$,如果原始数据只有一个样本,则展开矩阵`col_x`的形状是$4\times 12$,那么运算结果将会是$4\times 2$。所以,在上面这个$8\times 2$的矩阵中,前4行应该是第一个样本的卷积结果,后4行是第二个样本的卷积结果。
2. 如果输出通道只有一个,则权重矩阵`w`展开后的`col_w`只有一列,那么运算结果将会是$8\times 1$;两个输出通道的运算结果是$8\times 2$。所以第一列和第二列应该是两个通道的数据,而不是两个样本的数据。
也就是说,在这个8x2的数组中:
也就是说,在这个数组中:
- 第1列的前4行是第1个样本的第1个通道的输出
- 第2列的前4行是第1个样本的第2个通道的输出
@@ -275,7 +275,7 @@ col_w=
于是我们可以分两步得到正确的矩阵形状:
1. 先把8x2的数据变成2个样本 * 输出高度 * 输出宽度的形状:
1. 先把数据变成2个样本 * 输出高度 * 输出宽度的形状:
```Python
out2 = output.reshape(batch_size, output_height, output_width, -1)
@@ -331,7 +331,7 @@ def test_4d_im2col():
```
correctness: True
```
上面的代码,首先生成了一个ConvLayer实例,然后分别调用内部实现的forward_numba()方法和forward_img2col()方法,得到f1和f2两个卷积结果矩阵,然后比较其数值,最后的返回值为True,说明im2col方法的正确性。
上面的代码,首先生成了一个`ConvLayer`实例,然后分别调用内部实现的`forward_numba()`方法和`forward_img2col()`方法,得到`f1``f2`两个卷积结果矩阵,然后比较其数值,最后的返回值为`True`,说明`im2col`方法的正确性。
#### 性能测试
@@ -344,7 +344,7 @@ def test_performance():
print("forward:", np.allclose(f1, f2, atol=1e-7))
```
上述代码先生成一个ConvLayer实例,然后分别调用1000次forward_numba()方法和1000次forward_img2col()方法,最后得到的结果是:
上述代码先生成一个`ConvLayer`实例,然后分别调用1000次`forward_numba()`方法和1000次`forward_img2col()`方法,最后得到的结果是:
```
method numba: 11.663846492767334
@@ -353,17 +353,17 @@ compare correctness of method 1 and method 2:
forward: True
```
numba方法会比im2col方法快3秒,目前看来numba方法稍占优势。但是如果没有numba的帮助,im2col方法会比方法1快几百倍。
`numba`方法会比`im2col`方法快3秒,目前看来`numba`方法稍占优势。但是如果没有`numba`的帮助,`im2col`方法会比方法1快几百倍。
### 代码位置
ch17, Level2
其中,Level2_Numba_Test.py是测试numba库的性能,Level2_Img2Col_Test是比较numba方法和im2col方法的前向计算性能。
其中,`Level2_Numba_Test.py`是测试`numba`库的性能,`Level2_Img2Col_Test`是比较`numba`方法和`im2col`方法的前向计算性能。
在Level2的主过程中有4个函数:
- test_2d_conv,理解2维下im2col的工作原理
- understand_4d_im2col,理解4维下im2col的工作原理
- test_4d_im2col,比较两种方法的结果,从而验证正确性
- test_performance,比较两种方法的性能
- `test_2d_conv`,理解2维下`im2col`的工作原理
- `understand_4d_im2col`,理解4维下`im2col`的工作原理
- `test_4d_im2col`,比较两种方法的结果,从而验证正确性
- `test_performance`,比较两种方法的性能
@@ -31,21 +31,21 @@ $$z_{12} = w_{11} \cdot a_{12} + w_{12} \cdot a_{13} + w_{21} \cdot a_{22} + w_{
$$z_{21} = w_{11} \cdot a_{21} + w_{12} \cdot a_{22} + w_{21} \cdot a_{31} + w_{22} \cdot a_{32} + b \tag{3}$$
$$z_{22} = w_{11} \cdot a_{22} + w_{12} \cdot a_{23} + w_{21} \cdot a_{32} + w_{22} \cdot a_{33} + b \tag{4}$$
求损失函数J对a11的梯度:
求损失函数$J$对$a_{11}$的梯度:
$$
\frac{\partial J}{\partial a_{11}}=\frac{\partial J}{\partial z_{11}} \frac{\partial z_{11}}{\partial a_{11}}=\delta_{z11}\cdot w_{11} \tag{5}
$$
上式中,$\delta_{z11}$是从网络后端回传到本层的z11单元的梯度。
上式中,$\delta_{z11}$是从网络后端回传到本层的$z_{11}$单元的梯度。
J对a12的梯度时,先看正向公式,发现a12对z11和z12都有贡献,因此需要二者的偏导数相加:
$J$对$a_{12}$的梯度时,先看正向公式,发现$a_{12}$对$z_{11}$和$z_{12}$都有贡献,因此需要二者的偏导数相加:
$$
\frac{\partial J}{\partial a_{12}}=\frac{\partial J}{\partial z_{11}} \frac{\partial z_{11}}{\partial a_{12}}+\frac{\partial J}{\partial z_{12}} \frac{\partial z_{12}}{\partial a_{12}}=\delta_{z11} \cdot w_{12}+\delta_{z12} \cdot w_{11} \tag{6}
$$
最复杂的是求a22的梯度,因为从正向公式看,所有的输出都有a22的贡献,所以:
最复杂的是求$a_{22}$的梯度,因为从正向公式看,所有的输出都有$a_{22}$的贡献,所以:
$$
\frac{\partial J}{\partial a_{22}}=\frac{\partial J}{\partial z_{11}} \frac{\partial z_{11}}{\partial a_{22}}+\frac{\partial J}{\partial z_{12}} \frac{\partial z_{12}}{\partial a_{22}}+\frac{\partial J}{\partial z_{21}} \frac{\partial z_{21}}{\partial a_{22}}+\frac{\partial J}{\partial z_{22}} \frac{\partial z_{22}}{\partial a_{22}}
@@ -54,9 +54,9 @@ $$
=\delta_{z11} \cdot w_{22} + \delta_{z12} \cdot w_{21} + \delta_{z21} \cdot w_{12} + \delta_{z22} \cdot w_{11} \tag{7}
$$
同理可得所有a的梯度。
同理可得所有$a$的梯度。
观察公式7中的w的顺序,貌似是把原始的卷积核旋转了180度,再与传入误差项做卷积操作,即可得到所有元素的误差项。而公式5和公式6并不完备,是因为二者处于角落,这和卷积正向计算中的padding是相同的现象。因此,我们把传入的误差矩阵Delta-In做一个zero padding,再乘以旋转180度的卷积核,就是要传出的误差矩阵Delta-Out,如图17-22所示。
观察公式7中的$w$的顺序,貌似是把原始的卷积核旋转了180度,再与传入误差项做卷积操作,即可得到所有元素的误差项。而公式5和公式6并不完备,是因为二者处于角落,这和卷积正向计算中的padding是相同的现象。因此,我们把传入的误差矩阵Delta-In做一个zero padding,再乘以旋转180度的卷积核,就是要传出的误差矩阵Delta-Out,如图17-22所示。
<img src="https://aiedugithub4a2.blob.core.windows.net/a2-images/Images/17/conv_backward.png" />
@@ -68,9 +68,9 @@ $$\delta_{out} = \delta_{in} * W^{rot180} \tag{8}$$
这个误差矩阵可以继续回传到下一层。
- 当Weights是3x3时,$\delta_{in}$需要padding=2,即加2圈0,才能和Weights卷积后,得到正确尺寸的$\delta_{out}$
- 当Weights是5x5时,$\delta_{in}$需要padding=4,即加4圈0,才能和Weights卷积后,得到正确尺寸的$\delta_{out}$
- 以此类推:当Weights是NxN时,$\delta_{in}$需要padding=N-1,即加N-1圈0
- 当Weights是$3\times 3$时,$\delta_{in}$需要padding=2,即加2圈0,才能和Weights卷积后,得到正确尺寸的$\delta_{out}$
- 当Weights是$5\times 5$时,$\delta_{in}$需要padding=4,即加4圈0,才能和Weights卷积后,得到正确尺寸的$\delta_{out}$
- 以此类推:当Weights是$N\times N$时,$\delta_{in}$需要padding=N-1,即加N-1圈0
举例:
@@ -102,9 +102,9 @@ $$\delta_{out} = \delta_{in} * W^{rot180} \tag{8}$$
$$
\begin{bmatrix}
\delta_{11} & 0 & \delta_{12} & 0 & \delta_{13}\\
0 & 0 & 0 & 0 & 0\\
\delta_{21} & 0 & \delta_{22} & 0 & \delta_{23}\\
\delta_{11} & 0 & \delta_{12} & 0 & \delta_{13}\\\\
0 & 0 & 0 & 0 & 0\\\\
\delta_{21} & 0 & \delta_{22} & 0 & \delta_{23}\\\\
\end{bmatrix}
$$
@@ -112,10 +112,10 @@ $$
$$
\begin{bmatrix}
\delta_{11} & 0 & 0 & \delta_{12} & 0 & 0 & \delta_{13}\\
0 & 0 & 0 & 0 & 0 & 0 & 0\\
0 & 0 & 0 & 0 & 0 & 0 & 0\\
\delta_{21} & 0 & 0 & \delta_{22} & 0 & 0 & \delta_{23}\\
\delta_{11} & 0 & 0 & \delta_{12} & 0 & 0 & \delta_{13}\\\\
0 & 0 & 0 & 0 & 0 & 0 & 0\\\\
0 & 0 & 0 & 0 & 0 & 0 & 0\\\\
\delta_{21} & 0 & 0 & \delta_{22} & 0 & 0 & \delta_{23}\\\\
\end{bmatrix}
$$
@@ -131,40 +131,32 @@ $$
正向公式:
$$z111 = w111 \cdot a11 + w112 \cdot a12 + w121 \cdot a21 + w122 \cdot a22$$
$$z112 = w111 \cdot a12 + w112 \cdot a13 + w121 \cdot a22 + w122 \cdot a23$$
$$z121 = w111 \cdot a21 + w112 \cdot a22 + w121 \cdot a31 + w122 \cdot a32$$
$$z122 = w111 \cdot a22 + w112 \cdot a23 + w121 \cdot a32 + w122 \cdot a33$$
$$z_{111} = w_{111} \cdot a_{11} + w_{112} \cdot a_{12} + w_{121} \cdot a_{21} + w_{122} \cdot a_{22}$$
$$z_{112} = w_{111} \cdot a_{12} + w_{112} \cdot a_{13} + w_{121} \cdot a_{22} + w_{122} \cdot a_{23}$$
$$z_{121} = w_{111} \cdot a_{21} + w_{112} \cdot a_{22} + w_{121} \cdot a_{31} + w_{122} \cdot a_{32}$$
$$z_{122} = w_{111} \cdot a_{22} + w_{112} \cdot a_{23} + w_{121} \cdot a_{32} + w_{122} \cdot a_{33}$$
$$z211 = w211 \cdot a11 + w212 \cdot a12 + w221 \cdot a21 + w222 \cdot a22$$
$$z212 = w211 \cdot a12 + w212 \cdot a13 + w221 \cdot a22 + w222 \cdot a23$$
$$z221 = w211 \cdot a21 + w212 \cdot a22 + w221 \cdot a31 + w222 \cdot a32$$
$$z222 = w211 \cdot a22 + w212 \cdot a23 + w221 \cdot a32 + w222 \cdot a33$$
$$z_{211} = w_{211} \cdot a_{11} + w_{212} \cdot a_{12} + w_{221} \cdot a_{21} + w_{222} \cdot a_{22}$$
$$z_{212} = w_{211} \cdot a_{12} + w_{212} \cdot a_{13} + w_{221} \cdot a_{22} + w_{222} \cdot a_{23}$$
$$z_{221} = w_{211} \cdot a_{21} + w_{212} \cdot a_{22} + w_{221} \cdot a_{31} + w_{222} \cdot a_{32}$$
$$z_{222} = w_{211} \cdot a_{22} + w_{212} \cdot a_{23} + w_{221} \cdot a_{32} + w_{222} \cdot a_{33}$$
J对a22的梯度:
$J$对$a_{22}$的梯度:
$$
\frac{\partial J}{\partial a_{22}}=\frac{\partial J}{\partial Z_{1}} \frac{\partial Z_{1}}{\partial a_{22}}+\frac{\partial J}{\partial Z_{2}} \frac{\partial Z_{2}}{\partial a_{22}}
$$
$$
=\frac{\partial J}{\partial z_{111}} \frac{\partial z_{111}}{\partial a_{22}}+\frac{\partial J}{\partial z_{112}} \frac{\partial z_{112}}{\partial a_{22}}+\frac{\partial J}{\partial z_{121}} \frac{\partial z_{121}}{\partial a_{22}}+\frac{\partial J}{\partial z_{122}} \frac{\partial z_{122}}{\partial a_{22}}
$$
$$
+\frac{\partial J}{\partial z_{211}} \frac{\partial z_{211}}{\partial a_{22}}+\frac{\partial J}{\partial z_{212}} \frac{\partial z_{212}}{\partial a_{22}}+\frac{\partial J}{\partial z_{221}} \frac{\partial z_{221}}{\partial a_{22}}+\frac{\partial J}{\partial z_{222}} \frac{\partial z_{222}}{\partial a_{22}}
$$
$$
=(\delta_{z111} \cdot w_{122} + \delta_{z112} \cdot w_{121} + \delta_{z121} \cdot w_{112} + \delta_{z122} \cdot w_{111})
$$
$$
+(\delta_{z211} \cdot w_{222} + \delta_{z212} \cdot w_{221} + \delta_{z221} \cdot w_{212} + \delta_{z222} \cdot w_{211})
$$
$$
=\delta_{z1} * W_1^{rot180} + \delta_{z2} * W_2^{rot180}
\begin{aligned}
\frac{\partial J}{\partial a_{22}}&=\frac{\partial J}{\partial Z_{1}} \frac{\partial Z_{1}}{\partial a_{22}}+\frac{\partial J}{\partial Z_{2}} \frac{\partial Z_{2}}{\partial a_{22}} \\\\
&=\frac{\partial J}{\partial z_{111}} \frac{\partial z_{111}}{\partial a_{22}}+\frac{\partial J}{\partial z_{112}} \frac{\partial z_{112}}{\partial a_{22}}+\frac{\partial J}{\partial z_{121}} \frac{\partial z_{121}}{\partial a_{22}}+\frac{\partial J}{\partial z_{122}} \frac{\partial z_{122}}{\partial a_{22}} \\\\
&+\frac{\partial J}{\partial z_{211}} \frac{\partial z_{211}}{\partial a_{22}}+\frac{\partial J}{\partial z_{212}} \frac{\partial z_{212}}{\partial a_{22}}+\frac{\partial J}{\partial z_{221}} \frac{\partial z_{221}}{\partial a_{22}}+\frac{\partial J}{\partial z_{222}} \frac{\partial z_{222}}{\partial a_{22}} \\\\
&=(\delta_{z111} \cdot w_{122} + \delta_{z112} \cdot w_{121} + \delta_{z121} \cdot w_{112} + \delta_{z122} \cdot w_{111}) \\\\
&+(\delta_{z211} \cdot w_{222} + \delta_{z212} \cdot w_{221} + \delta_{z221} \cdot w_{212} + \delta_{z222} \cdot w_{211})\\\\
&=\delta_{z1} * W_1^{rot180} + \delta_{z2} * W_2^{rot180}
\end{aligned}
$$
因此和公式8相似,先在$\delta_{in}$外面加padding,然后和对应的旋转后的卷积核相乘,再把几个结果相加,就得到了需要前传的梯度矩阵:
$$\delta_{out} = \sum_m \delta_{in\_m} * W^{rot180}_m \tag{9}$$
$$\delta_{out} = \sum_m \delta_{in\_m} * W^{rot180}_ m \tag{9}$$
### 17.3.4 有多个输入时的梯度计算
@@ -178,35 +170,35 @@ $$\delta_{out} = \sum_m \delta_{in\_m} * W^{rot180}_m \tag{9}$$
$$
\begin{aligned}
z11 &= w111 \cdot a111 + w112 \cdot a112 + w121 \cdot a121 + w122 \cdot a122
\\
&+ w211 \cdot a211 + w212 \cdot a212 + w221 \cdot a221 + w222 \cdot a222
z_{11} &= w_{111} \cdot a_{111} + w_{112} \cdot a_{112} + w_{121} \cdot a_{121} + w_{122} \cdot a_{122}
\\\\
&+ w_{211} \cdot a_{211} + w_{212} \cdot a_{212} + w_{221} \cdot a_{221} + w_{222} \cdot a_{222}
\end{aligned}
\tag{10}
$$
$$
\begin{aligned}
z12 &= w111 \cdot a112 + w112 \cdot a113 + w121 \cdot a122 + w122 \cdot a123 \\
&+ w211 \cdot a212 + w212 \cdot a213 + w221 \cdot a222 + w222 \cdot a223
z_{12} &= w_{111} \cdot a_{112} + w_{112} \cdot a_{113} + w_{121} \cdot a_{122} + w_{122} \cdot a_{123} \\\\
&+ w_{211} \cdot a_{212} + w_{212} \cdot a_{213} + w_{221} \cdot a_{222} + w_{222} \cdot a_{223}
\end{aligned}\tag{11}$$
$$
\begin{aligned}
z21 &= w111 \cdot a121 + w112 \cdot a122 + w121 \cdot a131 + w122 \cdot a132 \\
&+ w211 \cdot a221 + w212 \cdot a222 + w221 \cdot a231 + w222 \cdot a232
z_{21} &= w_{111} \cdot a_{121} + w_{112} \cdot a_{122} + w_{121} \cdot a_{131} + w_{122} \cdot a_{132} \\\\
&+ w_{211} \cdot a_{221} + w_{212} \cdot a_{222} + w_{221} \cdot a_{231} + w_{222} \cdot a_{232}
\end{aligned}\tag{12}$$
$$
\begin{aligned}
z22 &= w111 \cdot a122 + w112 \cdot a123 + w121 \cdot a132 + w122 \cdot a133 \\
&+ w211 \cdot a222 + w212 \cdot a223 + w221 \cdot a232 + w222 \cdot a233
z_{22} &= w_{111} \cdot a_{122} + w_{112} \cdot a_{123} + w_{121} \cdot a_{132} + w_{122} \cdot a_{133} \\\\
&+ w_{211} \cdot a_{222} + w_{212} \cdot a_{223} + w_{221} \cdot a_{232} + w_{222} \cdot a_{233}
\end{aligned}\tag{13}$$
最复杂的情况,求J对a122的梯度:
最复杂的情况,求$J$对$a_{122}$的梯度:
$$
\begin{aligned}
\frac{\partial J}{\partial a111}&=\frac{\partial J}{\partial z11}\frac{\partial z11}{\partial a122} + \frac{\partial J}{\partial z12}\frac{\partial z12}{\partial a122} + \frac{\partial J}{\partial z21}\frac{\partial z21}{\partial a122} + \frac{\partial J}{\partial z22}\frac{\partial z22}{\partial a122}
\\
&=\delta_{z11} \cdot w122 + \delta_{z12} \cdot w121 + \delta_{z21} \cdot w112 + \delta_{z22} \cdot w111
\frac{\partial J}{\partial a_{111}}&=\frac{\partial J}{\partial z_{11}}\frac{\partial z_{11}}{\partial a_{122}} + \frac{\partial J}{\partial z_{12}}\frac{\partial z_{12}}{\partial a_{122}} + \frac{\partial J}{\partial z_{21}}\frac{\partial z_{21}}{\partial a_{122}} + \frac{\partial J}{\partial z_{22}}\frac{\partial z_{22}}{\partial a_{122}}
\\\\
&=\delta_{z_{11}} \cdot w_{122} + \delta_{z_{12}} \cdot w_{121} + \delta_{z_{21}} \cdot w_{112} + \delta_{z_{22}} \cdot w_{111}
\end{aligned}
$$
@@ -214,12 +206,12 @@ $$
$$\delta_{out1} = \delta_{in} * W_1^{rot180} \tag{14}$$
最复杂的情况,求J对a222的梯度:
求$J$对$a_{222}$的梯度:
$$
\begin{aligned}
\frac{\partial J}{\partial a211}&=\frac{\partial J}{\partial z11}\frac{\partial z11}{\partial a222} + \frac{\partial J}{\partial z12}\frac{\partial z12}{\partial a222} + \frac{\partial J}{\partial z21}\frac{\partial z21}{\partial a222} + \frac{\partial J}{\partial z22}\frac{\partial z22}{\partial a222} \\
&=\delta_{z11} \cdot w222 + \delta_{z12} \cdot w221 + \delta_{z21} \cdot w212 + \delta_{z22} \cdot w211
\frac{\partial J}{\partial a_{211}}&=\frac{\partial J}{\partial z_{11}}\frac{\partial z_{11}}{\partial a_{222}} + \frac{\partial J}{\partial z_{12}}\frac{\partial z_{12}}{\partial a_{222}} + \frac{\partial J}{\partial z_{21}}\frac{\partial z_{21}}{\partial a_{222}} + \frac{\partial J}{\partial z_{22}}\frac{\partial z_{22}}{\partial a_{222}} \\\\
&=\delta_{z_{11}} \cdot w_{222} + \delta_{z_{12}} \cdot w_{221} + \delta_{z_{21}} \cdot w_{212} + \delta_{z_{22}} \cdot w_{211}
\end{aligned}
$$
@@ -240,7 +232,7 @@ $$\delta_{out2} = \delta_{in} * W_2^{rot180} \tag{15}$$
$$
\begin{aligned}
\frac{\partial J}{\partial w_{11}} &= \frac{\partial J}{\partial z_{11}}\frac{\partial z_{11}}{\partial w_{11}} + \frac{\partial J}{\partial z_{12}}\frac{\partial z_{12}}{\partial w_{11}} + \frac{\partial J}{\partial z_{21}}\frac{\partial z_{21}}{\partial w_{11}} + \frac{\partial J}{\partial z_{22}}\frac{\partial z_{22}}{\partial w_{11}}
\\
\\\\
&=\delta_{z11} \cdot a_{11} + \delta_{z12} \cdot a_{12} + \delta_{z21} \cdot a_{21} + \delta_{z22} \cdot a_{22}
\end{aligned}
\tag{9}
@@ -251,7 +243,7 @@ $$
$$
\begin{aligned}
\frac{\partial J}{\partial w_{12}} &= \frac{\partial J}{\partial z_{11}}\frac{\partial z_{11}}{\partial w_{12}} + \frac{\partial J}{\partial z_{12}}\frac{\partial z_{12}}{\partial w_{12}} + \frac{\partial J}{\partial z_{21}}\frac{\partial z_{21}}{\partial w_{12}} + \frac{\partial J}{\partial z_{22}}\frac{\partial z_{22}}{\partial w_{12}}
\\
\\\\
&=\delta_{z11} \cdot a_{12} + \delta_{z12} \cdot a_{13} + \delta_{z21} \cdot a_{22} + \delta_{z22} \cdot a_{23}
\end{aligned}
\tag{10}
@@ -274,7 +266,7 @@ $$\delta_w = A * \delta_{in} \tag{11}$$
$$
\begin{aligned}
\frac{\partial J}{\partial b} &= \frac{\partial J}{\partial z_{11}}\frac{\partial z_{11}}{\partial b} + \frac{\partial J}{\partial z_{12}}\frac{\partial z_{12}}{\partial b} + \frac{\partial J}{\partial z_{21}}\frac{\partial z_{21}}{\partial b} + \frac{\partial J}{\partial z_{22}}\frac{\partial z_{22}}{\partial b}
\\
\\\\
&=\delta_{z11} + \delta_{z12} + \delta_{z21} + \delta_{z22}
\end{aligned}
\tag{12}
@@ -302,8 +294,8 @@ $$
$$
w=\begin{pmatrix}
0 & -1 & 0 \\
0 & 2 & 0 \\
0 & -1 & 0 \\\\
0 & 2 & 0 \\\\
0 & -1 & 0
\end{pmatrix}
$$
@@ -327,13 +319,13 @@ $$
z = x * w
$$
$$
loss = {1 \over 2}(z-y)^2
loss = \frac{1}{2}(z-y)^2
$$
反向求解w的梯度公式(从公式11得到):
$$
{\partial loss \over \partial w}={\partial loss \over \partial z}{\partial z \over \partial w}=x * (z-y)
\frac{\partial loss}{\partial w}=\frac{\partial loss}{\partial z}\frac{\partial z}{\partial w}=x * (z-y)
$$
即w的梯度为预测图片z减去目标图片y的结果,再与原始图片x做卷积,其中x为被卷积图片,z-y为卷积核。
@@ -40,12 +40,11 @@
假设输入图片的形状是 $W_1 \times H_1 \times D_1$,其中W是图片宽度,H是图片高度,D是图片深度(多个图层),F是池化的视野(正方形),S是池化的步长,则输出图片的形状是:
$$
\begin{aligned}
W_2 &= (W_1 - F)/S + 1 \\
H_2 &= (H_1 - F)/S + 1 \\
D_2 &= D_1
\end{aligned}
\begin{cases}
W_2 = (W_1 - F)/S + 1 \\\\
H_2 = (H_1 - F)/S + 1 \\\\
D_2 = D_1
\end{cases}
$$
池化层不会改变图片的深度,即D值前后相同。
@@ -157,8 +157,8 @@ $$
$$
$$
\begin{aligned}
\frac{\partial loss}{\partial h_{t2}}&=\frac{\partial loss}{\partial z_{t2}}\frac{\partial z_{t2}}{\partial s_{t2}}\frac{\partial s_{t2}}{\partial h_{t2}} \\
&=dz_{t2} \cdot V \cdot Tanh'(s_{t2}) \\
\frac{\partial loss}{\partial h_{t2}}&=\frac{\partial loss}{\partial z_{t2}}\frac{\partial z_{t2}}{\partial s_{t2}}\frac{\partial s_{t2}}{\partial h_{t2}} \\\\
&=dz_{t2} \cdot V \cdot Tanh'(s_{t2}) \\\\
&=dz_{t2} \cdot V \cdot (1-s_{t2}^2) \rightarrow dh_{t2}
\end{aligned} \tag{8}
$$
@@ -157,7 +157,7 @@ class timestep(object):
$$
\begin{aligned}
\frac{\partial loss_t}{\partial z_t}&=\frac{\partial loss_t}{\partial a_t}\frac{\partial a_t}{\partial z_t} \\
\frac{\partial loss_t}{\partial z_t}&=\frac{\partial loss_t}{\partial a_t}\frac{\partial a_t}{\partial z_t} \\\\
&= a_t - y_t \rightarrow dz_t
\end{aligned}
\tag{7}
@@ -166,17 +166,17 @@ $$
再进一步计算s和h的误差。对于t4来说,s和h节点的路径比较单一,直接从z节点向下反向推导即可:
$$
\frac{\partial loss_{t4}}{\partial s_{t4}}=\frac{\partial loss_{t4}}{\partial z_{t4}}\frac{\partial z_{t4}}{\partial s_{t4}} = dz_{t4} \cdot V^T \tag{8}
\frac{\partial loss_{t4}}{\partial s_{t4}}=\frac{\partial loss_{t4}}{\partial z_{t4}}\frac{\partial z_{t4}}{\partial s_{t4}} = dz_{t4} \cdot V^{\top} \tag{8}
$$
$$
\frac{\partial loss_{t4}}{\partial h_{t4}}=\frac{\partial loss_{t4}}{\partial s_{t4}}\frac{\partial s_{t4}}{\partial h_{t4}}=dz_{t4} \cdot V^T \odot Tanh'(s_{t4}) \rightarrow dh_{t4} \tag{9}
\frac{\partial loss_{t4}}{\partial h_{t4}}=\frac{\partial loss_{t4}}{\partial s_{t4}}\frac{\partial s_{t4}}{\partial h_{t4}}=dz_{t4} \cdot V^{\top} \odot Tanh'(s_{t4}) \rightarrow dh_{t4} \tag{9}
$$
提醒两点:
1. 公式8、9中用了$loss_{t4}$而不是$Loss$,因为只针对第4个时间步,而不是所有时间步。
2. 出现了$V^T$,因为在本例中V是一个矩阵,而非标量,在求导时需要转置。
2. 出现了$V^{\top}$,因为在本例中V是一个矩阵,而非标量,在求导时需要转置。
对于t1、t2、t3的s节点来说,都有两个方向的反向路径,第一个是从本时间步的z节点,第二个是从后一个时间步的h节点,因此,s的反向计算应该是两个路径的和。
@@ -185,9 +185,9 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial s_{t3}}&=\frac{\partial loss_{t3}}{\partial s_{t3}} + \frac{\partial loss_{t4}}{\partial s_{t3}}
\\
&=\frac{\partial loss_{t3}}{\partial s_{t3}} + \frac{\partial loss_{t4}}{\partial h_{t4}}\frac{\partial h_{t4}}{\partial s_{t3}} \\
&=dz_{t3} \cdot V^T + dh_{t4} \cdot W^T
\\\\
&=\frac{\partial loss_{t3}}{\partial s_{t3}} + \frac{\partial loss_{t4}}{\partial h_{t4}}\frac{\partial h_{t4}}{\partial s_{t3}} \\\\
&=dz_{t3} \cdot V^{\top} + dh_{t4} \cdot W^{\top}
\end{aligned}
$$
@@ -195,8 +195,8 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial s_t}&=\frac{\partial loss_t}{\partial s_t} + \frac{\partial Loss}{\partial h_{t+1}}\frac{\partial h_{t+1}}{\partial s_t} \\
&=dz_t \cdot V^T + dh_{t+1} \cdot W^T
\frac{\partial Loss}{\partial s_t}&=\frac{\partial loss_t}{\partial s_t} + \frac{\partial Loss}{\partial h_{t+1}}\frac{\partial h_{t+1}}{\partial s_t} \\\\
&=dz_t \cdot V^{\top} + dh_{t+1} \cdot W^{\top}
\end{aligned}
\tag{10}
$$
@@ -205,8 +205,8 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h_t} &= \frac{\partial Loss}{\partial s_t} \frac{\partial s_t}{\partial h_t} \\
&= (dz \cdot V^T + dh_{t+1} \cdot W^T) \odot Tanh'(s_t) \rightarrow dh_t
\frac{\partial Loss}{\partial h_t} &= \frac{\partial Loss}{\partial s_t} \frac{\partial s_t}{\partial h_t} \\\\
&= (dz \cdot V^{\top} + dh_{t+1} \cdot W^{\top} ) \odot Tanh'(s_t) \rightarrow dh_t
\end{aligned}
\tag{11}
$$
@@ -214,13 +214,13 @@ $$
下面计算V的误差,V只与z节点和s节点有关,而且4个时间步是相同的:
$$
\frac{\partial loss_t}{\partial V_t}=\frac{\partial loss_t}{\partial z_t}\frac{\partial z_t}{\partial V_t}=s_t^T \cdot dz_t \rightarrow dV_t \tag{12}
\frac{\partial loss_t}{\partial V_t}=\frac{\partial loss_t}{\partial z_t}\frac{\partial z_t}{\partial V_t}=s_t^{\top} \cdot dz_t \rightarrow dV_t \tag{12}
$$
下面计算U的误差,U只与节点h和输入x有关,而且4个时间步是相同的,但是U参与了所有时间步的计算,因此要用 $Loss$ 求 $U_t$ 的偏导:
$$
\frac{\partial Loss}{\partial U_t}=\frac{\partial Loss}{\partial h_t}\frac{\partial h_t}{\partial U_t}=x_t^T \cdot dh_t \rightarrow dU_t \tag{13}
\frac{\partial Loss}{\partial U_t}=\frac{\partial Loss}{\partial h_t}\frac{\partial h_t}{\partial U_t}=x_t^{\top} \cdot dh_t \rightarrow dU_t \tag{13}
$$
下面计算W的误差,从图19-11中看,t1没有W参与计算的,与其它三个时间步不同,所以对于t1来说:
@@ -232,7 +232,7 @@ $$
对于t2、t3、t4
$$
\frac{\partial Loss}{\partial W_t}=\frac{\partial Loss}{\partial h_t}\frac{\partial h_t}{\partial W_t}=s_{t-1}^T \cdot dh_{t} \rightarrow dW_{t} \tag{15}
\frac{\partial Loss}{\partial W_t}=\frac{\partial Loss}{\partial h_t}\frac{\partial h_t}{\partial W_t}=s_{t-1}^{\top} \cdot dh_{t} \rightarrow dW_{t} \tag{15}
$$
下面是t1的反向传播函数,与其他3个t不同的是dW部分为0:
@@ -84,13 +84,13 @@ $$
对于图19-14的最后一个时间步来说,节点s和h的误差只与$loss_{\tau}$有关:
$$
\frac{\partial Loss}{\partial s_{\tau}}=\frac{\partial loss_{\tau}}{\partial s_{\tau}} = \frac{\partial loss_{\tau}}{\partial z_{\tau}}\frac{\partial z_{\tau}}{\partial s_{\tau}} = dz_{\tau} \cdot V^T
\frac{\partial Loss}{\partial s_{\tau}}=\frac{\partial loss_{\tau}}{\partial s_{\tau}} = \frac{\partial loss_{\tau}}{\partial z_{\tau}}\frac{\partial z_{\tau}}{\partial s_{\tau}} = dz_{\tau} \cdot V^{\top}
\tag{8}
$$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h_{\tau}}&=\frac{\partial loss_{\tau}}{\partial h_{\tau}} = \frac{\partial loss_{\tau}}{\partial z_{\tau}}\frac{\partial z_{\tau}}{\partial s_{\tau}}\frac{\partial s_{\tau}}{\partial h_{\tau}} \\ &= dz_{\tau} \cdot V^T \odot \sigma'(s_{\tau}) \rightarrow dh_{\tau}
\frac{\partial Loss}{\partial h_{\tau}}&=\frac{\partial loss_{\tau}}{\partial h_{\tau}} = \frac{\partial loss_{\tau}}{\partial z_{\tau}}\frac{\partial z_{\tau}}{\partial s_{\tau}}\frac{\partial s_{\tau}}{\partial h_{\tau}} \\\\ &= dz_{\tau} \cdot V^{\top} \odot \sigma'(s_{\tau}) \rightarrow dh_{\tau}
\end{aligned}
\tag{9}
$$
@@ -99,16 +99,16 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial s_3}&=\frac{\partial loss_3}{\partial s_3} + \frac{\partial loss_4}{\partial h_4}\frac{\partial h_4}{\partial s_3} \\
&=dz_3 \cdot V^T + dh_{4} \cdot W^T
\frac{\partial Loss}{\partial s_3}&=\frac{\partial loss_3}{\partial s_3} + \frac{\partial loss_4}{\partial h_4}\frac{\partial h_4}{\partial s_3} \\\\
&=dz_3 \cdot V^{\top} + dh_{4} \cdot W^{\top}
\end{aligned}
\tag{10}
$$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h_3}&=\frac{\partial Loss}{\partial s_3}\frac{\partial s_3}{\partial h_3} \\
&=(dz_3 \cdot V^T + dh_4 \cdot W^T) \odot \sigma'(s_3) \rightarrow dh_3
\frac{\partial Loss}{\partial h_3}&=\frac{\partial Loss}{\partial s_3}\frac{\partial s_3}{\partial h_3} \\\\
&=(dz_3 \cdot V^{\top} + dh_4 \cdot W^{\top} ) \odot \sigma'(s_3) \rightarrow dh_3
\end{aligned}
\tag{11}
$$
@@ -116,7 +116,7 @@ $$
扩展到一般性:
$$
\frac{\partial Loss}{\partial h_t}=(dz_t \cdot V^T + dh_{t+1} \cdot W^T) \odot \sigma'(s_t) \rightarrow dh_t
\frac{\partial Loss}{\partial h_t}=(dz_t \cdot V^{\top} + dh_{t+1} \cdot W^{\top} ) \odot \sigma'(s_t) \rightarrow dh_t
\tag{12}
$$
@@ -135,8 +135,8 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h_3}&=\frac{\partial loss_4}{\partial h_3}
=\frac{\partial loss_4}{\partial h_4}\frac{\partial h_4}{\partial s_3}\frac{\partial s_3}{\partial h_3} \\
&=dh_{4} \cdot W^T \odot \sigma'(s_3)
=\frac{\partial loss_4}{\partial h_4}\frac{\partial h_4}{\partial s_3}\frac{\partial s_3}{\partial h_3} \\\\
&=dh_{4} \cdot W^{\top} \odot \sigma'(s_3)
\end{aligned}
\tag{13}
$$
@@ -144,7 +144,7 @@ $$
扩展到一般性:
$$
\frac{\partial Loss}{\partial h_t}=dh_{t+1} \cdot W^T \odot \sigma'(s_t) \rightarrow dh_t
\frac{\partial Loss}{\partial h_t}=dh_{t+1} \cdot W^{\top} \odot \sigma'(s_t) \rightarrow dh_t
\tag{14}
$$
@@ -152,21 +152,21 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h_1}&=dh_{2} \cdot W^T \odot \sigma'(s_1) \\
&=dh_3 \cdot (W^T \odot \sigma'(s_2)) \cdot (W^T \odot \sigma'(s_1)) \\
&=dh_4 \cdot (W^T \odot \sigma'(s_3)) \cdot (W^T \odot \sigma'(s_2)) \cdot (W^T \odot \sigma'(s_1)) \\
&=dh_4 \prod_{t=1}^3 W^T \odot \sigma'(s_t)
\frac{\partial Loss}{\partial h_1}&=dh_{2} \cdot W^{\top} \odot \sigma'(s_1) \\\\
&=dh_3 \cdot (W^{\top} \odot \sigma'(s_2)) \cdot (W^{\top} \odot \sigma'(s_1)) \\\\
&=dh_4 \cdot (W^{\top} \odot \sigma'(s_3)) \cdot (W^{\top} \odot \sigma'(s_2)) \cdot (W^{\top} \odot \sigma'(s_1)) \\\\
&=dh_4 \prod_{t=1}^3 W^{\top} \odot \sigma'(s_t)
\end{aligned}
$$
扩展到一般性:
$$
\frac{\partial Loss}{\partial h_k}=dh_{\tau} \prod_{t=k}^{\tau-1} W^T \odot \sigma'(s_t) \rightarrow dh_k \tag{16}
\frac{\partial Loss}{\partial h_k}=dh_{\tau} \prod_{t=k}^{\tau-1} W^{\top} \odot \sigma'(s_t) \rightarrow dh_k \tag{16}
$$
$$
dh_{\tau}=dz_{\tau} \cdot V^T \odot \sigma'(s_{\tau}) \tag{17}
dh_{\tau}=dz_{\tau} \cdot V^{\top} \odot \sigma'(s_{\tau}) \tag{17}
$$
公式17为最后一个时间步的梯度(公式9)的一般形式。
@@ -40,11 +40,11 @@ $$
对于所有的时间步:
$$
s1 = Tanh(h1) \tag{5}
s1 = \tanh(h1) \tag{5}
$$
$$
s2 = Tanh(h2) \tag{6}
s2 = \tanh(h2) \tag{6}
$$
对于最后一个时间步:
@@ -84,22 +84,22 @@ $$
$$
$$
\frac{\partial Loss}{\partial V}=\frac{\partial Loss}{\partial z}\frac{\partial z}{\partial V}=s2^T \cdot dz \rightarrow dV \tag{11}
\frac{\partial Loss}{\partial V}=\frac{\partial Loss}{\partial z}\frac{\partial z}{\partial V}=s2^{\top} \cdot dz \rightarrow dV \tag{11}
$$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h2} &= \frac{\partial Loss}{\partial z}\frac{\partial z}{\partial s2}\frac{\partial s2}{\partial h2}
\\
&=(dz \cdot V^T) \odot \sigma'(s2) \rightarrow dh2
\\\\
&=(dz \cdot V^{\top}) \odot \sigma'(s2) \rightarrow dh2
\end{aligned}
\tag{12}
$$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h1} &= \frac{\partial Loss}{\partial h2}\frac{\partial h2}{\partial s1}\frac{\partial s1}{\partial h1} \\
&=(dh2 \cdot Q^T) \odot \sigma'(s1) \rightarrow dh1
\frac{\partial Loss}{\partial h1} &= \frac{\partial Loss}{\partial h2}\frac{\partial h2}{\partial s1}\frac{\partial s1}{\partial h1} \\\\
&=(dh2 \cdot Q^{\top}) \odot \sigma'(s1) \rightarrow dh1
\end{aligned}
\tag{13}
$$
@@ -113,8 +113,8 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h2_t} &= \frac{\partial Loss}{\partial h2_{t+1}}\frac{\partial h2_{t+1}}{\partial s2_t}\frac{\partial s2_t}{\partial h2_t}
\\
&=(dh2_{t+1} \cdot W2^T) \odot \sigma'(s2_t) \rightarrow dh2_t
\\\\
&=(dh2_{t+1} \cdot W2^{\top}) \odot \sigma'(s2_t) \rightarrow dh2_t
\end{aligned}
\tag{15}
$$
@@ -126,8 +126,8 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h1_t} &= \frac{\partial Loss}{\partial h1_{t+1}}\frac{\partial h1_{t+1}}{\partial s1_t}\frac{\partial s1_t}{\partial h1_t}+\frac{\partial loss_t}{\partial h2_t}\frac{\partial h2_t}{\partial s1_t}\frac{\partial s1_t}{\partial h1_t}
\\
&=(dh1_{t+1} \cdot W1^T + dh2_t\cdot Q^T) \odot \sigma'(s1_t) \rightarrow dh1_t
\\\\
&=(dh1_{t+1} \cdot W1^{\top} + dh2_t\cdot Q^{\top}) \odot \sigma'(s1_t) \rightarrow dh1_t
\end{aligned}
\tag{17}
$$
@@ -141,21 +141,21 @@ $$
对于其他时间步:
$$
\frac{\partial Loss}{\partial W1}=s1^T_{t-1} \cdot dh_1 \rightarrow dW1 \tag{19}
\frac{\partial Loss}{\partial W1}=s1^{\top}_ {t-1} \cdot dh_1 \rightarrow dW1 \tag{19}
$$
$$
\frac{\partial Loss}{\partial W2}=s2^T_{t-1} \cdot dh2 \rightarrow dW2 \tag{20}
\frac{\partial Loss}{\partial W2}=s2^{\top}_ {t-1} \cdot dh2 \rightarrow dW2 \tag{20}
$$
对于所有时间步:
$$
\frac{\partial Loss}{\partial Q}=\frac{\partial Loss}{\partial h2}\frac{\partial h2}{\partial Q}=s1^T \cdot dh2 \rightarrow dQ \tag{21}
\frac{\partial Loss}{\partial Q}=\frac{\partial Loss}{\partial h2}\frac{\partial h2}{\partial Q}=s1^{\top} \cdot dh2 \rightarrow dQ \tag{21}
$$
$$
\frac{\partial Loss}{\partial U}=\frac{\partial Loss}{\partial h1}\frac{\partial h1}{\partial U}=x^T \cdot dh1 \rightarrow dU \tag{22}
\frac{\partial Loss}{\partial U}=\frac{\partial Loss}{\partial h1}\frac{\partial h1}{\partial U}=x^{\top} \cdot dh1 \rightarrow dU \tag{22}
$$
#### 代码实现
@@ -24,14 +24,14 @@
在图19-22中,$h_{tn}$中的n表示时间步,在图中取值为1至4。
- $h_{t1}$至$h_{t4}$是正向循环的四个隐层状态值,$U$、$V$、$W$ 分别是它们的权重矩阵值;
- $h'_{t1}$至$h'_{t4}$是逆向循环的四个隐层状态值,$U'$、$V'$、 $W'$ 分别是它们的权重矩阵值;
- $h'_ {t1}$至$h'_ {t4}$是逆向循环的四个隐层状态值,$U'$、$V'$、 $W'$ 分别是它们的权重矩阵值;
- $S_{t1}$至$S_{t4}$是正逆两个方向的隐层状态值的和。
但是,请大家记住,图19-22和上面的相关解释是不正确的!主要的问题集中在 $s_t$ 是如何生成的。
$h_t$ 和 $h'_t$ 到$s_t$之间不是矩阵相乘的关系,所以没有 $V$ 和 $V'$ 这两个权重矩阵。
$h_t$ 和 $h'_ t$ 到$s_t$之间不是矩阵相乘的关系,所以没有 $V$ 和 $V'$ 这两个权重矩阵。
正向循环的最后一个时间步$h_{t4}$和逆向循环的第一个时间步$h_{t4}'$共同生成$s_{t4}$,这也是不对的。因为对于正向循环来说,用 $h_{t4}$ 没问题。但是对于逆向循环来说,$h'_{t4}$ 只是第一个时间步的结果,后面的计算还未发生,所以 $h'_{t4}$ 非常不准确。
正向循环的最后一个时间步$h_{t4}$和逆向循环的第一个时间步$h_{t4}'$共同生成$s_{t4}$,这也是不对的。因为对于正向循环来说,用 $h_{t4}$ 没问题。但是对于逆向循环来说,$h'_ {t4}$ 只是第一个时间步的结果,后面的计算还未发生,所以 $h'_{t4}$ 非常不准确。
正确的双向循环神经网络图应该如图19-23所示。
@@ -131,7 +131,7 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h1_\tau}&=\frac{\partial loss_\tau}{\partial h1_\tau}=\frac{\partial loss_\tau}{\partial z_\tau}\frac{\partial z_\tau}{\partial s_\tau}\frac{\partial s_\tau}{\partial s1_\tau}\frac{\partial s1_\tau}{\partial h1_\tau} \\
\frac{\partial Loss}{\partial h1_\tau}&=\frac{\partial loss_\tau}{\partial h1_\tau}=\frac{\partial loss_\tau}{\partial z_\tau}\frac{\partial z_\tau}{\partial s_\tau}\frac{\partial s_\tau}{\partial s1_\tau}\frac{\partial s1_\tau}{\partial h1_\tau} \\\\
&=dz_\tau \cdot V^T \odot \sigma'(s1_\tau) \rightarrow dh1_\tau
\end{aligned}
\tag{9}
@@ -146,10 +146,10 @@ $$
$$
\begin{aligned}
\frac{\partial Loss}{\partial h1_t} &= \frac{\partial loss_t}{\partial z_t}\frac{\partial z_t}{\partial s_t}\frac{\partial s_t}{\partial s1_t}\frac{\partial s1_t}{\partial h1_t} + \frac{\partial Loss}{\partial h1_{t+1}}\frac{\partial h1_{t+1}}{\partial s1_{t}}\frac{\partial s1_t}{\partial h1_t}
\\
&=dz_t \cdot V^T \odot \sigma'(s1_t) + \frac{\partial Loss}{\partial h1_{t+1}} \cdot W1^T \odot \sigma'(s1_t)
\\
&=(dz_t \cdot V^T + dh1_{t+1} \cdot W1^T) \odot \sigma'(s1_t) \rightarrow dh1_t
\\\\
&=dz_t \cdot V^{\top} \odot \sigma'(s1_t) + \frac{\partial Loss}{\partial h1_{t+1}} \cdot W1^{\top} \odot \sigma'(s1_t)
\\\\
&=(dz_t \cdot V^{\top} + dh1_{t+1} \cdot W1^{\top}) \odot \sigma'(s1_t) \rightarrow dh1_t
\end{aligned} \tag{10}
$$
@@ -158,19 +158,19 @@ $$
对于$V$来说,只有当前时间步的损失函数会给它反向传播的误差,与别的时间步没有关系,所以有:
$$
\frac{\partial loss_t}{\partial V_t} = \frac{\partial loss_t}{\partial z_t}\frac{\partial z_t}{\partial V_t}= s_t^T \cdot dz_t \rightarrow dV_t \tag{11}
\frac{\partial loss_t}{\partial V_t} = \frac{\partial loss_t}{\partial z_t}\frac{\partial z_t}{\partial V_t}= s_t^{\top} \cdot dz_t \rightarrow dV_t \tag{11}
$$
对于$U1$,后面的时间步都会给它反向传播误差,但是我们只从$h1$节点考虑:
$$
\frac{\partial Loss}{\partial U1_t} = \frac{\partial Loss}{\partial h1_t}\frac{\partial h1_t}{\partial U1_t}= x^T_t \cdot dh1_t \rightarrow dU1_t \tag{12}
\frac{\partial Loss}{\partial U1_t} = \frac{\partial Loss}{\partial h1_t}\frac{\partial h1_t}{\partial U1_t}= x^{\top}_ t \cdot dh1_t \rightarrow dU1_t \tag{12}
$$
对于$W1$,和$U1$的考虑是一样的,只从当前时间步的$h1$节点考虑:
$$
\frac{\partial Loss}{\partial W1_t} = \frac{\partial Loss}{\partial h1_t}\frac{\partial h1_t}{\partial W1_t}= s1_{t-1}^T \cdot dh1_t \rightarrow dW1_t \tag{13}
\frac{\partial Loss}{\partial W1_t} = \frac{\partial Loss}{\partial h1_t}\frac{\partial h1_t}{\partial W1_t}= s1_{t-1}^{\top} \cdot dh1_t \rightarrow dW1_t \tag{13}
$$
对于第一个时间步,$s1_{t-1}$不存在,所以没有$dW1$
@@ -184,7 +184,7 @@ $$
逆向循环的反向传播和正向循环一模一样,只是把 $1$ 变成 $2$ 即可,比如公式13变成:
$$
\frac{\partial Loss}{\partial W2_t} = \frac{\partial Loss}{\partial h2_t}\frac{\partial h2_t}{\partial W2_t}= s2_{t-1}^T \cdot dh2_t \rightarrow dW2_t
\frac{\partial Loss}{\partial W2_t} = \frac{\partial Loss}{\partial h2_t}\frac{\partial h2_t}{\partial W2_t}= s2_{t-1}^{\top} \cdot dh2_t \rightarrow dW2_t
$$
### 19.7.4 代码实现
@@ -271,4 +271,4 @@ loss=0.146799, acc=0.958000
ch19, Level7
其中,Level7_Base_MNIST.py是单向的循环神经网络,Level7_BiRnn_MNIST.py是双向的循环神经网络。
其中,Level7_Base_MNIST.py是单向的循环神经网络,Level7_BiRnn_MNIST.py是双向的循环神经网络。
@@ -77,7 +77,7 @@ LSTM设计了 **门控(gate)** 结构,控制信息的保留和丢弃。LST
1. 遗忘门
由上图可知,遗忘门的输出为$f_t$, 采用sigmoid激活函数,将输出映射到[0,1]区间。上一时刻细胞状态$c_{t-1}$通过遗忘门时,与$ft$结果相乘,显然,乘数为0的信息被全部丢弃,为1的被全部保留。这样就决定了上一细胞状态$c_{t-1}$有多少能进入当前状态$c_t$。
由上图可知,遗忘门的输出为$f_t$, 采用sigmoid激活函数,将输出映射到[0,1]区间。上一时刻细胞状态$c_{t-1}$通过遗忘门时,与$f_t$结果相乘,显然,乘数为0的信息被全部丢弃,为1的被全部保留。这样就决定了上一细胞状态$c_{t-1}$有多少能进入当前状态$c_t$。
遗忘门$f_t$的公式如下:
@@ -95,11 +95,11 @@ LSTM设计了 **门控(gate)** 结构,控制信息的保留和丢弃。LST
$$
\begin{aligned}
f_t &= \sigma([W_{fh}\;W_{fx}] \begin{bmatrix}h_{t-1}\\\\x_t \end{bmatrix}+b_f) \\
&= \sigma(W_{fh}h_{t-1}+W_{fx}x_t+b_f) \tag{1''}
\end{aligned}
f_t &= \sigma([W_{fh}\;W_{fx}] \begin{bmatrix}h_{t-1}\\\\x_t \end{bmatrix}+b_f) \\\\
&= \sigma(W_{fh}h_{t-1}+W_{fx}x_t+b_f)
\end{aligned} \tag{1''}
$$
后两种形式将权重矩阵放在状态向量前面,在讲解原理时,与公式$(1)$没有区别,但在代码实现时会出现一些问题,所以,在本章中我们采用公式$(1)$的表达方式。
@@ -113,10 +113,10 @@ LSTM设计了 **门控(gate)** 结构,控制信息的保留和丢弃。LST
i_t = \sigma(h_{t-1} \cdot W_i + x_t \cdot U_i + b_i) \tag{2}
$$
即时细胞状态 $\tilde{c}_t$的公式如下:
即时细胞状态 $\tilde{c}_ t$的公式如下:
$$
\tilde{c}_t = \tanh(h_{t-1} \cdot W_c + x_t \cdot U_c + b_c) \tag{3}
\tilde{c}_ t = \tanh(h_{t-1} \cdot W_c + x_t \cdot U_c + b_c) \tag{3}
$$
上一时刻保留的信息,加上当前输入保留的信息,构成了当前时刻的细胞状态$c_t$。
@@ -168,7 +168,7 @@ LSTM使用时序反向传播算法(Backpropagation Through Time, BPTT)进行
图20-4 带有一个输出的LSTM单元
假设当前LSTM cell处于第$l$层、$t$时刻。那么,它从两个方向接受反向传播的误差:一个是从$t$时刻$l+1$层的输入传回误差,记为$\delta^{l+1}_{x_t}$;另一个是从$t+1$时刻$l$层传回的误差,记为$\delta^{l}_{h_t}$。(注意,这里的下标不是$h_{t+1}$,而是$h_t$)。
假设当前LSTM cell处于第$l$层、$t$时刻。那么,它从两个方向接受反向传播的误差:一个是从$t$时刻$l+1$层的输入传回误差,记为$\delta^{l+1}_ {x_t}$;另一个是从$t+1$时刻$l$层传回的误差,记为$\delta^{l}_ {h_t}$。(注意,这里的下标不是$h_{t+1}$,而是$h_t$)。
我们先复习几个在推导过程中会使用到的激活函数,以及其导数公式。令sigmoid = $\sigma$,则:
@@ -177,7 +177,7 @@ $$
$$
$$
\sigma^{'}(z) = y(1-y) \tag{10}
\sigma^{\prime}(z) = y(1-y) \tag{10}
$$
$$
@@ -185,32 +185,32 @@ $$
$$
$$
\tanh^{'}(z) = 1-y^2 \tag{12}
\tanh^{\prime}(z) = 1-y^2 \tag{12}
$$
假设某一线性函数 $z_i$ 经过Softmax函数之后的预测输出为 $\hat{y}_i$,该输出的标签值为 $y_i$,则:
假设某一线性函数 $z_i$ 经过Softmax函数之后的预测输出为 $\hat{y}_ i$,该输出的标签值为 $y_i$,则:
$$
softmax(z_i) = \hat{y}_i = \frac{e^{z_i}}{\sum_{j=1}^me^{z_j}} \tag{13}
softmax(z_i) = \hat{y}_ i = \frac{e^{z_i}}{\sum_{j=1}^me^{z_j}} \tag{13}
$$
$$
\frac{\partial{loss}}{\partial{z_i}} = \hat{y}_i - y_i \tag{14}
\frac{\partial{loss}}{\partial{z_i}} = \hat{y}_ i - y_i \tag{14}
$$
从图中可知,从上层传回的误差为输出层$z_t$向$h^l_t$传回的误差,假设输出层的激活函数为softmax函数,输出层标签值为$y$,则:
$$
\delta^{l+1}_{x_t} = \frac{\partial{loss}}{\partial{z_t}} \cdot \frac{\partial{z_t}}{\partial{h^l_t}} = (a - y) \cdot V \tag{15}
\delta^{l+1}_ {x_t} = \frac{\partial{loss}}{\partial{z_t}} \cdot \frac{\partial{z_t}}{\partial{h^l_t}} = (a - y) \cdot V \tag{15}
$$
从$t+1$时刻传回的误差为$\delta^{l}_{h_t}$,若$t$为时序的最后一个时间点,则$\delta^{l}_{h_t}=0$。
从$t+1$时刻传回的误差为$\delta^{l}_ {h_t}$,若$t$为时序的最后一个时间点,则$\delta^{l}_ {h_t}=0$。
该cell的隐层$h^l_t$的最终误差为两项误差之和,即:
$$
\delta^l_t = \frac{\partial{loss}}{\partial{h_t}} = \delta^{l+1}_{x_t} + \delta^{l}_{h_t} = (a - y) \cdot V \tag{16}
\delta^l_t = \frac{\partial{loss}}{\partial{h_t}} = \delta^{l+1}_ {x_t} + \delta^{l}_ {h_t} = (a - y) \cdot V \tag{16}
$$
接下来的推导过程仅与本层相关,为了方便推导,我们忽略层次信息,令$\delta^l_t = \delta_t$。
@@ -219,8 +219,8 @@ $$
$$
\begin{aligned}
\delta_{z_{ot}} &= \frac{\partial{loss}}{\partial{z_{o_t}}} = \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{o_t}} \cdot \frac{\partial{o_t}}{\partial{z_{o_t}}} \\
&= \delta_t \cdot diag[\tanh(c_t)] \cdot diag[o_t \circ (1 - o_t)] \\
\delta_{z_{ot}} &= \frac{\partial{loss}}{\partial{z_{o_t}}} = \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{o_t}} \cdot \frac{\partial{o_t}}{\partial{z_{o_t}}} \\\\
&= \delta_t \cdot diag[\tanh(c_t)] \cdot diag[o_t \circ (1 - o_t)] \\\\
&= \delta_t \circ \tanh(c_t) \circ o_t \circ (1 - o_t)
\end{aligned}
\tag{17}
@@ -228,8 +228,8 @@ $$
$$
\begin{aligned}
\delta_{c_t} &= \frac{\partial{loss}}{\partial{c_t}} = \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{\tanh(c_t)}} \cdot \frac{\partial{\tanh(c_t)}}{\partial{c_t}} \\
&= \delta_t \cdot diag[o_t] \cdot diag[1-\tanh^2(c_t)] \\
\delta_{c_t} &= \frac{\partial{loss}}{\partial{c_t}} = \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{\tanh(c_t)}} \cdot \frac{\partial{\tanh(c_t)}}{\partial{c_t}} \\\\
&= \delta_t \cdot diag[o_t] \cdot diag[1-\tanh^2(c_t)] \\\\
&= \delta_t \circ o_t \circ (1-\tanh^2(c_t))
\end{aligned}
\tag{18}
@@ -237,26 +237,26 @@ $$
$$
\begin{aligned}
\delta_{z_{\tilde{c}t}} &= \frac{\partial{loss}}{\partial{z_{\tilde{c}_t}}} = \frac{\partial{loss}}{\partial{c_t}} \cdot \frac{\partial{c_t}}{\partial{\tilde{c}_t}} \cdot \frac{\partial{\tilde{c}_t}}{\partial{z_{\tilde{c}_t}}} \\
&= \delta_{c_t} \cdot diag[i_t] \cdot diag[1-(\tilde{c}_t)^2] \\
&= \delta_{c_t} \circ i_t \circ (1-(\tilde{c}_t)^2)
\delta_{z_{\tilde{c}t}} &= \frac{\partial{loss}}{\partial{z_{\tilde{c}_ t}}} = \frac{\partial{loss}}{\partial{c_t}} \cdot \frac{\partial{c_t}}{\partial{\tilde{c}_ t}} \cdot \frac{\partial{\tilde{c}_ t}}{\partial{z_{\tilde{c}_ t}}} \\\\
&= \delta_{c_t} \cdot diag[i_t] \cdot diag[1-(\tilde{c}_ t)^2] \\\\
&= \delta_{c_t} \circ i_t \circ (1-(\tilde{c}_ t)^2)
\end{aligned}
\tag{19}
$$
$$
\begin{aligned}
\delta_{z_{it}} &= \frac{\partial{loss}}{\partial{z_{i_t}}} = \frac{\partial{loss}}{\partial{c_t}} \cdot \frac{\partial{c_t}}{\partial{i_t}} \cdot \frac{\partial{i_t}}{\partial{z_{i_t}}} \\
&= \delta_{c_t} \cdot diag[\tilde{c}_t] \cdot diag[i_t \circ (1 - i_t)] \\
&= \delta_{c_t} \circ \tilde{c}_t \circ i_t \circ (1 - i_t)
\delta_{z_{it}} &= \frac{\partial{loss}}{\partial{z_{i_t}}} = \frac{\partial{loss}}{\partial{c_t}} \cdot \frac{\partial{c_t}}{\partial{i_t}} \cdot \frac{\partial{i_t}}{\partial{z_{i_t}}} \\\\
&= \delta_{c_t} \cdot diag[\tilde{c}_ t] \cdot diag[i_t \circ (1 - i_t)] \\\\
&= \delta_{c_t} \circ \tilde{c}_ t \circ i_t \circ (1 - i_t)
\end{aligned}
\tag{20}
$$
$$
\begin{aligned}
\delta_{z_{ft}} &= \frac{\partial{loss}}{\partial{z_{f_t}}} = \frac{\partial{loss}}{\partial{c_t}} \cdot \frac{\partial{c_t}}{\partial{f_t}} \cdot \frac{\partial{f_t}}{\partial{z_{f_t}}} \\
&= \delta_{c_t} \cdot diag[c_{t-1}] \cdot diag[f_t \circ (1 - f_t)] \\
\delta_{z_{ft}} &= \frac{\partial{loss}}{\partial{z_{f_t}}} = \frac{\partial{loss}}{\partial{c_t}} \cdot \frac{\partial{c_t}}{\partial{f_t}} \cdot \frac{\partial{f_t}}{\partial{z_{f_t}}} \\\\
&= \delta_{c_t} \cdot diag[c_{t-1}] \cdot diag[f_t \circ (1 - f_t)] \\\\
&= \delta_{c_t} \circ c_{t-1} \circ f_t \circ (1 - f_t)
\end{aligned}
\tag{21}
@@ -265,12 +265,12 @@ $$
于是,在$t$时刻,输出层参数的各项误差为:
$$
d_{W_{o,t}} = \frac{\partial{loss}}{\partial{W_{o,t}}} = \frac{\partial{loss}}{\partial{z_{o_t}}} \cdot \frac{\partial{z_{o_t}}}{\partial{W_o}} = h^T_{t-1} \cdot \delta_{z_{ot}}
d_{W_{o,t}} = \frac{\partial{loss}}{\partial{W_{o,t}}} = \frac{\partial{loss}}{\partial{z_{o_t}}} \cdot \frac{\partial{z_{o_t}}}{\partial{W_o}} = h^{\top}_ {t-1} \cdot \delta_{z_{ot}}
\tag{22}
$$
$$
d_{U_{o,t}} = \frac{\partial{loss}}{\partial{U_{o,t}}} = \frac{\partial{loss}}{\partial{z_{o_t}}} \cdot \frac{\partial{z_{o_t}}}{\partial{U_o}} = x^T_t \cdot \delta_{z_{ot}}
d_{U_{o,t}} = \frac{\partial{loss}}{\partial{U_{o,t}}} = \frac{\partial{loss}}{\partial{z_{o_t}}} \cdot \frac{\partial{z_{o_t}}}{\partial{U_o}} = x^{\top}_ t \cdot \delta_{z_{ot}}
\tag{23}
$$
@@ -282,12 +282,12 @@ $$
最终误差为各时刻误差之和,则:
$$
d_{W_o} = \sum^\tau_{t=1}d_{W_{o,t}} = \sum^\tau_{t=1}h^T_{t-1} \cdot \delta_{z_{ot}}
d_{W_o} = \sum^\tau_{t=1}d_{W_{o,t}} = \sum^\tau_{t=1}h^{\top}_ {t-1} \cdot \delta_{z_{ot}}
\tag{25}
$$
$$
d_{U_o} = \sum^\tau_{t=1}d_{U_{o,t}} = \sum^\tau_{t=1}x^T_t \cdot \delta_{z_{ot}}
d_{U_o} = \sum^\tau_{t=1}d_{U_{o,t}} = \sum^\tau_{t=1}x^{\top}_ t \cdot \delta_{z_{ot}}
\tag{26}
$$
@@ -300,12 +300,12 @@ $$
同理可得:
$$
d_{W_{c}} = \sum^\tau_{t=1}d_{W_{c,t}} = \sum^\tau_{t=1}h^T_{t-1} \cdot \delta_{z_{\tilde{c}t}}
d_{W_{c}} = \sum^\tau_{t=1}d_{W_{c,t}} = \sum^\tau_{t=1}h^{\top}_ {t-1} \cdot \delta_{z_{\tilde{c}t}}
\tag{28}
$$
$$
d_{U_{c}} = \sum^\tau_{t=1}d_{U_{c,t}} = \sum^\tau_{t=1}x^T_t \cdot \delta_{z_{\tilde{c}t}}
d_{U_{c}} = \sum^\tau_{t=1}d_{U_{c,t}} = \sum^\tau_{t=1}x^{\top}_ t \cdot \delta_{z_{\tilde{c}t}}
\tag{29}
$$
@@ -315,12 +315,12 @@ d_{b_{c}} = \sum^\tau_{t=1}d_{b_{c,t}} = \sum^\tau_{t=1}\delta_{z_{\tilde{c}t}}
$$
$$
d_{W_{i}} = \sum^\tau_{t=1}d_{W_{i,t}} = \sum^\tau_{t=1}h^T_{t-1} \cdot \delta_{z_{it}}
d_{W_{i}} = \sum^\tau_{t=1}d_{W_{i,t}} = \sum^\tau_{t=1}h^{\top}_ {t-1} \cdot \delta_{z_{it}}
\tag{31}
$$
$$
d_{U_{i}} = \sum^\tau_{t=1}d_{U_{i,t}} = \sum^\tau_{t=1}x^T_t \cdot \delta_{z_{it}}
d_{U_{i}} = \sum^\tau_{t=1}d_{U_{i,t}} = \sum^\tau_{t=1}x^{\top}_ t \cdot \delta_{z_{it}}
\tag{32}
$$
@@ -330,12 +330,12 @@ d_{b_{i}} = \sum^\tau_{t=1}d_{b_{i,t}} =\sum^\tau_{t=1}\delta_{z_{it}}
$$
$$
d_{W_{f}} = \sum^\tau_{t=1}d_{W_{f,t}} = \sum^\tau_{t=1}h^T_{t-1} \cdot \delta_{z_{ft}}
d_{W_{f}} = \sum^\tau_{t=1}d_{W_{f,t}} = \sum^\tau_{t=1}h^{\top}_ {t-1} \cdot \delta_{z_{ft}}
\tag{34}
$$
$$
d_{U_{f}} = \sum^\tau_{t=1}d_{U_{f,t}} = \sum^\tau_{t=1}x^T_t \cdot \delta_{z_{ft}}
d_{U_{f}} = \sum^\tau_{t=1}d_{U_{f,t}} = \sum^\tau_{t=1}x^{\top}_ t \cdot \delta_{z_{ft}}
\tag{35}
$$
@@ -350,9 +350,9 @@ $$
$$
\begin{aligned}
\delta_{h_{t-1}} = \frac{\partial{loss}}{\partial{h_{t-1}}} &= \frac{\partial{loss}}{\partial{z_{ft}}} \cdot \frac{\partial{z_{ft}}}{\partial{h_{t-1}}} + \frac{\partial{loss}}{\partial{z_{it}}} \cdot \frac{\partial{z_{it}}}{\partial{h_{t-1}}} \\
&+ \frac{\partial{loss}}{\partial{z_{\tilde{c}t}}} \cdot \frac{\partial{z_{\tilde{c}t}}}{\partial{h_{t-1}}} + \frac{\partial{loss}}{\partial{z_{ot}}} \cdot \frac{\partial{z_{ot}}}{\partial{h_{t-1}}} \\
&= \delta_{z_{ft}} \cdot W_f^T + \delta_{z_{it}} \cdot W_i^T + \delta_{z_{\tilde{c}t}} \cdot W_c^T + \delta_{z_{ot}} \cdot W_o^T
\delta_{h_{t-1}} = \frac{\partial{loss}}{\partial{h_{t-1}}} &= \frac{\partial{loss}}{\partial{z_{ft}}} \cdot \frac{\partial{z_{ft}}}{\partial{h_{t-1}}} + \frac{\partial{loss}}{\partial{z_{it}}} \cdot \frac{\partial{z_{it}}}{\partial{h_{t-1}}} \\\\
&+ \frac{\partial{loss}}{\partial{z_{\tilde{c}t}}} \cdot \frac{\partial{z_{\tilde{c}t}}}{\partial{h_{t-1}}} + \frac{\partial{loss}}{\partial{z_{ot}}} \cdot \frac{\partial{z_{ot}}}{\partial{h_{t-1}}} \\\\
&= \delta_{z_{ft}} \cdot W_f^{\top} + \delta_{z_{it}} \cdot W_i^{\top} + \delta_{z_{\tilde{c}t}} \cdot W_c^{\top} + \delta_{z_{ot}} \cdot W_o^{\top}
\end{aligned}
\tag{37}
$$
@@ -361,9 +361,9 @@ $$
$$
\begin{aligned}
\delta_{x_t} = \frac{\partial{loss}}{\partial{x_t}} &= \frac{\partial{loss}}{\partial{z_{ft}}} \cdot \frac{\partial{z_{ft}}}{\partial{x_t}} + \frac{\partial{loss}}{\partial{z_{it}}} \cdot \frac{\partial{z_{it}}}{\partial{x_t}} \\
&+ \frac{\partial{loss}}{\partial{z_{\tilde{c}t}}} \cdot \frac{\partial{z_{\tilde{c}t}}}{\partial{x_t}} + \frac{\partial{loss}}{\partial{z_{ot}}} \cdot \frac{\partial{z_{ot}}}{\partial{x_t}} \\
&= \delta_{z_{ft}} \cdot U_f^T + \delta_{z_{it}} \cdot U_i^T + \delta_{z_{\tilde{c}t}} \cdot U_c^T + \delta_{z_{ot}} \cdot U_o^T
\delta_{x_t} = \frac{\partial{loss}}{\partial{x_t}} &= \frac{\partial{loss}}{\partial{z_{ft}}} \cdot \frac{\partial{z_{ft}}}{\partial{x_t}} + \frac{\partial{loss}}{\partial{z_{it}}} \cdot \frac{\partial{z_{it}}}{\partial{x_t}} \\\\
&+ \frac{\partial{loss}}{\partial{z_{\tilde{c}t}}} \cdot \frac{\partial{z_{\tilde{c}t}}}{\partial{x_t}} + \frac{\partial{loss}}{\partial{z_{ot}}} \cdot \frac{\partial{z_{ot}}}{\partial{x_t}} \\\\
&= \delta_{z_{ft}} \cdot U_f^{\top} + \delta_{z_{it}} \cdot U_i^{\top} + \delta_{z_{\tilde{c}t}} \cdot U_c^{\top} + \delta_{z_{ot}} \cdot U_o^{\top}
\end{aligned}
\tag{38}
$$
@@ -87,8 +87,8 @@ $$
$$
\begin{aligned}
\delta_{z_{zt}} &= \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{z_t}} \cdot \frac{\partial{z_t}}{\partial{z_{z_t}}} \\
&= \delta_t \cdot (-diag[h_{t-1}] + diag[\tilde h_t]) \cdot diag[z_t \circ (1-z_t)] \\
\delta_{z_{zt}} &= \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{z_t}} \cdot \frac{\partial{z_t}}{\partial{z_{z_t}}} \\\\
&= \delta_t \cdot (-diag[h_{t-1}] + diag[\tilde h_t]) \cdot diag[z_t \circ (1-z_t)] \\\\
&= \delta_t \circ (\tilde h_t - h_{t-1}) \circ z_t \circ (1-z_t)
\end{aligned}
\tag{8}
@@ -96,8 +96,8 @@ $$
$$
\begin{aligned}
\delta_{z_{\tilde{h}t}} &= \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{\tilde h_t}} \cdot \frac{\partial{\tilde h_t}}{\partial{z_{\tilde h_t}}} \\
&= \delta_t \cdot diag[z_t] \cdot diag[1-(\tilde h_t)^2] \\
\delta_{z_{\tilde{h}t}} &= \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{\tilde h_t}} \cdot \frac{\partial{\tilde h_t}}{\partial{z_{\tilde h_t}}} \\\\
&= \delta_t \cdot diag[z_t] \cdot diag[1-(\tilde h_t)^2] \\\\
&= \delta_t \circ z_t \circ (1-(\tilde h_t)^2)
\end{aligned}
\tag{9}
@@ -105,8 +105,8 @@ $$
$$
\begin{aligned}
\delta_{z_{rt}} &= \frac{\partial{loss}}{\partial{\tilde h_t}} \cdot \frac{\partial{\tilde h_t}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{r_t}} \cdot \frac{\partial{r_t}}{\partial{z_{r_t}}} \\
&= \delta_{z_{\tilde{h}t}} \cdot W_h^T \cdot diag[h_{t-1}] \cdot diag[r_t \circ (1-r_t)] \\
\delta_{z_{rt}} &= \frac{\partial{loss}}{\partial{\tilde h_t}} \cdot \frac{\partial{\tilde h_t}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{r_t}} \cdot \frac{\partial{r_t}}{\partial{z_{r_t}}} \\\\
&= \delta_{z_{\tilde{h}t}} \cdot W_h^T \cdot diag[h_{t-1}] \cdot diag[r_t \circ (1-r_t)] \\\\
&= \delta_{z_{\tilde{h}t}} \cdot W_h^T \circ h_{t-1} \circ r_t \circ (1-r_t)
\end{aligned}
\tag{10}
@@ -116,42 +116,42 @@ $$
$$
\begin{aligned}
d_{W_{h,t}} = \frac{\partial{loss}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{W_h}} = (r_t \circ h_{t-1})^T \cdot \delta_{z_{\tilde{h}t}}
d_{W_{h,t}} = \frac{\partial{loss}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{W_h}} = (r_t \circ h_{t-1})^{\top} \cdot \delta_{z_{\tilde{h}t}}
\end{aligned}
\tag{11}
$$
$$
\begin{aligned}
d_{U_{h,t}} = \frac{\partial{loss}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{U_h}} = x_t^T \cdot \delta_{z_{\tilde{h}t}}
d_{U_{h,t}} = \frac{\partial{loss}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{U_h}} = x_t^{\top} \cdot \delta_{z_{\tilde{h}t}}
\end{aligned}
\tag{12}
$$
$$
\begin{aligned}
d_{W_{r,t}} = \frac{\partial{loss}}{\partial{z_{r_t}}} \cdot \frac{\partial{z_{r_t}}}{\partial{W_r}} = h_{t-1}^T \cdot \delta_{z_{rt}}
d_{W_{r,t}} = \frac{\partial{loss}}{\partial{z_{r_t}}} \cdot \frac{\partial{z_{r_t}}}{\partial{W_r}} = h_{t-1}^{\top} \cdot \delta_{z_{rt}}
\end{aligned}
\tag{13}
$$
$$
\begin{aligned}
d_{U_{r,t}} = \frac{\partial{loss}}{\partial{z_{r_t}}} \cdot \frac{\partial{z_{r_t}}}{\partial{U_r}} = x_t^T \cdot \delta_{z_{rt}}
d_{U_{r,t}} = \frac{\partial{loss}}{\partial{z_{r_t}}} \cdot \frac{\partial{z_{r_t}}}{\partial{U_r}} = x_t^{\top} \cdot \delta_{z_{rt}}
\end{aligned}
\tag{14}
$$
$$
\begin{aligned}
d_{W_{z,t}} = \frac{\partial{loss}}{\partial{z_{z_t}}} \cdot \frac{\partial{z_{z_t}}}{\partial{W_z}} = h_{t-1}^T \cdot \delta_{z_{zt}}
d_{W_{z,t}} = \frac{\partial{loss}}{\partial{z_{z_t}}} \cdot \frac{\partial{z_{z_t}}}{\partial{W_z}} = h_{t-1}^{\top} \cdot \delta_{z_{zt}}
\end{aligned}
\tag{15}
$$
$$
\begin{aligned}
d_{U_{z,t}} = \frac{\partial{loss}}{\partial{z_{z_t}}} \cdot \frac{\partial{z_{z_t}}}{\partial{U_z}} = x_t^T \cdot \delta_{z_{zt}}
d_{U_{z,t}} = \frac{\partial{loss}}{\partial{z_{z_t}}} \cdot \frac{\partial{z_{z_t}}}{\partial{U_z}} = x_t^{\top} \cdot \delta_{z_{zt}}
\end{aligned}
\tag{16}
$$
@@ -159,32 +159,32 @@ $$
可学习参数的最终误差为各个时刻误差之和,即:
$$
d_{W_h} = \sum_{t=1}^{\tau} d_{W_{h,t}} = \sum_{t=1}^{\tau} (r_t \circ h_{t-1})^T \cdot \delta_{z_{\tilde{h}t}}
d_{W_h} = \sum_{t=1}^{\tau} d_{W_{h,t}} = \sum_{t=1}^{\tau} (r_t \circ h_{t-1})^{\top} \cdot \delta_{z_{\tilde{h}t}}
\tag{17}
$$
$$
d_{U_h} = \sum_{t=1}^{\tau} d_{U_{h,t}} = \sum_{t=1}^{\tau} x_t^T \cdot \delta_{z_{\tilde{h}t}}
d_{U_h} = \sum_{t=1}^{\tau} d_{U_{h,t}} = \sum_{t=1}^{\tau} x_t^{\top} \cdot \delta_{z_{\tilde{h}t}}
\tag{18}
$$
$$
d_{W_r} = \sum_{t=1}^{\tau} d_{W_{r,t}} = \sum_{t=1}^{\tau} h_{t-1}^T \cdot \delta_{z_{rt}}
d_{W_r} = \sum_{t=1}^{\tau} d_{W_{r,t}} = \sum_{t=1}^{\tau} h_{t-1}^{\top} \cdot \delta_{z_{rt}}
\tag{19}
$$
$$
d_{U_r} = \sum_{t=1}^{\tau} d_{U_{r,t}} = \sum_{t=1}^{\tau} x_t^T \cdot \delta_{z_{rt}}
d_{U_r} = \sum_{t=1}^{\tau} d_{U_{r,t}} = \sum_{t=1}^{\tau} x_t^{\top} \cdot \delta_{z_{rt}}
\tag{20}
$$
$$
d_{W_z} = \sum_{t=1}^{\tau} d_{W_{z,t}} = \sum_{t=1}^{\tau} h_{t-1}^T \cdot \delta_{z_{zt}}
d_{W_z} = \sum_{t=1}^{\tau} d_{W_{z,t}} = \sum_{t=1}^{\tau} h_{t-1}^{\top} \cdot \delta_{z_{zt}}
\tag{21}
$$
$$
d_{U_z} = \sum_{t=1}^{\tau} d_{U_{z,t}} = \sum_{t=1}^{\tau} x_t^T \cdot \delta_{z_{zt}}
d_{U_z} = \sum_{t=1}^{\tau} d_{U_{z,t}} = \sum_{t=1}^{\tau} x_t^{\top} \cdot \delta_{z_{zt}}
\tag{22}
$$
@@ -194,10 +194,10 @@ $$
$$
\begin{aligned}
\delta_{h_{t-1}} = \frac{\partial{loss}}{\partial{h_{t-1}}} &= \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{h_{t-1}}} + \frac{\partial{loss}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{h_{t-1}}} \\
&+ \frac{\partial{loss}}{\partial{z_{rt}}} \cdot \frac{\partial{z_{rt}}}{\partial{h_{t-1}}} + \frac{\partial{loss}}{\partial{z_{zt}}} \cdot \frac{\partial{z_{zt}}}{\partial{h_{t-1}}} \\
&= \delta_{t} \circ (1-z_t) + \delta_{z_{\tilde{h}t}} \cdot W_h^T \circ r_t \\
&+ \delta_{z_{rt}} \cdot W_r^T + \delta_{z_{zt}} \cdot W_z^T
\delta_{h_{t-1}} = \frac{\partial{loss}}{\partial{h_{t-1}}} &= \frac{\partial{loss}}{\partial{h_t}} \cdot \frac{\partial{h_t}}{\partial{h_{t-1}}} + \frac{\partial{loss}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{h_{t-1}}} \\\\
&+ \frac{\partial{loss}}{\partial{z_{rt}}} \cdot \frac{\partial{z_{rt}}}{\partial{h_{t-1}}} + \frac{\partial{loss}}{\partial{z_{zt}}} \cdot \frac{\partial{z_{zt}}}{\partial{h_{t-1}}} \\\\
&= \delta_{t} \circ (1-z_t) + \delta_{z_{\tilde{h}t}} \cdot W_h^{\top} \circ r_t \\\\
&+ \delta_{z_{rt}} \cdot W_r^{\top} + \delta_{z_{zt}} \cdot W_z^{\top}
\end{aligned}
\tag{23}
$$
@@ -206,9 +206,9 @@ $$
$$
\begin{aligned}
\delta_{x_t} &= \frac{\partial{loss}}{\partial{x_t}} = \frac{\partial{loss}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{x_t}} \\
&+ \frac{\partial{loss}}{\partial{z_{r_t}}} \cdot \frac{\partial{z_{r_t}}}{\partial{x_t}} + \frac{\partial{loss}}{\partial{z_{z_t}}} \cdot \frac{\partial{z_{z_t}}}{\partial{x_t}} \\
&= \delta_{z_{\tilde{h}t}} \cdot U_h^T + \delta_{z_{rt}} \cdot U_r^T + \delta_{z_{zt}} \cdot U_z^T
\delta_{x_t} &= \frac{\partial{loss}}{\partial{x_t}} = \frac{\partial{loss}}{\partial{z_{\tilde h_t}}} \cdot \frac{\partial{z_{\tilde h_t}}}{\partial{x_t}} \\\\
&+ \frac{\partial{loss}}{\partial{z_{r_t}}} \cdot \frac{\partial{z_{r_t}}}{\partial{x_t}} + \frac{\partial{loss}}{\partial{z_{z_t}}} \cdot \frac{\partial{z_{z_t}}}{\partial{x_t}} \\\\
&= \delta_{z_{\tilde{h}t}} \cdot U_h^{\top} + \delta_{z_{rt}} \cdot U_r^{\top} + \delta_{z_{zt}} \cdot U_z^{\top}
\end{aligned}
\tag{24}
$$
@@ -324,4 +324,4 @@ ch20, Level2
### 思考和练习
1. 仿照LSTM的实现方式,自己实现GRU单元的前向计算和反向传播。
2. 仿照LSTM的实例,使用GRU进行训练,并比较效果。
2. 仿照LSTM的实例,使用GRU进行训练,并比较效果。
@@ -63,9 +63,9 @@ $$
$$
\begin{aligned}
c &= h_3 \\
c &= g(h_3) \\
c &= g(h1, h2, h3) \\
c &= h_3 \\\\
c &= g(h_3) \\\\
c &= g(h1, h2, h3) \\\\
\end{aligned}
$$
@@ -79,9 +79,9 @@ $$
$$
\begin{cases}
y_1 = f(y_0, h^\prime_{0}, c) \\
y_1 = f(y_0, h^\prime_{0}, c) \\\\
y_t = f(y_{t-1}, h^\prime_{t-1}), t \in [2,4]
\end{cases}
$$
以上是序列到序列模型的结构简介,具体实现将在以后补充。
以上是序列到序列模型的结构简介,具体实现将在以后补充。