Main Content

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

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

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

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

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

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

  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")
imgLayer = 
  ImageInputLayer with properties:

                      Name: 'input_1'
                 InputSize: [300 300 3]
        SplitComplexInputs: 0

   Hyperparameters
          DataAugmentation: 'none'
             Normalization: 'zerocenter'
    NormalizationDimension: 'auto'
                      Mean: []

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

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

関数 analyzeNetwork を使用して、ネットワーク内の層を表示および検査します。

analyzeNetwork(lgraph);

特徴抽出層の選択

YOLO v2 の特徴抽出層は、出力特徴幅と高さが入力イメージより 8 ~ 16 倍小さいと最も効果的です。この量のダウンサンプリングは空間分解能と出力される特徴の品質とのトレードオフです。関数 analyzeNetwork またはディープ ネットワーク デザイナー アプリを使用して、ネットワーク内の層の出力サイズを決定できます。最適な特徴抽出層の選択には、実証的評価が必要であることに注意してください。

特徴抽出層を "block_12_add" に設定します。この層の出力サイズは、300×300 の入力イメージ サイズの 16 分の 1 です。

featureExtractionLayer = "block_12_add";

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

次に、関数 removeLayers を使用して、特徴抽出層の後の層をすべて削除します。

index = find(strcmp({lgraph.Layers(1:end).Name},featureExtractionLayer));
lgraph = removeLayers(lgraph,{lgraph.Layers(index+1:end).Name});

YOLO v2 検出サブネットワークの作成

検出サブネットワークは直列で接続された畳み込み層、ReLU 層、バッチ正規化層のグループで構成されます。これらの層に yolov2TransformLayeryolov2OutputLayer が続きます。

まず、直列で接続された畳み込み層、ReLU 層、バッチ正規化層のグループを 2 つ作成します。畳み込み層のフィルター サイズを 3 x 3 に設定し、特徴抽出層の出力に含まれるチャネルの数に合わせてフィルター数を設定します。畳み込み層のパディングに "same" を指定して、入力のサイズを保持します。

filterSize = [3 3];
numFilters = 96;

detectionLayers = [
    convolution2dLayer(filterSize,numFilters,"Name","yolov2Conv1","Padding", "same", "WeightsInitializer",@(sz)randn(sz)*0.01)
    batchNormalizationLayer("Name","yolov2Batch1")
    reluLayer("Name","yolov2Relu1")
    convolution2dLayer(filterSize,numFilters,"Name","yolov2Conv2","Padding", "same", "WeightsInitializer",@(sz)randn(sz)*0.01)
    batchNormalizationLayer("Name","yolov2Batch2")
    reluLayer("Name","yolov2Relu2")
    ]
detectionLayers = 
  6x1 Layer array with layers:

     1   'yolov2Conv1'    2-D Convolution       96 3x3 convolutions with stride [1  1] and padding 'same'
     2   'yolov2Batch1'   Batch Normalization   Batch normalization
     3   'yolov2Relu1'    ReLU                  ReLU
     4   'yolov2Conv2'    2-D Convolution       96 3x3 convolutions with stride [1  1] and padding 'same'
     5   'yolov2Batch2'   Batch Normalization   Batch normalization
     6   'yolov2Relu2'    ReLU                  ReLU

次に、検出サブネットワークの最後の部分を作成します。この部分には畳み込み層があり、さらに yolov2TransformLayeryolov2OutputLayer が続きます。畳み込み層の出力は、各アンカー ボックスについて以下を予測します。

  1. オブジェクト クラスの確率。

  2. x と y の位置のオフセット。

  3. 幅と高さのオフセット。

アンカー ボックスとクラス数を指定し、畳み込み層のフィルター数を計算します。

numClasses = 5;

anchorBoxes = [
    16 16
    32 16
    ];

numAnchors = size(anchorBoxes,1);
numPredictionsPerAnchor = 5;
numFiltersInLastConvLayer = numAnchors*(numClasses+numPredictionsPerAnchor);

convolution2dLayeryolov2TransformLayer、および yolov2OutputLayer を検出サブネットワークに追加します。

detectionLayers = [
    detectionLayers
    convolution2dLayer(1,numFiltersInLastConvLayer,"Name","yolov2ClassConv",...
    "WeightsInitializer", @(sz)randn(sz)*0.01)
    yolov2TransformLayer(numAnchors,"Name","yolov2Transform")
    yolov2OutputLayer(anchorBoxes,"Name","yolov2OutputLayer")
    ]
detectionLayers = 
  9x1 Layer array with layers:

     1   'yolov2Conv1'         2-D Convolution            96 3x3 convolutions with stride [1  1] and padding 'same'
     2   'yolov2Batch1'        Batch Normalization        Batch normalization
     3   'yolov2Relu1'         ReLU                       ReLU
     4   'yolov2Conv2'         2-D Convolution            96 3x3 convolutions with stride [1  1] and padding 'same'
     5   'yolov2Batch2'        Batch Normalization        Batch normalization
     6   'yolov2Relu2'         ReLU                       ReLU
     7   'yolov2ClassConv'     2-D Convolution            20 1x1 convolutions with stride [1  1] and padding [0  0  0  0]
     8   'yolov2Transform'     YOLO v2 Transform Layer.   YOLO v2 Transform Layer with 2 anchors.
     9   'yolov2OutputLayer'   YOLO v2 Output             YOLO v2 Output with 2 anchors.

YOLO v2 検出ネットワークの完了

特徴抽出ネットワークに検出サブネットワークを接続します。

lgraph = addLayers(lgraph,detectionLayers);
lgraph = connectLayers(lgraph,featureExtractionLayer,"yolov2Conv1");

関数 analyzeNetwork を使用して、ネットワークをチェックします。その後、関数 trainYOLOv2ObjectDetector を使用してネットワークに学習させることができます。

analyzeNetwork(lgraph)