首先介绍下卷积神经网络
输入层我就不讲了,我主要根据代码讲下卷积层,池化层,全连接层。
(一)
卷积层
'''
-1代表着矩阵行不确定我这里用n表示,[-1,28,28,1]的意思是n行28列,
它的子元素是一个28行1列的矩阵,例如
[[[[1]], [[1]], [[1]], [[1]]],
[[[1]], [[1]], [[1]], [[1]]]]
可以表示为【2,4,1,1】它的子元素[[1]]为1行1列。在这里这个1也可以理解为通道数为1
'''
x_image = tf.reshape(x, [-1, 28, 28, 1])
'''
w_conv1代表着filter【5,5】为卷积核大小,1为通道数,32为卷积核的个数,卷积核个
数的选取需要凭经验,也许有大神知道一定的规律,这里我讲一下卷积核的通道数为什么需
要和输入的通道数一样,其实原理很简单,我们需要x_image和w_conv1相乘,也就需要它们两
个的子元素相乘,上边已经说过x_image的子元素为【28,1】,要想两者相乘,则w_conv1
子元素必须为【1,n]
'''
w_conv1 = weight_variable([5, 5, 1, 32])
卷积的计算包括两部分,输入和filter
卷积的计算(注意,下面蓝色矩阵周围有一圈灰色的框,那些就是上面所说到的填充值)
蓝色的矩阵(输入图像)对粉色的矩阵(filter)进行矩阵内积计算并将三个内积运算的结果与偏置值b相加(比如上面图的计算:2+(-2+1-2)+(1-2-2) + 1= 2 - 3 - 3 + 1 = -3),计算后的值就是绿框矩阵的一个元素。下面的动态图形象地展示了卷积层的计算过程:
代码中我们需要定义一个方法,来实现卷积
def conv2d(x, w):
b = tf.nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME')
return b
这里有 tf.nn.conv2d函数的介绍,https://www.cnblogs.com/qggg/p/6832342.html
我主要介绍下padding(卷积层的) = 'SAME’和padding(卷积层的) = 'VALUE’的区别
之前在讨论卷积神经网络的时候,我们是使用filter来做元素乘法运算来完成卷积运算的。目的是为了完成探测垂直边缘这种特征。但这样做会带来两个问题。
卷积运算后,输出图片尺寸缩小;
越是边缘的像素点,对于输出的影响越小,因为卷积运算在移动的时候到边缘就结束了。中间的像素点有可能会参与多次计算,但是边缘像素点可能只参与一次。所以我们的结果可能会丢失边缘信息。
那么为了解决这个问题,我们引入padding, 什么是padding呢,就是我们认为的扩充图片, 在图片外围补充一些像素点,把这些像素点初始化为0.
① SAME