Main Content

ロゴ認識ネットワーク

この例では、深層学習を使用するロゴ分類用途のコード生成を説明します。LogoNet と呼ばれる事前学習済みのネットワークを使用し、入力イメージを 32 個のロゴ カテゴリに分類します。この例では、前処理された学習データ セットを使用してネットワークに学習させる方法も説明します。最後に、この例では codegen コマンドを使用して MEX 関数を生成し、予測を実行します。

この例では、次の概念を説明します。

  • ロゴを抽出し、そのサイズを 227×227×3 に変更することによる学習イメージの前処理。その後のイメージ拡張を使用した学習データのサイズの拡大。

  • モーメンタム項付き確率的勾配降下法 (SGDM) オプティマイザーを使用したネットワークの学習。

  • CUDA® MEX の生成と MEX の実行。

サードパーティの必要条件

必須

この例では、CUDA MEX を生成します。CUDA 対応 NVIDIA® GPU および互換性のあるドライバーが必要です。

オプション

スタティック ライブラリ、ダイナミック ライブラリ、または実行可能ファイルなどの MEX 以外のビルドについて、この例では以下の要件も適用されます。

GPU 環境の検証

この例を実行するためのコンパイラおよびライブラリが正しく設定されていることを確認するために、関数coder.checkGpuInstall (GPU Coder)を使用します。

envCfg = coder.gpuEnvConfig('host');
envCfg.DeepLibTarget = 'cudnn';
envCfg.DeepCodegen = 1;
envCfg.Quiet = 1;
coder.checkGpuInstall(envCfg);

ロゴ認識ネットワーク

ロゴは、ユーザーがブランドを識別したり認識したりするのに役立ちます。多くの企業が広告、ドキュメント資料、プロモーションに自社のロゴを取り入れています。ロゴ認識ネットワークは MATLAB® で開発されたものであり、22 個の層が含まれています。ネットワークには、畳み込み最大プーリング層が 4 セット、全結合層が 3 セット、計算量を減らすドロップアウト層が複数あります。ネットワークは、サイズが 227×227×3 の入力イメージを受け取り、それを 32 個のロゴ カテゴリに分類します。このネットワークは認識に焦点を当てているため、位置推定を必要としない用途で使用できます。ネットワークの学習は、Flickr32Logos[1] と Flickr32 Plus[2] という学習データ セットを使用して MATLAB で行われました。2 つのデータ セットは、各ロゴにつき約 200 個のイメージを含んでいます。ネットワークの学習は、モーメンタム項付き確率的勾配降下法 (SGDM) オプティマイザーを使用して、学習率 0.0001、エポック数 40、ミニバッチのサイズ 45 で行いました。この例では既定で、事前学習済みのロゴ認識ネットワークを使用します。事前学習済みのネットワークを使用することで、学習の完了を待つことなく例全体を実行できます。

ネットワークに学習させるには、次のコードで変数 doTrainingtrue に設定します。また、Deep Learning for Logo Recognition から Logos-32plus データ セットをダウンロードし、Logos-32plus_v1.0.1.zip ファイルのダウンロード場所を logozipPath に指定しなければなりません。Logos-32plus データ セットのサイズは 1.95 GB です。インターネット接続の速度によっては、ダウンロード プロセスに時間がかかることがあります。データ セットには、合計 7830 枚のさまざまなブランドのロゴ イメージを含む 32 個のイメージ サブフォルダーがあります。groundtruth MAT ファイルは、各イメージのロゴの境界ボックスの情報を提供します。

関数 preprocessLogoData は、ネットワーク学習用にデータを前処理します。Logos-32plus データ セット内のイメージのサイズは可変です。イメージのサイズはネットワークの入力層のサイズ (227×227×3) に合わせて変更しなければなりません。イメージには、削除しなければならないバックグラウンド情報も含まれています。preprocessLogoData.m は、境界ボックスの情報を使用してロゴを抽出し、ネットワークの学習に使用できる imageDatastore オブジェクトを作成することにより、これらの手順を実行します。関数 trainLogonet は、ロゴ認識層を作成し、指定した学習オプションを使用してネットワークに学習させます。ネットワークには、各ロゴにつき約 110 個のイメージが含まれる学習データを使用して学習させます。

データ拡張を使用して学習サンプルの数を増やすこともできます。データ拡張は、ネットワークで過適合が発生したり、学習イメージの正確な詳細が記憶されたりすることを防止するのに役立ちます。学習データを増やすために、ランダム反転、ガウスぼかし、せん断、およびコントラスト正規化の 4 種類のデータ拡張が提供されています。データ拡張を使用するには、次のコードで変数 doAugmentationtrue に設定します。

doTraining = false;

if ~doTraining
    getLogonet;
else
    logozipPath  = '';% provide path of the downloaded zip file
    zipData = fullfile(logozipPath,'Logos-32plus_v1.0.1.zip');
    unpackedData = fullfile(logozipPath,'Logos32plus');
    
    if ~exist(unpackedData,'dir')
        unzip(zipData,unpackedData);
    end

    doAugmentation = false;
    logoData = preprocessLogoData(unpackedData,doAugmentation);
    trainLogonet(logoData);
end

load('LogoNet.mat');
convnet
convnet = 
  SeriesNetwork with properties:

         Layers: [22×1 nnet.cnn.layer.Layer]
     InputNames: {'imageinput'}
    OutputNames: {'classoutput'}

ネットワーク アーキテクチャを表示するには、関数analyzeNetworkを使用します。

analyzeNetwork(convnet)

エントリポイント関数 logonet_predict

エントリポイント関数 logonet_predict.m は、イメージ入力を受け取り、LogoNet.mat ファイルに保存されている深層学習ネットワークを使用して、イメージについて予測を実行します。この関数は、LogoNet.mat からネットワーク オブジェクトを永続変数 logonet に読み込み、それ以降の予測の呼び出しではこの永続変数を再利用します。

type('logonet_predict.m')
function out = logonet_predict(in)
%#codegen

% Copyright 2017-2022 The MathWorks, Inc.

% A persistent object logonet is used to load the network object. At the
% first call to this function, the persistent object is constructed and
% setup. When the function is called subsequent times, the same object is
% reused to call predict on inputs, thus avoiding reconstructing and
% reloading the network object.
persistent logonet;

if isempty(logonet)
    
    logonet = coder.loadDeepLearningNetwork('LogoNet.mat','logonet');
end

out = logonet.predict(in);

end

関数 logonet_predict の CUDA MEX の生成

MEX ターゲットの GPU 構成オブジェクトを作成し、ターゲット言語を C++ に設定します。関数coder.DeepLearningConfig (GPU Coder)を使用して、CuDNN 深層学習構成オブジェクトを作成します。これを GPU コード構成オブジェクトの DeepLearningConfig プロパティに割り当てます。CUDA MEX を生成するには、codegen コマンドを使用し、入力のサイズを [227,227,3] に指定します。この値は logonet ネットワークの入力層サイズに対応します。

cfg = coder.gpuConfig('mex');
cfg.TargetLang = 'C++';
cfg.DeepLearningConfig = coder.DeepLearningConfig('cudnn');
codegen -config cfg logonet_predict -args {ones(227,227,3,'uint8')} -report
Code generation successful: View report

生成された MEX の実行

入力イメージを読み込みます。入力イメージに対して logonet_predict_mex を呼び出します。

im = imread('test.png');
imshow(im);

im = imresize(im, [227,227]);
predict_scores = logonet_predict_mex(im);

上位 5 つの予測スコアを Wordnet 辞書の synset (ロゴ) に含まれる単語にマッピングします。

synsetOut = convnet.Layers(end).Classes;

[val,indx] = sort(predict_scores, 'descend');
scores = val(1:5)*100;
top5labels = synsetOut(indx(1:5));

上位 5 つの分類ラベルを表示します。

outputImage = zeros(227,400,3, 'uint8');
for k = 1:3
    outputImage(:,174:end,k) = im(:,:,k);
end

scol = 1;
srow = 20;

for k = 1:5
    outputImage = insertText(outputImage, [scol, srow],...
        [char(top5labels(k)),' ',num2str(scores(k),'%2.2f'),'%'],...
        'TextColor', 'w','FontSize',15, 'BoxColor', 'black');
    srow = srow + 20;
end

 imshow(outputImage);

メモリに読み込まれた静的ネットワーク オブジェクトをクリアします。

clear mex;

参考文献

[1] Romberg, Stefan, Lluis Garcia Pueyo, Rainer Lienhart, and Roelof van Zwol. "Scalable Logo Recognition in Real-World Images." ACM International Conference on Multimedia Retrieval 2011 (ICMR11): 1-8. https://doi.org/10.1145/1991996.1992021

[2] Bianco, Simone, Marco Buzzelli, Davide Mazzini, and Raimondo Schettini. "Deep Learning for Logo Recognition." Neurocomputing 245 (2017): 23-30. https://doi.org/10.1016/j.neucom.2017.03.051.

関連するトピック