当前位置: 首页 > news >正文

建站不备案网站开发初级技术人员

建站不备案,网站开发初级技术人员,网站开发学习案例,access是不是常用的网页制作工具本文代码下载地址#xff1a;我的github本文主要讲解将CNN应用于人脸识别的流程#xff0c;程序基于PythonnumpytheanoPIL开发#xff0c;采用类似LeNet5的CNN模型#xff0c;应用于olivettifaces人脸数据库#xff0c;实现人脸识别的功能#xff0c;模型的误差降到了5%以…本文代码下载地址我的github本文主要讲解将CNN应用于人脸识别的流程程序基于PythonnumpytheanoPIL开发采用类似LeNet5的CNN模型应用于olivettifaces人脸数据库实现人脸识别的功能模型的误差降到了5%以下。本程序只是个人学习过程的一个toy implement样本很小模型随时都会过拟合。 但是本文意在理清程序开发CNN模型的具体步骤特别是针对图像识别从拿到图像数据库到实现一个针对这个图像数据库的CNN模型我觉得本文对这些流程的实现具有参考意义。《本文目录》 一、olivettifaces人脸数据库介绍 二、CNN的基本“构件”LogisticRegression、HiddenLayer、LeNetConvPoolLayer 三、组建CNN模型设置优化算法应用于Olivetti Faces进行人脸识别 四、训练结果以及参数设置的讨论 五、利用训练好的参数初始化模型 六、一些需要说明的一、olivettifaces人脸数据库介绍Olivetti Faces是纽约大学的一个比较小的人脸库由40个人的400张图片构成即每个人的人脸图片为10张。每张图片的灰度级为8位每个像素的灰度大小位于0-255之间每张图片大小为64×64。如下图这个图片大小是1190*942一共有20*20张人脸故每张人脸大小是1190/20*942/20即57*472679本文所用的训练数据就是这张图片400个样本40个类别乍一看样本好像比较小用CNN效果会好吗先别下结论请往下看。 要运行CNN算法这张图片必须先转化为数组或者说矩阵这个用到python的图像库PIL几行代码就可以搞定具体的方法我之前刚好写过一篇文章也是用这张图考虑到文章冗长就不复制过来了链接在此《利用Python PIL、cPickle读取和保存图像数据库》。训练机器学习算法我们一般将原始数据分成训练数据training_set、验证数据(validation_set)、测试数据(testing_set)。本程序将training_set、validation_set、testing_set分别设置为320、40、40个样本。它们的label为039对应40个不同的人。这部分的代码如下[python] view plain copy 加载图像数据的函数,dataset_path即图像olivettifaces的路径 加载olivettifaces后划分为train_data,valid_data,test_data三个数据集 函数返回train_data,valid_data,test_data以及对应的label   def load_data(dataset_path):      img  Image.open(dataset_path)      img_ndarray  numpy.asarray(img, dtypefloat64)/256      facesnumpy.empty((400,2679))      for row in range(20):         for column in range(20):          faces[row*20column]numpy.ndarray.flatten(img_ndarray [row*57:(row1)*57,column*47:(column1)*47])        labelnumpy.empty(400)      for i in range(40):      label[i*10:i*1010]i      labellabel.astype(numpy.int)        #分成训练集、验证集、测试集大小如下      train_datanumpy.empty((320,2679))      train_labelnumpy.empty(320)      valid_datanumpy.empty((40,2679))      valid_labelnumpy.empty(40)      test_datanumpy.empty((40,2679))      test_labelnumpy.empty(40)        for i in range(40):      train_data[i*8:i*88]faces[i*10:i*108]      train_label[i*8:i*88]label[i*10:i*108]      valid_data[i]faces[i*108]      valid_label[i]label[i*108]      test_data[i]faces[i*109]      test_label[i]label[i*109]        #将数据集定义成shared类型才能将数据复制进GPU利用GPU加速程序。      def shared_dataset(data_x, data_y, borrowTrue):          shared_x  theano.shared(numpy.asarray(data_x,                                                 dtypetheano.config.floatX),                                   borrowborrow)          shared_y  theano.shared(numpy.asarray(data_y,                                                 dtypetheano.config.floatX),                                   borrowborrow)          return shared_x, T.cast(shared_y, int32)            train_set_x, train_set_y  shared_dataset(train_data,train_label)      valid_set_x, valid_set_y  shared_dataset(valid_data,valid_label)      test_set_x, test_set_y  shared_dataset(test_data,test_label)      rval  [(train_set_x, train_set_y), (valid_set_x, valid_set_y),              (test_set_x, test_set_y)]      return rval  二、CNN的基本“构件”LogisticRegression、HiddenLayer、LeNetConvPoolLayer卷积神经网络CNN的基本结构就是输入层、卷积层conv、子采样层pooling、全连接层、输出层分类器。  卷积层子采样层一般都会有若干个本程序实现的CNN模型参考LeNet5有两个“卷积子采样层”LeNetConvPoolLayer。全连接层相当于MLP多层感知机中的隐含层HiddenLayer。输出层即分类器一般采用softmax回归也有人直接叫逻辑回归其实就是多类别的logistics regression本程序也直接用LogisticRegression表示。总结起来要组建CNN模型必须先定义LeNetConvPoolLayer、HiddenLayer、LogisticRegression这三种layer这一点在我上一篇文章介绍CNN算法时讲得很详细包括代码注解因为太冗长这里给出链接《DeepLearning tutorial4CNN卷积神经网络原理简介代码详解》。代码太长就不贴具体的了只给出框架具体可以下载我的代码看看[python] view plain copy#分类器即CNN最后一层采用逻辑回归softmax  class LogisticRegression(object):      def __init__(self, input, n_in, n_out):          self.W  ....          self.b  ....          self.p_y_given_x  ...          self.y_pred  ...          self.params  ...      def negative_log_likelihood(self, y):      def errors(self, y):    #全连接层分类器前一层  class HiddenLayer(object):      def __init__(self, rng, input, n_in, n_out, WNone, bNone,activationT.tanh):          self.input  input          self.W  ...          self.b  ...          lin_output  ...          self.params  [self.W, self.b]    #卷积采样层convmaxpooling  class LeNetConvPoolLayer(object):      def __init__(self, rng, input, filter_shape, image_shape, poolsize(2, 2)):          self.input  input          self.W  ...          self.b  ...          # 卷积          conv_out  ...          # 子采样          pooled_out ...          self.output  ...          self.params  [self.W, self.b]  三、组建CNN模型设置优化算法应用于Olivetti Faces进行人脸识别上面定义好了CNN的几个基本“构件”现在我们使用这些构件来组建CNN模型本程序的CNN模型参考LeNet5具体为inputlayer0(LeNetConvPoolLayer)layer1(LeNetConvPoolLayer)layer2(HiddenLayer)layer3(LogisticRegression)这是一个串联结构代码也很好写直接用第二部分定义好的各种layer去组建就行了上一layer的输出接下一layer的输入具体可以看看代码evaluate_olivettifaces函数中的“建立CNN模型”部分。CNN模型组建好了就剩下用优化算法求解了优化算法采用批量随机梯度下降算法MSGD所以要先定义MSGD的一些要素主要包括代价函数训练、验证、测试model、参数更新规则即梯度下降。这部分的代码在evaluate_olivettifaces函数中的“定义优化算法的一些基本要素”部分。优化算法的基本要素也定义好了接下来就要运用人脸图像数据集来训练这个模型了训练过程有训练步数n_epoch的设置每个epoch会遍历所有的训练数据training_set本程序中也就是320个人脸图。还有迭代次数iter一次迭代遍历一个batch里的所有样本具体为多少要看所设置的batch_size。关于参数的设定我在下面会讨论。这一部分的代码在evaluate_olivettifaces函数中的“训练CNN阶段”部分。 代码很长只贴框架具体可以下载我的代码看看[python] view plain copydef evaluate_olivettifaces(learning_rate0.05, n_epochs200,                      datasetolivettifaces.gif,                      nkerns[5, 10], batch_size40):           #随机数生成器用于初始化参数....      #加载数据.....      #计算各数据集的batch个数....      #定义几个变量x代表人脸数据作为layer0的输入......        ######################      #建立CNN模型:      #inputlayer0(LeNetConvPoolLayer)layer1(LeNetConvPoolLayer)layer2(HiddenLayer)layer3(LogisticRegression)      ######################      ...      ....      ......        #########################      # 定义优化算法的一些基本要素代价函数训练、验证、测试model、参数更新规则即梯度下降      #########################      ...      ....      ......        #########################      # 训练CNN阶段寻找最优的参数。      ########################      ...      .....      .......  另外值得一提的是在训练CNN阶段我们必须定时地保存模型的参数这是在训练机器学习算法时一个经常会做的事情这一部分的详细介绍我之前写过一篇文章《DeepLearning tutorial2机器学习算法在训练过程中保存参数》。简单来说我们要保存CNN模型中layer0、layer1、layer2、layer3的参数所以在“训练CNN阶段”这部分下面有一句代码[python] view plain copysave_params(layer0.params,layer1.params,layer2.params,layer3.params)  这个函数具体定义为[python] view plain copy#保存训练参数的函数  def save_params(param1,param2,param3,param4):            import cPickle            write_file  open(params.pkl, wb)             cPickle.dump(param1, write_file, -1)          cPickle.dump(param2, write_file, -1)          cPickle.dump(param3, write_file, -1)          cPickle.dump(param4, write_file, -1)          write_file.close()    如果在其他算法中你要保存的参数有五个六个甚至更多那么改一下这个函数的参数就行啦。四、训练结果以及参数设置的讨论ok上面基本介绍完了CNN模型的构建以及模型的训练我将它们的代码都放在train_CNN_olivettifaces.py这个源文件中将Olivetti Faces这张图片跟这个代码文件放在同个目录下运行这个文件几分钟就可以训练完模型并且在同个目录下得到一个params.pkl文件这个文件保存的就是最后的模型的参数方便你以后直接使用这个模型。好了现在讨论一下怎么设置参数具体来说程序中可以设置的参数包括学习速率learning_rate、batch_size、n_epochs、nkerns、poolsize。下面逐一讨论调节它们时对模型的影响。调节learning_rate学习速率learning_rate就是运用SGD算法时梯度前面的系数非常重要设得太大的话算法可能永远都优化不了设得太小会使算法优化得太慢而且可能还会掉入局部最优。可以形象地将learning_rate比喻成走路时步子的大小想象一下要从一个U形的山谷的一边走到山谷最低点如果步子特别大像巨人那么大那会直接从一边跨到另一边然后又跨回这边如此往复。如果太小了可能你走着走着就掉入了某些小坑因为山路总是凹凸不平的局部最优掉入这些小坑后如果步子还是不变就永远走不出那个坑。好回到本文的模型下面是我使用时的记录固定其他参数调节learning_rate1kerns[20, 50], batch_size40poolsize22learning_rate0.1时validation-error一直是97.5%没降下来分析了一下觉得应该是学习速率太大跳过了最优。2nkerns[20, 50], batch_size40poolsize22learning_rate0.01时训练到epoch 60多时validation-error降到5%test-error降到15%3nkerns[20, 50], batch_size40poolsize22learning_rate0.05时训练到epoch 36时validation-error降到2.5%test-error降到5%注意验证集和测试集都只有40张图片也就是说只有一两张识别错了还是不错的数据集再大点误差率可以降到更小。最后我将learning_rate设置为0.05。PS学习速率应该自适应地减小是有专门的一些算法的本程序没有实现这个功能有时间再研究一下。调节batch_size 因为我们采用minibatch SGD算法来优化所以是一个batch一个batch地将数据输入CNN模型中然后计算这个batch的所有样本的平均损失即代价函数是所有样本的平均。而batch_size就是一个batch的所包含的样本数显然batch_size将影响到模型的优化程度和速度。回到本文的模型首先因为我们train_dataset是320valid_dataset和test_dataset都是40所以batch_size最好都是40的因子也就是能让40整除比如40、20、10、5、2、1否则会浪费一些样本比如设置为30则320/3010余数时20这20个样本是没被利用的。并且如果batch_size设置为30则得出的validation-error和test-error只是30个样本的错误率并不是全部40个样本的错误率。这是设置batch_size要注意的。特别是样本比较少的时候。 下面是我实验时的记录固定其他参数改变batch_size:batch_size1、2、5、10、20时validation-error一直是97.5%没降下来。我觉得可能是样本类别覆盖率过小因为我们的数据是按类别排的每个类别10个样本是连续排在一起的batch_size等于20时其实只包含了两个类别这样优化会很慢。因此最后我将batch_size设为40也就是valid_dataset和test_dataset的大小了没办法原始数据集样本太少了。一般我们都不会让batch_size达到valid_dataset和test_dataset的大小的。关于n_epochs n_epochs也就是最大的训练步数比如设为200那训练过程最多遍历你的数据集200遍当遍历了200遍你的dataset时程序会停止。n_epochs就相当于一个停止程序的控制参数并不会影响CNN模型的优化程度和速度只是一个控制程序结束的参数。nkerns[20, 50]20表示第一个卷积层的卷积核的个数50表示第二个卷积层的卷积核的个数。这个我也是瞎调的暂时没什么经验可以总结。不过从理论上来说卷积核的个数其实就代表了特征的个数你提取的特征越多可能最后分类就越准。但是特征太多卷积核太多会增加参数的规模加大了计算复杂度而且有时候卷积核也不是越多越好应根据具体的应用对象来确定。所以我觉得CNN虽号称自动提取特征免去复杂的特征工程但是很多参数比如这里的nkerns还是需要去调节的还是需要一些“人工”的。 下面是我的实验记录固定batch_size40learning_rate0.05poolsize221nkerns[20, 50]时训练到epoch 36时validation-error降到2.5%test-error降到5%2nkerns[10, 30]时训练到epoch 46时validation-error降到5%test-error降到5%3nkerns[5, 10]时训练到epoch 38时validation-error降到5%test-error降到7.5%poolsize(2, 2)poolzize在本程序中是设置为(2,2)即从一个2*2的区域里maxpooling出1个像素说白了就算4和像素保留成1个像素。本例程中人脸图像大小是57*47对这种小图像来说(2,2)时比较合理的。如果你用的图像比较大可以把poolsize设的大一点。分割线上面部分介绍完了CNN模型构建以及模型训练的过程代码都在train_CNN_olivettifaces.py里面训练完可以得到一个params.pkl文件这个文件保存的就是最后的模型的参数方便你以后直接使用这个模型。以后只需利用这些保存下来的参数来初始化CNN模型就得到一个可以使用的CNN系统将人脸图输入这个CNN系统预测人脸图的类别。 接下来就介绍怎么使用训练好的参数的方法这部分的代码放在use_CNN_olivettifaces.py文件中。五、利用训练好的参数初始化模型在train_CNN_olivettifaces.py中的LeNetConvPoolLayer、HiddenLayer、LogisticRegression是用随机数生成器去随机初始化的我们将它们定义为可以用参数来初始化的版本其实很简单代码只需要做稍微的改动只需要在LogisticRegression、HiddenLayer、LeNetConvPoolLayer这三个class的__init__()函数中加两个参数params_W,params_b然后将params_W,params_b赋值给这三个class里的W和b[python] view plain copyself.W  params_W  self.b  params_b  params_W,params_b就是从params.pkl文件中读取来的读取的函数[python] view plain copy#读取之前保存的训练参数  #layer0_params~layer3_params都是包含W和b的,layer*_params[0]是Wlayer*_params[1]是b  def load_params(params_file):      fopen(params_file,rb)      layer0_paramscPickle.load(f)      layer1_paramscPickle.load(f)      layer2_paramscPickle.load(f)      layer3_paramscPickle.load(f)      f.close()      return layer0_params,layer1_params,layer2_params,layer3_params  ok可以用参数初始化的CNN定义好了那现在就将需要测试的人脸图输入该CNN测试其类别。同样的需要写一个读图像的函数load_data()代码就不贴了。将图像数据输入CNN的输出便是该图像的类别这一部分的代码在use_CNN()函数中代码很容易看懂。这一部分还涉及到theano.function的使用我把一些笔记记在了use_CNN_olivettifaces.py代码的最后因为跟代码相关结合代码来看会比较好所以下面就不讲这部分有兴趣的看看代码。最后说说测试的结果我仍然以整副olivettifaces.gif作为输入得出其类别后跟真正的label对比程序输出被错分的那些图像运行结果如下错了五张我标了三张六、一些需要说明的首先是本文的严谨性在文章开头我就说这只是一个toy implement400张图片根本不适合用DL来做。当然我写这篇文章只是为了总结一下这个实现流程这一点希望对读者也有参考意义。最后我的代码都放在这里github地址可以下载authorweponbloghttp://blog.csdn.net/u012162613/article/details/43277187本文代码下载地址我的github本文主要讲解将CNN应用于人脸识别的流程程序基于PythonnumpytheanoPIL开发采用类似LeNet5的CNN模型应用于olivettifaces人脸数据库实现人脸识别的功能模型的误差降到了5%以下。本程序只是个人学习过程的一个toy implement样本很小模型随时都会过拟合。但是本文意在理清程序开发CNN模型的具体步骤特别是针对图像识别从拿到图像数据库到实现一个针对这个图像数据库的CNN模型我觉得本文对这些流程的实现具有参考意义。《本文目录》一、olivettifaces人脸数据库介绍二、CNN的基本“构件”LogisticRegression、HiddenLayer、LeNetConvPoolLayer三、组建CNN模型设置优化算法应用于Olivetti Faces进行人脸识别四、训练结果以及参数设置的讨论五、利用训练好的参数初始化模型六、一些需要说明的一、olivettifaces人脸数据库介绍Olivetti Faces是纽约大学的一个比较小的人脸库由40个人的400张图片构成即每个人的人脸图片为10张。每张图片的灰度级为8位每个像素的灰度大小位于0-255之间每张图片大小为64×64。如下图这个图片大小是1190*942一共有20*20张人脸故每张人脸大小是1190/20*942/20即57*472679本文所用的训练数据就是这张图片400个样本40个类别乍一看样本好像比较小用CNN效果会好吗先别下结论请往下看。要运行CNN算法这张图片必须先转化为数组或者说矩阵这个用到python的图像库PIL几行代码就可以搞定具体的方法我之前刚好写过一篇文章也是用这张图考虑到文章冗长就不复制过来了链接在此《利用Python PIL、cPickle读取和保存图像数据库》。训练机器学习算法我们一般将原始数据分成训练数据training_set、验证数据(validation_set)、测试数据(testing_set)。本程序将training_set、validation_set、testing_set分别设置为320、40、40个样本。它们的label为039对应40个不同的人。这部分的代码如下[python] view plain copy 加载图像数据的函数,dataset_path即图像olivettifaces的路径 加载olivettifaces后划分为train_data,valid_data,test_data三个数据集 函数返回train_data,valid_data,test_data以及对应的label   def load_data(dataset_path):      img  Image.open(dataset_path)      img_ndarray  numpy.asarray(img, dtypefloat64)/256      facesnumpy.empty((400,2679))      for row in range(20):         for column in range(20):          faces[row*20column]numpy.ndarray.flatten(img_ndarray [row*57:(row1)*57,column*47:(column1)*47])        labelnumpy.empty(400)      for i in range(40):      label[i*10:i*1010]i      labellabel.astype(numpy.int)        #分成训练集、验证集、测试集大小如下      train_datanumpy.empty((320,2679))      train_labelnumpy.empty(320)      valid_datanumpy.empty((40,2679))      valid_labelnumpy.empty(40)      test_datanumpy.empty((40,2679))      test_labelnumpy.empty(40)        for i in range(40):      train_data[i*8:i*88]faces[i*10:i*108]      train_label[i*8:i*88]label[i*10:i*108]      valid_data[i]faces[i*108]      valid_label[i]label[i*108]      test_data[i]faces[i*109]      test_label[i]label[i*109]        #将数据集定义成shared类型才能将数据复制进GPU利用GPU加速程序。      def shared_dataset(data_x, data_y, borrowTrue):          shared_x  theano.shared(numpy.asarray(data_x,                                                 dtypetheano.config.floatX),                                   borrowborrow)          shared_y  theano.shared(numpy.asarray(data_y,                                                 dtypetheano.config.floatX),                                   borrowborrow)          return shared_x, T.cast(shared_y, int32)            train_set_x, train_set_y  shared_dataset(train_data,train_label)      valid_set_x, valid_set_y  shared_dataset(valid_data,valid_label)      test_set_x, test_set_y  shared_dataset(test_data,test_label)      rval  [(train_set_x, train_set_y), (valid_set_x, valid_set_y),              (test_set_x, test_set_y)]      return rval  二、CNN的基本“构件”LogisticRegression、HiddenLayer、LeNetConvPoolLayer卷积神经网络CNN的基本结构就是输入层、卷积层conv、子采样层pooling、全连接层、输出层分类器。  卷积层子采样层一般都会有若干个本程序实现的CNN模型参考LeNet5有两个“卷积子采样层”LeNetConvPoolLayer。全连接层相当于MLP多层感知机中的隐含层HiddenLayer。输出层即分类器一般采用softmax回归也有人直接叫逻辑回归其实就是多类别的logistics regression本程序也直接用LogisticRegression表示。总结起来要组建CNN模型必须先定义LeNetConvPoolLayer、HiddenLayer、LogisticRegression这三种layer这一点在我上一篇文章介绍CNN算法时讲得很详细包括代码注解因为太冗长这里给出链接《DeepLearning tutorial4CNN卷积神经网络原理简介代码详解》。代码太长就不贴具体的了只给出框架具体可以下载我的代码看看[python] view plain copy#分类器即CNN最后一层采用逻辑回归softmax  class LogisticRegression(object):      def __init__(self, input, n_in, n_out):          self.W  ....          self.b  ....          self.p_y_given_x  ...          self.y_pred  ...          self.params  ...      def negative_log_likelihood(self, y):      def errors(self, y):    #全连接层分类器前一层  class HiddenLayer(object):      def __init__(self, rng, input, n_in, n_out, WNone, bNone,activationT.tanh):          self.input  input          self.W  ...          self.b  ...          lin_output  ...          self.params  [self.W, self.b]    #卷积采样层convmaxpooling  class LeNetConvPoolLayer(object):      def __init__(self, rng, input, filter_shape, image_shape, poolsize(2, 2)):          self.input  input          self.W  ...          self.b  ...          # 卷积          conv_out  ...          # 子采样          pooled_out ...          self.output  ...          self.params  [self.W, self.b]  三、组建CNN模型设置优化算法应用于Olivetti Faces进行人脸识别上面定义好了CNN的几个基本“构件”现在我们使用这些构件来组建CNN模型本程序的CNN模型参考LeNet5具体为inputlayer0(LeNetConvPoolLayer)layer1(LeNetConvPoolLayer)layer2(HiddenLayer)layer3(LogisticRegression)这是一个串联结构代码也很好写直接用第二部分定义好的各种layer去组建就行了上一layer的输出接下一layer的输入具体可以看看代码evaluate_olivettifaces函数中的“建立CNN模型”部分。CNN模型组建好了就剩下用优化算法求解了优化算法采用批量随机梯度下降算法MSGD所以要先定义MSGD的一些要素主要包括代价函数训练、验证、测试model、参数更新规则即梯度下降。这部分的代码在evaluate_olivettifaces函数中的“定义优化算法的一些基本要素”部分。优化算法的基本要素也定义好了接下来就要运用人脸图像数据集来训练这个模型了训练过程有训练步数n_epoch的设置每个epoch会遍历所有的训练数据training_set本程序中也就是320个人脸图。还有迭代次数iter一次迭代遍历一个batch里的所有样本具体为多少要看所设置的batch_size。关于参数的设定我在下面会讨论。这一部分的代码在evaluate_olivettifaces函数中的“训练CNN阶段”部分。代码很长只贴框架具体可以下载我的代码看看[python] view plain copydef evaluate_olivettifaces(learning_rate0.05, n_epochs200,                      datasetolivettifaces.gif,                      nkerns[5, 10], batch_size40):           #随机数生成器用于初始化参数....      #加载数据.....      #计算各数据集的batch个数....      #定义几个变量x代表人脸数据作为layer0的输入......        ######################      #建立CNN模型:      #inputlayer0(LeNetConvPoolLayer)layer1(LeNetConvPoolLayer)layer2(HiddenLayer)layer3(LogisticRegression)      ######################      ...      ....      ......        #########################      # 定义优化算法的一些基本要素代价函数训练、验证、测试model、参数更新规则即梯度下降      #########################      ...      ....      ......        #########################      # 训练CNN阶段寻找最优的参数。      ########################      ...      .....      .......  另外值得一提的是在训练CNN阶段我们必须定时地保存模型的参数这是在训练机器学习算法时一个经常会做的事情这一部分的详细介绍我之前写过一篇文章《DeepLearning tutorial2机器学习算法在训练过程中保存参数》。简单来说我们要保存CNN模型中layer0、layer1、layer2、layer3的参数所以在“训练CNN阶段”这部分下面有一句代码[python] view plain copysave_params(layer0.params,layer1.params,layer2.params,layer3.params)  这个函数具体定义为[python] view plain copy#保存训练参数的函数  def save_params(param1,param2,param3,param4):            import cPickle            write_file  open(params.pkl, wb)             cPickle.dump(param1, write_file, -1)          cPickle.dump(param2, write_file, -1)          cPickle.dump(param3, write_file, -1)          cPickle.dump(param4, write_file, -1)          write_file.close()    如果在其他算法中你要保存的参数有五个六个甚至更多那么改一下这个函数的参数就行啦。四、训练结果以及参数设置的讨论ok上面基本介绍完了CNN模型的构建以及模型的训练我将它们的代码都放在train_CNN_olivettifaces.py这个源文件中将Olivetti Faces这张图片跟这个代码文件放在同个目录下运行这个文件几分钟就可以训练完模型并且在同个目录下得到一个params.pkl文件这个文件保存的就是最后的模型的参数方便你以后直接使用这个模型。好了现在讨论一下怎么设置参数具体来说程序中可以设置的参数包括学习速率learning_rate、batch_size、n_epochs、nkerns、poolsize。下面逐一讨论调节它们时对模型的影响。调节learning_rate学习速率learning_rate就是运用SGD算法时梯度前面的系数非常重要设得太大的话算法可能永远都优化不了设得太小会使算法优化得太慢而且可能还会掉入局部最优。可以形象地将learning_rate比喻成走路时步子的大小想象一下要从一个U形的山谷的一边走到山谷最低点如果步子特别大像巨人那么大那会直接从一边跨到另一边然后又跨回这边如此往复。如果太小了可能你走着走着就掉入了某些小坑因为山路总是凹凸不平的局部最优掉入这些小坑后如果步子还是不变就永远走不出那个坑。好回到本文的模型下面是我使用时的记录固定其他参数调节learning_rate1kerns[20, 50], batch_size40poolsize22learning_rate0.1时validation-error一直是97.5%没降下来分析了一下觉得应该是学习速率太大跳过了最优。2nkerns[20, 50], batch_size40poolsize22learning_rate0.01时训练到epoch 60多时validation-error降到5%test-error降到15%3nkerns[20, 50], batch_size40poolsize22learning_rate0.05时训练到epoch 36时validation-error降到2.5%test-error降到5%注意验证集和测试集都只有40张图片也就是说只有一两张识别错了还是不错的数据集再大点误差率可以降到更小。最后我将learning_rate设置为0.05。PS学习速率应该自适应地减小是有专门的一些算法的本程序没有实现这个功能有时间再研究一下。调节batch_size因为我们采用minibatch SGD算法来优化所以是一个batch一个batch地将数据输入CNN模型中然后计算这个batch的所有样本的平均损失即代价函数是所有样本的平均。而batch_size就是一个batch的所包含的样本数显然batch_size将影响到模型的优化程度和速度。回到本文的模型首先因为我们train_dataset是320valid_dataset和test_dataset都是40所以batch_size最好都是40的因子也就是能让40整除比如40、20、10、5、2、1否则会浪费一些样本比如设置为30则320/3010余数时20这20个样本是没被利用的。并且如果batch_size设置为30则得出的validation-error和test-error只是30个样本的错误率并不是全部40个样本的错误率。这是设置batch_size要注意的。特别是样本比较少的时候。下面是我实验时的记录固定其他参数改变batch_size:batch_size1、2、5、10、20时validation-error一直是97.5%没降下来。我觉得可能是样本类别覆盖率过小因为我们的数据是按类别排的每个类别10个样本是连续排在一起的batch_size等于20时其实只包含了两个类别这样优化会很慢。因此最后我将batch_size设为40也就是valid_dataset和test_dataset的大小了没办法原始数据集样本太少了。一般我们都不会让batch_size达到valid_dataset和test_dataset的大小的。关于n_epochsn_epochs也就是最大的训练步数比如设为200那训练过程最多遍历你的数据集200遍当遍历了200遍你的dataset时程序会停止。n_epochs就相当于一个停止程序的控制参数并不会影响CNN模型的优化程度和速度只是一个控制程序结束的参数。nkerns[20, 50]20表示第一个卷积层的卷积核的个数50表示第二个卷积层的卷积核的个数。这个我也是瞎调的暂时没什么经验可以总结。不过从理论上来说卷积核的个数其实就代表了特征的个数你提取的特征越多可能最后分类就越准。但是特征太多卷积核太多会增加参数的规模加大了计算复杂度而且有时候卷积核也不是越多越好应根据具体的应用对象来确定。所以我觉得CNN虽号称自动提取特征免去复杂的特征工程但是很多参数比如这里的nkerns还是需要去调节的还是需要一些“人工”的。下面是我的实验记录固定batch_size40learning_rate0.05poolsize221nkerns[20, 50]时训练到epoch 36时validation-error降到2.5%test-error降到5%2nkerns[10, 30]时训练到epoch 46时validation-error降到5%test-error降到5%3nkerns[5, 10]时训练到epoch 38时validation-error降到5%test-error降到7.5%poolsize(2, 2)poolzize在本程序中是设置为(2,2)即从一个2*2的区域里maxpooling出1个像素说白了就算4和像素保留成1个像素。本例程中人脸图像大小是57*47对这种小图像来说(2,2)时比较合理的。如果你用的图像比较大可以把poolsize设的大一点。分割线上面部分介绍完了CNN模型构建以及模型训练的过程代码都在train_CNN_olivettifaces.py里面训练完可以得到一个params.pkl文件这个文件保存的就是最后的模型的参数方便你以后直接使用这个模型。以后只需利用这些保存下来的参数来初始化CNN模型就得到一个可以使用的CNN系统将人脸图输入这个CNN系统预测人脸图的类别。接下来就介绍怎么使用训练好的参数的方法这部分的代码放在use_CNN_olivettifaces.py文件中。五、利用训练好的参数初始化模型在train_CNN_olivettifaces.py中的LeNetConvPoolLayer、HiddenLayer、LogisticRegression是用随机数生成器去随机初始化的我们将它们定义为可以用参数来初始化的版本其实很简单代码只需要做稍微的改动只需要在LogisticRegression、HiddenLayer、LeNetConvPoolLayer这三个class的__init__()函数中加两个参数params_W,params_b然后将params_W,params_b赋值给这三个class里的W和b[python] view plain copyself.W  params_W  self.b  params_b  params_W,params_b就是从params.pkl文件中读取来的读取的函数[python] view plain copy#读取之前保存的训练参数  #layer0_params~layer3_params都是包含W和b的,layer*_params[0]是Wlayer*_params[1]是b  def load_params(params_file):      fopen(params_file,rb)      layer0_paramscPickle.load(f)      layer1_paramscPickle.load(f)      layer2_paramscPickle.load(f)      layer3_paramscPickle.load(f)      f.close()      return layer0_params,layer1_params,layer2_params,layer3_params  ok可以用参数初始化的CNN定义好了那现在就将需要测试的人脸图输入该CNN测试其类别。同样的需要写一个读图像的函数load_data()代码就不贴了。将图像数据输入CNN的输出便是该图像的类别这一部分的代码在use_CNN()函数中代码很容易看懂。这一部分还涉及到theano.function的使用我把一些笔记记在了use_CNN_olivettifaces.py代码的最后因为跟代码相关结合代码来看会比较好所以下面就不讲这部分有兴趣的看看代码。最后说说测试的结果我仍然以整副olivettifaces.gif作为输入得出其类别后跟真正的label对比程序输出被错分的那些图像运行结果如下错了五张我标了三张六、一些需要说明的首先是本文的严谨性在文章开头我就说这只是一个toy implement400张图片根本不适合用DL来做。当然我写这篇文章只是为了总结一下这个实现流程这一点希望对读者也有参考意义。最后我的代码都放在这里github地址可以下载
http://www.pierceye.com/news/40426/

相关文章:

  • 桐乡住房和城乡规划建设局网站南京网站制作希丁哥
  • 中国免费网站服务器主机域名西安制作标书的公司
  • 在线生成手机网站17做网店网站
  • 外贸网站建设要求如何做品牌网站
  • 网站建设盈利WordPress工具站点
  • 天津网站优化公司价格doc文件打开乱码怎么办
  • 网站建设与管理名词解释网页制作颜色的代码大全
  • 镇江网站建设找思创网络怎么可以自己做网站被百度收到
  • 二次元网站模板迪庆企业网站建设
  • 网站404页面优化做一个官网要多少钱
  • 企业建设门户网站的需求如何在自己的网站上做友情链接
  • 网站群系统单页面网站推广方法
  • 网站建设---部署与发布文化体育局网站建设
  • 站长工具权重查询如何申请企业邮箱
  • 国外做鞋子的网站商务信息网站怎么做
  • 无线网站制作wordpress qq悬浮窗
  • 凡科网站建设套餐报价不属于企业网站建设基本标准
  • 河池网站建设公司wordpress 插件 破解版
  • 开发网站实时监控做装修网站卖钱
  • 洛阳便宜网站建设价格网站建设有没有
  • 海南做网站电话设计院门户网站建设方案
  • wordpress分权限浏览网站seo优化管理系统
  • 开网站建设公司好线上商城推广
  • windows 2008 搭建网站企业英语网站
  • 怎么在网站做谷歌广告专业网络推广外包
  • 中卫网站建设公司南阳注册公司多少钱
  • pdf怎么做电子书下载网站seo产品是什么意思
  • 做最精彩的绳艺网站登陆网站取消备案
  • 男女激烈做羞羞事网站网站韩剧大气wordpress主题
  • 网站做端口是什么情况佛山建站佛山网页设计