SOLOv2 を使用したインスタンス セグメンテーションの実行
この例では、深層学習 SOLOv2 ネットワークを使用して、ビン内のランダムに回転する機械部品のオブジェクト インスタンスをセグメント化する方法を示します。
インスタンス セグメンテーションは、オブジェクトを検出して位置を推定すると同時に、検出された各インスタンスのセグメンテーション マップを生成するコンピューター ビジョン技術です。SOLOv2 を使用したインスタンス セグメンテーションの詳細については、Get Started with SOLOv2 for Instance Segmentationを参照してください。
この例では、最初に、単一のクラスを検出できる事前学習済みの SOLOv2 ネットワークを使用してインスタンスのセグメンテーションを実行する方法を示します。次に、オプションで転移学習を使用して SOLOv2 ネットワークの構成および学習を行い、予測結果を評価できます。
事前学習済み SOLOv2 ネットワークのダウンロード
既定では、この例では、補助関数 downloadTrainedNetwork を使用して、SOLOv2 インスタンス セグメンテーション ネットワークの事前学習済みバージョンをダウンロードします。補助関数は、この例にサポート ファイルとして添付されています。事前学習済みのネットワークを使用することで、学習の完了を待たずに例全体を実行できます。
trainedSOLOv2_url = "https://ssd.mathworks.com/supportfiles/vision/data/trainedSOLOv2BinDataset.zip";
downloadTrainedNetwork(trainedSOLOv2_url,pwd);Downloading pretrained network. This can take several minutes to download... Done.
load("trainedSOLOv2.mat");ビン ピッキング データセットのダウンロード
この例では、ビン ピッキング データ セットを使用します。データ セットには、Simulink® ソフトウェアで生成された 3 次元パイプ コネクタの 150 個のイメージが格納されています。データは、さまざまな視角やさまざまなライティング条件での、ビン内にランダムな向きで置かれた機械部品のイメージで構成されています。データ セットには、すべてのイメージ内のすべてのオブジェクトについてインスタンス マスク情報が含まれており、すべての種類の機械部品が 1 つのクラスに結合されています。
データ セットの場所として dataDir を指定します。補助関数 downloadBinObjectData を使用してデータ セットをダウンロードします。この関数は、この例にサポート ファイルとして添付されています。
dataDir = fullfile(tempdir,"BinDataset"); dataset_url = "https://ssd.mathworks.com/supportfiles/vision/data/binDataset.zip"; downloadBinObjectData(dataset_url,dataDir);
インスタンス セグメンテーションの実行
データ セットからサンプル イメージを読み取ります。
sampleImage = imread("testBinDataImage.png");関数segmentObjectsを使用して、各オブジェクト インスタンスのマスク、ラベル、および信頼度スコアを予測します。
[masks,labels,scores] = segmentObjects(net,sampleImage,Threshold=0.4);
関数insertObjectMaskを使用して、イメージの上にインスタンス マスクを重ねて表示します。関数linesを使用してカラーマップを指定し、各オブジェクト インスタンスが異なる色で表示されるようにします。補助関数 getBoxFromMask を使用して、セグメント化された各オブジェクト インスタンスに対応する境界ボックスを生成し、確率スコアをラベルとしてイメージ上に重ね合わせます。
maskColors = lines(numel(labels)); overlayedMasks = insertObjectMask(sampleImage,masks,MaskColor=maskColors); imshow(overlayedMasks) boxes = getBoxFromMask(masks); showShape("rectangle",boxes,Label="Scores: "+num2str(scores),LabelOpacity=0.4);

学習用データの準備
MAT ファイルから注釈データを読み取るファイル データストアを作成します。この例にサポート ファイルとして添付されている関数 matReaderBinData を使用し、MAT ファイルを解析して、対応する学習データを、イメージ データ、境界ボックス、オブジェクト マスク、およびラベルを格納する 1 行 4 列の cell 配列として返します。
annsDir = fullfile(dataDir,"synthetic_parts_dataset","annotations"); ds = fileDatastore(annsDir,FileExtensions=".mat",ReadFcn=@(x)matReaderBinData(x,dataDir));
データの分割
この例の再現性を向上させるには、グローバルな乱数の状態を既定の状態に設定します。
rng("default");データを学習セット、検証セット、テスト セットに分割します。イメージの総数が比較的少ないため、データの比較的大部分 (70%) を学習に割り当てます。検証用に 15% を割り当て、残りをテスト用に割り当てます。
numImages = length(ds.Files); numTrain = floor(0.7*numImages); numVal = floor(0.15*numImages); shuffledIndices = randperm(numImages); trainDS = subset(ds,shuffledIndices(1:numTrain)); valDS = subset(ds,shuffledIndices(numTrain+1:numTrain+numVal)); testDS = subset(ds,shuffledIndices(numTrain+numVal+1:end));
学習データの可視化
ファイル データストアの学習サブセットからサンプル イメージを読み取って、学習用のグラウンド トゥルース データをプレビューします。
gsSample = preview(trainDS);
gsImg = gsSample{1};
boxes = gsSample{2};
labels = gsSample{3};
masks = gsSample{4};関数 insertObjectMasks を使用してインスタンス マスクおよび対応する境界ボックスとラベルをサンプル イメージに重ね合わせることにより、グラウンド トゥルース データを可視化します。
overlayedMasks = insertObjectMask(gsImg,masks,Opacity=0.5); imshow(overlayedMasks) showShape("rectangle",boxes,Label=string(labels),Color="green");

SOLOv2 ネットワーク アーキテクチャの定義
solov2オブジェクトを使用して、SOLOv2 インスタンス セグメンテーション モデルを作成します。COCO データ セットで学習させた事前学習済み SOLOv2 インスタンス セグメンテーション ネットワークの名前を指定します。クラス名、推定アンカー ボックス、およびネットワーク入力サイズを指定します。オプションの名前と値の引数 InputSize を使用して入力サイズを指定し、すべてのイメージのサイズが変更されるようにします。
networkToTrain = solov2("resnet50-coco","Object",InputSize=[736 1280 3]);
学習オプションの指定
関数trainingOptions (Deep Learning Toolbox)を使用してネットワーク学習オプションを指定します。SGDM ソルバーを使用して、インスタンス セグメンテーション ネットワークに 5 エポック学習させます。エポックごとの学習率低下係数を 0.99 に指定します。最初の反復で確実に勾配が収束するようにするには、名前と値の引数 GradientThreshold を 35 に設定します。名前と値の引数 ValidationData を検証データ valDS として指定します。
options = trainingOptions("sgdm", ... InitialLearnRate=0.0005, ... LearnRateSchedule="piecewise", ... LearnRateDropPeriod=1, ... LearnRateDropFactor=0.99, ... Momentum=0.9, ... MaxEpochs=5, ... MiniBatchSize=4, ... ExecutionEnvironment="auto", ... VerboseFrequency=5, ... Plots="training-progress", ... ResetInputNormalization=false, ... ValidationData=valDS, ... ValidationFrequency=25, ... GradientThreshold=35, ... OutputNetwork="best-validation-loss");
SOLOv2 ネットワークの学習
ネットワークに学習させるには、変数 doTraining を true に設定します。関数trainSOLOV2を使用してネットワークに学習させます。事前学習済みのバックボーン ネットワークから抽出された特徴を再利用してデータ セットの検出ヘッドを最適化するには、名前と値の引数 FreezeSubNetwork を指定して、特徴抽出サブネットワークを凍結します。
可能であれば、1 つ以上の GPU で学習を行います。GPU を使用するには、Parallel Computing Toolbox™ ライセンスと CUDA® 対応の NVIDIA® GPU が必要です。詳細については、GPU 計算の要件 (Parallel Computing Toolbox)を参照してください。学習には 24 GB のメモリを搭載した NVIDIA Titan RTX™ で約 15 分を要します。
doTraining =false; if doTraining net = trainSOLOV2(trainDS,networkToTrain,options,FreezeSubNetwork="backbone"); modelDateTime = string(datetime("now",Format="yyyy-MM-dd-HH-mm-ss")); save(fullfile(tempdir,"trainedSOLOv2"+modelDateTime+".mat"), ... "net"); else load("trainedSOLOv2.mat"); end
学習済みの SOLOv2 ネットワークの評価
平均適合率を測定して、学習済みの SOLOv2 ネットワークを評価します。適合率は、ネットワークがオブジェクトを正しく分類する能力を定量化したものです。
すべてのテスト イメージのインスタンスのマスクを検出します。
resultsDS = segmentObjects(net,testDS,Threshold=0.1);
Running SoloV2 network -------------------------- * Processed 23 images.
関数evaluateInstanceSegmentationを使用して、平均適合率 (AP) メトリクスおよび平均適合率の平均 (mAP) メトリクスを計算します。この例では、オブジェクトが 1 つのクラスにのみ存在するため、AP と mAP は同じになります。
metrics = evaluateInstanceSegmentation(resultsDS,testDS,0.5); summarize(metrics)
ans=1×3 table
NumObjects mAPOverlapAvg mAP0.5
__________ _____________ _______
184 0.98784 0.98784
すべてのテスト イメージのメトリクスを表示して、期待どおりに実行されていないイメージを特定します。
display(metrics.ImageMetrics)
23×3 table
NumObjects APOverlapAvg AP
__________ ____________ __________
1 8 1 {[ 1]}
2 8 1 {[ 1]}
3 8 1 {[ 1]}
4 8 1 {[ 1]}
5 8 1 {[ 1]}
6 8 1 {[ 1]}
7 8 0.85938 {[0.8594]}
8 8 1 {[ 1]}
9 8 1 {[ 1]}
10 8 1 {[ 1]}
11 8 1 {[ 1]}
12 8 1 {[ 1]}
13 8 0.85938 {[0.8594]}
14 8 1 {[ 1]}
15 8 1 {[ 1]}
16 8 1 {[ 1]}
17 8 1 {[ 1]}
18 8 1 {[ 1]}
19 8 1 {[ 1]}
20 8 1 {[ 1]}
21 8 1 {[ 1]}
22 8 1 {[ 1]}
23 8 1 {[ 1]}
適合率/再現率 (PR) 曲線は、さまざまなレベルの再現率におけるインスタンス セグメンテーション モデルの適合率を示しています。すべてのレベルの再現率で適合率が 1 になるのが理想的です。関数 evaluateInstanceSegmentation の出力から、適合率、再現率、平均適合率のメトリクスを抽出します。
[precision,recall] = precisionRecall(metrics); averagePrecision = averagePrecision(metrics);
テスト データの PR 曲線をプロットします。
figure
plot(recall{:},precision{:})
title(sprintf("Average Precision for Single Class Instance Segmentation: " + "%.2f",averagePrecision))
xlabel("Recall")
ylabel("Precision")
grid on
サポート関数
関数 getBoxFromMask は、インスタンス マスクを境界ボックスに変換します。
function boxes = getBoxFromMask(masks) for idx = 1:size(masks,3) mask = masks(:,:,idx); [ptsR, ptsC] = find(mask); minR = min(ptsR); maxR = max(ptsR); minC = min(ptsC); maxC = max(ptsC); boxes(idx,:) = [minC minR maxC-minC maxR-minR]; end end
参考
solov2 | segmentObjects | trainSOLOV2 | evaluateInstanceSegmentation | insertObjectMask
トピック
- Get Started with SOLOv2 for Instance Segmentation
- MATLAB による深層学習 (Deep Learning Toolbox)
- 深層学習用のデータストア (Deep Learning Toolbox)
