tf.nn.conv2d是TensorFlow里面实现卷积的函数。
tf.nn.conv2d(input, filter, strides,padding, use_cudnn_on_gpu=None, name=None)
除去name参数用以指定该操作的name,与方法有关的一共五个参数:
第一个参数input:指需要做卷积的输入图像,它要求是一个Tensor,具有[batch,in_height, in_width, in_channels]这样的shape,具体含义是[训练时一个batch的图片数量, 图片高度, 图片宽度, 图像通道数],注意这是一个4维的Tensor,要求类型为float32和float64其中之一
第二个参数filter:相当于CNN中的卷积核,它要求是一个Tensor,具有[filter_height, filter_width, in_channels, out_channels]这样的shape,具体含义是[卷积核的高度,卷积核的宽度,图像通道数,卷积核个数],要求类型与参数input相同,有一个地方需要注意,第三维in_channels,就是参数input的第四维
第三个参数strides:卷积时在图像每一维的步长,这是一个一维的向量,长度4。对于图片,因为只有两维,通常strides取[1,stride,stride,1]
第四个参数padding:string类型的量,只能是"SAME","VALID"其中之一,这个值决定了不同的卷积方式。若是"SAME",表示卷积核可以停留在图像边缘,也就是输出与输入形状相同。若为"VALID",则输出形状为:(in_height- filter_height+1)*(in_width- filter_width+1)
第五个参数:use_cudnn_on_gpu:bool类型,是否使用cudnn加速,默认为true
结果返回一个Tensor,这个输出,就是我们常说的featuremap
那么TensorFlow的卷积具体是怎样实现的呢,下面将举例说明。
详细的卷积过程可以看帖子:http://blog.csdn.net/huahuazhu/article/details/73469491
1单通道、一个卷积核
1.考虑一种简单的情况,现在有一张5×5单通道的图像(对应的shape:[1,5,5,1]),用一个3×3的卷积核(对应的shape:[3,3,1,1])去做卷积,最后会得到一张3×3的feature map。padding的值为‘VALID’
图像矩阵
1 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
卷积核矩阵
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
卷积过程:
2. 将1中的padding的值改为‘SAME’时,表示卷积核可以停留在图像边缘,也就是输出与输入形状相同,则输出5×5的feature map。
在计算时可以认为是图像的边缘补0,再进行滑动计算点积。
0 |
0 |
0 |
0 |
0 |
0 |
0 |
|
1 |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
0 |
0 |
|
0 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
|
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
|
|||
0 |
0 |
0 |
1 |
1 |
0 |
0 |
|
|||
0 |
0 |
1 |
1 |
0 |
0 |
0 |
|
|||
0 |
0 |
0 |
0 |
0 |
0 |
0 |
|
代码实现如下:
运行结果如下:
[[[[4.]
[ 3.]
[ 4.]]
[[ 2.]
[ 4.]
[ 3.]]
[[ 2.]
[ 3.]
[ 4.]]]]
###############
[[[[2.]
[ 2.]
[ 3.]
[ 1.]
[ 1.]]
[[ 1.]
[ 4.]
[ 3.]
[ 4.]
[ 1.]]
[[ 1.]
[ 2.]
[ 4.]
[ 3.]
[ 3.]]
[[ 1.]
[ 2.]
[ 3.]
[ 4.]
[ 1.]]
[[ 0.]
[ 2.]
[ 2.]
[ 1.]
[ 1.]]]]
2 多通道多卷积核
下面对http://blog.csdn.net/huahuazhu/article/details/73469491中多通道多卷积核的例子进行实现。
下图中左侧为输入的三通道(R\G\B)的7*7图片,中间为两个核函数(即滤波器)Filter W0,Filter W1,右侧为输出Output Volume为两张3*3的feature map
代码实现如下:
运行结果如下:
[[[[0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 1.]
[ 1. 0. 0.]
[ 2. 1. 1.]
[ 0. 0. 2.]
[ 1. 0. 2.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 2. 0. 0.]
[ 0. 1. 1.]
[ 1. 1. 2.]
[ 0. 2. 0.]
[ 0. 1. 1.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 2. 1.]
[ 2. 1. 0.]
[ 2. 0. 2.]
[ 1. 0. 2.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 2. 2. 0.]
[ 2. 1. 1.]
[ 0. 2. 1.]
[ 1. 1. 2.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 1. 2. 2.]
[ 2. 1. 2.]
[ 0. 1. 2.]
[ 0. 1. 1.]
[ 0. 2. 1.]
[ 0. 0. 0.]]
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]]]
[[[[-1. 1.]
[ 0. 0.]
[ 0. 1.]]
[[ 0. 1.]
[-1. -1.]
[-1. 0.]]
[[ 1. 0.]
[-1. 0.]
[ 1. 0.]]]
[[[ 0. -1.]
[-1. -1.]
[ 0. -1.]]
[[ 1. -1.]
[ 1. 0.]
[ 0. -1.]]
[[ 0. 0.]
[-1. -1.]
[-1. 0.]]]
[[[ 0. 1.]
[ 0. -1.]
[ 0. 1.]]
[[-1. 1.]
[-1. -1.]
[ 1. -1.]]
[[-1. -1.]
[ 1. 1.]
[-1. -1.]]]]
[[[[-1. 1.]
[ 4. -4.]
[ 2. -9.]]
[[-8. -2.]
[-8. -7.]
[ 0. -6.]]
[[ 1. -4.]
[-4. -7.]
[ 1. 0.]]]]
对比一下,和理论分析的一致。
参考文档
【1】http://blog.csdn.net/mao_xiao_feng/article/details/53444333