Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenDocCN
d2l-zh
提交
bdcff098
D
d2l-zh
项目概览
OpenDocCN
/
d2l-zh
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
d2l-zh
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bdcff098
编写于
8月 26, 2018
作者:
A
Aston Zhang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
conv layer done
上级
f2d8031d
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
14 addition
and
13 deletion
+14
-13
chapter_convolutional-neural-networks/conv-layer.md
chapter_convolutional-neural-networks/conv-layer.md
+14
-13
未找到文件。
chapter_convolutional-neural-networks/conv-layer.md
浏览文件 @
bdcff098
...
...
@@ -22,7 +22,7 @@ $$
### 互相关运算和卷积运算
你也许会好奇卷积层为何能使用互相关运算替代卷积运算。实际上,卷积运算与互相关运算类似。我们只需将核数组左右翻转并上下翻转,再与输入数组做互相关运算,即得到卷积运算的输出。可见,卷积运算和互相关运算虽然类似,但
输出并不一样。然而,在深度学习中卷积核都是学出来的:卷积层无论使用互相关运算或卷积运算都不影响模型预测时的输出。为了解释这一点,假设卷积层使用互相关运算学出图5.1中的卷积核。设其他条件不变,卷积层使用卷积运算学出的卷积核即图5.1中的卷积核按上下、左右翻转。也就是说,图5.1中的输入与使用卷积运算学出的卷积核
再做卷积运算时,依然得到图5.1中的输出。为了与大多数深度学习文献一致,如无特别说明,本书中提到的卷积运算均指互相关运算。
你也许会好奇卷积层为何能使用互相关运算替代卷积运算。实际上,卷积运算与互相关运算类似。我们只需将核数组左右翻转并上下翻转,再与输入数组做互相关运算,即得到卷积运算的输出。可见,卷积运算和互相关运算虽然类似,但
如果它们使用相同的核数组,对于同一个输入,输出往往并不相同。然而,在深度学习中核数组都是学出来的:卷积层无论使用互相关运算或卷积运算都不影响模型预测时的输出。为了解释这一点,假设卷积层使用互相关运算学出图5.1中的核数组。设其他条件不变,使用卷积运算学出的核数组即图5.1中的核数组按上下、左右翻转。也就是说,图5.1中的输入与学出的已翻转的核数组
再做卷积运算时,依然得到图5.1中的输出。为了与大多数深度学习文献一致,如无特别说明,本书中提到的卷积运算均指互相关运算。
下面我们将上述过程实现在
`corr2d`
函数里。它接受输入数组
`X`
与核数组
`K`
,并输出数组
`Y`
。
...
...
@@ -94,9 +94,9 @@ Y
## 通过数据学习核数组
最后我们来看一个例子,它使用
前面的
`X`
和
`Y`
来学习我们构造的
`K`
。我们首先构造一个卷积层,将其卷积核初始化成随机数组。然后在每一个迭代里,我们使用平方误差来比较
`Y`
和卷积层的输出,然后计算梯度来更新权重
。
最后我们来看一个例子,它使用
物体边缘检测中的输入数据
`X`
和输出数据
`Y`
来学习我们构造的核数组
`K`
。我们首先构造一个卷积层,将其卷积核初始化成随机数组。然后在每一次迭代中,我们使用平方误差来比较
`Y`
和卷积层的输出,然后计算梯度来更新权重。为了简单起见,这里的卷积层忽略了偏差
。
虽然我们之前构造了
Conv2D类,但由于
`corr2d`
使用了对单个元素赋值(
`[i, j]=`
)的操作会导致无法自动求导,下面我们使用Gluon提供的Conv2D
类来实现这个例子。
虽然我们之前构造了
`Conv2D`
类,但由于
`corr2d`
使用了对单个元素赋值(
`[i, j]=`
)的操作从而无法自动求导。下面我们使用Gluon提供的
`Conv2D`
类来实现这个例子。
```
{.python .input n=83}
# 构造一个输出通道是 1(将在后面小节介绍通道),核数组形状是 (1,2) 的二维卷积层。
...
...
@@ -118,27 +118,28 @@ for i in range(10):
conv2d.weight.data()[:] -= 3e-2 * conv2d.weight.grad()
```
可以看到10次迭代后误差已经降到了一个比较小的值
,现在来看一下学习到的核
。
可以看到10次迭代后误差已经降到了一个比较小的值
。现在来看一下学习到的核数组
。
```
{.python .input}
conv2d.weight.data().reshape((1, 2))
```
我们看到学到的核与我们之前定义的
`K`
非常接近。
我们看到学到的核数组与我们之前定义的核数组较接近。
## 小结
-
二维卷积层的核心计算是二维互相关运算。在最简单的形式下,它对二维输入数据和卷积核做互相关运算然后加上偏差。
-
我们可以设计卷积核来检测图像中的边缘,同时也可以通过数据来学习它。
*
二维卷积层的核心计算是二维互相关运算。在最简单的形式下,它对二维输入数据和卷积核做互相关运算然后加上偏差。
*
我们可以设计卷积核来检测图像中的边缘。
*
我们可以通过数据来学习卷积核。
## 练习
-
构造一个
`X`
,它有水平方向的边缘,如何设计
`K`
来检测它?如果是对角方向的边缘呢?
-
试着对我们构造的
`Conv2D`
进行自动求导,会有什么样的错误信息?
-
在Conv2D的
`forward`
函数里,将
`corr2d`
替换成
`nd.Convolution`
使得其可以求导。
-
试着将conv2d的核构造成
`(2, 2)`
,会学出什么样的结果?
-
如何通过变化输入和核的矩阵来将互相关运算表示成一个矩阵乘法。
-
如何构造一个全连接层来进行物体边缘检测?
*
构造一个输入图像
`X`
,令它有水平方向的边缘。如何设计卷积核
`K`
来检测图像中水平边缘?如果是对角方向的边缘呢?
*
试着对我们自己构造的
`Conv2D`
类进行自动求导,会有什么样的错误信息?在该类的
`forward`
函数里,将
`corr2d`
函数替换成
`nd.Convolution`
类使得自动求导变得可行。
*
如何通过变化输入和核的数组将互相关运算表示成一个矩阵乘法?
*
如何构造一个全连接层来进行物体边缘检测?
## 扫码直达[讨论区](https://discuss.gluon.ai/t/topic/6314)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录