5.6.2.1 ディープラーニング：畳み込みニューラルネットによる分類

# 目次へのリンク


[MATLABによる画像処理・コンピュータービジョン入門目次](https://qiita.com/tohruk/items/e5f7939b622bcf2e3c4c)



# 概要


MATLABとDeep Learning Toolboxを活用することで畳み込みニューラルネットワーク(Convolutional Neural Network; CNN)を容易に学習することができます。




画像分類などの認識タスクを容易に試すことができます。




使用したバージョンはR2020aです。




対応ファイル



   -  [I5_06_2_1_myTrainCNN.m](https://github.com/mathworks/MATLAB-IPCV-Eval-Kit-JP/blob/master/demo_files/I5_06_2_1_myTrainCNN) 

# 画像データセットの準備


数字をランダムなアフィン変換した画像を使って分類要のCNNを学習します。




28x28ピクセルのグレースクール画像が0から9までのフォルダごとに各1000枚あります。


```matlab:code
digitDatasetPath = fullfile(matlabroot,'toolbox','nnet','nndemos', ...
    'nndatasets','DigitDataset');
dir(digitDatasetPath) % フォルダの内容を表示
```
```text:output
.               1               4               7               digitTest.csv   
..              2               5               8               digitTrain.csv  
0               3               6               9               
```


`imageDatastore`を使って各フォルダの画像ファイル一覧を取得します。


```matlab:code
imds = imageDatastore(digitDatasetPath, ...
    'IncludeSubfolders',true,'LabelSource','foldernames');
```


各クラスの画像数の確認します。


```matlab:code
imds.countEachLabel
```
| |Label|Count|
|:--:|:--:|:--:|
|1|0|1000|
|2|1|1000|
|3|2|1000|
|4|3|1000|
|5|4|1000|
|6|5|1000|
|7|6|1000|
|8|7|1000|
|9|8|1000|
|10|9|1000|



各フォルダごとに10枚ずつ表示します。


```matlab:code
figure;
montage(imds.Files(1:100:end)); % 100毎飛ばしで各数字ごとに10毎表示
```

![figure_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/392e873e-8779-c549-505e-a37abcb0f8b5.png)



学習用(75%)と検証用(25%)のデータセットに分割します。


```matlab:code
numTrainFiles = 750;
[imdsTrain,imdsValidation] = splitEachLabel(imds,numTrainFiles,'randomize');
imdsTrain.countEachLabel
```
| |Label|Count|
|:--:|:--:|:--:|
|1|0|750|
|2|1|750|
|3|2|750|
|4|3|750|
|5|4|750|
|6|5|750|
|7|6|750|
|8|7|750|
|9|8|750|
|10|9|750|

```matlab:code
imdsValidation.countEachLabel
```
| |Label|Count|
|:--:|:--:|:--:|
|1|0|250|
|2|1|250|
|3|2|250|
|4|3|250|
|5|4|250|
|6|5|250|
|7|6|250|
|8|7|250|
|9|8|250|
|10|9|250|



以上で学習データおよびテストデータの準備は完了です。


# 畳み込みニューラルネットワークの構造を定義


畳み込みニューラルネットワークの層を定義します。


```matlab:code
layers = [
    imageInputLayer([28 28 1])
    
    convolution2dLayer(3,8,'Padding','same')
    batchNormalizationLayer
    reluLayer
    
    maxPooling2dLayer(2,'Stride',2)
    
    convolution2dLayer(3,16,'Padding','same')
    batchNormalizationLayer
    reluLayer
    
    maxPooling2dLayer(2,'Stride',2)
    
    convolution2dLayer(3,32,'Padding','same')
    batchNormalizationLayer
    reluLayer
    
    fullyConnectedLayer(10)
    softmaxLayer
    classificationLayer];
```
# 学習用オプションを設定


`trainingOptions`関数を用いて学習オプションを設定します。




オプティマイザーは確率的勾配降下法（stochastic gradient descent with momentum）を使用します。




GPUを使う場合はメモリ量に応じて`MiniBatchSize`を調整します。


```matlab:code
options = trainingOptions('sgdm', ...
    'InitialLearnRate',0.01, ...
    'MaxEpochs',4, ...
    'Shuffle','every-epoch', ...
    'ValidationData',imdsValidation, ...
    'ValidationFrequency',30, ...
    'Verbose',false, ...
    'Plots','training-progress');
```
# 学習を実行


学習を実行します。学習後、`SeriesNetwork` クラスのオブジェクトが生成されます。


```matlab:code
net = trainNetwork(imdsTrain, layers, options);
```

![figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/4410282b-1c48-833a-30d9-43d1934958c4.png)


# 学習済みモデルの検証


検証用画像2500枚の一部（250枚）を表示して確認します。


```matlab:code
figure;
montage(imdsValidation.Files(1:10:end));
```


![figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/64725133-7146-10d9-e144-eacb38ed1215.png)



検証用の画像を一枚読込みます。


```matlab:code
I = imread(imdsValidation.Files{521});
figure; imshow(I);
```


![figure_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/88358b99-9f42-4813-a351-b2ac895d5cc4.png)



学習したネットワークで分類を実行します。


```matlab:code
[YPredClass, YPredScore]  = classify(net, I)
```
```text:output
YPredClass = 
     2 

YPredScore = 1x10 の single 行ベクトル    
    0.0005    0.0208    0.6476    0.0615    0.1296    0.0000    0.0000    0.1076    0.0316    0.0007

```


スコアを同時に出力することもできます。


```matlab:code
[YPredClass, YPredScore] = classify(net, imdsValidation);
```


混合行列を計算します。


```matlab:code
figure
cm = confusionchart(imdsValidation.Labels,YPredClass, ...
    'Title','数字の分類', ...
    'RowSummary','row-normalized', ...
    'ColumnSummary','column-normalized');
```


![figure_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/11b5806b-e946-52ba-17a9-2330719ca60b.png)



全体の精度(平均)を計算します。


```matlab:code
accuracy = sum(YPredClass == imdsValidation .Labels)/numel(YPredClass)
```
```text:output
accuracy = 0.9916
```
# ディープニューラルネットワークデザイナーを使った学習


今まではMATLABのプログラムベースで学習を行いました。




もっと簡単にネットワークの構築から学習データの指定、学習、学習済みモデルのエクスポートが行えます。


```matlab:code
deepNetworkDesigner
```


ディープネットワークデザイナーを起動したらワークスペースから定義済みのネットワークをインポートします。





![image_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/c0ec174e-551e-77d1-ec82-8b7ba09681ca.png)





![image_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/8e6bbcb6-d405-23b9-c680-29c55d6fde60.png)




次にインポートしたネットワークを確認します。層構造やパラメーターを変更することが可能です。





![image_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/701c051d-5e84-24d8-f3d6-9facf5250837.png)




学習データを設定していきます。「データ」タブをクリックし、「データのインポート」をクリックします。




今回はワークスペースで定義した学習用データと検証用データをそれぞれセットします。





![image_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/f4bece1b-2c2f-7d50-8ea4-5ac589e37e61.png)




各クラス別の学習データの分布を確認します。





![image_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/eab821ae-6eba-ecce-0256-140291e36716.png)




学習を行います。「学習」タブをクリックし、「学習オプション」をクリックします。




プログラム実行時と同様にパラメーターを変更します。





![image_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/57584ba9-0856-e781-bc13-e2e1be2977a3.png)




変更ができたら「学習」をクリックします。





![image_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/d89a2af7-2e66-b647-216e-f3f8c512c8b2.png)




学習が完了したら学習済みモデルをエクスポートしたり、GUIで行った処理をMATLABプログラム化することができます。





![image_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14336/1a6d0b49-9aaa-f11b-00b7-3293e852c77c.png)



# まとめ


MATLABで畳み込みニューラルネットワークを学習する手順を紹介しました。




ディープニューラルネットワークデザイナーを使うとより簡単に学習を行うことができます。



# 参考

   -  [分類向けのシンプルなディープラーニングネットワークの学習](https://jp.mathworks.com/help/deeplearning/ug/create-simple-deep-learning-network-for-classification.html) 
   -  [ディープニューラルネットワークデザイナー入門](https://jp.mathworks.com/help/deeplearning/gs/get-started-with-deep-network-designer.html?lang=en) 


# 謝辞


本記事は @eigs さんの[livescript2markdown](https://github.com/minoue-xx/livescript2markdown)を使わせていただいてます。



# 目次へのリンク


[MATLABによる画像処理・コンピュータービジョン入門目次](https://qiita.com/tohruk/items/e5f7939b622bcf2e3c4c)