メインコンテンツ

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

イメージ分類のためのビジョン変換ネットワークの学習

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

ViT [1] は、変換アーキテクチャを使用してイメージ入力を特徴ベクトルに符号化するニューラル ネットワーク モデルです。このネットワークは、バックボーンおよびヘッドという 2 つの主要コンポーネントで構成されます。バックボーンは、ネットワークの符号化ステップを担当します。バックボーンは、入力イメージを受け取り、特徴ベクトルを出力します。ヘッドは、予測の実行を担当します。ヘッドは、符号化された特徴ベクトルを予測スコアにマッピングします。

この例で使用する事前学習済みの ViT ネットワークには、イメージの強い特徴表現を学習させてあります。転移学習を使用することで、特定のタスクに合わせてこのモデルを微調整できます。この特徴表現を転移学習させて新しいデータ セット用に微調整するには、ネットワークのヘッドをタスク データ分類用の新しいヘッドに置き換えてから、新しいデータ セットでネットワークを微調整します。

次の図は、K 個のクラスの予測を行う ViT ネットワークのアーキテクチャ、および K* 個のクラスを含む新しいデータ セットの転移学習を可能にするためのネットワーク編集方法の概要を示しています。

この例では、解像度 384×384 の ImageNet 2012 データ セットを使用し、パッチ サイズが 16 である基本サイズの ViT モデル (パラメーター数 8,680 万個) を微調整します。

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

visionTransformer (Computer Vision Toolbox)関数を使用して、事前学習済みの ViT ネットワークを読み込みます。この関数には、Deep Learning Toolbox™ ライセンスと Computer Vision Toolbox™ Model for Vision Transformer Network サポート パッケージが必要です。このサポート パッケージは、アドオン エクスプローラーからダウンロードできます。このサポート パッケージがインストールされていない場合、関数によってダウンロード用リンクが表示されます。

net = visionTransformer
net = 
  dlnetwork with properties:

         Layers: [143×1 nnet.cnn.layer.Layer]
    Connections: [167×2 table]
     Learnables: [200×3 table]
          State: [0×3 table]
     InputNames: {'imageinput'}
    OutputNames: {'softmax'}
    Initialized: 1

  View summary with summary.

ネットワークの入力サイズを表示します。

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

   384   384     3

ViT ネットワークを微調整するには、通常、注意層のみを微調整し、他の学習可能なパラメーターを固定します [2]。この例にサポート ファイルとして添付されている freezeNetwork 関数を使用し、ネットワークの重みを固定します。この関数にアクセスするには、例をライブ スクリプトとして開きます。

net = freezeNetwork(net,LayersToIgnore="SelfAttentionLayer");

学習データの読み込み

Flowers データ セット [3] をダウンロードし、解凍します。このデータ セットのサイズは約 218 MB です。このデータ セットには、5 つのクラス ("デイジー""タンポポ""バラ""ヒマワリ"、および "チューリップ") に属する 3670 個の花のイメージが格納されています。

url = "http://download.tensorflow.org/example_images/flower_photos.tgz";
downloadFolder = tempdir;
filename = fullfile(downloadFolder,"flower_dataset.tgz");

imageFolder = fullfile(downloadFolder,"flower_photos");
if ~datasetExists(imageFolder)
    disp("Downloading Flowers data set (218 MB)...")
    websave(filename,url);
    untar(filename,downloadFolder)
end

イメージを含むイメージ データストアを作成します。

imds = imageDatastore(imageFolder,IncludeSubfolders=true,LabelSource="foldernames");

クラス数を表示します。

classNames = categories(imds.Labels);
numClasses = numel(categories(imds.Labels))
numClasses = 5

splitEachLabel 関数を使用して、データストアを学習用、検証用、テスト用のパーティションに分割します。イメージの 80% を学習に使用し、検証用に 10%、テスト用に 10% を確保します。

[imdsTrain,imdsValidation,imdsTest] = splitEachLabel(imds,0.8,0.1);

学習を改善するには、ランダムな回転、スケーリング、および水平反転が含まれるように学習データを拡張します。ネットワークの入力サイズと一致するようにイメージのサイズを変更します。

augmenter = imageDataAugmenter( ...
    RandXReflection=true, ...
    RandRotation=[-90 90], ...
    RandScale=[1 2]);
augimdsTrain = augmentedImageDatastore(inputSize(1:2),imdsTrain,DataAugmentation=augmenter);

検証イメージとテスト イメージのサイズをネットワークの入力サイズと一致するように変更する拡張イメージ データストアを作成します。検証データとテスト データに追加の拡張を適用しないでください。

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

ネットワーク分類ヘッドの置き換え

ViT ネットワークには 2 つの主要コンポーネントがあります。ネットワーク本体は、入力イメージから特徴を抽出します。分類ヘッドは、抽出された特徴を、各クラスの予測スコアを表す確率ベクトルにマッピングします。ニューラル ネットワークに学習させて新しいクラスのセットでイメージを分類するには、分類ヘッドを、抽出された特徴を新しいクラスのセットの予測スコアにマッピングする新しい分類ヘッドに置き換えます。

analyzeNetwork 関数を使用してネットワーク アーキテクチャを表示します。抽出された特徴を予測スコアのベクトルにマッピングする層を、ネットワークの最後に配置します。この場合、"head" という名前の全結合層は、抽出された特徴を長さ 1000 のベクトルにマッピングします。この長さは、ネットワークに学習させた予測対象クラスの数です。"softmax" という名前のソフトマックス層は、それらのベクトルを確率ベクトルにマッピングします。

analyzeNetwork(net)

学習データ内のクラス数と一致する出力サイズをもつ新しい全結合層を作成します。

  • 出力サイズを学習データのクラス数に設定します。

  • 層の名前を "head" に設定します。

layer = fullyConnectedLayer(numClasses,Name="head");

replaceLayer関数を使用し、全結合層を新しい層に置き換えます。ソフトマックス層は学習可能なパラメーターがないため、置き換える必要がありません。

net = replaceLayer(net,"head",layer);

学習オプションの指定

学習オプションを指定します。オプションの中から選択するには、経験的解析が必要です。実験を実行してさまざまな学習オプションの構成を調べるには、実験マネージャーアプリを使用できます。

  • Adam オプティマイザーを使用して学習させます。

  • 微調整を行うため、学習率を 0.0001 に下げます。

  • 学習を 4 エポック行います。

  • ミニバッチ サイズとして 12 を使用します。ViT ネットワークの学習には、通常、大量のメモリが必要です。メモリが不足する場合は、より小さいミニバッチ サイズを使用してみてください。または、visionTransformer 関数でモデル名として "tiny-16-imagenet-384" を指定し、小型の ViT モデル (パラメーター数 570 万個) などのより小さなモデルを使用してみてください。

  • エポックごとに 1 回、検証データを使用してネットワークを検証します。

  • 検証損失が最も少ないネットワークを出力します。

  • 学習の進行状況をプロットで監視し、精度メトリクスを監視します。

  • 詳細出力を無効にします。

miniBatchSize = 12;

numObservationsTrain = numel(augimdsTrain.Files);
numIterationsPerEpoch = floor(numObservationsTrain/miniBatchSize);

options = trainingOptions("adam", ...
    MaxEpochs=4, ...
    InitialLearnRate=0.0001, ...
    MiniBatchSize=miniBatchSize, ...
    ValidationData=augimdsValidation, ...
    ValidationFrequency=numIterationsPerEpoch, ...
    OutputNetwork="best-validation", ...
    Plots="training-progress", ...
    Metrics="accuracy", ...
    Verbose=false);

ニューラル ネットワークの学習

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

この例では、24 GB の RAM を搭載した NVIDIA Titan RTX GPU を使用してネットワークに学習させます。学習の実行には約 37 分かかります。

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

ニューラル ネットワークのテスト

テスト データを使用して、ネットワークの精度を評価します。

テスト データを使用して予測を行います。予測スコアをクラス ラベルに変換するには、onehotdecode関数を使用します。

YTest = minibatchpredict(net,augimdsTest);
YTest = onehotdecode(YTest,classNames,2);

テストの分類結果を混同行列に表示します。

figure
TTest = imdsTest.Labels;
confusionchart(TTest,YTest)

テストの精度を評価します。

accuracy = mean(YTest == TTest)
accuracy = 0.9564

新しいデータを使用した予測

学習済みのニューラル ネットワークを使用して、テスト データの最初のイメージで予測を行います。

テスト データの最初のファイルからイメージを読み取ります。

idx = 1;
testData = readByIndex(augimdsTest,idx);
I = testData.input{1};

イメージを使用して予測を行います。

Y = minibatchpredict(net,single(I));

onehotdecode 関数を使用して、最も確率の高いラベルを取得します。

label = onehotdecode(Y,classNames,2);

イメージと予測されたラベルを表示します。

imshow(I)
title(label)

fprintf("Image Credit: %s\n",flowerCredit(augimdsValidation.Files(idx)))
Image Credit: CC-BY by mikeyskatie - https://www.flickr.com/photos/mikeyskatie/5948835387/

参考文献

  1. Dosovitskiy, Alexey, Lucas Beyer, Alexander Kolesnikov, Dirk Weissenborn, Xiaohua Zhai, Thomas Unterthiner, Mostafa Dehghani et al. "An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale." Preprint, submitted June 3, 2021. https://doi.org/10.48550/arXiv.2010.11929

  2. Touvron, Hugo, Matthieu Cord, Alaaeldin El-Nouby, Jakob Verbeek, and Hervé Jégou. "Three things everyone should know about vision transformers." In Computer Vision–ECCV 2022, edited by Shai Avidan, Gabriel Brostow, Moustapha Cissé, Giovanni Maria Farinella, and Tal Hassner, 13684: 497-515. Cham: Springer Nature Switzerland, 2022. https://doi.org/10.1007/978-3-031-20053-3_29.

  3. TensorFlow. “Tf_flowers | TensorFlow Datasets.” Accessed June 16, 2023. https://www.tensorflow.org/datasets/catalog/tf_flowers.

参考

(Computer Vision Toolbox) | (Computer Vision Toolbox) | | |

トピック