Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

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 がインストールされていない場合、ダウンロード用リンクが表示されます。AlexNet は、100 万個を超えるイメージについて学習済みであり、イメージを 1000 個のオブジェクト カテゴリ (キーボード、マウス、鉛筆、多くの動物など) に分類できます。結果として、このモデルは広範囲のイメージに対する豊富な特徴表現を学習しています。

net = alexnet;

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

analyzeNetwork(net)

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

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

   227   227     3

最後の層の置き換え

事前学習済みのネットワーク net の最後の 3 つの層は、1000 個のクラスに対して構成されています。これらの 3 つの層を、新しい分類問題に対して微調整しなければなりません。事前学習済みのネットワークから、最後の 3 つの層を除くすべての層を抽出します。

layersTransfer = net.Layers(1:end-3);

最後の 3 つの層を全結合層、ソフトマックス層、および分類出力層に置き換えることによって、層を新しい分類タスクに転移させます。新しいデータに従って新しい全結合層のオプションを指定します。全結合層のサイズが新しいデータのクラス数と同じになるように設定します。新しい層での学習速度を転移層より速くするには、全結合層の WeightLearnRateFactor および BiasLearnRateFactor の値を大きくします。

numClasses = numel(categories(imdsTrain.Labels))
numClasses = 5
layers = [
    layersTransfer
    fullyConnectedLayer(numClasses,'WeightLearnRateFactor',20,'BiasLearnRateFactor',20)
    softmaxLayer
    classificationLayer];

ネットワークの学習

ネットワークにはサイズが 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, ...
    'InitialLearnRate',1e-4, ...
    'Shuffle','every-epoch', ...
    'ValidationData',augimdsValidation, ...
    'ValidationFrequency',3, ...
    'Verbose',false, ...
    'Plots','training-progress');

転移層と新しい層とで構成されるネットワークに学習させます。既定で、trainNetwork は、使用可能な GPU があれば GPU を使用し、なければ CPU を使用します。GPU で学習を行うには、Parallel Computing Toolbox™ とサポートされている GPU デバイスが必要です。サポートされているデバイスについては、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。trainingOptions の名前と値のペアの引数 'ExecutionEnvironment' を使用して、実行環境を指定することもできます。

netTransfer = trainNetwork(augimdsTrain,layers,options);

検証イメージの分類

微調整したネットワークを使用して検証イメージを分類します。

[YPred,scores] = classify(netTransfer,augimdsValidation);

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 = 1

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

参照

[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

参考

| | |

関連するトピック