ロゴ認識ネットワーク
この例では、深層学習を使用するロゴ分類用途のコード生成を説明します。LogoNet と呼ばれる事前学習済みのネットワークを使用し、入力イメージを 32 個のロゴ カテゴリに分類します。この例では、前処理済みの学習データ セットを使用してネットワークに学習させる方法についても説明します。最後に、この例では codegen
コマンドを使用して MEX 関数を生成し、予測を実行します。
この例では、以下の概念を説明します。
ロゴを抽出し、227×227×3 にサイズ変更して、学習イメージを前処理する。続いて、イメージ拡張を使用して学習データのサイズを増やす。
モーメンタム項付き確率的勾配降下法 (SGDM) オプティマイザーを使用してネットワークに学習させる。
CUDA® MEX を生成し、MEX を実行する。
サードパーティの必要条件
必須
この例では、CUDA MEX を生成します。CUDA 対応 NVIDIA® GPU および互換性のあるドライバーが必要です。
オプション
スタティック ライブラリ、ダイナミック ライブラリ、または実行可能ファイルなどの MEX 以外のビルドについて、この例では以下の要件も適用されます。
NVIDIA Toolkit。
NVIDIA cuDNN ライブラリ。
コンパイラおよびライブラリの環境変数。詳細については、サードパーティ ハードウェアと前提条件となる製品の設定を参照してください。
GPU 環境の検証
関数coder.checkGpuInstall
を使用して、この例を実行するためのコンパイラおよびライブラリが正しく設定されていることを検証します。
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 で学習させました。この例では既定で、事前学習済みのロゴ認識ネットワークを使用します。事前学習済みのネットワークを使用することで、学習の完了を待つことなく例全体を実行できます。
ネットワークに学習させるには、次のコードで変数 doTraining
を true
に設定します。また、Deep Learning for Logo Recognition から Logos-32plus データ セットをダウンロードし、logozipPath
に、ダウンロードした Logos-32plus_v1.0.1.zip ファイルの場所を指定しなければなりません。Logos-32plus データ セットのサイズは 1.95 GB です。インターネット接続の速度によっては、ダウンロード プロセスに時間がかかることがあります。データ セットには、32 個のイメージ サブフォルダーがあり、さまざまなブランドの合計 7830 個のロゴ イメージが含まれます。groundtruth MAT ファイルは、各イメージのロゴの境界ボックス情報を提供します。
関数 preprocessLogoData
は、ネットワークに学習させるためにデータを前処理します。Logos-32plus データ セットのイメージはサイズがさまざまです。ネットワークの入力層のサイズ (227×227×3) に合わせてイメージのサイズを変更しなければなりません。イメージには、削除しなければならない背景情報も含まれています。preprocessLogoData.m
は、境界ボックス情報を使用してロゴを抽出し、ネットワークに学習させるために使用できる imageDatastore
オブジェクトを作成することにより、これらの手順を実行します。関数 trainLogonet
は、ロゴ認識層を作成し、指定された学習オプションを使用してネットワークに学習させます。ネットワークには、各ロゴに対して少なくとも 110 個のイメージを含むデータを使用して学習させます。
データ拡張を使用して、学習サンプルの数を増やすこともできます。データ拡張は、ネットワークで過適合が発生したり、学習イメージの正確な詳細が記憶されたりすることを防止するのに役立ちます。学習データを増やすために、ランダム反転、ガウスぼかし、せん断、コントラスト正規化の 4 種類のデータ拡張が用意されています。データ拡張を使用するには、次のコードで変数 doAugmentation
を true
に設定します。
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
(Deep Learning Toolbox)を使用します。
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
を使用して 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.