神經網路 | 基於MATLAB 使用CNN擬合一個迴歸模型來預測手寫數字的旋轉角度(卷積神經網路)

衝動的MJ發表於2019-03-07

博主github:https://github.com/MichaelBeechan   

博主CSDN:https://blog.csdn.net/u011344545 

上一篇寫了一個:實現簡單的數字分類問題(卷積神經網路)

%% Time:2019.3.7
%% Name:Michael Beechan
%% Github:https://github.com/MichaelBeechan
%% Function:
%% 如何使用卷積神經網路擬合一個迴歸模型來預測手寫數字的旋轉角度。

 

%% 載入資料
%% 資料集包含手寫數字的合成影像,以及每幅影像旋轉的對應角度(以角度為單位)。
%% 使用digitTrain4DArrayData和digitTest4DArrayData將訓練和驗證影像載入為4D陣列。
%% 輸出YTrain和YValidation是以角度為單位的旋轉角度。每個訓練和驗證資料集包含5000張影像。

[XTrain, ~, Ytrain] = digitTrain4DArrayData;
[XValidation, ~, YValidation] = digitTest4DArrayData;

%% 隨機顯示20張訓練影像

numTrainImages = numel(YTrrain);
figure;
idx = randperm(numTrainImages, 20);
for i = 1 : numel(idx)
    subplot(4, 5, i);
    imshow(XTrain(:, :, :, idx(i)))
    drawnow
end

%% 資料歸一化處理
%% 當訓練神經網路時,確保你的資料在網路的所有階段都是標準化的通常是有幫助的。
%% 歸一化有助於使用梯度下降來穩定和加速網路訓練。
%% 如果您的資料規模太小,那麼損失可能會變成NaN,並且在培訓期間網路引數可能會出現分歧。
%% 標準化資料的常用方法包括重新標定資料,使其範圍變為[0,1]或使其均值為0,標準差為1。

%{
你可以標準化以下資料:
1、輸入資料。在將預測器輸入到網路之前對它們進行規範化。在本例中,輸入影像已經標準化為[0,1]範圍。
2、層輸出。您可以使用批處理規範化層對每個卷積和完全連線層的輸出進行規範化。
3、響應。如果使用批處理規範化層對網路末端的層輸出進行規範化,則在開始訓練時對網路的預測進行規範化。
        如果響應的規模與這些預測非常不同,那麼網路訓練可能無法收斂。
        如果你的回答沒有得到很好的擴充套件,那麼試著將其標準化,看看網路培訓是否有所改善。
        如果在訓練前對響應進行規範化,則必須轉換訓練網路的預測,以獲得原始響應的預測。

%}

%% 一般來說,資料不必完全標準化。
%% 但是,如果在本例中訓練網路來預測100*YTrain或YTrain+500而不是YTrain,那麼損失就變成NaN,
%% 當訓練開始時,網路引數就會出現分歧。
%% 即使網路預測aY + b和網路預測Y之間的唯一區別是重新調整最終完全連線層的權重和偏差,這些結果仍然會出現。
%% 如果輸入或響應的分佈非常不均勻或傾斜,還可以執行非線性轉換(例如,取對數)


%% 繪製響應分佈:在分類問題中,輸出是類概率,類概率總是歸一化的。
figure;
histogram(YTrain)
axis tight
ylabel('Counts')
xlabel('Rotation Angle')

*********************************************************************************************************************

今天太晚了,明天接著學習,明天見!!!!

*********************************************************************************************************************

2019.3.8
閒言少敘,繼續努力

%% 建立網路層
%% 第一層定義輸入資料的大小和型別。輸入的影像大小為28×28×1。建立與訓練影像大小相同的影像輸入層。
%% 網路的中間層定義了網路的核心架構,大部分計算和學習都在這個架構中進行。
%% 最後一層定義輸出資料的大小和型別。對於迴歸問題,全連線層必須先於網路末端的迴歸層。

layers = [
    imageInputLayer([28 28 1])
    batchNormalizationLayer
    reluLayer
   
    averagePooling2dLayer(2, 'Stride', 2)
   
    convolution2dLayer(3, 16, 'Padding', 'same')
    batchNormalizationLayer
    reluLayer
   
    averagePooling2dLayer(2, 'Stride', 2)
   
    convolution2dLayer(3, 32, 'Padding', 'same')
    batchNormalizationLayer
    reluLayer
   
    concolution2dLayer(3, 32, 'Padding', 'same')
    batchNormalizationLayer
    reluLayer
   
    dropoutLayer(0, 2)
    fullyConnectedLayer(1)
    regressionLayer];
 

%% 訓練網路——Options
%% Train for 30 epochs 學習率0.001 在20個epoch後降低學習率。
%% 通過指定驗證資料和驗證頻率,監控培訓過程中的網路準確性。
%% 根據訓練資料對網路進行訓練,並在訓練過程中定期對驗證資料進行精度計算。
%% 驗證資料不用於更新網路權重。開啟訓練進度圖,並關閉命令視窗輸出。

miniBatchSize = 128;
validationFrequency = floor(numel(YTrain) / miniBatchSize);
options = trainingOptions('sgdm', ...
    'MiniBatchSize', miniBatchSize, ...
    'MaxEpochs', 30, ...
    'InitialLearnRate', 1e-3, ...
    'LearnRateSchedule', 'piecewise', ...
    'LearnRateDropFactor', 0.1, ...
    'LearnRateDropPeriod', 20, ...
    'Shuffle', 'every-epoch', ...
    'ValidationData', {XValidation, YValidation}, ...
    'ValidationFrequency', validationFrequency, ...
    'Plots', 'training-progress', ...
    'Verbose', false);
net = trainNetwork(XTrain, YTrain, layer, options);

net = trainNetwork(XTrain, YTrain, layers, options);
%% net細節
net.Layers

ans =

  17x1 Layer array with layers:

     1   'imageinput'         Image Input           28x28x1 images with 'zerocenter' normalization
     2   'batchnorm_1'        Batch Normalization   Batch normalization with 1 channels
     3   'relu_1'             ReLU                  ReLU
     4   'avgpool_1'          Average Pooling       2x2 average pooling with stride [2  2] and padding [0  0  0  0]
     5   'conv_1'             Convolution           16 3x3x1 convolutions with stride [1  1] and padding 'same'
     6   'batchnorm_2'        Batch Normalization   Batch normalization with 16 channels
     7   'relu_2'             ReLU                  ReLU
     8   'avgpool_2'          Average Pooling       2x2 average pooling with stride [2  2] and padding [0  0  0  0]
     9   'conv_2'             Convolution           32 3x3x16 convolutions with stride [1  1] and padding 'same'
    10   'batchnorm_3'        Batch Normalization   Batch normalization with 32 channels
    11   'relu_3'             ReLU                  ReLU
    12   'conv_3'             Convolution           32 3x3x32 convolutions with stride [1  1] and padding 'same'
    13   'batchnorm_4'        Batch Normalization   Batch normalization with 32 channels
    14   'relu_4'             ReLU                  ReLU
    15   'dropout'            Dropout               20% dropout
    16   'fc'                 Fully Connected       1 fully connected layer
    17   'regressionoutput'   Regression Output     mean-squared-error with response 'Response'

 

%% test 網路
%% 通過評估驗證資料的準確性來測試網路的效能。
%% 使用predict預測驗證影像的旋轉角度

YPredicted = predict(net, XValidation);

 

%% 評估效能
%% 計算預測旋轉角和實際旋轉角的預測誤差

predictionError = YValidation - YPredicted;

 

%% 從真實角度計算在可接受誤差範圍內的預測數。
%% 設定閾值為10度。計算預測在此閾值內的百分比。

thr = 10;
numCorrect = sum(abs(predictionError) < thr);
numValidationImages = numel(YValidation);

 

accuracy = numCorrect / numValidationImages

accuracy =

    0.9446

%% 使用RMSE來測量預測旋轉角度和實際旋轉角度的差異
squares = predictionError.^2;
rmse = sqrt(mean(squares))

rmse =

  single

    5.1258

%% 顯示每個數字類的殘差框圖
residualMatrix = reshape(predictionError, 500, 10);
%% 殘差矩陣的每一列對應於每一位數字的殘差。
figure
boxplot(residualMatrix, ...
    'Labels', {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'})
xlabel('Digit Class')
ylabel('Degrees Error')
title('Residuals')

%% 最後演示修正後的數字旋轉效果
%% 使用imrotate(影像處理工具箱)根據預測的旋轉角度旋轉49位樣本數字

%% 'bicubic'    Bicubic interpolation. 雙立方插值。注:這種插值方法可以產生超出原始範圍的畫素值。
%% 'crop'       使輸出影像B與輸入影像A大小相同,裁剪旋轉後的影像以適應。

idx = randperm(numValidationImages, 49);
for i = 1 : numel(idx)
    image = XValidation(:, :, :, idx(i));
    predictedAngle = YPredicted(idx(i));
    imagesRotated(:, :, :, i) = imrotate(image, predictedAngle, 'bicubic', 'crop');
end

 

%% 顯示    montage:可以使用蒙太奇(影像處理工具箱)將數字一起顯示在單個影像中。
figure
subplot(1, 2, 1)
montage(XValidation(:, :, :, idx))
title('Original')

subplot(1, 2, 2)
montage(imagesRotated)
title('Corrected')

大概就這樣了,你看懂了嗎???????

原始碼下載:https://download.csdn.net/download/u011344545/11008030

相關文章