Main Content

YOLO v2 オブジェクト検出器の ONNX へのエクスポート

この例では、YOLO v2 オブジェクト検出ネットワークを ONNX™ (Open Neural Network Exchange) モデルの形式にエクスポートする方法を説明します。YOLO v2 ネットワークをエクスポートした後に、このネットワークを他の深層学習フレームワークにインポートして推論を行わせることができます。この例では、インポートした ONNX モデルを使用して推論を行うためのワークフローについても説明します。

YOLO v2 ネットワークのエクスポート

検出ネットワークを ONNX にエクスポートし、オブジェクト検出結果を生成するのに必要なメタデータを収集します。

まず、事前学習済みの YOLO v2 オブジェクト検出器をワークスペースに読み込みます。

input = load("yolov2VehicleDetector.mat");
net = input.detector.Network;

次に、推論で使用する YOLO v2 検出器のメタデータを取得します。この検出器のメタデータには、ネットワーク入力のイメージ サイズ、アンカー ボックス、および最終畳み込み層の活性化サイズが含まれています。

入力 YOLO v2 ネットワークから、ネットワーク入力のイメージ サイズを読み取ります。

inputImageSize = net.Layers(1,1).InputSize;

入力検出器から、学習に使用するアンカー ボックスを読み取ります。

anchorBoxes = input.detector.AnchorBoxes;

関数 analyzeNetwork を使用して、入力ネットワークに含まれる最終畳み込み層の活性化サイズを取得します。

analyzeNetwork(net);

finalActivationSize = [16 16 24];

ONNX モデル形式へのエクスポート

関数exportONNXNetwork (Deep Learning Toolbox)を使用して、YOLO v2 オブジェクト検出ネットワークを ONNX 形式のファイルとしてエクスポートします。ファイル名を yolov2.onnx と指定します。この関数は、エクスポートされた ONNX ファイルを現在の作業フォルダーに保存します。関数 exportONNXNetwork を使用するには、Deep Learning Toolbox™ および Deep Learning Toolbox Converter for ONNX Model Format サポート パッケージが必要です。このサポート パッケージがインストールされていない場合、関数によってダウンロード用リンクが表示されます。

filename = "yolov2.onnx";
exportONNXNetwork(net,filename);

関数 exportONNXNetwork は、入力 YOLO v2 ネットワークに含まれるyolov2TransformLayeryolov2OutputLayerを、それぞれ、基本的な ONNX 演算子と単位行列演算子にマッピングします。このネットワークをエクスポートした後、ONNX のインポートをサポートする深層学習フレームワークに yolov2.onnx ファイルをインポートできます。たとえば、関数 importONNXNetwork を使用して ONNX モデルを MATLAB にインポートし直すことができます。ONNX からモデルをインポートする方法の詳細については、事前学習済みの ONNX YOLO v2 オブジェクト検出器のインポートの例を参照してください。

エクスポートした YOLO v2 ネットワークを使用したオブジェクト検出

エクスポート完了後、深層学習フレームワークに ONNX モデルをインポートし、以下のワークフローを使用してオブジェクト検出を行うことができます。このワークフローでは、ONNX ネットワークに加え、MATLAB ワークスペースから取得した YOLO v2 検出器のメタデータ (inputImageSizeanchorBoxes、および finalActivationSize) が必要になります。以下のコードは、ワークフローを MATLAB で実装したものです。選択したフレームワークに応じて、このコードを等価なコードに変換しなければなりません。

入力イメージの前処理

推論に使用できるように、イメージを前処理します。イメージは、RGB イメージでなければならず、ネットワーク入力のイメージ サイズに合わせてサイズを変更しなければなりません。また、イメージのピクセル値は、区間 [0 1] の範囲内になければなりません。

I = imread('highway.png');
resizedI = imresize(I,inputImageSize(1:2));
rescaledI = rescale(resizedI);

入力の受け渡しと ONNX モデルの実行

選択した深層学習フレームワークで、ONNX モデルを実行します。その際、インポートした ONNX モデルへの入力として、前処理されたイメージを使用します。

ONNX モデルの出力からの予測の抽出

このモデルは以下を予測します。

  • グラウンド トゥルース ボックスとの Intersection over Union (IoU)

  • 各アンカー ボックスの境界ボックス パラメーター xyw、および h

  • 各アンカー ボックスのクラスの確率

ONNX モデルの出力は、予測を含む特徴マップで、そのサイズは predictionsPerAnchor x numAnchors x numGrids です。

  • numAnchors はアンカー ボックスの数です。

  • numGrids は、最終畳み込み層の高さと幅の積として計算されたグリッドの数です。

  • predictionsPerAnchor は、[IoU;x;y;w;h;class probabilities] の形式の出力予測です。

  • 特徴マップの先頭行には、各アンカー ボックスの IoU の予測が格納されます。

  • 特徴マップの 2 行目と 3 行目には、各アンカー ボックスの重心座標 (x,y) の予測が格納されます。

  • 特徴マップの 4 行目と 5 行目には、各アンカー ボックスの幅と高さの予測が格納されます。

  • 特徴マップの 6 行目には、各アンカー ボックスのクラスの確率の予測が格納されます。

最終検出結果の計算

前処理されたテスト イメージの最終検出結果を計算するには、次を実行しなければなりません。

  • ネットワークの入力層のサイズに合わせて境界ボックス パラメーターを再スケーリング。

  • 予測からオブジェクトの信頼度スコアを計算。

  • オブジェクトの信頼度スコアが高い予測を取得。

  • 非最大抑制を実行。

実装ガイドとして、後処理関数yolov2PostProcess のコードを使用してください。

[bboxes,scores,labels] = yolov2PostProcess(featureMap,inputImageSize,finalActivationsSize,anchorBoxes);

検出結果の表示

Idisp = insertObjectAnnotation(resizedI,'rectangle',bboxes,scores);
figure
imshow(Idisp)

後処理関数

function  [bboxes,scores,labels] = yolov2PostProcess(featureMap,inputImageSize,finalActivationsSize,anchorBoxes)

% Extract prediction values from the feature map.
iouPred = featureMap(1,:,:);
xyPred = featureMap(2:3,:,:);
whPred = featureMap(4:5,:,:);
probPred = featureMap(6:end,:,:);

% Rescale the bounding box parameters.
bBoxes = rescaleBbox(xyPred,whPred,anchorBoxes,finalActivationsSize,inputImageSize);

% Rearrange the feature map as a two-dimensional matrix for efficient processing.
predVal = [bBoxes;iouPred;probPred];
predVal = reshape(predVal,size(predVal,1),[]);

% Compute object confidence scores from the rearranged prediction values.
[confScore,idx] = computeObjectScore(predVal);

% Obtain predictions with high object confidence scores.
[bboxPred,scorePred,classPred] = selectMaximumPredictions(confScore,idx,predVal);

% To get the final detections, perform nonmaximum suppression with an overlap threshold of 0.5.
[bboxes,scores,labels] = selectStrongestBboxMulticlass(bboxPred', scorePred', classPred','RatioType','Union','OverlapThreshold',0.5);

end
function bBoxes = rescaleBbox(xyPred,whPred,anchorBoxes,finalActivationsSize,inputImageSize)

% To rescale the bounding box parameters, compute the scaling factor by using the network parameters inputImageSize and finalActivationSize.
scaleY = inputImageSize(1)/finalActivationsSize(1); 
scaleX = inputImageSize(2)/finalActivationsSize(2);
scaleFactor = [scaleY scaleX];

bBoxes = zeros(size(xyPred,1)+size(whPred,1),size(anchors,1),size(xyPred,3),'like',xyPred);
for rowIdx=0:finalActivationsSize(1,1)-1
    for colIdx=0:finalActivationsSize(1,2)-1
        ind = rowIdx*finalActivationsSize(1,2)+colIdx+1;
        for anchorIdx = 1 : size(anchorBoxes,1)
              
            % Compute the center with respect to image.
            cx = (xyPred(1,anchorIdx,ind)+colIdx)* scaleFactor(1,2);
            cy = (xyPred(2,anchorIdx,ind)+rowIdx)* scaleFactor(1,1);
              
            % Compute the width and height with respect to the image.
            bw = whPred(1,anchorIdx,ind)* anchorBoxes(anchorIdx,2);
            bh = whPred(2,anchorIdx,ind)* anchorBoxes(anchorIdx,1);
              
            bBoxes(1,anchorIdx,ind) = (cx-bw/2);
            bBoxes(2,anchorIdx,ind) = (cy-bh/2);
            bBoxes(3,anchorIdx,ind) = bw;
            bBoxes(4,anchorIdx,ind) = bh;
        end
    end
end
end
function [confScore,idx] = computeObjectScore(predVal)
iouPred = predVal(5,:); 
probPred = predVal(6:end,:); 
[imax,idx] = max(probPred,[],1); 
confScore = iouPred.*imax;
end
function [bboxPred,scorePred,classPred] = selectMaximumPredictions(confScore,idx,predVal)
% Specify the threshold for confidence scores.
confScoreId = confScore >= 0.5;
% Obtain the confidence scores greater than or equal to 0.5.
scorePred = confScore(:,confScoreId);
% Obtain the class IDs for predictions with confidence scores greater than
% or equal to 0.5.
classPred = idx(:,confScoreId);
% Obtain the bounding box parameters for predictions with confidence scores
% greater than or equal to 0.5.
bboxesXYWH = predVal(1:4,:);
bboxPred = bboxesXYWH(:,confScoreId);
end

参考文献

[1] Redmon, Joseph, and Ali Farhadi. "YOLO9000: Better, Faster, Stronger." In 2017 IEEE Conference on Computer Vision and Pattern Recognition (CVPR), 6517–25. Honolulu, HI: IEEE, 2017. https://doi.org/10.1109/CVPR.2017.690.