このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
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);
Downloading Bin Object Dataset. This can take several minutes to download... Done.
インスタンス セグメンテーションの実行
データ セットからサンプル イメージを読み取ります。
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); display(metrics.DatasetMetrics)
1×3 table NumObjects mAP AP __________ _______ __________ 184 0.98784 {[0.9878]}
すべてのテスト イメージのメトリクスを表示して、期待どおりに実行されていないイメージを特定します。
display(metrics.ImageMetrics)
23×3 table NumObjects mAP 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 1 {[ 1]} 8 8 1 {[ 1]} 9 8 1 {[ 1]} 10 8 1 {[ 1]} 11 8 1 {[ 1]} 12 8 1 {[ 1]} 13 8 1 {[ 1]} 14 8 1 {[ 1]} 15 8 1 {[ 1]} 16 8 0.85938 {[0.8594]} 17 8 0.85938 {[0.8594]} 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 = metrics.ClassMetrics.Precision; recall = metrics.ClassMetrics.Recall; averagePrecision = metrics.ClassMetrics.AP;
テスト データの PR 曲線をプロットします。
figure plot(recall{1},precision{1}) title(sprintf("Average Precision for Single Class Instance Segmentation: " + "%.2f",averagePrecision{1})) 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)