tensorflow_CNN 卷积神经网络_简单教程

本文建立一个卷积神经网络---典型的深度学习样例。例如,在这个数字识别的例子中,它就达到了高于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中,输入数据并不是与隐藏层中的神经元全连接;而只是很小的包含图片像素值的局部空间相连。如下图所示:


    更精确地来说,在本例子中,隐藏层的每一个神经元是与一个输入层中5*5小区域(25个神经元)相连接。我们可看成一个5*5大小的窗口在包含整个照片的输入层(28*28)上滑行。窗口滑过整层的所有神经元。对于每一位置的窗口,隐藏层中都有一个神经元来处理这部分信息。

       可理解为窗口从图片的左上角开始;这部分信息输入给隐藏层中的第一个神经元。然后窗口向右滑动一个像素;该部分的信息与隐藏层中的第二个神经元相连接。一直持续这个动作直到整体平面从上到下,从左到右被窗口全部转换:

分析这个具体例子,可以发现输入照片大小为28*28,窗口为5*5,会产生第一层隐藏层中24*24排列的神经元,这是因为我们需要从上到下移动窗口23次,从左到右移动窗口23次来覆盖整个输入图片。在这里是假设窗口每次只移动一个像素,所以新窗口与上次的窗口会有重叠。

       在卷积层中每次移动超过一个像素是可能的,这个参数叫作步长。另外一个扩展是对边缘填充0(或其它值),所以窗口可滑过图像的边缘,这可能会产生更好的结果。控制这个特性的参数是padding,你可以用它来决定padding的大小。探讨这两个参数的实现细节同样超出了本书的讨论范围。

       基于我们研究的样例,遵循之前章节的形式,我们需要一个bias b与一个5*5的矩阵W来连接输入层与隐藏层的神经元。CNN的一个关键特性是这个权重矩阵W与bias b是隐藏层中所有神经元间共享的。本例子中是24*24(576)个神经元。读者将会发现与全连接的神经网络相比,这会大大减少权重参数的数量。具体来说,由于共享了权重矩阵W,参数数量会从14000(5*5*24*24)降到25(5*5)。

       这个共享的矩阵W与bias b在CNN中经常被叫作kernel或filter。这些filters与图像处理程序中润色图片的那些是类似的,此处是用来找出有鉴别性的feature。建议读者查阅GIMP手册中的例子来了解卷积是如何工作的。

       一个矩阵与bias定义了一个kernel。一个kernel仅仅只检测图像中一个特定相关的feature,所以建议使用多个kernels,每个想检测的特征一个kernel。这就意味着CNN中一个完整的卷积层包含了很多kernels。描述这些kernels的一个常用方法如下:

  隐藏层的第一层包含了多个kernels。此处,我们使用了32个kernels,每一个定义了5*5的权重矩阵W和bias b,这两个参数也是隐藏层间共享的。

      为了简化代码,定义了如下两个函数来表示权重W与bias b:


              为了不深入到细节,可通过自定义用一些随机值来初始化权重与一些正值来初始化化bias。
对于我们描述的卷积层,经常在卷积层后面加一个池化层。池化层简单的浓缩卷积层的输出结果并创建一个压缩版本的信息并输出。本例子中,我们使用2*2区域的卷积层,通过池化将其压缩成一个点:


  有多种不同的实现方式来池化浓缩信息;本例子中,我们使用的方法叫max-pooling。这种方法中通过只保留2*2区域中的最大值来压缩信息。

如上面所提到的,卷积层中包含了很多kernels,我们会对每一个应用max-pooling。一般来说,会有很多池化层跟卷积层:

            通过池化层将24*24的卷积结果转变成了12*12排列,该排列中的每一元素都是来源于2*2区域。不像是卷积层,这里的数据是平的,并不是由一个滑动窗口创建。
      直观地来说,池化就是找出某一特征是否在图片中出现,该特征的确切位置不如其它特征的相关位置重要。

二、实现模型

我们需要定义几个参数来表示卷积与池化层。在每个维度中我们使用步长为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://www.jianshu.com/p/3b611043cbae
可参考: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

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值