tf.nn.conv2d(
input,
filter,
strides,
padding,
use_cudnn_on_gpu=True,
data_format='NHWC',
dilations=[1, 1, 1, 1],
name=None
)
在给定4-D输入和滤波器(filter)张量的情况下计算2-D卷积。
input tensor shape:[batch, in_height, in_width, in_channels]
filter tensor shape:[filter_height, filter_width, in_channels, out_channels]
1.将filter flattens(展平)为具有形如[filter_height * filter_width * in_channels,output_channels]的二维矩阵。
2.从input tensor中提取image patches以形成virtual tensor形如[batch,out_height,out_width,filter_height * filter_width * in_channels]。
3.对于每个patch,right-multiplies(右乘)filter matrix和image patch vector。
详细地,使用默认的NHWC格式,
output[b, i, j, k] =
sum_{di, dj, q} input[b, strides[1] * i + di, strides[2] * j + dj, q] *
filter[di, dj, q, k]
必须有strides[0] = strides[3] = 1。绝大多数情况下,水平的stride和竖直的stride一样,strides = [1,stride,stride,1]。
tensorflow中的tf.nn.conv2d函数,实际上相当于用filter,以一定的步长stride在image上进行滑动,计算重叠部分的内积和,即为卷积结果。
每个filter会在width维, height维上,以局部连接和空间共享,并贯穿整个depth维的方式得到一个Feature Map。
通常大家都想要在卷积时保持图片的原始尺寸。 选择3x3的filter和1的zero padding,或5x5的filter和2的zero padding可以保持图片的原始尺寸。 这也是为什么大家多选择3x3和5x5的filter的原因。 另一个原因是3x3的filter考虑到了像素与其距离为1以内的所有其他像素的关系,而5x5则是考虑像素与其距离为2以内的所有其他像素的关系。
尺寸:Feature Map的尺寸等于(input_size + 2 * padding_size − filter_size)/stride+1。
注意:上面的式子是计算width或height一维的。padding_size也表示的是单边补零的个数。例如(4+2-3)/1+1 = 4,保持原尺寸。
不用去背这个式子。其中(input_size + 2 * padding_size)是经过Zero padding扩充后真正要卷积的尺寸。 减去 filter_size后表示可以滑动的范围。 再除以可以一次滑动(stride)多少后得到滑动了多少次,也就意味着得到了多少个输出节点。 再加上第一个不需要滑动也存在的输出节点后就是最后的尺寸。