CNN卷积神经网络基础学习知识原理.doc

上传人:小** 文档编号:2538569 上传时间:2020-04-19 格式:DOC 页数:35 大小:244.39KB
返回 下载 相关 举报
CNN卷积神经网络基础学习知识原理.doc_第1页
第1页 / 共35页
CNN卷积神经网络基础学习知识原理.doc_第2页
第2页 / 共35页
点击查看更多>>
资源描述

《CNN卷积神经网络基础学习知识原理.doc》由会员分享,可在线阅读,更多相关《CNN卷积神经网络基础学习知识原理.doc(35页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、,.一、CNN卷积神经网络原理简介http:/ Learning(深度学习)学习笔记整理系列之(七),以及UFLDL上的卷积特征提取、池化CNN的最大特点就是稀疏连接(局部感受)和权值共享,如下面两图所示,左为稀疏连接,右为权值共享。稀疏连接和权值共享可以减少所要训练的参数,减少计算复杂度。 至于CNN的结构,以经典的LeNet5来说明:这个图真是无处不在,一谈CNN,必说LeNet5,这图来自于这篇论文:Gradient-Based Learning Applied to Document Recognition,论文很长,第7页那里开始讲LeNet5这个结构,建议看看那部分。我这里简单说一

2、下,LeNet5这张图从左到右,先是input,这是输入层,即输入的图片。input-layer到C1这部分就是一个卷积层(convolution运算),C1到S2是一个子采样层(pooling运算),关于卷积和子采样的具体过程可以参考下图:然后,S2到C3又是卷积,C3到S4又是子采样,可以发现,卷积和子采样都是成对出现的,卷积后面一般跟着子采样。S4到C5之间是全连接的,这就相当于一个MLP的隐含层了(如果你不清楚MLP,参考DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解)。C5到F6同样是全连接,也是相当于一个MLP的隐含层。最后从F6到输出outpu

3、t,其实就是一个分类器,这一层就叫分类层。ok,CNN的基本结构大概就是这样,由输入、卷积层、子采样层、全连接层、分类层、输出这些基本“构件”组成,一般根据具体的应用或者问题,去确定要多少卷积层和子采样层、采用什么分类器。当确定好了结构以后,如何求解层与层之间的连接参数?一般采用向前传播(FP)+向后传播(BP)的方法来训练。具体可参考上面给出的链接。二、CNN卷积神经网络代码详细解读(基于python+theano)代码来自于深度学习教程:Convolutional Neural Networks (LeNet),这个代码实现的是一个简化了的LeNet5,具体如下: 没有实现location

4、-specific gain and bias parameters 用的是maxpooling,而不是average_pooling 分类器用的是softmax,LeNet5用的是rbf LeNet5第二层并不是全连接的,本程序实现的是全连接另外,代码里将卷积层和子采用层合在一起,定义为“LeNetConvPoolLayer“(卷积采样层),这好理解,因为它们总是成对出现。但是有个地方需要注意,代码中将卷积后的输出直接作为子采样层的输入,而没有加偏置b再通过sigmoid函数进行映射,即没有了下图中fx后面的bx以及sigmoid映射,也即直接由fx得到Cx。最后,代码中第一个卷积层用的卷积

5、核有20个,第二个卷积层用50个,而不是上面那张LeNet5图中所示的6个和16个。了解了这些,下面看代码:(1)导入必要的模块pythonview plaincopy1. importcPickle2. importgzip3. importos4. importsys5. importtime6. 7. importnumpy8. 9. importtheano10. importtheano.tensorasT11. fromtheano.tensor.signalimportdownsample12. fromtheano.tensor.nnetimportconv(2)定义CNN的基

6、本构件CNN的基本构件包括卷积采样层、隐含层、分类器,如下 定义LeNetConvPoolLayer(卷积+采样层)见代码注释:pythonview plaincopy1. 2. 卷积+下采样合成一个层LeNetConvPoolLayer3. rng:随机数生成器,用于初始化W4. input:4维的向量,theano.tensor.dtensor45. filter_shape:(numberoffilters,numinputfeaturemaps,filterheight,filterwidth)6. image_shape:(batchsize,numinputfeaturemaps,

7、imageheight,imagewidth)7. poolsize:(#rows,#cols)8. 9. classLeNetConvPoolLayer(object):10. def_init_(self,rng,input,filter_shape,image_shape,poolsize=(2,2):11. 12. #assertcondition,condition为True,则继续往下执行,condition为False,中断程序13. #image_shape1和filter_shape1都是numinputfeaturemaps,它们必须是一样的。14. assertimage

8、_shape1=filter_shape115. self.input=input16. 17. #每个隐层神经元(即像素)与上一层的连接数为numinputfeaturemaps*filterheight*filterwidth。18. #可以用numpy.prod(filter_shape1:)来求得19. fan_in=numpy.prod(filter_shape1:)20. 21. #lowerlayer上每个神经元获得的梯度来自于:numoutputfeaturemaps*filterheight*filterwidth/poolingsize22. fan_out=(filter

9、_shape0*numpy.prod(filter_shape2:)/23. numpy.prod(poolsize)24. 25. #以上求得fan_in、fan_out,将它们代入公式,以此来随机初始化W,W就是线性卷积核26. W_bound=numpy.sqrt(6./(fan_in+fan_out)27. self.W=theano.shared(28. numpy.asarray(29. rng.uniform(low=-W_bound,high=W_bound,size=filter_shape),30. dtype=theano.config.floatX31. ),32. b

10、orrow=True33. )34. 35. #thebiasisa1Dtensor-onebiasperoutputfeaturemap36. #偏置b是一维向量,每个输出图的特征图都对应一个偏置,37. #而输出的特征图的个数由filter个数决定,因此用filter_shape0即numberoffilters来初始化38. b_values=numpy.zeros(filter_shape0,),dtype=theano.config.floatX)39. self.b=theano.shared(value=b_values,borrow=True)40. 41. #将输入图像与fi

11、lter卷积,conv.conv2d函数42. #卷积完没有加b再通过sigmoid,这里是一处简化。43. conv_out=conv.conv2d(44. input=input,45. filters=self.W,46. filter_shape=filter_shape,47. image_shape=image_shape48. )49. 50. #maxpooling,最大子采样过程51. pooled_out=downsample.max_pool_2d(52. input=conv_out,53. ds=poolsize,54. ignore_border=True55. )

12、56. 57. #加偏置,再通过tanh映射,得到卷积+子采样层的最终输出58. #因为b是一维向量,这里用维度转换函数dimshuffle将其reshape。比如b是(10,),59. #则b.dimshuffle(x,0,x,x)将其reshape为(1,10,1,1)60. self.output=T.tanh(pooled_out+self.b.dimshuffle(x,0,x,x)61. #卷积+采样层的参数62. self.params=self.W,self.b 定义隐含层HiddenLayer这个跟上一篇文章DeepLearning tutorial(3)MLP多层感知机原理简

13、介+代码详解中的HiddenLayer是一致的,直接拿过来:pythonview plaincopy1. 2. 注释:3. 这是定义隐藏层的类,首先明确:隐藏层的输入即input,输出即隐藏层的神经元个数。输入层与隐藏层是全连接的。4. 假设输入是n_in维的向量(也可以说时n_in个神经元),隐藏层有n_out个神经元,则因为是全连接,5. 一共有n_in*n_out个权重,故W大小时(n_in,n_out),n_in行n_out列,每一列对应隐藏层的每一个神经元的连接权重。6. b是偏置,隐藏层有n_out个神经元,故b时n_out维向量。7. rng即随机数生成器,numpy.rando

14、m.RandomState,用于初始化W。8. input训练模型所用到的所有输入,并不是MLP的输入层,MLP的输入层的神经元个数时n_in,而这里的参数input大小是(n_example,n_in),每一行一个样本,即每一行作为MLP的输入层。9. activation:激活函数,这里定义为函数tanh10. 11. classHiddenLayer(object):12. def_init_(self,rng,input,n_in,n_out,W=None,b=None,13. activation=T.tanh):14. self.input=input#类HiddenLayer的i

15、nput即所传递进来的input15. 16. 17. 注释:18. 代码要兼容GPU,则必须使用dtype=theano.config.floatX,并且定义为theano.shared19. 另外,W的初始化有个规则:如果使用tanh函数,则在-sqrt(6./(n_in+n_hidden)到sqrt(6./(n_in+n_hidden)之间均匀20. 抽取数值来初始化W,若时sigmoid函数,则以上再乘4倍。21. 22. #如果W未初始化,则根据上述方法初始化。23. #加入这个判断的原因是:有时候我们可以用训练好的参数来初始化W,见我的上一篇文章。24. ifWisNone:25.

16、 W_values=numpy.asarray(26. rng.uniform(27. low=-numpy.sqrt(6./(n_in+n_out),28. high=numpy.sqrt(6./(n_in+n_out),29. size=(n_in,n_out)30. ),31. dtype=theano.config.floatX32. )33. ifactivation=theano.tensor.nnet.sigmoid:34. W_values*=435. W=theano.shared(value=W_values,name=W,borrow=True)36. 37. ifbis

17、None:38. b_values=numpy.zeros(n_out,),dtype=theano.config.floatX)39. b=theano.shared(value=b_values,name=b,borrow=True)40. 41. #用上面定义的W、b来初始化类HiddenLayer的W、b42. self.W=W43. self.b=b44. 45. #隐含层的输出46. lin_output=T.dot(input,self.W)+self.b47. self.output=(48. lin_outputifactivationisNone49. elseactiva

18、tion(lin_output)50. )51. 52. #隐含层的参数53. self.params=self.W,self.b 定义分类器 (Softmax回归)采用Softmax,这跟DeepLearning tutorial(1)Softmax回归原理简介+代码详解中的LogisticRegression是一样的,直接拿过来:pythonview plaincopy1. 2. 定义分类层LogisticRegression,也即Softmax回归3. 在deeplearningtutorial中,直接将LogisticRegression视为Softmax,4. 而我们所认识的二类别的

19、逻辑回归就是当n_out=2时的LogisticRegression5. 6. #参数说明:7. #input,大小就是(n_example,n_in),其中n_example是一个batch的大小,8. #因为我们训练时用的是MinibatchSGD,因此input这样定义9. #n_in,即上一层(隐含层)的输出10. #n_out,输出的类别数11. classLogisticRegression(object):12. def_init_(self,input,n_in,n_out):13. 14. #W大小是n_in行n_out列,b为n_out维向量。即:每个输出对应W的一列以及b

20、的一个元素。15. self.W=theano.shared(16. value=numpy.zeros(17. (n_in,n_out),18. dtype=theano.config.floatX19. ),20. name=W,21. borrow=True22. )23. 24. self.b=theano.shared(25. value=numpy.zeros(26. (n_out,),27. dtype=theano.config.floatX28. ),29. name=b,30. borrow=True31. )32. 33. #input是(n_example,n_in),

21、W是(n_in,n_out),点乘得到(n_example,n_out),加上偏置b,34. #再作为T.nnet.softmax的输入,得到p_y_given_x35. #故p_y_given_x每一行代表每一个样本被估计为各类别的概率36. #PS:b是n_out维向量,与(n_example,n_out)矩阵相加,内部其实是先复制n_example个b,37. #然后(n_example,n_out)矩阵的每一行都加b38. self.p_y_given_x=T.nnet.softmax(T.dot(input,self.W)+self.b)39. 40. #argmax返回最大值下标,

22、因为本例数据集是MNIST,下标刚好就是类别。axis=1表示按行操作。41. self.y_pred=T.argmax(self.p_y_given_x,axis=1)42. 43. #params,LogisticRegression的参数44. self.params=self.W,self.b到这里,CNN的基本”构件“都有了,下面要用这些”构件“组装成LeNet5(当然,是简化的,上面已经说了),具体来说,就是组装成:LeNet5=input+LeNetConvPoolLayer_1+LeNetConvPoolLayer_2+HiddenLayer+LogisticRegressio

23、n+output。然后将其应用于MNIST数据集,用BP算法去解这个模型,得到最优的参数。(3)加载MNIST数据集(mnist.pkl.gz)pythonview plaincopy1. 2. 加载MNIST数据集load_data()3. 4. defload_data(dataset):5. #dataset是数据集的路径,程序首先检测该路径下有没有MNIST数据集,没有的话就下载MNIST数据集6. #这一部分就不解释了,与softmax回归算法无关。7. data_dir,data_file=os.path.split(dataset)8. ifdata_dir=andnotos.p

24、ath.isfile(dataset):9. #Checkifdatasetisinthedatadirectory.10. new_path=os.path.join(11. os.path.split(_file_)0,12. .,13. data,14. dataset15. )16. ifos.path.isfile(new_path)ordata_file=mnist.pkl.gz:17. dataset=new_path18. 19. if(notos.path.isfile(dataset)anddata_file=mnist.pkl.gz:20. importurllib21.

25、 origin=(22. http:/www.iro.umontreal.ca/lisa/deep/data/mnist/mnist.pkl.gz23. )24. printDownloadingdatafrom%s%origin25. urllib.urlretrieve(origin,dataset)26. 27. print.loadingdata28. #以上是检测并下载数据集mnist.pkl.gz,不是本文重点。下面才是load_data的开始29. 30. #从mnist.pkl.gz里加载train_set,valid_set,test_set,它们都是包括label的31.

26、#主要用到python里的gzip.open()函数,以及cPickle.load()。32. #rb表示以二进制可读的方式打开文件33. f=gzip.open(dataset,rb)34. train_set,valid_set,test_set=cPickle.load(f)35. f.close()36. 37. 38. #将数据设置成sharedvariables,主要时为了GPU加速,只有sharedvariables才能存到GPUmemory中39. #GPU里数据类型只能是float。而data_y是类别,所以最后又转换为int返回40. defshared_dataset(d

27、ata_xy,borrow=True):41. data_x,data_y=data_xy42. shared_x=theano.shared(numpy.asarray(data_x,43. dtype=theano.config.floatX),44. borrow=borrow)45. shared_y=theano.shared(numpy.asarray(data_y,46. dtype=theano.config.floatX),47. borrow=borrow)48. returnshared_x,T.cast(shared_y,int32)49. 50. 51. test_s

28、et_x,test_set_y=shared_dataset(test_set)52. valid_set_x,valid_set_y=shared_dataset(valid_set)53. train_set_x,train_set_y=shared_dataset(train_set)54. 55. rval=(train_set_x,train_set_y),(valid_set_x,valid_set_y),56. (test_set_x,test_set_y)57. returnrval(4)实现LeNet5并测试pythonview plaincopy1. 2. 实现LeNet5

29、3. LeNet5有两个卷积层,第一个卷积层有20个卷积核,第二个卷积层有50个卷积核4. 5. defevaluate_lenet5(learning_rate=0.1,n_epochs=200,6. dataset=mnist.pkl.gz,7. nkerns=20,50,batch_size=500):8. 9. learning_rate:学习速率,随机梯度前的系数。10. n_epochs训练步数,每一步都会遍历所有batch,即所有样本11. batch_size,这里设置为500,即每遍历完500个样本,才计算梯度并更新参数12. nkerns=20,50,每一个LeNetCon

30、vPoolLayer卷积核的个数,第一个LeNetConvPoolLayer有13. 20个卷积核,第二个有50个14. 15. 16. rng=numpy.random.RandomState(23455)17. 18. #加载数据19. datasets=load_data(dataset)20. train_set_x,train_set_y=datasets021. valid_set_x,valid_set_y=datasets122. test_set_x,test_set_y=datasets223. 24. #计算batch的个数25. n_train_batches=trai

31、n_set_x.get_value(borrow=True).shape026. n_valid_batches=valid_set_x.get_value(borrow=True).shape027. n_test_batches=test_set_x.get_value(borrow=True).shape028. n_train_batches/=batch_size29. n_valid_batches/=batch_size30. n_test_batches/=batch_size31. 32. #定义几个变量,index表示batch下标,x表示输入的训练数据,y对应其标签33.

32、 index=T.lscalar()34. x=T.matrix(x)35. y=T.ivector(y)36. 37. #38. #BUILDACTUALMODEL#39. #40. print.buildingthemodel41. 42. 43. #我们加载进来的batch大小的数据是(batch_size,28*28),但是LeNetConvPoolLayer的输入是四维的,所以要reshape44. layer0_input=x.reshape(batch_size,1,28,28)45. 46. #layer0即第一个LeNetConvPoolLayer层47. #输入的单张图片(

33、28,28),经过conv得到(28-5+1,28-5+1)=(24,24),48. #经过maxpooling得到(24/2,24/2)=(12,12)49. #因为每个batch有batch_size张图,第一个LeNetConvPoolLayer层有nkerns0个卷积核,50. #故layer0输出为(batch_size,nkerns0,12,12)51. layer0=LeNetConvPoolLayer(52. rng,53. input=layer0_input,54. image_shape=(batch_size,1,28,28),55. filter_shape=(nke

34、rns0,1,5,5),56. poolsize=(2,2)57. )58. 59. 60. #layer1即第二个LeNetConvPoolLayer层61. #输入是layer0的输出,每张特征图为(12,12),经过conv得到(12-5+1,12-5+1)=(8,8),62. #经过maxpooling得到(8/2,8/2)=(4,4)63. #因为每个batch有batch_size张图(特征图),第二个LeNetConvPoolLayer层有nkerns1个卷积核64. #,故layer1输出为(batch_size,nkerns1,4,4)65. layer1=LeNetConv

35、PoolLayer(66. rng,67. input=layer0.output,68. image_shape=(batch_size,nkerns0,12,12),#输入nkerns0张特征图,即layer0输出nkerns0张特征图69. filter_shape=(nkerns1,nkerns0,5,5),70. poolsize=(2,2)71. )72. 73. 74. #前面定义好了两个LeNetConvPoolLayer(layer0和layer1),layer1后面接layer2,这是一个全连接层,相当于MLP里面的隐含层75. #故可以用MLP中定义的HiddenLaye

36、r来初始化layer2,layer2的输入是二维的(batch_size,num_pixels),76. #故要将上层中同一张图经不同卷积核卷积出来的特征图合并为一维向量,77. #也就是将layer1的输出(batch_size,nkerns1,4,4)flatten为(batch_size,nkerns1*4*4)=(500,800),作为layer2的输入。78. #(500,800)表示有500个样本,每一行代表一个样本。layer2的输出大小是(batch_size,n_out)=(500,500)79. layer2_input=layer1.output.flatten(2)80

37、. layer2=HiddenLayer(81. rng,82. input=layer2_input,83. n_in=nkerns1*4*4,84. n_out=500,85. activation=T.tanh86. )87. 88. #最后一层layer3是分类层,用的是逻辑回归中定义的LogisticRegression,89. #layer3的输入是layer2的输出(500,500),layer3的输出就是(batch_size,n_out)=(500,10)90. layer3=LogisticRegression(input=layer2.output,n_in=500,n_out=10)91. 92. #代价函数NLL93. cost=layer3.negative_l

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁