UFLDL学习笔记7(Working with Large Images)

UFLDL学习笔记7(Working with Large Images)

最近在学习UFLDL Tutorial,这是一套关于无监督学习的教程。在此感觉Andrew Ng做的真的是非常认真。下面把我的代码贴出来,方便大家学习调试。所有代码已经过matlab调试通过。

 

Convolution and Pooling

本章是使用卷积神经网络进行分类。分类的图片有四种:飞机、汽车、猫、狗(如图1)。每幅图像的大小为64*64*3(彩色)。train图片2000幅,test图片3200幅。使用卷积神经网络的准确率为80%左右。这个结果还是相当不错的。

图1

代码编写

一、cnnExercise.m 主函数。包括训练特征,评测结果。

Step 0. 初始化参数。无需编写。

Step 1. 训练Sparse Autoencoder。代码:

 

[plain] view plaincopy
 
  1. % 读取在Linear Decoders with Autoencoders一章中训练好的权值  
  2. load STL10Features  %包含optTheta, ZCAWhite, meanPatch  

Step 2a. 计算卷积后的图像。代码详见cnnConvolve.m,在本文后面有写。

 

Step 2b. 检查cnnConvolve.m。无需编写。

Step 2c. 执行Pool。作用是降维,且对图像偏移等有抑制作用。代码详见cnnPool.m,在本文后面有写。

Step 2d. 检查cnnPool.m。无需编写

Step 3. 对训练集和测试集执行卷积和Pool。无需编写。我的i-7电脑上大概花了半小时左右。算好的特征会写出到硬盘cnnPooledFeatures.mat,以后就可以直接读取并直接用其进行分类了,免得重复计算。

Step 4. 用训练集训练Softmax分类器。无需编写。

Step 5. 用测试集评测结果。无需编写。我的准确率78.56%。由于权值是随机初始化的,结果每次可能会稍有不同。

 

二、cnnConvolve.m 计算卷积后的图像。由于这个自己要写的部分比较散,所以我把整个.m文件都贴上来。UFLDL已经把架子搭好了,只有少部分是需要自己编写的。

 

[plain] view plaincopy
 
  1. function convolvedFeatures = cnnConvolve(patchDim, numFeatures, images, W, b, ZCAWhite, meanPatch)  
  2. %cnnConvolve Returns the convolution of the features given by W and b with  
  3. %the given images  
  4. %  
  5. % Parameters:  
  6. %  patchDim - patch (feature) dimension  
  7. %  numFeatures - number of features  
  8. %  images - large images to convolve with, matrix in the form  
  9. %           images(r, c, channel, image number)  
  10. %  W, b - W, b for features from the sparse autoencoder  
  11. %  ZCAWhite, meanPatch - ZCAWhitening and meanPatch matrices used for  
  12. %                        preprocessing  
  13. %  
  14. % Returns:  
  15. %  convolvedFeatures - matrix of convolved features in the form  
  16. %                      convolvedFeatures(featureNum, imageNum, imageRow, imageCol)  
  17.   
  18. numImages = size(images, 4);  
  19. imageDim = size(images, 1);  
  20. imageChannels = size(images, 3);  
  21.   
  22. convolvedFeatures = zeros(numFeatures, numImages, imageDim - patchDim + 1, imageDim - patchDim + 1);  
  23.   
  24. % Instructions:  
  25. %   Convolve every feature with every large image here to produce the   
  26. %   numFeatures x numImages x (imageDim - patchDim + 1) x (imageDim - patchDim + 1)   
  27. %   matrix convolvedFeatures, such that   
  28. %   convolvedFeatures(featureNum, imageNum, imageRow, imageCol) is the  
  29. %   value of the convolved featureNum feature for the imageNum image over  
  30. %   the region (imageRow, imageCol) to (imageRow + patchDim - 1, imageCol + patchDim - 1)  
  31. %  
  32. % Expected running times:   
  33. %   Convolving with 100 images should take less than 3 minutes   
  34. %   Convolving with 5000 images should take around an hour  
  35. %   (So to save time when testing, you should convolve with less images, as  
  36. %   described earlier)  
  37.   
  38. % -------------------- YOUR CODE HERE --------------------  
  39. % Precompute the matrices that will be used during the convolution. Recall  
  40. % that you need to take into account the whitening and mean subtraction  
  41. % steps  
  42.   
  43. subplot(247)  
  44. imagesc(images(:,:,:,7))  
  45. subplot(248)  
  46. imagesc(images(:,:,:,8))  
  47.   
  48. % 变换,参考UFLDL  
  49. WT = W*ZCAWhite;  
  50.   
  51. % --------------------------------------------------------  
  52.   
  53. convolvedFeatures = zeros(numFeatures, numImages, imageDim - patchDim + 1, imageDim - patchDim + 1);  
  54. for imageNum = 1:numImages  
  55.   for featureNum = 1:numFeatures  
  56.   
  57.     % convolution of image with feature matrix for each channel  
  58.     convolvedImage = zeros(imageDim - patchDim + 1, imageDim - patchDim + 1);  
  59.     for channel = 1:3  
  60.   
  61.       % Obtain the feature (patchDim x patchDim) needed during the convolution  
  62.       % ---- YOUR CODE HERE ----  
  63.       feature = zeros(8,8); % You should replace this  
  64.         
  65.       % 当前featureNum, 当前channel的权值。size:1*64  
  66.       WT_curr = WT(featureNum, (channel-1)*patchDim*patchDim+1:channel*patchDim*patchDim);  
  67.       feature = reshape(WT_curr, patchDim, patchDim);   %size:8*8  
  68.   
  69.       % ------------------------  
  70.   
  71.       % Flip the feature matrix because of the definition of convolution, as explained later  
  72.       feature = flipud(fliplr(squeeze(feature)));  
  73.         
  74.       % Obtain the image  
  75.       im = squeeze(images(:, :, channel, imageNum));    %获取当前imageNum当前channel图像  
  76.   
  77.       % Convolve "feature" with "im", adding the result to convolvedImage  
  78.       % be sure to do a 'valid' convolution  
  79.       % ---- YOUR CODE HERE ----  
  80.   
  81.       tmp = conv2(im,feature);  %计算卷积  
  82.       convolvedImage = convolvedImage + tmp(patchDim:end-patchDim+1, patchDim:end-patchDim+1);  %切除边缘   
  83.         
  84.       % ------------------------  
  85.     end  
  86.       
  87.     % Subtract the bias unit (correcting for the mean subtraction as well)  
  88.     % Then, apply the sigmoid function to get the hidden activation  
  89.     % ---- YOUR CODE HERE ----  
  90.       
  91.     convolvedImage = convolvedImage - WT(featureNum,:)*meanPatch + b(featureNum);   %去除偏置,详见UFLDL  
  92.     convolvedImage = sigmoid(convolvedImage);   %经过sigmoid函数  
  93.       
  94.     % ------------------------  
  95.       
  96.     % The convolved feature is the sum of the convolved values for all channels  
  97.     convolvedFeatures(featureNum, imageNum, :, :) = convolvedImage;  
  98.   end  
  99. end  
  100.   
  101. end  
  102.   
  103. function sigm = sigmoid(x)  
  104.     sigm = 1 ./ (1 + exp(-x));  
  105. end  


三、cnnPool.m 进行Pool操作。卷积后的图像是57*57,教程中用的pool大小是19*19。这部分代码比较容易,代码:

 

 

[plain] view plaincopy
 
  1. row = floor(convolvedDim / poolDim);  
  2. col = floor(convolvedDim / poolDim);  
  3.   
  4. for imageNum = 1:numImages  
  5.     for featureNum = 1:numFeatures  
  6.         for i1 = 1:row  
  7.             for j1 = 1:col  
  8.                 tmpM = convolvedFeatures(featureNum, imageNum, (i1-1)*poolDim+1:i1*poolDim, (j1-1)*poolDim+1:j1*poolDim);  
  9.                 pooledFeatures(featureNum, imageNum, i1, j1) = mean(mean(tmpM));  
  10.             end  
  11.         end  
  12.     end  
  13. end  


四、RecognizeKQQ.m 自己添加的函数。由于cnnExercise.m中输出了cnnPooledFeatures,因此可以直接进行softmax的训练和测试。就不用计算那么久了。这个函数这是为了我自己方便测试用的。只要load一些数据然后把Step 4, Step 5原封不动拷贝过来就行了。代码:

 

 

[plain] view plaincopy
 
  1. close all  
  2.   
  3. load stlTrainSubset.mat % loads numTrainImages, trainImages, trainLabels  
  4. load stlTestSubset.mat  % loads numTestImages,  testImages,  testLabels  
  5. load cnnPooledFeatures  
  6.   
  7. %% STEP 4: Use pooled features for classification  
  8. %  Now, you will use your pooled features to train a softmax classifier,  
  9. %  using softmaxTrain from the softmax exercise.  
  10. %  Training the softmax classifer for 1000 iterations should take less than  
  11. %  10 minutes.  
  12.   
  13. % Add the path to your softmax solution, if necessary  
  14. % addpath /path/to/solution/  
  15.   
  16. % Setup parameters for softmax  
  17. softmaxLambda = 1e-4;  
  18. numClasses = 4;  
  19. % Reshape the pooledFeatures to form an input vector for softmax  
  20. softmaxX = permute(pooledFeaturesTrain, [1 3 4 2]);  
  21. softmaxX = reshape(softmaxX, numel(pooledFeaturesTrain) / numTrainImages,...  
  22.     numTrainImages);  
  23. softmaxY = trainLabels;  
  24.   
  25. options = struct;  
  26. options.maxIter = 200;  
  27. softmaxModel = softmaxTrain(numel(pooledFeaturesTrain) / numTrainImages,...  
  28.     numClasses, softmaxLambda, softmaxX, softmaxY, options);  
  29.   
  30. %%======================================================================  
  31. %% STEP 5: Test classifer  
  32. %  Now you will test your trained classifer against the test images  
  33.   
  34. softmaxX = permute(pooledFeaturesTest, [1 3 4 2]);  
  35. softmaxX = reshape(softmaxX, numel(pooledFeaturesTest) / numTestImages, numTestImages);  
  36. softmaxY = testLabels;  
  37.   
  38. [pred] = softmaxPredict(softmaxModel, softmaxX);  
  39. acc = (pred(:) == softmaxY(:));  
  40. acc = sum(acc) / size(acc, 1);  
  41. fprintf('Accuracy: %2.3f%%\n', acc * 100);  
  42.   
  43. % You should expect to get an accuracy of around 80% on the test images.  


小结

 

我们来总结一下网络的结构,如下图所示

接近80%的准确率还是非常不错的!

posted @ 2015-11-18 15:44  菜鸡一枚  阅读(140)  评论(0)    收藏  举报