Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

SSD オブジェクト検出ネットワークの作成

この例では、事前学習済みの MobileNet v2 ネットワークを変更して SSD オブジェクト検出ネットワークを作成する方法を示します。

事前学習済みネットワークを SSD ネットワークに変換する手順は、イメージ分類の転移学習手順に似ています。

  1. 事前学習済みのネットワークを読み込みます。

  2. 事前学習済みのネットワークから特徴抽出に使用する層を 1 つ以上選択します。

  3. 特徴抽出層の後のすべての層を削除します。

  4. オブジェクト検出タスクをサポートする新しい層を追加します。

事前学習済みのネットワークの読み込み

mobilenetv2 を使用して事前学習済みの MobileNet v2 ネットワークを読み込みます。これには、MobileNet v2 Network™ サポート パッケージの Deep Learning Toolbox モデルが必要です。このサポート パッケージがインストールされていない場合、関数によってダウンロード用リンクが表示されます。ネットワークを読み込んだ後、そのネットワークを layerGraph オブジェクトに変換して、層を操作できるようにします。

net = mobilenetv2();
lgraph = layerGraph(net);

ネットワーク入力サイズの更新

学習データの要件を満たすよう、ネットワーク入力サイズを更新します。たとえば、学習データが 300 x 300 の RGB イメージだと仮定します。入力サイズを設定します。

imageInputSize = [300 300 3];

次に、元の層と同じ名前で、新しいイメージ入力層を作成します。

imgLayer = imageInputLayer(imageInputSize,"Name","input_1");

古いイメージ入力層を、新しいイメージ入力層に置き換えます。

lgraph = replaceLayer(lgraph,"input_1",imgLayer);

特徴抽出層の選択

SSD は複数の特徴マップを使用して、オブジェクトの位置を予測します。通常は、マルチスケールの特徴の利点を活かすために、さまざまな出力サイズをもつ特徴抽出層を選択します。関数 analyzeNetwork またはディープ ネットワーク デザイナー アプリを使用して、ネットワーク内の層の出力サイズを決定できます。最適な特徴抽出層のセットの選択には、実証的評価が必要であることに注意してください。

説明を簡潔にするために、この例では機能抽出層を 1 つ使う場合について説明します。特徴抽出層を "block_12_add" に設定します。

featureExtractionLayer = "block_12_add";

特徴抽出層の後の層の削除

次に、特徴抽出層の後の層を削除します。そのためには、ネットワークをディープ ネットワーク デザイナー アプリへインポートし、層を手動で削除し、変更済みのネットワークをワークスペースへエクスポートします。

この例では、変更済みのネットワークを読み込みます。この例にサポート ファイルとして追加してあったネットワークです。

modified = load("mobilenetv2Block12Add.mat");
lgraph = modified.mobilenetv2Block12Add;

AnchorBoxLayer の接続

アンカー ボックスとオブジェクト クラス数を指定し、anchorBoxLayer を使用してアンカー ボックス層を作成します。

numClasses = 5;

anchorBoxes = [
    16 16
    32 16
    ];

anchorBox = anchorBoxLayer(anchorBoxes,"Name","anchors");

アンカー ボックス層を特徴抽出層に接続します。

lgraph = addLayers(lgraph,anchorBox);
lgraph = connectLayers(lgraph,"block_12_add","anchors");

SSD 分類分岐の作成

畳み込みフィルターの数が numClasses + 1numAnchors 倍と等しい畳み込み層を作成します。この追加クラスは背景クラスです。

numAnchors = size(anchorBoxes,1);
numClassesPlusBackground = numClasses + 1;
numClsFilters = numAnchors * numClassesPlusBackground;
filterSize = 3;
conv = convolution2dLayer(filterSize,numClsFilters,...
    "Name","convClassification",...
    "Padding","same");

畳み込み層を追加し、アンカー ボックス層に接続します。

lgraph = addLayers(lgraph,conv);
lgraph = connectLayers(lgraph,"anchors","convClassification");

SSD 回帰分岐の作成

畳み込みフィルターの数がアンカー ボックスの数の 4 倍と等しい畳み込み層を作成します。

numRegFilters = 4 * numAnchors;
conv = convolution2dLayer(filterSize,numRegFilters,...
    "Name","convRegression",...
    "Padding","same");

畳み込み層を追加し、アンカー ボックス層に接続します。

lgraph = addLayers(lgraph,conv);
lgraph = connectLayers(lgraph,"anchors","convRegression");

分類特徴のマージ

クラスの数と特徴抽出層の数で初期化した ssdMergeLayer を作成します。

numFeatureExtractionLayers = numel(featureExtractionLayer);
mergeClassification = ssdMergeLayer(numClassesPlusBackground,numFeatureExtractionLayers,...
    "Name","mergeClassification");

SSD マージ層を追加し、convClassification 層に接続します。

lgraph = addLayers(lgraph,mergeClassification);
lgraph = connectLayers(lgraph,"convClassification","mergeClassification/in1");

回帰特徴のマージ

アンカー ボックスの位置の調整に使用する座標オフセットの数と特徴抽出層の数で初期化した ssdMergeLayer を作成します。

numCoordinates = 4;
mergeRegression = ssdMergeLayer(numCoordinates,numFeatureExtractionLayers,...
    "Name","mergeRegression");

SSD マージ層を追加し、convRegression 層に接続します。

lgraph = addLayers(lgraph,mergeRegression);
lgraph = connectLayers(lgraph,"convRegression","mergeRegression/in1");

SSD 検出ネットワークの完成

分類分岐を完成させるには、ソフトマックス層と焦点損失層を作成して接続します。

clsLayers = [
    softmaxLayer("Name","softmax")
    focalLossLayer("Name","focalLoss")
    ];

lgraph = addLayers(lgraph,clsLayers);
lgraph = connectLayers(lgraph,"mergeClassification","softmax");

回帰分岐を完成させるには、ボックス回帰層を作成して接続します。

reg = rcnnBoxRegressionLayer("Name","boxRegression");

lgraph = addLayers(lgraph,reg);
lgraph = connectLayers(lgraph,"mergeRegression","boxRegression");

analyzeNetwork を使用して、ネットワークをチェックします。

analyzeNetwork(lgraph)

SSD ネットワークが完成しました。関数 trainSSDObjectDetector を使用して学習させることができます。