Convolution Neural Network (CNN) 原理与实现

本文结合Deep learning的一个应用,Convolution Neural Network 进行一些基本应用,参考Lecun的Document 0.1进行部分拓展,与结果展示(in Python)。

分为以下几部分:

1. Convolution(卷积)

2. Pooling(降采样过程)

3. CNN结构

4.  跑实验

下面分别介绍。


PS:本篇blog为ese机器学习短期班参考资料(20140516课程),本文只是简要讲最naive最simple的思想,重在实践部分,原理课上详述。


1. Convolution(卷积)

类似于高斯卷积,对imagebatch中的所有image进行卷积。对于一张图,其所有feature map用一个filter卷成一张feature map。 如下面的代码,对一个imagebatch(含两张图)进行操作,每个图初始有3张feature map(R,G,B), 用两个9*9的filter进行卷积,结果是,每张图得到两个feature map。

卷积操作由theano的conv.conv2d实现,这里我们用随机参数W,b。结果有点像edge detector是不是?

Code: (详见注释)


[python]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. # -*- coding: utf-8 -*-  
  2. """ 
  3. Created on Sat May 10 18:55:26 2014 
  4.  
  5. @author: rachel 
  6.  
  7. Function: convolution option of two pictures with same size (width,height) 
  8. input: 3 feature maps (3 channels <RGB> of a picture) 
  9. convolution: two 9*9 convolutional filters 
  10. """  
  11.   
  12. from theano.tensor.nnet import conv  
  13. import theano.tensor as T  
  14. import numpy, theano  
  15.   
  16.   
  17. rng = numpy.random.RandomState(23455)  
  18.   
  19. # symbol variable  
  20. input = T.tensor4(name = 'input')  
  21.   
  22. # initial weights  
  23. w_shape = (2,3,9,9#2 convolutional filters, 3 channels, filter shape: 9*9  
  24. w_bound = numpy.sqrt(3*9*9)  
  25. W = theano.shared(numpy.asarray(rng.uniform(low = -1.0/w_bound, high = 1.0/w_bound,size = w_shape),  
  26.                                 dtype = input.dtype),name = 'W')  
  27.   
  28. b_shape = (2,)  
  29. b = theano.shared(numpy.asarray(rng.uniform(low = -.5, high = .5, size = b_shape),  
  30.                                 dtype = input.dtype),name = 'b')  
  31.                                   
  32. conv_out = conv.conv2d(input,W)  
  33.   
  34. #T.TensorVariable.dimshuffle() can reshape or broadcast (add dimension)  
  35. #dimshuffle(self,*pattern)  
  36. # >>>b1 = b.dimshuffle('x',0,'x','x')  
  37. # >>>b1.shape.eval()  
  38. # array([1,2,1,1])  
  39. output = T.nnet.sigmoid(conv_out + b.dimshuffle('x',0,'x','x'))  
  40. f = theano.function([input],output)  
  41.   
  42.   
  43.   
  44.   
  45.   
  46. # demo  
  47. import pylab  
  48. from PIL import Image  
  49. #minibatch_img = T.tensor4(name = 'minibatch_img')  
  50.   
  51. #-------------img1---------------  
  52. img1 = Image.open(open('//home//rachel//Documents//ZJU_Projects//DL//Dataset//rachel.jpg'))  
  53. width1,height1 = img1.size  
  54. img1 = numpy.asarray(img1, dtype = 'float32')/256. # (height, width, 3)  
  55.   
  56. # put image in 4D tensor of shape (1,3,height,width)  
  57. img1_rgb = img1.swapaxes(0,2).swapaxes(1,2).reshape(1,3,height1,width1) #(3,height,width)  
  58.   
  59.   
  60. #-------------img2---------------  
  61. img2 = Image.open(open('//home//rachel//Documents//ZJU_Projects//DL//Dataset//rachel1.jpg'))  
  62. width2,height2 = img2.size  
  63. img2 = numpy.asarray(img2,dtype = 'float32')/256.  
  64. img2_rgb = img2.swapaxes(0,2).swapaxes(1,2).reshape(1,3,height2,width2) #(3,height,width)  
  65.   
  66.   
  67.   
  68. #minibatch_img = T.join(0,img1_rgb,img2_rgb)  
  69. minibatch_img = numpy.concatenate((img1_rgb,img2_rgb),axis = 0)  
  70. filtered_img = f(minibatch_img)  
  71.   
  72.   
  73. # plot original image and two convoluted results  
  74. pylab.subplot(2,3,1);pylab.axis('off');  
  75. pylab.imshow(img1)  
  76.   
  77. pylab.subplot(2,3,4);pylab.axis('off');  
  78. pylab.imshow(img2)  
  79.   
  80. pylab.gray()  
  81. pylab.subplot(2,3,2); pylab.axis("off")  
  82. pylab.imshow(filtered_img[0,0,:,:]) #0:minibatch_index; 0:1-st filter  
  83.   
  84. pylab.subplot(2,3,3); pylab.axis("off")  
  85. pylab.imshow(filtered_img[0,1,:,:]) #0:minibatch_index; 1:1-st filter  
  86.   
  87. pylab.subplot(2,3,5); pylab.axis("off")  
  88. pylab.imshow(filtered_img[1,0,:,:]) #0:minibatch_index; 0:1-st filter  
  89.   
  90. pylab.subplot(2,3,6); pylab.axis("off")  
  91. pylab.imshow(filtered_img[1,1,:,:]) #0:minibatch_index; 1:1-st filter  
  92. pylab.show()  






2. Pooling(降采样过程)


最常用的Maxpooling. 解决了两个问题:

1. 减少计算量

2. 旋转不变性 (原因自己悟)

     PS:对于旋转不变性,回忆下SIFT,LBP:采用主方向;HOG:选择不同方向的模版

Maxpooling的降采样过程会将feature map的长宽各减半。(下面结果图中没有体现出来,python自动给拉到一样大了,但实际上像素数是减半的)


Code: (详见注释)


[python]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. # -*- coding: utf-8 -*-  
  2. """ 
  3. Created on Sat May 10 18:55:26 2014 
  4.  
  5. @author: rachel 
  6.  
  7. Function: convolution option  
  8. input: 3 feature maps (3 channels <RGB> of a picture) 
  9. convolution: two 9*9 convolutional filters 
  10. """  
  11.   
  12. from theano.tensor.nnet import conv  
  13. import theano.tensor as T  
  14. import numpy, theano  
  15.   
  16.   
  17. rng = numpy.random.RandomState(23455)  
  18.   
  19. # symbol variable  
  20. input = T.tensor4(name = 'input')  
  21.   
  22. # initial weights  
  23. w_shape = (2,3,9,9#2 convolutional filters, 3 channels, filter shape: 9*9  
  24. w_bound = numpy.sqrt(3*9*9)  
  25. W = theano.shared(numpy.asarray(rng.uniform(low = -1.0/w_bound, high = 1.0/w_bound,size = w_shape),  
  26.                                 dtype = input.dtype),name = 'W')  
  27.   
  28. b_shape = (2,)  
  29. b = theano.shared(numpy.asarray(rng.uniform(low = -.5, high = .5, size = b_shape),  
  30.                                 dtype = input.dtype),name = 'b')  
  31.                                   
  32. conv_out = conv.conv2d(input,W)  
  33.   
  34. #T.TensorVariable.dimshuffle() can reshape or broadcast (add dimension)  
  35. #dimshuffle(self,*pattern)  
  36. # >>>b1 = b.dimshuffle('x',0,'x','x')  
  37. # >>>b1.shape.eval()  
  38. # array([1,2,1,1])  
  39. output = T.nnet.sigmoid(conv_out + b.dimshuffle('x',0,'x','x'))  
  40. f = theano.function([input],output)  
  41.   
  42.   
  43.   
  44.   
  45.   
  46. # demo  
  47. import pylab  
  48. from PIL import Image  
  49. from matplotlib.pyplot import *  
  50.   
  51. #open random image  
  52. img = Image.open(open('//home//rachel//Documents//ZJU_Projects//DL//Dataset//rachel.jpg'))  
  53. width,height = img.size  
  54. img = numpy.asarray(img, dtype = 'float32')/256. # (height, width, 3)  
  55.   
  56.   
  57. # put image in 4D tensor of shape (1,3,height,width)  
  58. img_rgb = img.swapaxes(0,2).swapaxes(1,2#(3,height,width)  
  59. minibatch_img = img_rgb.reshape(1,3,height,width)  
  60. filtered_img = f(minibatch_img)  
  61.   
  62.   
  63. # plot original image and two convoluted results  
  64. pylab.figure(1)  
  65. pylab.subplot(1,3,1);pylab.axis('off');  
  66. pylab.imshow(img)  
  67. title('origin image')  
  68.   
  69. pylab.gray()  
  70. pylab.subplot(2,3,2); pylab.axis("off")  
  71. pylab.imshow(filtered_img[0,0,:,:]) #0:minibatch_index; 0:1-st filter  
  72. title('convolution 1')  
  73.   
  74. pylab.subplot(2,3,3); pylab.axis("off")  
  75. pylab.imshow(filtered_img[0,1,:,:]) #0:minibatch_index; 1:1-st filter  
  76. title('convolution 2')  
  77.   
  78. #pylab.show()  
  79.   
  80.   
  81.   
  82.   
  83. # maxpooling  
  84. from theano.tensor.signal import downsample  
  85.   
  86. input = T.tensor4('input')  
  87. maxpool_shape = (2,2)  
  88. pooled_img = downsample.max_pool_2d(input,maxpool_shape,ignore_border = False)  
  89.   
  90. maxpool = theano.function(inputs = [input],  
  91.                           outputs = [pooled_img])  
  92.   
  93. pooled_res = numpy.squeeze(maxpool(filtered_img))                
  94. #pylab.figure(2)  
  95. pylab.subplot(235);pylab.axis('off');  
  96. pylab.imshow(pooled_res[0,:,:])  
  97. title('down sampled 1')  
  98.   
  99. pylab.subplot(236);pylab.axis('off');  
  100. pylab.imshow(pooled_res[1,:,:])  
  101. title('down sampled 2')  
  102.   
  103. pylab.show()  





3. CNN结构

想必大家随便google下CNN的图都滥大街了,这里拖出来那时候学CNN的时候一张图,自认为陪上讲解的话画得还易懂(<!--囧-->)

废话不多说了,直接上Lenet结构图:(从下往上顺着箭头看,最下面为底层original input)





4. CNN代码


资源里下载吧,我放上去了喔~(in python)

这里贴少部分代码,仅表示建模的NN:

[python]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. rng = numpy.random.RandomState(23455)  
  2.   
  3.     # transfrom x from (batchsize, 28*28) to (batchsize,feature,28,28))  
  4.     # I_shape = (28,28),F_shape = (5,5),  
  5.     N_filters_0 = 20  
  6.     D_features_0= 1  
  7.     layer0_input = x.reshape((batch_size,D_features_0,28,28))  
  8.     layer0 = LeNetConvPoolLayer(rng, input = layer0_input, filter_shape = (N_filters_0,D_features_0,5,5),  
  9.                                 image_shape = (batch_size,1,28,28))  
  10.     #layer0.output: (batch_size, N_filters_0, (28-5+1)/2, (28-5+1)/2) -> 20*20*12*12  
  11.       
  12.     N_filters_1 = 50  
  13.     D_features_1 = N_filters_0  
  14.     layer1 = LeNetConvPoolLayer(rng,input = layer0.output, filter_shape = (N_filters_1,D_features_1,5,5),  
  15.                                 image_shape = (batch_size,N_filters_0,12,12))  
  16.     # layer1.output: (20,50,4,4)  
  17.       
  18.     layer2_input = layer1.output.flatten(2# (20,50,4,4)->(20,(50*4*4))  
  19.     layer2 = HiddenLayer(rng,layer2_input,n_in = 50*4*4,n_out = 500, activation = T.tanh)  
  20.       
  21.     layer3 = LogisticRegression(input = layer2.output, n_in = 500, n_out = 10)  

layer0, layer1 :分别是卷积+降采样

layer2+layer3:组成一个MLP(ANN)

训练模型:

[python]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. cost = layer3.negative_log_likelihood(y)  
  2. params = layer3.params + layer2.params + layer1.params + layer0.params  
  3. gparams = T.grad(cost,params)  
  4.   
  5. updates = []  
  6. for par,gpar in zip(params,gparams):  
  7.     updates.append((par, par - learning_rate * gpar))  
  8.   
  9. train_model = theano.function(inputs = [minibatch_index],  
  10.                               outputs = [cost],  
  11.                               updates = updates,  
  12.                               givens = {x: train_set_x[minibatch_index * batch_size : (minibatch_index+1) * batch_size],  
  13.                                         y: train_set_y[minibatch_index * batch_size : (minibatch_index+1) * batch_size]})  


根据cost(最上层MLP的输出NLL),对所有层的parameters进行训练

剩下的具体见代码和注释。

PS:数据为MNIST所有数据






final result:

Optimization complete. Best validation score of 0.990000 % obtained at iteration 122500, with test performance 0.950000 %

原文链接:http://blog.csdn.net/abcjennifer/article/details/25912675

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
mdCNN is a Matlab framework for Convolutional Neural Network (CNN) supporting 1D, 2D and 3D kernels. Network is Multidimensional, kernels are in 3D and convolution is done in 3D. It is suitable for volumetric input such as CT / MRI / video sections. But can also process 1d/2d images. Framework supports all the major features such as dropout, padding, stride, max pooling, L2 regularization, momentum, cross entropy, MSE. The framework Its completely written in Matlab, No dependencies are needed. It is pretty optimized, when training or testing all of the CPU cores are participating using Matlab Built-in Multi-threading. There are several examples for training a network on MNIST, CIFAR10, 1D CNN, and MNIST3d - a special expansion of MNIST dataset to 3D volumes. MNIST Demo will download the dataset and start the training process. It will reach 99.2% in several minutes. CIFAR10 demo reaches about 80% but it takes longer to converge. For 3D volumes there is a demo file that will creates a 3d volume from each digit in MNIST dataset, then starts training on the 28x28x28 samples. It will reach similar accuracy as in the 2d demo This framework was used in a project classifying Vertebra in a 3D CT images. =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ To run MNIST demo: Go into the folder 'Demo/MNIST' , Run 'demoMnist.m' file. After 15 iterations it will open a GUI where you can test the network performance. In addition layer 1 filters will be shown. To run MNIST3D demo: Go into the folder 'Demo/MNIST3d' , and run 'demoMnist3D.m' file. =~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~ Check the 'mdCNN documentation.docx' file for more specification on how to configure a network For general questions regarding network design and training, please use this forum https://groups.google.com/forum/#!forum/mdcnn-multidimensional-cnn-library-in-matlab Any other issues you can contact me at hagaygarty@gmail.com Please use matlab 2014 and above

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值