本文建立一个卷积神经网络---典型的深度学习样例。例如,在这个数字识别的例子中,它就达到了高于99%的精度。通过示例代码来讲解神经网络中最重要的两个概念:卷积和池化,关于它们参数的细节超出了本书的讨论范围。但是,读者可以运行本章中的所有代码,也希望读者能从中理解卷积网络背后的整体认识。
一、卷积神经网络
卷积神经网络(CNN)是深度学习一个特殊示例,它在计算机视觉有非常重要的影响。
CNN的一个典型特性就是它们的输入基本全是图片,这可以有很高效的实现并减少需要的参数。让我们回顾一下MNIST数字识别样例:读入MNIST数据并定义placeholders后:
我们可以对输入照片数据的形状(shape)进行重建,代码如下: x_image = tf.reshape(x,[-1,28,28,1])
在这里,我们把输入的shape转换成了 4维的张量(tensor),第2、3维度对应的是照片的长度和宽度,最后一个维度是颜色通道数,本例子中是黑白照片,所以是1(彩色照片是RGB,所以是3).我们可把神经网络的输入看作是2维空间中大小为28*28的神经元:
定义卷积神经网络有两个基本概念:filters与characteristic maps。这些概念可被表述为一组特殊的神经元,稍后我们就会看到。最后要的是我们先简明介绍这两个概念对CNN的重要性。
卷积层的主要目的就是检测图像中的特征或可见特性,如边缘,线,块,颜色等等。这些是由隐藏层负责的,它们会与输入层相连接。在CNN中,输入数据并不是与隐藏层中的神经元全连接;而只是很小的包含图片像素值的局部空间相连。如下图所示:
隐藏层的第一层包含了多个kernels。此处,我们使用了32个kernels,每一个定义了5*5的权重矩阵W和bias b,这两个参数也是隐藏层间共享的。
为了简化代码,定义了如下两个函数来表示权重W与bias b:
二、实现模型
我们需要定义几个参数来表示卷积与池化层。在每个维度中我们使用步长为1(滑动窗口步长),并用0来padding的模型。使用的池化层是在2*2区域上。为了简单计算,建议使用如下两个函数来实现卷积跟池化:
现在可以实现第一个卷积层与池化层。此处我们使用了32个filters,每一个都有一个大小为5*5的窗口。我们必须定义一个tensor来保存shape为[5,5,1,32]权重矩阵W:前两个参数是窗口的大小,第三个参数是channel的数量。最后一个定义了我们想使用多少个特征。更进一步,还需要为每一个权重矩阵定义bias。使用之前定义的函数来创建变量:
ReLU(Rectified Linear unit)激活函数最近变成了神经网络中隐藏层的默认激活函数。这个简单的函数包含了返回max(0,x),所以对于负值,它会返回0,其它返回x。
在我们的例子中,我们会在卷积层后的隐藏层中使用这个激活函数。
代码中首先对输入图像x_image计算卷积,计算得到的结果保存在2D tensor W_conv1中,然后与bias求和,接下来应用ReLU激活函数。最后一步,对输出应用max-pooling:
当构建一个深度神经网络时,可以相互叠加很多层。为演示如何做到这样,我会创建64个filters且窗口大小为5*5的第二层卷积层。此时我们会需传递32个channels,因为这是前一层的输出结果:
当我们对12*12排列应用5*5的窗口,步长为1时,卷积层的输出结果是7*7维度。下一步是对输出的7*7增加一个全连接层,最终结果输入给softmax层。
我们使用包含1024个神经元的一层来处理整个图片。权重与bias的tensor如下:
tensor的第一维度表示第二层卷积层的输出,大小为7*7带有64个filters,第二个参数是层中的神经元数量,我们可自由设置。
接下来,我们将tensor打平到vector中。我们在之前章节中已经看到softmax需要将图片打平成一个vector任为输入。通过打平后的vector乘以权重矩阵W_fc1,再加上bias b_fc1,最后应用ReLU激活函数后就能实现:
下一步是使用神经网络中叫做dropout的技术来减少有效参数的数量。这包含了移除结点及它们相关的输入、输出连接。决定哪一个神经元丢弃,哪一个神经元保留是随机的。为了选择神经元比较一致,对神经元是否被丢弃赋予一个概率。
不多介绍dropout的太多细节,但dropout可以降低模型过拟合数据的风险。当隐藏层中有大量神经元时,就会导致过于表现的模型;此时就会发生过拟合,尤其模型的参数数量超过输入的维度时,更容易产生过拟合。最好要避免产生过拟合,因为过拟合的模型预测非常不准。
在本模型中,我们采用dropout,它会在softmax层前先调用tf.nn.dropout函数。我们还需要创建一个placholder来保存神经元被保留的概率:
最后,在模型中添加softmax层。Softmax函数返回输入属于每一个分类(本例子中是数字)的概率且概率总和为1。Softmax层如下:
三、训练与评估模型
现在我们已经准备好训练模型,模型会在卷积层中调整所有参数,一个全连接层来获得预测照片的结果。如果我们想知道模型表现如何,就需要之前的测试集。
接下来的实现代码与上一章节中的十分类似,但有一个例外:将原来的梯度下降优化算法替换为ADAM优化算法,因为这个算法根据文献中的说明,它实现一种更有效的优化算法。
同样还需要在feed_dict参数中提供keep_prob,用来控制dropout层保留神经元的概率。
四、模型运行结果
完整代码可在github上的CNN.py下载到。
可参考:http://v.youku.com/v_show/id_XMTYyMTc3ODc0OA==.html?f=27327189&o=1&spm=a2h1n.8251843.playList.5!25~5~A
可参考:http://www.tensorfly.cn/tfdoc/tutorials/mnist_pros.html