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]

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

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

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

特徴抽出層の選択

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

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

featureExtractionLayer = "block_12_add";

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

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

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

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

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'    Convolution           96 3x3 convolutions with stride [1  1] and padding 'same'
     2   'yolov2Batch1'   Batch Normalization   Batch normalization
     3   'yolov2Relu1'    ReLU                  ReLU
     4   'yolov2Conv2'    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'         Convolution               96 3x3 convolutions with stride [1  1] and padding 'same'
     2   'yolov2Batch1'        Batch Normalization       Batch normalization
     3   'yolov2Relu1'         ReLU                      ReLU
     4   'yolov2Conv2'         Convolution               96 3x3 convolutions with stride [1  1] and padding 'same'
     5   'yolov2Batch2'        Batch Normalization       Batch normalization
     6   'yolov2Relu2'         ReLU                      ReLU
     7   'yolov2ClassConv'     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(lgraph) を使用してネットワークを確認してから、関数 trainYOLOv2ObjectDetector を使用して YOLO v2 オブジェクト検出器に学習させます。