了解过机器学习的人都知道通用公式:y = w * x + b
weight:权重比
bias:偏斜量
但是很多人不清楚CNN(卷积神经网络)里面的weight 和bias在哪儿,是怎么参与运算的。这篇文章就为大家揭晓。
首先介绍shape(形状):
在CNN里面永远绕不开一个概念:shape:形状
在测试中,我们输入了100*100的原始图片 “一.png”:
然后将它转换为 shape[100,100] 的数组,作为整个神经网络的输入:
输入 -> 输出(标签):
输入: [100, 100] 的数组横着放就变成了 [1, 100 * 100],表示有1个 [100 * 100] 原始输入。
输出: 输出的最终结果也就是数据的标签,图像分类,用onehot表示38个分类,所以形状为 [1, 38],表示有1个 [38] 标签。
过程: 所以整个CNN神经网络在做的事情就是把 [1,100 * 100] 输入向量,映射到,[1, 38] 标签向量。
通常情况,我们需要更多的数据进行训练和测试,所以准备的数据如下:
训练数据:[142, 100 * 100],142幅 [100 * 100] 训练图片
训练标签:[142, 38],142个 [38] 对应的标签
测试数据:[38, 100 * 100],38幅 [100 * 100] 测试图片
测试标签:[38, 38],38个 [38] 对应的标签
输入 -> 卷积:
卷积的过程,引用一幅形象的图:
大多数卷积的过程中,形状是没有发生变化的。那么他需要多少个weight 和 bias呢?
以图片中的例子给大家逐步解释:
以卷积核为单位: 卷积核形状为 [3, 3] 时,每一次卷积就需要 [3, 3]个w, [0] 个b
以图为单位: 图的形状为[5, 5], 每个点都需要 [3, 3]的卷积神经,需要[5, 5, 3, 3]个w, [0] 个 b
存在2个图片为输入: 需要[5, 5, 3, 3, 2]个w, [0] 个 b
存在4个特征图为输出: 需要[5, 5, 3, 3, 2, 4]个w, [4] 个 b
结论:w 和输入的形状强相关,b 和输出的形状相关。
在实际编写tensorflow过程中,定义w, b时,输入图片的形状就不需要指定了。所以定义如下:
W_conv1 = weight_variable([3, 3, 2, 4])
b_conv1 = bias_variable([4])
h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)
卷积 -> 池化:
卷积的过程,引用一幅形象的图:
在池化过程中,其实就是求了局部最大值,平均值等。并没有使用到 w 和 b
但是图片的形状却发生了变化。
原图形状:[100, 100]
第一次池化形状:[50, 50]
第二次池化形状:[25, 25]
第三次池化形状:[12, 12]
池化 -> 全连接 -> 输出:
这个过程,引用一幅形象的图:
最后这个过程就贴近于传统的神经网络过程,形状上的变化为:
第一次全连接:
输入:[12, 12, 64],经过3次池化操后,已经变成了长:12,高:12,数量:64的一组小特征图片。
输出:[12 * 12 * 64], 将一组特征图片,平铺开,成为一位数组。
h_pool2_flat = tf.reshape(h_pool2, [-1, 12 * 12 * 64])
第二次全连接:(图中的第一层)
输入:[12 * 12 * 64],一维数组
输出:[784],一维数组
一次输出需要:[784] 个w, [1]个b
全部输出需要:[12 * 12 * 64, 784]个w, [784]个b
W_fc1 = weight_variable([12 * 12 * 64, 784])
b_fc1 = bias_variable([784])
h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)
最终输出:
图中处理的是数字分类问题,一共10个类别。形状为 [10]
我处理汉字分类问题时,一共38个类别,所以形状为 [38]
学习建议:
多学习基础理论和原理,最好是图像化的,通过形状的变化,能够更好的帮助大家理解。