图片来源于http://cs231n.github.io/convolutional-networks,侵删
转载请注明出处:https://www.jianshu.com/p/e9f2083f730a 如果觉得有用,麻烦点个赞噢~
卷积运算,如果用数学公式来说明,会让很多人头大(包括我)。
关于卷积运算的文章,网上可以搜到很多,虽然大部分都没解释清楚,但也不乏非常棒的,比如这篇:https://zhuanlan.zhihu.com/p/61898234,文中有一个关于图像卷积过程的gif动图,特别好,如下:
如果看懂这个gif图,那恭喜你,你已经搞懂了,不用再看下面的文字介绍了。
下面我根据上面的gif图,做简单的若干点说明,把卷积的关键知识点列出来:
以下是针对经典的图像卷积
-
输入(
input
)的图像,数据形状是(width_in, height_in, channel_in)
,如gif图中,图像的宽高均为5,channel_in
为3. -
原始图像中的channel,指的是通道,比如彩色图片通常有3个通道分别是:R, G, B
-
单个卷积核(
kernel
)的的数据形状是(width_k, height_k, channel_in)
-
【重点】单个卷积核跟原始图像之间的卷积运算,用文字来描述就是:按元素相乘,比如:
input[0][0][0]
跟kernel[0][0][0]
相乘,input[1][1][1]
跟kernel[1][1][1]
相乘。最后将所有元素加和。 -
单个卷积核不是一个二维矩阵,而是带厚度的,即
channel_in
。并且,kernel的channel跟输入的channel一一对应地做按元素相乘运算。 -
【重点】单个卷积核跟输入卷积后,得到的output的形状是
(width_out, height_out)
。发现没?没有channel!如gif图所示,单个卷积核,我们称之为Filter
,即过滤器,意义是将原图在某个层面上过滤得到特征。 -
【重点】输出(
output
)的宽高,是可设计的,可以跟原图尺寸一样,也可以变大或者减小。这里会涉及到pad
、stride
、dilate
三个参数,比如,对于宽高是2x2的原图,卷积核宽高是3x3,步长stride
是1,膨胀系数dilate
是0,如果希望输出的宽高也是2x2,要求pad是多少呢?答案是:原图四条边各填充1层。填充的数值通常是0。在gif图里,原图数据四条边全是0,就是被填充的。计算pad是有公式的。我们先不看前面的二维矩阵,拿掉一个维度,现在看一维的情况,total_pad = (len_out - 1) x stride + kernel_size - len_in
,其中,total_pad
是总填充数,kernel_size
是一维卷积核的长度(如果膨胀系数dilate
不为0,那kernel_size
是膨胀后的长度。所谓膨胀,就是卷积核每两个元素之间插入dilate
个0。)对应gif图里的取值,len_out
=3,stride
=2,kernel_size
=3,len_in
=5,可以算出total_pad
=2。即在一维输入的两侧各填充1个0。现在代入二维矩阵的情况,不就是在四条边各填充一层嘛。 -
【重点】如果想得到输出(
output
)具有channel_out
个通道呢?增加Filter即可,也就是增加卷积核数。gif图里,输出有两个通道,对应了两个卷积核。 -
一次Conv2D,表达式是:
output = W * input + bias
。W
是权重,bias
是偏置。它们都是深度学习要学习的对象。W
是由卷积核组成的,gif图里的两个Filter组成了W,与之对应的两个bias组成了bias
。那么权重W
中有多少个参数呢?答案是:width_k * height_k * channel_in * channel_out
。gif里就是 3 * 3 * 3 * 2 = 18。加上bias
的两个参数,这层Conv2D的参数总共有20个。
网友评论