メインコンテンツ

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

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

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

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

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

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

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

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

imagePretrainedNetwork 関数を使用して事前学習済みの MobileNet v2 ネットワークを読み込みます。このネットワークには、Deep Learning Toolbox Model for MobileNet v2 Network サポート パッケージが必要です。このサポート パッケージがインストールされていない場合、関数によってダウンロード用リンクが表示されます。

net = imagePretrainedNetwork("mobilenetv2")
net = 
  dlnetwork with properties:

         Layers: [153×1 nnet.cnn.layer.Layer]
    Connections: [162×2 table]
     Learnables: [210×3 table]
          State: [104×3 table]
     InputNames: {'input_1'}
    OutputNames: {'Logits_softmax'}
    Initialized: 1

  View summary with summary.

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

学習データの要件を満たすよう、ネットワーク入力サイズを更新します。たとえば、学習データが 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: []

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

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

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

analyzeNetwork(net);

特徴抽出層の選択

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

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

featureExtractionLayer = "block_12_add";

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

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

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

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

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

まず、直列で接続された畳み込み層、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 = 
  6×1 Layer array with layers:

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

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

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

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

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

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

numClasses = 5;

anchorBoxes = [16 16; 32 16];

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

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

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

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

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

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

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

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

analyzeNetwork(net)

ネットワークから yolov2ObjectDetector オブジェクトを作成します。その後、関数 trainYOLOv2ObjectDetector を使用してネットワークに学習させることができます。

 classNames = ["person" "bicycle" "car" "bus" "truck"];
 detector = yolov2ObjectDetector(net,classNames,anchorBoxes)
detector = 
  yolov2ObjectDetector with properties:

                  Network: [1×1 dlnetwork]
                InputSize: [300 300 3]
        TrainingImageSize: [300 300]
              AnchorBoxes: [2×2 double]
               ClassNames: [5×1 categorical]
    ReorganizeLayerSource: ''
              LossFactors: [5 1 1 1]
                ModelName: ''

参考

|

トピック