メインコンテンツ

AlexNet を使用した転移学習

この例では、事前学習済みの AlexNet 畳み込みニューラル ネットワークを微調整して、新しいイメージ コレクションを分類する方法を説明します。

AlexNet は、100 万個を超えるイメージで学習しており、イメージを 1000 個のオブジェクト カテゴリ (キーボード、マグ カップ、鉛筆、多くの動物など) に分類できます。このネットワークは広範囲にわたるイメージについての豊富な特徴表現を学習しています。このネットワークは入力としてイメージを取り、イメージ内のオブジェクトのラベルを各オブジェクト カテゴリの確率と共に出力します。

転移学習は、深層学習アプリケーションでよく使用されています。事前学習済みのネットワークを取得して、新しいタスクの学習の開始点として使用できます。通常は、転移学習によってネットワークを微調整する方が、ランダムに初期化された重みでゼロからネットワークに学習させるよりもはるかに簡単で時間がかかりません。少ない数の学習イメージを使用して、新しいタスクに学習済みの特徴を高速に転移できます。

データの読み込み

新しいイメージを解凍してイメージ データストアとして読み込みます。imageDatastore は、フォルダー名に基づいてイメージに自動的にラベルを付け、データを ImageDatastore オブジェクトとして格納します。イメージ データストアを使用すると、メモリに収まらないデータなどの大きなイメージ データを格納し、畳み込みニューラル ネットワークの学習中にイメージをバッチ単位で効率的に読み取ることができます。

unzip('MerchData.zip');
imds = imageDatastore('MerchData', ...
    'IncludeSubfolders',true, ...
    'LabelSource','foldernames');

データを学習データ セットと検証データ セットに分割します。イメージの 70% を学習に使用し、30% を検証に使用します。splitEachLabel は、images データストアを 2 つの新しいデータストアに分割します。

[imdsTrain,imdsValidation] = splitEachLabel(imds,0.7,'randomized');

このとき、この非常に小さなデータ セットには、55 個の学習イメージと 20 個の検証イメージが格納されています。いくつかのサンプル イメージを表示します。

numTrainImages = numel(imdsTrain.Labels);
idx = randperm(numTrainImages,16);
figure
for i = 1:16
    subplot(4,4,i)
    I = readimage(imdsTrain,idx(i));
    imshow(I)
end

事前学習済みのネットワークの読み込み

事前学習済みの AlexNet ネットワークと対応するクラス名を読み込みます。これには、Deep Learning Toolbox™ Model for AlexNet Network サポート パッケージが必要です。このサポート パッケージがインストールされていない場合、ソフトウェアによってダウンロード用リンクが表示されます。使用可能なすべてのネットワークについては、事前学習済みの深層ニューラル ネットワークを参照してください。

classNames = categories(imdsTrain.Labels);
numClasses = numel(classNames)
numClasses = 5
net = imagePretrainedNetwork("alexnet",NumClasses=numClasses);
net = setLearnRateFactor(net,"fc8/Weights",20);
net = setLearnRateFactor(net,"fc8/Bias",20);

analyzeNetwork を使用して、ネットワーク アーキテクチャを対話的に可視化し、ネットワーク層についての詳細情報を表示します。

analyzeNetwork(net)

最初の層であるイメージ入力層には、サイズが 227 x 227 x 3 の入力イメージが必要です。ここで、3 はカラー チャネルの数です。

inputSize = net.Layers(1).InputSize
inputSize = 1×3

   227   227     3

ネットワークの学習

ネットワークにはサイズが 227 x 227 x 3 の入力イメージが必要ですが、イメージ データストアにあるイメージのサイズは異なります。拡張イメージ データストアを使用して学習イメージのサイズを自動的に変更します。学習イメージに対して実行する追加の拡張演算として、学習イメージを縦軸に沿ってランダムに反転させる演算や、水平方向および垂直方向に最大 30 ピクセルだけランダムに平行移動させる演算を指定します。データ拡張は、ネットワークで過適合が発生したり、学習イメージの正確な詳細が記憶されたりすることを防止するのに役立ちます。

pixelRange = [-30 30];
imageAugmenter = imageDataAugmenter( ...
    'RandXReflection',true, ...
    'RandXTranslation',pixelRange, ...
    'RandYTranslation',pixelRange);
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain, ...
    'DataAugmentation',imageAugmenter);

他のデータ拡張を実行せずに検証イメージのサイズを自動的に変更するには、追加の前処理演算を指定せずに拡張イメージ データストアを使用します。

augimdsValidation = augmentedImageDatastore(inputSize(1:2),imdsValidation);

学習オプションを指定します。転移学習の場合、事前学習済みのネットワークの初期の層からの特徴 (転移された層の重み) を保持します。転移層での学習速度を下げるため、初期学習率を小さな値に設定します。上記の手順では、全結合層の学習率係数を大きくして、新しい最後の層での学習時間を短縮しています。この学習率設定の組み合わせによって、新しい層でのみ学習が急速に進み、他の層での学習速度は低下します。転移学習の実行時には、同じエポック数の学習を行う必要はありません。エポックとは、学習データ セット全体の完全な学習サイクルのことです。ミニバッチのサイズと検証データを指定します。学習中は ValidationFrequency 回の反復ごとにネットワークが検証されます。

options = trainingOptions("sgdm", ...
    MiniBatchSize=10, ...
    MaxEpochs=6, ...
    Metrics="accuracy", ...
    InitialLearnRate=1e-4, ...
    Shuffle="every-epoch", ...
    ValidationData=augimdsValidation, ...
    ValidationFrequency=3, ...
    Verbose=false, ...
    Plots="training-progress");

関数trainnetを使用してニューラル ネットワークに学習させます。分類には、クロスエントロピー損失を使用します。既定では、関数 trainnet は利用可能な GPU がある場合にそれを使用します。GPU での学習には、Parallel Computing Toolbox™ ライセンスとサポートされている GPU デバイスが必要です。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。そうでない場合、関数 trainnet は CPU を使用します。実行環境を指定するには、ExecutionEnvironment 学習オプションを使用します。

net = trainnet(augimdsTrain,net,"crossentropy",options);

検証イメージの分類

検証イメージを分類します。複数の観測値を使用して予測を行うには、関数minibatchpredictを使用します。予測スコアをラベルに変換するには、関数 scores2label を使用します。関数 minibatchpredict は利用可能な GPU がある場合に自動的にそれを使用します。GPU を使用するには、Parallel Computing Toolbox™ ライセンスとサポートされている GPU デバイスが必要です。サポートされているデバイスの詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。そうでない場合、関数は CPU を使用します。

scores = minibatchpredict(net,augimdsValidation);
YPred = scores2label(scores,classNames);

4 個のサンプル検証イメージと、その予測ラベルを表示します。

idx = randperm(numel(imdsValidation.Files),4);
figure
for i = 1:4
    subplot(2,2,i)
    I = readimage(imdsValidation,idx(i));
    imshow(I)
    label = YPred(idx(i));
    title(string(label));
end

検証セットに対する分類精度を計算します。精度とは、ネットワークによって予測が正しく行われるラベルの割合です。

YValidation = imdsValidation.Labels;
accuracy = mean(YPred == YValidation)
accuracy = 0.9500

分類精度の向上に関するヒントは、深層学習のヒントとコツを参照してください。

参照

[1] Krizhevsky, Alex, Ilya Sutskever, and Geoffrey E. Hinton. "ImageNet Classification with Deep Convolutional Neural Networks." Advances in neural information processing systems. 2012.

[2] BVLC AlexNet Model. https://github.com/BVLC/caffe/tree/master/models/bvlc_alexnet

参考

| | | |

トピック