本文共 1531 字,大约阅读时间需要 5 分钟。
输入矩阵格式:四个维度,依次为:样本数、图像高度、图像宽度、图像通道数
输出矩阵格式:与输出矩阵的维度顺序和含义相同,但是后三个维度(图像高度、图像宽度、图像通道数)的尺寸发生变化。
权重矩阵(卷积核)格式:同样是四个维度,但维度的含义与上面两者都不同,为:卷积核高度、卷积核宽度、输入通道数、输出通道数(卷积核个数)
输入矩阵、权重矩阵、输出矩阵这三者之间的相互决定关系
卷积核的输入通道数(in depth)由输入矩阵的通道数所决定。(红色标注)
输出矩阵的通道数(out depth)由卷积核的输出通道数所决定。(绿色标注)
输出矩阵的高度和宽度(height, width)这两个维度的尺寸由输入矩阵、卷积核、扫描方式所共同决定。计算公式如下。(蓝色标注)
以 AlexNet 模型的第一个卷积层为例,
后期 GoogLeNet、ResNet 等经典模型中普遍使用一个像素大小的卷积核作为降低参数复杂度的手段。
从下面的运算可以看到,其实 1 x 1 卷积没有什么神秘的,其作用就是将输入矩阵的通道数量缩减后输出(512 降为 32),并保持它在宽度和高度维度上的尺寸(227 x 227)。实际上,全连接层也可以被视为是一种极端情况的卷积层,其卷积核尺寸就是输入矩阵尺寸,因此输出矩阵的高度和宽度尺寸都是1。
- 总结下来,其实只需要认识到,虽然输入的每一张图像本身具有三个维度,但是对于卷积核来讲依然只是一个一维向量。 - 卷积核做的,其实就是与感受野范围内的像素点进行点积(而不是矩阵乘法)。def conv_layer(x, out_channel, k_size, stride, padding): in_channel = x.shape[3].value w = tf.Variable(tf.truncated_normal([k_size, k_size, in_channel, out_channel], mean=0, stddev=stddev)) b = tf.Variable(tf.zeros(out_channel)) y = tf.nn.conv2d(x, filter=w, strides=[1, stride, stride, 1], padding=padding) y = tf.nn.bias_add(y, b) y = tf.nn.relu(y) return x