MATLAB Examples

CNNによるノイズ除去(縦線・横線+ゴマ塩)

Contents

初期化

clear; close all force; clc

学習用・テスト画像生成

X = digitTrainCellArrayData;

Test = X(4501:5000); % テスト画像群(500枚)
X = X(1:4500);       % 学習用画像群(4500枚)

% trainNetworkの仕様に合わせるため学習データは4-Dに変換
numOfSamples = size(X,2); % 画像サンプル数
imageSize = size(X{1});   % 画像サイズ

for i = 1:numOfSamples
    % 教師画像の作成
    XResponse(:,:,1,i) = X{i};
    % ノイズ画像の作成
    randrow = randi(imageSize(1));
    randcol = randi(imageSize(2));
    XTrain(:,:,1,i) = X{i};
    XTrain(randrow,:,1,i) = 1;
    XTrain(:,randcol,1,i) = 1;
    XTrain(:,:,1,i) = imnoise(XTrain(:,:,1,i),'salt & pepper',0.1);
end

画像の確認

imshow([XResponse(:,:,1,2),XTrain(:,:,1,2)])
title('Original Image(Left) / Noisy Image(Right)')

% 学習画像数の確認
size(XTrain)
ans =
          28          28           1        4500

レイヤーの定義

layers = [imageInputLayer([28 28 1], 'Normalization','none','Name','input');          % 入力画像サイズ:28x28x1、入力で明るさの正規化なし  3次元目は1もしくは3
    convolution2dLayer(3,32,'Padding',[1 1 1 1],'Name','conv1');                % 3x3x1のフィルタを32セット(マップ) (出力:28x28x32) パディングあり
    reluLayer('Name','relu1');                                                  % ReLU(Rectified Linear Unit)活性化関数層
    maxPooling2dLayer(2,'Stride',2,'Name','mpool1','HasUnpoolingOutputs',true); % max pooling層:2x2の領域内の最大値を出力  (出力:14x14x32) 領域内の平均移動への対応
    convolution2dLayer(3,32,'Padding',[1 1 1 1],'Name','conv2');                % 3x531のフィルタを32セット(マップ) (出力:14x14x32) パディングあり
    reluLayer('Name','relu2');                                                  % ReLU(Rectified Linear Unit)活性化関数層
    maxUnpooling2dLayer('Name','upool1');                                       % max 逆pooling層:max pooling層で削除した次元に戻す
    convolution2dLayer(3,32,'Padding',[1 1 1 1],'Name','conv3');                % 3x3x1のフィルタを32セット(マップ) (出力:28x28x32) パディングあり
    reluLayer('Name','relu3');                                                  % ReLU(Rectified Linear Unit)活性化関数層
    convolution2dLayer(3,1,'Padding',[1 1 1 1],'Name','conv4');                 % 3x3x1のフィルタを1セット(マップ) (出力:28x28x1) パディングあり
    regressionLayer('Name','routput');                                          % 回帰層:RMSE
    ]

layers = layerGraph(layers);
% 最大逆プーリング層の追加のため、最大プーリング層で削ったインデックスとサイズの情報を接続
layers = connectLayers(layers,'mpool1/indices','upool1/indices');
layers = connectLayers(layers,'mpool1/size','upool1/size');
layers = 
  次の層をもつ 11x1 の Layer 配列:

     1   'input'     イメージの入力    28x28x1 イメージ
     2   'conv1'     たたみ込み      ストライド [1  1] およびパディング [1  1  1  1] の 32 3x3 たたみ込み
     3   'relu1'     ReLU       ReLU
     4   'mpool1'    最大プーリング    ストライド [2  2] およびパディング [0  0  0  0] の 2x2 最大プーリング
     5   'conv2'     たたみ込み      ストライド [1  1] およびパディング [1  1  1  1] の 32 3x3 たたみ込み
     6   'relu2'     ReLU       ReLU
     7   'upool1'    最大逆プーリング   最大逆プーリング
     8   'conv3'     たたみ込み      ストライド [1  1] およびパディング [1  1  1  1] の 32 3x3 たたみ込み
     9   'relu3'     ReLU       ReLU
    10   'conv4'     たたみ込み      ストライド [1  1] およびパディング [1  1  1  1] の 1 3x3 たたみ込み
    11   'routput'   回帰出力       mean-squared-error

学習用オプションを、trainingOptions関数を用い設定

   必要であれば、GPUのメモリに応じてMiniBatchSizeを調整
options = trainingOptions('adam', 'MaxEpochs',15,...
    'Plots','training-progress'); % 最大15世代まで学習

[学習] ネットワークを教師付き学習(SeriesNetwork クラスのオブジェクトが学習後に生成される)

if exist('trainNetwork_TMP.m','file')
    net = trainNetwork_TMP(XTrain, XResponse, layers, options);
else
    net = trainNetwork(XTrain, XResponse, layers, options);
end
%load('trainednet_several.mat');
単一の CPU で学習中。
|========================================================================================|
|  Epoch  |  Iteration  |  Time Elapsed  |  Mini-batch  |  Mini-batch  |  Base Learning  |
|         |             |   (hh:mm:ss)   |     RMSE     |     Loss     |      Rate       |
|========================================================================================|
|       1 |           1 |       00:00:01 |         7.31 |         26.7 |          0.0010 |
|       2 |          50 |       00:00:33 |         4.31 |          9.3 |          0.0010 |
|       3 |         100 |       00:01:01 |         3.80 |          7.2 |          0.0010 |
|       5 |         150 |       00:01:36 |         3.23 |          5.2 |          0.0010 |
|       6 |         200 |       00:02:05 |         3.10 |          4.8 |          0.0010 |
|       8 |         250 |       00:02:36 |         2.87 |          4.1 |          0.0010 |
|       9 |         300 |       00:03:04 |         2.80 |          3.9 |          0.0010 |
|      10 |         350 |       00:03:32 |         2.72 |          3.7 |          0.0010 |
|      12 |         400 |       00:03:59 |         2.62 |          3.4 |          0.0010 |
|      13 |         450 |       00:04:27 |         2.53 |          3.2 |          0.0010 |
|      15 |         500 |       00:04:56 |         2.47 |          3.1 |          0.0010 |
|      15 |         525 |       00:05:13 |         2.51 |          3.2 |          0.0010 |
|========================================================================================|

テスト画像の生成と評価

% ノイズ画像の作成
randrow = randi(imageSize(1));
randcol = randi(imageSize(2));
testI = Test{randi(500)}; % テスト画像群から1枚を選択

noisyI = imnoise(testI,'salt & pepper',0.1); % ゴマ塩ノイズ
noisyI(randrow,:) = 1; % 横線の挿入
noisyI(:,randcol) = 1; % 縦線の挿入

% 学習したネットワークでノイズ除去
predI = predict(net,noisyI);
imshow([testI,noisyI,predI(:,:,1,1)])
title('Original Image(Left) / Noisy Image(Centre) / Denoised Image(Right)')

終了

Copyright 2018 The MathWorks, Inc.