卷积神经网络Lenet-5实现-深入浅出

卷积神经网络算法是n年前就有的算法,只是近年来因为深度学习相关算法为多层网络的训练提供了新方法,然后现在电脑的计算能力已非当年的那种计算水平,同时现在的训练数据很多,于是神经网络的相关算法又重新火了起来,因此卷积神经网络就又活了起来。

在开始前,我们需要明确的是网上讲的卷积神经网络的相关教程一般指的是神经网络的前向传导过程,反向传播都是用梯度下降法进行训练,大部分深度学习库,都已经把反向求导的功能给封装好了,如果想要深入学习反向求导,就需要自己慢慢学了。

因为卷积神经网络的经典模型是:Lenet-5实现,只要理解了这个的前向传导过程,基本上就OK了,因此我们后面主要讲解Lenet-5的实现。

一、理论阶段

作为CNN的入门文章,没有打算啰嗦太多的东西,因为什么权值共享、局部感受野什么的,讲那么多,都是那些生物学的相关理论,看了那些玩意,大部分初学者已经烦了。卷积神经网络的相关博文也是一大堆,但是讲的,基本上都是抄过来抄过去,就像我之前不理解从S2层到C3层是怎么实现的,网上看了一大堆教程,没有一个解答这个问题的。我的个人感觉整个过程,就只有S2到C3是最难理解的。接着我将用最浅显易懂的方式进行讲解。

1、卷积

卷积的概念这个我想只要学过图像处理的人都懂的概念了,这个不解释。我们知道对于给定的一幅图像来说,给定一个卷积核,卷积就是根据卷积窗口,进行像素的加权求和。

卷积神经网络与我们之前所学到的图像的卷积的区别,我的理解是:我们之前学图像处理遇到卷积,一般来说,这个卷积核是已知的,比如各种边缘检测算子、高斯模糊等这些,都是已经知道卷积核,然后再与图像进行卷积运算。然而深度学习中的卷积神经网络卷积核是未知的,我们训练一个神经网络,就是要训练得出这些卷积核,而这些卷积核就相当于我们学单层感知器的时候的那些参数W,因此你可以把这些待学习的卷积核看成是神经网络的训练参数W。

2、池化

刚开始学习CNN的时候,看到这个词,好像高大上的样子,于是查了很多资料,理论一大堆,但是实践、算法实现却都没讲到,也不懂池化要怎么实现?其实所谓的池化,就是图片下采样。这个时候,你会发现CNN每一层的构建跟图像高斯金字塔的构建有点类似,因此你如果已经懂得了图像金字塔融合的相关算法,那么就变的容易理解了。在高斯金子塔构建中,每一层通过卷积,然后卷积后进行下采样,而CNN也是同样的过程。废话不多说,这里就讲一下,CNN的池化:

CNN的池化(图像下采样)方法很多:Mean pooling(均值采样)、Max pooling(最大值采样)、Overlapping (重叠采样)、L2 pooling(均方采样)、Local Contrast Normalization(归一化采样)、Stochasticpooling(随即采样)、Def-pooling(形变约束采样)。其中最经典的是最大池化,因此我就解释一下最大池化的实现:

原图片

为了简单起见,我用上面的图片作为例子,假设上面的图片大小是4*4的,如上图所示,然后图片中每个像素点的值是上面各个格子中的数值。然后我要对这张4*4的图片进行池化,池化的大小为(2,2),跨步为2,那么采用最大池化也就是对上面4*4的图片进行分块,每个块的大小为2*2,然后统计每个块的最大值,作为下采样后图片的像素值,具体计算如下图所示:

也就是说我们最后得到下采样后的图片为:

这就是所谓的最大池化。当然以后你还会遇到各种池化方法,比如均值池化,也就是对每个块求取平均值作为下采样的新像素值。还有重叠采样的池化,我上面这个例子是没有重叠的采样的,也就是每个块之间没有相互重叠的部分,上面我说的跨步为2,就是为了使得分块都非重叠,等等,这些以后再跟大家解释池化常用方法。这里就先记住最大池化就好了,因为这个目前是最常用的。

3、feature maps 

这个单词国人把它翻译成特征图,挺起来很专业的名词。那么什么叫特征图呢?特征图其实说白了就是CNN中的每张图片,都可以称之为特征图张。在CNN中,我们要训练的卷积核并不是仅仅只有一个,这些卷积核用于提取特征,卷积核个数越多,提取的特征越多,理论上来说精度也会更高,然而卷积核一堆,意味着我们要训练的参数的个数越多。在LeNet-5经典结构中,第一层卷积核选择了6个,而在AlexNet中,第一层卷积核就选择了96个,具体多少个合适,还有待学习。

回到特征图概念,CNN的每一个卷积层我们都要人为的选取合适的卷积核个数,及卷积核大小。每个卷积核与图片进行卷积,就可以得到一张特征图了,比如LeNet-5经典结构中,第一层卷积核选择了6个,我们可以得到6个特征图,这些特征图也就是下一层网络的输入了。我们也可以把输入图片看成一张特征图,作为第一层网络的输入。

4、CNN的经典结构

对于刚入门CNN的人来说,我们首先需要现在的一些经典结构:

(1)LeNet-5。这个是n多年前就有的一个CNN的经典结构,主要是用于手写字体的识别,也是刚入门需要学习熟悉的一个网络,我的这篇博文主要就是要讲这个网络

(2)AlexNet。

在imagenet上的图像分类challenge上大神Alex提出的alexnet网络结构模型赢得了2012届的冠军,振奋人心,利用CNN实现了图片分类,别人用传统的机器学习算法调参跳到半死也就那样,Alex利用CNN精度远超传统的网络。

其它的还有什么《Network In Network》,GoogLeNet、Deconvolution Network,在以后的学习中我们会遇到。比如利用Deconvolution Network反卷积网络实现图片的去模糊,牛逼哄哄。

OK,理论阶段就啰嗦到这里就好了,接着就讲解 LeNet-5, LeNet-5是用于手写字体的识别的一个经典CNN:

LeNet-5结构

输入:32*32的手写字体图片,这些手写字体包含0~9数字,也就是相当于10个类别的图片

输出:分类结果,0~9之间的一个数

因此我们可以知道,这是一个多分类问题,总共有十个类,因此神经网络的最后输出层必然是SoftMax问题,然后神经元的个数是10个。LeNet-5结构:

输入层:32*32的图片,也就是相当于1024个神经元

C1层:paper作者,选择6个特征卷积核,然后卷积核大小选择5*5,这样我们可以得到6个特征图,然后每个特征图的大小为32-5+1=28,也就是神经元的个数由1024减小到了28*28=784。

S2层:这就是下采样层,也就是使用最大池化进行下采样,池化的size,选择(2,2),也就是相当于对C1层28*28的图片,进行分块,每个块的大小为2*2,这样我们可以得到14*14个块,然后我们统计每个块中,最大的值作为下采样的新像素,因此我们可以得到S1结果为:14*14大小的图片,共有6个这样的图片。

C3层:卷积层,这一层我们选择卷积核的大小依旧为5*5,据此我们可以得到新的图片大小为14-5+1=10,然后我们希望可以得到16张特征图。那么问题来了?这一层是最难理解的,我们知道S2包含:6张14*14大小的图片,我们希望这一层得到的结果是:16张10*10的图片。这16张图片的每一张,是通过S2的6张图片进行加权组合得到的,具体是怎么组合的呢?问题如下图所示:

为了解释这个问题,我们先从简单的开始,我现在假设输入6特征图的大小是5*5的,分别用6个5*5的卷积核进行卷积,得到6个卷积结果图片大小为1*1,如下图所示:

为了简便起见,我这里先做一些标号的定义:我们假设输入第i个特征图的各个像素值为x1i,x2i……x25i,因为每个特征图有25个像素。因此第I个特征图经过5*5的图片卷积后,得到的卷积结果图片的像素值Pi可以表示成:

这个是卷积公式,不解释。因此对于上面的P1~P6的计算方法,这个就是直接根据公式。然后我们把P1~P6相加起来,也就是:

P=P1+P2+……P6

把上面的Pi的计算公式,代入上式,那么我们可以得到:

P=WX

其中X就是输入的那6张5*5特征图片的各个像素点值,而W就是我们需要学习的参数,也就相当于6个5*5的卷积核,当然它包含着6*(5*5)个参数。因此我们的输出特征图就是:

Out=f(P+b)

这个就是从S2到C3的计算方法,其中b表示偏置项,f为激活函数。

我们回归到原来的问题:有6张输入14*14的特征图片,我们希望用5*5的卷积核,然后最后我们希望得到一张10*10的输出特征图片?

根据上面的过程,也就是其实我们用5*5的卷积核去卷积每一张输入的特征图,当然每张特征图的卷积核参数是不一样的,也就是不共享,因此我们就相当于需要6*(5*5)个参数。对每一张输入特征图进行卷积后,我们得到6张10*10,新图片,这个时候,我们把这6张图片相加在一起,然后加一个偏置项b,然后用激活函数进行映射,就可以得到一张10*10的输出特征图了。

而我们希望得到16张10*10的输出特征图,因此我们就需要卷积参数个数为16*(6*(5*5))=16*6*(5*5)个参数。总之,C3层每个图片是通过S2图片进行卷积后,然后相加,并且加上偏置b,最后在进行激活函数映射得到的结果。

S4层:下采样层,比较简单,也是知己对C3的16张10*10的图片进行最大池化,池化块的大小为2*2。因此最后S4层为16张大小为5*5的图片。至此我们的神经元个数已经减少为:16*5*5=400。

C5层:我们继续用5*5的卷积核进行卷积,然后我们希望得到120个特征图。这样C5层图片的大小为5-5+1=1,也就是相当于1个神经元,120个特征图,因此最后只剩下120个神经元了。这个时候,神经元的个数已经够少的了,后面我们就可以直接利用全连接神经网络,进行这120个神经元的后续处理,后面具体要怎么搞,只要懂多层感知器的都懂了,不解释。

上面的结构,只是一种参考,在现实使用中,每一层特征图需要多少个,卷积核大小选择,还有池化的时候采样率要多少,等这些都是变化的,这就是所谓的CNN调参,我们需要学会灵活多变。

比如我们可以把上面的结构改为:C1层卷积核大小为7*7,然后把C3层卷积核大小改为3*3等,然后特征图的个数也是自己选,说不定得到手写字体识别的精度比上面那个还高,这也是有可能的,总之一句话:需要学会灵活多变,需要学会CNN的调参。

二、实战阶段

学习CNN的源码实现网站:http://deeplearning.net/tutorial/lenet.html#lenet

1、训练数据获取

在theano学习库中有手写字体的库,可以从网上下载到,名为:mnist.pkl.gz的手写字体库,里面包含了三个部分的数据,训练数据集train_set:50000个训练样本,验证集valid_set,我们可以用如下的代码读取这些数据,然后用plot显示其中的一张图片:

[python] view plain copy

  1. <span style="font-size:18px;">import cPickle
  2. import gzip
  3. import numpy as np
  4. import matplotlib.pyplot as plt
  5. f = gzip.open(‘mnist.pkl.gz‘, ‘rb‘)
  6. train_set, valid_set, test_set = cPickle.load(f)
  7. f.close()
  8. tx,ty=train_set;
  9. #查看训练样本
  10. print np.shape(tx)#可以看到tx大小为(50000,28*28)的二维矩阵
  11. print np.shape(ty)#可以看到ty大小为(50000,1)的矩阵
  12. #图片显示
  13. A=tx[8].reshape(28,28)#第八个训练样本
  14. Y=ty[8]
  15. print Y
  16. plt.imshow(A,cmap=‘gray‘)#显示手写字体图片</span>

在上面的代码中我显示的是第8张图片,可以看到如下结果:

第八个样本是数字1。

2、LeNet-5实现

首先你要知道mnist.pkl.gz这个库给我们的图片的大小是28*28的,因此我们可以第一步选择5*5的卷积核进行卷积得到24*24,同时我们希望C1层得到20张特征图,等等,具体的代码实现如下;

[python] view plain copy

  1. import os
  2. import sys
  3. import timeit
  4. import numpy
  5. import theano
  6. import theano.tensor as T
  7. from theano.tensor.signal import downsample
  8. from theano.tensor.nnet import conv
  9. from logistic_sgd import LogisticRegression, load_data
  10. from mlp import HiddenLayer
  11. #卷积神经网络的一层,包含:卷积+下采样两个步骤
  12. #算法的过程是:卷积-》下采样-》激活函数
  13. class LeNetConvPoolLayer(object):
  14. #image_shape是输入数据的相关参数设置  filter_shape本层的相关参数设置
  15. def __init__(self, rng, input, filter_shape, image_shape, poolsize=(2, 2)):
  16. """
  17. :type rng: numpy.random.RandomState
  18. :param rng: a random number generator used to initialize weights
  19. 3、input: 输入特征图数据,也就是n幅特征图片
  20. 4、参数 filter_shape: (number of filters, num input feature maps,
  21. filter height, filter width)
  22. num of filters:是卷积核的个数,有多少个卷积核,那么本层的out feature maps的个数
  23. 也将生成多少个。num input feature maps:输入特征图的个数。
  24. 然后接着filter height, filter width是卷积核的宽高,比如5*5,9*9……
  25. filter_shape是列表,因此我们可以用filter_shape[0]获取卷积核个数
  26. 5、参数 image_shape: (batch size, num input feature maps,
  27. image height, image width),
  28. batch size:批量训练样本个数 ,num input feature maps:输入特征图的个数
  29. image height, image width分别是输入的feature map图片的大小。
  30. image_shape是一个列表类型,所以可以直接用索引,访问上面的4个参数,索引下标从
  31. 0~3。比如image_shape[2]=image_heigth  image_shape[3]=num input feature maps
  32. 6、参数 poolsize: 池化下采样的的块大小,一般为(2,2)
  33. """
  34. assert image_shape[1] == filter_shape[1]#判断输入特征图的个数是否一致,如果不一致是错误的
  35. self.input = input
  36. # fan_in=num input feature maps *filter height*filter width
  37. #numpy.prod(x)函数为计算x各个元素的乘积
  38. #也就是说fan_in就相当于每个即将输出的feature  map所需要链接参数权值的个数
  39. fan_in = numpy.prod(filter_shape[1:])
  40. # fan_out=num output feature maps * filter height * filter width
  41. fan_out = (filter_shape[0] * numpy.prod(filter_shape[2:]) /
  42. numpy.prod(poolsize))
  43. # 把参数初始化到[-a,a]之间的数,其中a=sqrt(6./(fan_in + fan_out)),然后参数采用均匀采样
  44. #权值需要多少个?卷积核个数*输入特征图个数*卷积核宽*卷积核高?这样没有包含采样层的链接权值个数
  45. W_bound = numpy.sqrt(6. / (fan_in + fan_out))
  46. self.W = theano.shared(
  47. numpy.asarray(
  48. rng.uniform(low=-W_bound, high=W_bound, size=filter_shape),
  49. dtype=theano.config.floatX
  50. ),
  51. borrow=True
  52. )
  53. # b为偏置,是一维的向量。每个输出特征图i对应一个偏置参数b[i]
  54. #,因此下面初始化b的个数就是特征图的个数filter_shape[0]
  55. b_values = numpy.zeros((filter_shape[0],), dtype=theano.config.floatX)
  56. self.b = theano.shared(value=b_values, borrow=True)
  57. # 卷积层操作,函数conv.conv2d的第一个参数为输入的特征图,第二个参数为随机出事化的卷积核参数
  58. #第三个参数为卷积核的相关属性,输入特征图的相关属性
  59. conv_out = conv.conv2d(
  60. input=input,
  61. filters=self.W,
  62. filter_shape=filter_shape,
  63. image_shape=image_shape
  64. )
  65. # 池化操作,最大池化
  66. pooled_out = downsample.max_pool_2d(
  67. input=conv_out,
  68. ds=poolsize,
  69. ignore_border=True
  70. )
  71. #激励函数,也就是说是先经过卷积核再池化后,然后在进行非线性映射
  72. # add the bias term. Since the bias is a vector (1D array), we first
  73. # reshape it to a tensor of shape (1, n_filters, 1, 1). Each bias will
  74. # thus be broadcasted across mini-batches and feature map
  75. # width & height
  76. self.output = T.tanh(pooled_out + self.b.dimshuffle(‘x‘, 0, ‘x‘, ‘x‘))
  77. # 保存参数
  78. self.params = [self.W, self.b]
  79. self.input = input
  80. #测试函数
  81. def evaluate_lenet5(learning_rate=0.1, n_epochs=200,
  82. dataset=‘mnist.pkl.gz‘,
  83. nkerns=[20, 50], batch_size=500):
  84. """ Demonstrates lenet on MNIST dataset
  85. :learning_rate: 梯度下降法的学习率
  86. :n_epochs: 最大迭代次数
  87. :type dataset: string
  88. :param dataset: path to the dataset used for training /testing (MNIST here)
  89. :nkerns: 每个卷积层的卷积核个数,第一层卷积核个数为 nkerns[0]=20,第二层卷积核个数
  90. 为50个
  91. """
  92. rng = numpy.random.RandomState(23455)
  93. datasets = load_data(dataset)#加载训练数据,训练数据包含三个部分
  94. train_set_x, train_set_y = datasets[0]#训练数据
  95. valid_set_x, valid_set_y = datasets[1]#验证数据
  96. test_set_x, test_set_y = datasets[2]#测试数据
  97. # 计算批量训练可以分多少批数据进行训练,这个只要是知道批量训练的人都知道
  98. n_train_batches = train_set_x.get_value(borrow=True).shape[0]#训练数据个数
  99. n_valid_batches = valid_set_x.get_value(borrow=True).shape[0]
  100. n_test_batches = test_set_x.get_value(borrow=True).shape[0]
  101. n_train_batches /= batch_size#批数
  102. n_valid_batches /= batch_size
  103. n_test_batches /= batch_size
  104. # allocate symbolic variables for the data
  105. index = T.lscalar()  # index to a [mini]batch
  106. # start-snippet-1
  107. x = T.matrix(‘x‘)   # the data is presented as rasterized images
  108. y = T.ivector(‘y‘)  # the labels are presented as 1D vector of
  109. # [int] labels
  110. # Reshape matrix of rasterized images of shape (batch_size, 28 * 28)
  111. # to a 4D tensor, compatible with our LeNetConvPoolLayer
  112. # (28, 28) is the size of MNIST images.
  113. layer0_input = x.reshape((batch_size, 1, 28, 28))
  114. ‘‘‘‘‘构建第一层网络:
  115. image_shape:输入大小为28*28的特征图,batch_size个训练数据,每个训练数据有1个特征图
  116. filter_shape:卷积核个数为nkernes[0]=20,因此本层每个训练样本即将生成20个特征图
  117. 经过卷积操作,图片大小变为(28-5+1 , 28-5+1) = (24, 24)
  118. 经过池化操作,图片大小变为 (24/2, 24/2) = (12, 12)
  119. 最后生成的本层image_shape为(batch_size, nkerns[0], 12, 12)‘‘‘
  120. layer0 = LeNetConvPoolLayer(
  121. rng,
  122. input=layer0_input,
  123. image_shape=(batch_size, 1, 28, 28),
  124. filter_shape=(nkerns[0], 1, 5, 5),
  125. poolsize=(2, 2)
  126. )
  127. ‘‘‘‘‘构建第二层网络:输入batch_size个训练图片,经过第一层的卷积后,每个训练图片有nkernes[0]个特征图,每个特征图
  128. 大小为12*12
  129. 经过卷积后,图片大小变为(12-5+1, 12-5+1) = (8, 8)
  130. 经过池化后,图片大小变为(8/2, 8/2) = (4, 4)
  131. 最后生成的本层的image_shape为(batch_size, nkerns[1], 4, 4)‘‘‘
  132. layer1 = LeNetConvPoolLayer(
  133. rng,
  134. input=layer0.output,
  135. image_shape=(batch_size, nkerns[0], 12, 12),
  136. filter_shape=(nkerns[1], nkerns[0], 5, 5),
  137. poolsize=(2, 2)
  138. )
  139. # the HiddenLayer being fully-connected, it operates on 2D matrices of
  140. # shape (batch_size, num_pixels) (i.e matrix of rasterized images).
  141. # This will generate a matrix of shape (batch_size, nkerns[1] * 4 * 4),
  142. # or (500, 50 * 4 * 4) = (500, 800) with the default values.
  143. layer2_input = layer1.output.flatten(2)
  144. ‘‘‘‘‘全链接:输入layer2_input是一个二维的矩阵,第一维表示样本,第二维表示上面经过卷积下采样后
  145. 每个样本所得到的神经元,也就是每个样本的特征,HiddenLayer类是一个单层网络结构
  146. 下面的layer2把神经元个数由800个压缩映射为500个‘‘‘
  147. layer2 = HiddenLayer(
  148. rng,
  149. input=layer2_input,
  150. n_in=nkerns[1] * 4 * 4,
  151. n_out=500,
  152. activation=T.tanh
  153. )
  154. # 最后一层:逻辑回归层分类判别,把500个神经元,压缩映射成10个神经元,分别对应于手写字体的0~9
  155. layer3 = LogisticRegression(input=layer2.output, n_in=500, n_out=10)
  156. # the cost we minimize during training is the NLL of the model
  157. cost = layer3.negative_log_likelihood(y)
  158. # create a function to compute the mistakes that are made by the model
  159. test_model = theano.function(
  160. [index],
  161. layer3.errors(y),
  162. givens={
  163. x: test_set_x[index * batch_size: (index + 1) * batch_size],
  164. y: test_set_y[index * batch_size: (index + 1) * batch_size]
  165. }
  166. )
  167. validate_model = theano.function(
  168. [index],
  169. layer3.errors(y),
  170. givens={
  171. x: valid_set_x[index * batch_size: (index + 1) * batch_size],
  172. y: valid_set_y[index * batch_size: (index + 1) * batch_size]
  173. }
  174. )
  175. #把所有的参数放在同一个列表里,可直接使用列表相加
  176. params = layer3.params + layer2.params + layer1.params + layer0.params
  177. #梯度求导
  178. grads = T.grad(cost, params)
  179. # train_model is a function that updates the model parameters by
  180. # SGD Since this model has many parameters, it would be tedious to
  181. # manually create an update rule for each model parameter. We thus
  182. # create the updates list by automatically looping over all
  183. # (params[i], grads[i]) pairs.
  184. updates = [
  185. (param_i, param_i - learning_rate * grad_i)
  186. for param_i, grad_i in zip(params, grads)
  187. ]
  188. train_model = theano.function(
  189. [index],
  190. cost,
  191. updates=updates,
  192. givens={
  193. x: train_set_x[index * batch_size: (index + 1) * batch_size],
  194. y: train_set_y[index * batch_size: (index + 1) * batch_size]
  195. }
  196. )
  197. # end-snippet-1
  198. ###############
  199. # TRAIN MODEL #
  200. ###############
  201. print ‘... training‘
  202. # early-stopping parameters
  203. patience = 10000  # look as this many examples regardless
  204. patience_increase = 2  # wait this much longer when a new best is
  205. # found
  206. improvement_threshold = 0.995  # a relative improvement of this much is
  207. # considered significant
  208. validation_frequency = min(n_train_batches, patience / 2)
  209. # go through this many
  210. # minibatche before checking the network
  211. # on the validation set; in this case we
  212. # check every epoch
  213. best_validation_loss = numpy.inf
  214. best_iter = 0
  215. test_score = 0.
  216. start_time = timeit.default_timer()
  217. epoch = 0
  218. done_looping = False
  219. while (epoch < n_epochs) and (not done_looping):
  220. epoch = epoch + 1
  221. for minibatch_index in xrange(n_train_batches):#每一批训练数据
  222. cost_ij = train_model(minibatch_index)
  223. iter = (epoch - 1) * n_train_batches + minibatch_index
  224. if (iter + 1) % validation_frequency == 0:
  225. # compute zero-one loss on validation set
  226. validation_losses = [validate_model(i) for i
  227. in xrange(n_valid_batches)]
  228. this_validation_loss = numpy.mean(validation_losses)
  229. print(‘epoch %i, minibatch %i/%i, validation error %f %%‘ %
  230. (epoch, minibatch_index + 1, n_train_batches,
  231. this_validation_loss * 100.))
  232. # if we got the best validation score until now
  233. if this_validation_loss < best_validation_loss:
  234. #improve patience if loss improvement is good enough
  235. if this_validation_loss < best_validation_loss *  \
  236. improvement_threshold:
  237. patience = max(patience, iter * patience_increase)
  238. # save best validation score and iteration number
  239. best_validation_loss = this_validation_loss
  240. best_iter = iter
  241. # test it on the test set
  242. test_losses = [
  243. test_model(i)
  244. for i in xrange(n_test_batches)
  245. ]
  246. test_score = numpy.mean(test_losses)
  247. print((‘     epoch %i, minibatch %i/%i, test error of ‘
  248. ‘best model %f %%‘) %
  249. (epoch, minibatch_index + 1, n_train_batches,
  250. test_score * 100.))
  251. if patience <= iter:
  252. done_looping = True
  253. break
  254. end_time = timeit.default_timer()
  255. print(‘Optimization complete.‘)
  256. print(‘Best validation score of %f %% obtained at iteration %i, ‘
  257. ‘with test performance %f %%‘ %
  258. (best_validation_loss * 100., best_iter + 1, test_score * 100.))
  259. print >> sys.stderr, (‘The code for file ‘ +
  260. os.path.split(__file__)[1] +
  261. ‘ ran for %.2fm‘ % ((end_time - start_time) / 60.))
  262. if __name__ == ‘__main__‘:
  263. evaluate_lenet5()
  264. def experiment(state, channel):
  265. evaluate_lenet5(state.learning_rate, dataset=state.dataset)

训练结果:

参考文献:

1、http://blog.csdn.net/zouxy09/article/details/8775360/

2、http://www.deeplearning.net/tutorial/lenet.html#lenet

**********************作者:hjimce   时间:2015.8.6  联系QQ:1393852684   地址:http://blog.csdn.net/hjimce 转载请保留本行信息********************

时间: 2024-12-29 12:04:22

卷积神经网络Lenet-5实现-深入浅出的相关文章

【卷积神经网络-进化史】从LeNet到AlexNet

[卷积神经网络-进化史]从LeNet到AlexNet 本博客是[卷积神经网络-进化史]的第一部分<从LeNet到AlexNet> 如需转载,请附上本文链接:http://blog.csdn.net/cyh_24/article/details/51440344 更多相关博客请猛戳:http://blog.csdn.net/cyh_24 本系列博客是对刘昕博士的<CNN的近期进展与实用技巧>的一个扩充性资料. 主要讨论CNN的发展,并且引用刘昕博士的思路,对CNN的发展作一个更加详细

经典卷积神经网络(LeNet、AlexNet、VGG、GoogleNet、ResNet)的实现(MXNet版本)

卷积神经网络(Convolutional Neural Network, CNN)是一种前馈神经网络,它的人工神经元可以响应一部分覆盖范围内的周围单元,对于大型图像处理有出色表现. 其中 文章 详解卷积神经网络(CNN)已经对卷积神经网络进行了详细的描述,这里为了学习MXNet的库,所以对经典的神经网络进行实现~加深学习印象,并且为以后的使用打下基础.其中参考的为Gluon社区提供的学习资料~ 1.简单LeNet的实现 def LeNet(): """ 较早的卷积神经网络 :

卷积神经网络-进化史】从LeNet到AlexNet

目录视图 摘要视图 订阅 [置顶] [卷积神经网络-进化史]从LeNet到AlexNet 标签: cnn 卷积神经网络 深度学习 2016年05月17日 23:20:3046038人阅读 评论(4) 收藏 举报  分类: [机器学习&深度学习](15)  版权声明:如需转载,请附上本文链接.作者主页:http://blog.csdn.net/cyh_24 https://blog.csdn.net/cyh24/article/details/51440344 目录(?)[+] [卷积神经网络-进

深入浅出——搞懂卷积神经网络误差分析(一)

第一部分 全连接网络的权值更新 卷积神经网络使用基于梯度的学习方法进行监督训练,实践中,一般使用随机梯度下降(机器学习中几种常见的梯度下降方式)的版本,对于每个训练样本均更新一次权值,误差函数使用误差平方和函数,误差方式采用平方误差代价函数. 注:本文主要按照参考文献中内容来写的,其中某些部分加入了自己解释,此文内容不断更新充实中,直到让人可以看完之后完全了解卷积神经网络的计算过程. 1.1 前向传播中样本的误差以及每层的输出 全连接区的第l层(l来表示当前层)的输出函数为: 全部训练集上的误差

深度学习方法(十一):卷积神经网络结构变化——Google Inception V1-V4,Xception(depthwise convolution)

技术交流QQ群:433250724,欢迎对算法.机器学习技术感兴趣的同学加入. 上一篇讲了深度学习方法(十):卷积神经网络结构变化--Maxout Networks,Network In Network,Global Average Pooling,本篇讲一讲Google的Inception系列net,以及还是Google的Xception.(扯一下,Google的Researcher们还是给了很多很棒的idea的,希望读者朋友和我自己在了解paper之余,可以提出自己的想法,并实现.) 如果想

深度学习方法(十):卷积神经网络结构变化——Maxout Networks,Network In Network,Global Average Pooling

技术交流QQ群:433250724,欢迎对算法.技术感兴趣的同学加入. 最近接下来几篇博文会回到神经网络结构的讨论上来,前面我在"深度学习方法(五):卷积神经网络CNN经典模型整理Lenet,Alexnet,Googlenet,VGG,Deep Residual Learning"一文中介绍了经典的CNN网络结构模型,这些可以说已经是家喻户晓的网络结构,在那一文结尾,我提到"是时候动一动卷积计算的形式了",原因是很多工作证明了,在基本的CNN卷积计算模式之外,很多简

卷积神经网络CNN在自然语言处理中的应用

卷积神经网络(Convolution Neural Network, CNN)在数字图像处理领域取得了巨大的成功,从而掀起了深度学习在自然语言处理领域(Natural Language Processing, NLP)的狂潮.2015年以来,有关深度学习在NLP领域的论文层出不穷.尽管其中必定有很多附庸风雅的水文,但是也存在很多经典的应用型文章.笔者在2016年也发表过一篇关于CNN在文本分类方面的论文,今天写这篇博客的目的,是希望能对CNN的结构做一个比较清晰的阐述,同时就目前的研究现状做一个

(转载)Convolutional Neural Networks卷积神经网络

Convolutional Neural Networks卷积神经网络 Contents 一:前导 Back Propagation反向传播算法 网络结构 学习算法 二:Convolutional Neural Networks卷积神经网络 三:LeCun的LeNet-5 四:CNNs的训练过程 五:总结 本文是我在20140822的周报,其中部分参照了以下博文或论文,如果在文中有一些没说明白的地方,可以查阅他们.对Yann LeCun前辈,和celerychen2009.zouxy09表示感谢

实战卷积神经网络

在近些年,深度学习领域的卷积神经网络(CNNs或ConvNets)在各行各业为我们解决了大量的实际问题.但是对于大多数人来说,CNN仿佛戴上了神秘的面纱. CNN能做什么 CNN是深度学习算法在图像处理领域的一个应用.主要被用来找寻图片中的模式.这个过程主要有两个步骤,首先要对图片做卷积,然后找寻模式.在神经网络中,前几层是用来寻找边界和角,随着层数的增加,我们就能识别更加复杂的特征.这个性质让CNN非常擅长识别图片中的物体. 学习CNN之前,我们需要对CNN和Deep Learning有一个简