機器學習實驗報告:利用3層神經網絡對CIFAR-10圖像數據庫進行分類


PS:這是6月份時的一個結課項目,當時的想法就是把之前在Coursera ML課上實現過的對手寫數字識別的方法遷移過來,但是最后的效果不太好…

2014年 6 月

 

一、實驗概述

實驗采用的是CIFAR-10 圖像數據庫,一共包括60000幅32x32 彩色圖像。這些圖像分為10類,每類6000幅。整個數據庫分為五個訓練包和一個測試包,每個包一萬幅圖像,所以一共5萬幅訓練圖像,1萬幅測試圖像。
    測試包中,每個類包括1000幅圖像,隨機排序。而5個訓練包合在一起,每類包括5000幅圖像。類的標記為:airplane、automobile、bird、cat、deer、dog、frog、horse、ship、truck這些類是完全互斥的,相互之間沒有重疊。汽車包括小轎車,SUV,等等。卡車只包括大型車輛。兩者都不包括皮卡。

  1. 實驗要求

    設計分類方法,區分一類圖像與其他類圖像。

    1. 給出構建訓練集與測試集的代碼,以正確率百分比形式給出結果(5分),以列表形式給出測試數據的結果並保存為電子表格。(5分)
    2. 寫出設計思路(10分)
    3. 詳細介紹采用的方法(10分)並給出實現代碼(訓練與預測部分)及解釋(10分)

     

    三、實驗細節

    3.1.給出構建訓練集與測試集的代碼,以正確率百分比形式給出結果

    CIFAR-10原始數據分為5個訓練包,以unint格式存儲在.mat格式文件中。在本實驗中,先5個訓練包合並,並用double()函數將其轉換double型,以便后續處理。

    本實驗先用PCA(主成分分析)對訓練集與測試集進行降維與白化處理,然后使用帶有一個隱藏層的3層神經網絡進行有監督學習,對CIFAR-10圖像數據庫進行十個類別的分類。

    最后得到的最佳結果是訓練集准確率為99.944%,測試集准確為52.28%。

    具體構建訓練集與測試集的代碼如下:

    %% take 6 batches data into one unite set

    load('data_batch_1.mat');

    data1 = double(data);

    labels1 = double(labels);

     

    load('data_batch_2.mat');

    data2 = double(data);

    labels2 = double(labels);

     

    load('data_batch_3.mat');

    data3 = double(data);

    labels3 = double(labels);

     

    load('data_batch_4.mat');

    data4 = double(data);

    labels4 = double(labels);

     

    load('data_batch_5.mat');

    data5 = double(data);

    labels5 = double(labels);

     

    load('test_batch.mat');

    testData = double(data);

    testLabels = double(labels);

     

    data = [data1; data2; data3; data4; data5; testData];

    labels = [labels1; labels2; labels3; labels4; labels5; testLabels];

     

    fprintf('\nthe size of dataset is ');

    fprintf('%d ', size(data));

     

    fprintf('\nthe size of labels is ');

    fprintf('%d ', size(labels));

     

    save('data_batch_1to6_double.mat','data','labels');

     

    3.2 以列表形式給出測試數據的結果並保存為電子表格

    各次測試數據結果如下,具體電子表格文件cifar_results.xls已附在文件中。

    No.

    representation model

    whitening

    size of training set(m)

    #features n

    iteration of training

    weight decay

    #unit in hidden layer

    final cost

    training set accurancy(%)

    test set accuracy

    time(s)

    1

    softmax

    Y

    50000

    400

    27

    1.00E-04

    400

    1.69

    42.8

    39.25

    16

    2

    softmax

    Y

    50000

    400

    4

    1

    400

    2.24

    41.386

    38.5

    12.47

    3

    softmax

    Y

    50000

    400

    4

    0

    400

    1.688

    42.87

    39.28

    11.92

    4

    neural network

    N

    1000

    500

    30

    1

    400

    2.42

    92.6

    23.8

    15

    5

    neural network

    N

    10000

    500

    300

    1

    400

    8.33E-01

    99.9

    22.59

    968.768

    6

    neural network

    Y

    1000

    400

    300

    1

    400

    1.83

    98.3

    18.7

    540

    7

    neural network

    Y

    50000

    400

    300

    1

    400

    8.63E-01

    99.8

    43.9

    2906.7

    8

    neural network

    Y

    10000

    400

    300

    10

    400

    1.30165

    99.79

    40.72

    1529.14

    9

    neural network

    Y

    2000

    400

    200

    100

    400

    3.23485

    31.15

    21.21

    276.9273

    10

    neural network

    Y

    2000

    400

    200

    10

    400

    1.73997

    98.6

    27

    280.447584

    11

    neural network

    Y

    2000

    400

    200

    3

    400

    8.18E-01

    100

    26.84

    279.236

    12

    neural network

    Y

    2000

    400

    200

    1

    400

    3.53E-01

    100

    26.66

    280.02

    13

    neural network

    Y

    2000

    400

    200

    50

    400

    2.96523

    67.75

    28.86

    283.637024

    14

    neural network

    Y

    2000

    400

    200

    25

    400

    2.50458

    75.9

    27.67

    274.069

    15

    neural network

    Y

    2000

    400

    200

    20

    400

    2.34985

    80.95

    27.47

    278.315288

    16

    neural network

    Y

    2000

    400

    200

    20

    800

    2.35565

    78.75

    27.46

    546.189679

    17

    neural network

    Y

    2000

    400

    200

    20

    200

    2.3464

    83

    27.81

    152.853709

    18

    neural network

    Y

    50000

    400

    500

    1.00E+01

    800

    7.67E-01

    99.944

    52.28

    16291.53784

    19

    neural network

    Y

    50000

    400

    500

    10

    400

    7.98E-01

    99.926

    46.27

    4580.601653

    20

    neural network

    Y

    50000

    400

    500

    10

    250

    8.94E-01

    99.824

    42.67

    3031.253023

    3.3 設計思路

    本實驗先用PCA(主成分分析)對訓練集與測試集進行降維與白化預處理,然后對預處理后的數據使用帶有一個隱藏層的3層神經網絡進行有監督學習,實現對CIFAR-10圖像數據庫十個類別的分類。

    剛開始較自然地想到利用softmax模型進行十類預測,但實現后發現對訓練集與測試集的預測准確率均不高。原因是輸入參數特征較多,只有輸入輸出兩層的softmax模型表達能力較弱。

    后來便采用帶有一個隱藏層的三層神經網絡的有監督學習算法,一開始沒有對數據進行白化和降維處理。算法訓練時間很長,預測的效果也不好。

    於是利用PCA對原有的數據進行降維與白化預處理。選擇保持主成分97%,及保留了數據的主要特征,同時將數據的特征維度從3072降到了400。大大提高了算法的訓練時間,減少了內存消耗。同時再對降維后的數據進行白化處理,去掉數據之間的關聯度,減少冗余信息量,有助於提升訓練及預測准確率。

    對數據利用PCA進行白化降維預處理后,訓練集的預測正確率已經達到相當高(99%),但測試集的預測正確率仍停留在40%左右。推測是發生了過擬合現象,故我增加了隱藏層的單元數到800個,同時調大權重衰減參數lambda,加大訓練迭代次數。得到了最后的結果:測試集預測正確率52.28%。

    由於電腦運行速度和內存限制,無法在有限時間內做出更多調試。理論上若有更多數據,同時利用交叉驗證集進行模型選擇,得到最優模型參數,增大訓練迭代次數,可以得到更好的預測結果,消除過擬合現象。

    3.4 詳細介紹采用的方法,並給出實現代碼(訓練與預測部分)及解釋

    主要運行文件為cifarNN.m

    3.4.1 PCA和白化(whitening)

    實驗中先采用PCA(主成分分析)對訓練集與測試集進行降維與白化處理。

      PCA是Principal Component Analysis主成分分析的縮寫。它具有2個功能,一是維數約簡,一是數據的可視化。在這里利用的是它的第一個功能維數約簡,以加快算法訓練速度,減少內存消耗。在本實驗中,利用PCA將每個圖像由32*32*3=3072維降低到400維,保留了97%的主要成分,同時大大加快訓練速度。

      PCA並不是線性回歸,因為線性回歸是保證得到的函數是y值方面誤差最小,而PCA是保證得到的函數到所降的維度上的誤差最小。另外線性回歸是通過x值來預測y值,而PCA中是將所有的x樣本都同等對待。

      在使用PCA前需要對數據進行預處理,首先是均值化,即對每個特征維,都減掉該維的平均值,然后就是將不同維的數據范圍歸一化到同一范圍,方法一般都是除以最大值。但是在對自然圖像進行均值處理時並不是不是減去該維的平均值,而是減去這張圖片本身的平均值。因為PCA的預處理是按照不同應用場合來定的。

      自然圖像指的是人眼經常看見的圖像,其符合某些統計特征。在對自然圖像進行學習時,其實不需要太關注對圖像做方差歸一化,因為自然圖像每一部分的統計特征都相似,只需做均值為0化就行了。不過對其它的圖片進行訓練時,比如手寫字識別等,就需要進行方差歸一化了。

      PCA的計算過程主要是要求2個東西,一個是降維后的各個向量的方向,另一個是原先的樣本在新的方向上投影后的值。

      首先需求出訓練樣本的協方差矩陣,如公式所示(輸入數據已經均值化過):

      

      求出訓練樣本的協方差矩陣后,將其進行SVD分解,得出的U向量中的每一列就是這些數據樣本的新的方向向量了,排在前面的向量代表的是主方向,依次類推。用U'*X得到的就是降維后的樣本值z了,即:

      這個z值的幾何意義是原先點到該方向上的距離值,但是這個距離有正負之分,這樣PCA的2個主要計算任務已經完成了。用U*z就可以將原先的數據樣本x給還原出來。

    在使用有監督學習時,要采用PCA降維,只需將訓練樣本的x值抽取出來,計算出主成分矩陣U以及降維后的值z,然后讓z和原先樣本的y值組合構成新的訓練樣本來訓練分類器。在測試過程中,同樣可以用原先的U來對新的測試樣本降維,然后輸入到訓練好的分類器中即可。

    白化(Whitening)的目的是去掉數據之間的相關聯度,是很多算法進行預處理的步驟。比如說當訓練圖片數據時,由於圖片中相鄰像素值有一定的關聯,所以很多信息是冗余的。這時候去相關的操作就可以采用白化操作。數據的白化必須滿足兩個條件:一是不同特征間相關性最小,接近0;二是所有特征的方差相等(不一定為1)。常見的白化操作有PCA whitening和ZCA whitening。在本實驗中采用的是PCA whitening.

    PCA whitening是指將數據x經過PCA降維為z后,可以看出z中每一維是獨立的,滿足whitening白化的第一個條件,這是只需要將z中的每一維都除以標准差就得到了每一維的方差為1,也就是說方差相等。公式為:

    本實驗中具體實現文件為pcaWhitening.m和pcaWhitening2.m,因為電腦內存的限制,如果對訓練集與測試集60000個數據同時進行處理會導致內存溢出,故分為兩部分分別處理。

    具體實現代碼如下:

    %% pca whitening

    clear all; close all;

     

    load('data_batch_1to6_double.mat');

    data = data(1:30000,:);

    % data: [60000x3072 double]

    % labels: [40000x3072 double]

    % batch_label: 'training batch 1 to 4'

     

    x = data';

    % x : 1000x3072

     

    %% Step 0: Zero-mean the data (by row)

    % make use of the mean and repmat/bsxfun functions.

    x = x - repmat(mean(x,1), size(x,1),1); % compute the mean value of each column

     

    %% Step 1: Implement PCA to obtain xRot

    % Implement PCA to obtain xRot, the matrix in which the data is expressed

    % with respect to the eigenbasis of sigma, which is the matrix U.

     

    xRot = zeros(size(x));

    [n,m] = size(x);

    sigma = 1/m*x*x';

    [u,s,v] = svd(sigma);

    xRot = u' * x; % 數據旋轉后的結果。

     

     

    %% Step 2: Find k, the number of components to retain

    % Write code to determine k, the number of components to retain in order

    % to retain at least 97% of the variance.

     

    k = 0; % Set k accordingly

    ss = diag(s);

    %其中cumsum(ss)求出的是一個累積向量,也就是說ss向量值的累加值

    %並且(cumsum(ss)/sum(ss))<=0.97是一個向量,值為0或者1的向量,為1表示滿足那個條件

    k = length(ss((cumsum(ss)/sum(ss))<=0.97));

    save('u_k','u','k');

     

    %% Step 3: Implement PCA with whitening and regularisation

    % Implement PCA with whitening and regularisation to produce the matrix

    % xPCAWhite.

     

    epsilon = 0.1;

    xTilde = u(:,1:k)' * x; % 數據降維后的結果,這里k希望保留的特征向量的數目。

    xPCAwhite = diag(1./sqrt(diag(s(1:k,1:k)) + epsilon)) * xTilde; % xPCAwhite

    data = xPCAwhite';

    save('data_batch_1to3_PCAwhite.mat','data','labels');

    fprintf('the size of data is');

    fprintf('%d', size(data));

     

    3.4.2 利用含一個隱藏層的神經網絡進行有監督學習,實現對CIFAR10-圖像數據庫的十類別分類

    具體實現步驟:

  2. 載入數據

    具體步驟在報告前半部分已描述。

  3. 隨機初始化參數

    利用randInitializeWeights.m進行參數的隨機初始化,具體實現代碼如下

    function W = randInitializeWeights(L_in, L_out)

    %RANDINITIALIZEWEIGHTS Randomly initialize the weights of a layer with L_in

    %incoming connections and L_out outgoing connections

    % W = RANDINITIALIZEWEIGHTS(L_in, L_out) randomly initializes the weights

    % of a layer with L_in incoming connections and L_out outgoing

    % connections.

    W = zeros(L_out, 1 + L_in);

    epsilon_init = 0.086;

    W = rand(L_out, 1 + L_in) * 2 * epsilon_init - epsilon_init;

     

    end

     

  4. 實現前向傳播算法,計算成本函數

    隱藏層單元輸出(activation)的表達式如下:

    也可以表示為

    矢量化表達式如下:

    這個步驟稱為前向傳播forward propagation,更一般的,對神經網絡中的l層和l+1層,有:

    成本函數的表達式形式如下

  5. 利用成本函數與成本函數的梯度,實現反向傳播算法,更新參數。

    用反向傳播(Backward propagation)算法計算預測誤差,需要用到成本函數的梯度,其表達式如下:

    具體代碼如下:

    % cost function

    %add the column of 1's to the X matrix.

    X = [ones(m, 1) X];

    a1 = X;

     

    % forward propagation

    % compute the activation 'a2' and output of prediction 'h'

    a2 = sigmoid(X * Theta1');

    a2 = [ ones(size(a2,1), 1) a2];

    h = sigmoid(a2 * Theta2');

    a3 = h;

     

    % create a 10*10 unit matrices

    Y = eye(num_labels);

    % conver y to binary matrix y_bin,size(y_bin)=[5000,10]

    y_bin = y * ones(1,num_labels);

     

    for i = 1:m

    num_digit = y_bin(i,1);

    y_bin(i,:) = Y(num_digit,:);

    end

     

    %J = sum(1/m*sum(-y_bin.*log(h)-(1-y_bin).*log(1-h)));

     

    J = sum(1/m*sum(-y_bin.*log(h)-(1-y_bin).*log(1-h))) + ...

    lambda/(2*m)*(sum(sum(Theta1(:,2:end).^2))+sum(sum(Theta2(:,2:end).^2)));

     

    % comput delta 3

    d3 = h - y_bin ; % Delta3: 5000*10

     

     

    % comput delta 2

    % feedforward

    z2 = a1 * Theta1';

    a2 = sigmoid(z2);

    a2 = [ ones(size(a2,1), 1) a2]; h = sigmoid(a2 * Theta2'); a3 = h;

    d2 = (d3*Theta2(:,2:end)).*sigmoidGradient(z2) ;

     

    % compute Delta 2

    Delta2 = d3' * a2;

    % compute gradient of Theta2

    Theta2_grad = 1/m*Delta2;

     

    % compute Delta 1

    Delta1 = d2' * a1; % compute gradient of Theta1

    Theta1_grad = 1/m*Delta1;

     

     

    % Part 3: Implement regularization with the cost function and gradients.

    Theta1_reg_ad = zeros(size(Theta1)); % the additional part of regularization

    Theta1_reg_ad(:,2:end) = lambda/m * Theta1(:,2:end) ;

    Theta1_grad = Theta1_grad + Theta1_reg_ad;

     

    Theta2_reg_ad = zeros(size(Theta2)); % the additional part of regularization

    Theta2_reg_ad(:,2:end) = lambda/m * Theta2(:,2:end) ;

    Theta2_grad = Theta2_grad + Theta2_reg_ad;

     

    % Unroll gradients

    grad = [Theta1_grad(:) ; Theta2_grad(:)];

     

    end

     

  6. 進行梯度檢查,若梯度檢查結果差距過大,返回第3.4步

    具體matlab代碼如下:

    %% Gradient checking

    % close gradient checking when training NN

    debug2 = false;

    if debug2

    [J grad] = nnCostFunction(p, input_layer_size, hidden_layer_size, ...

    num_labels, X, y, lambda);

    numGrad = computeNumericalGradient( @(x) nnCostFunction(p, input_layer_size, hidden_layer_size, ...

    num_labels, x, y, lambda), initial_nn_params);

    disp([numGrad grad]);

    diff = norm(numGrad-grad)/norm(numGrad+grad);

    disp(diff);

    end

     

  7. 訓練神經網絡,得到最佳預測參數

    算法調用minFunc()更新參數W,b,以便得到更好的預測模型。

    具體實現代碼如下:

    % choose lambda to avoid overfit

    lambda = 10;

     

    % Create "short hand" for the cost function to be minimized

    costFunction = @(p) nnCostFunction(p, ...

    input_layer_size, ...

    hidden_layer_size, ...

    num_labels, X, y, lambda);

     

    % Now, costFunction is a function that takes in only one argument (the

    % neural network parameters)

     

    % use minFunc to improve running speed

    addpath minFunc/

    options.maxIter = 500;

    options.Method = 'lbfgs';

    minFuncOptions.display = 'on';

    [nn_params, cost] = minFunc(costFunction, initial_nn_params, options);

     

    % Obtain Theta1 and Theta2 back from nn_params

    Theta1 = reshape(nn_params(1:hidden_layer_size * (input_layer_size + 1)), ...

    hidden_layer_size, (input_layer_size + 1));

     

    Theta2 = reshape(nn_params((1 + (hidden_layer_size * (input_layer_size + 1))):end), ...

    num_labels, (hidden_layer_size + 1));

     

    7.利用訓練得到的參數對測試集進行預測,與測試集標簽進行比對,計算預測正確率

    具體實現代碼如下:

    %% Implement Predict

    % After training the neural network, then we use it to predict

    % the labels. The "predict" function use the

    % neural network to predict the labels of the training set and test set.

     

    pred = predict(Theta1, Theta2, X);

    fprintf('\nTraining Set Accuracy: %f\n', mean(double(pred == y)) * 100);

     

    pred2 = predict(Theta1, Theta2, testData);

    fprintf('\nTesting Set Accuracy: %f\n', mean(double(pred2 == testLabels)) * 100);

     

     

     


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM