最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

Faster R-CNN の例

R-CNN オブジェクト検出ネットワークの作成

この例では、事前学習済みの ResNet-50 ネットワークを R-CNN オブジェクト検出ネットワークに変更する方法を説明します。この例で作成するネットワークは、trainRCNNObjectDetector を使用して学習させることができます。

% Load pretrained ResNet-50.
net = resnet50();

% Convert network into a layer graph object to manipulate the layers.
lgraph = layerGraph(net);

ネットワークを R-CNN ネットワークに変換する手順は、イメージ分類の転移学習のワークフローと同じです。最後の 3 つの分類層を、検出するオブジェクト クラスの数と背景クラスをサポートできる新しい層で置き換えます。

ResNet-50 では、最後の 3 つの層は、fc1000、fc1000_softmax、および ClassificationLayer_fc1000 という名前です。ネットワークを表示して、変更するネットワークのセクションを拡大します。

figure
plot(lgraph)
ylim([-5 16])

% Remove the the last 3 layers. 
layersToRemove = {
    'fc1000'
    'fc1000_softmax'
    'ClassificationLayer_fc1000'
    };

lgraph = removeLayers(lgraph, layersToRemove);

% Display the results after removing the layers.
figure
plot(lgraph)
ylim([-5 16])

ネットワークに新しい分類層を追加します。層は、ネットワークが検出する必要のあるオブジェクトの数を分類し、追加の背景クラスも分類するように設定します。検出中、ネットワークでは、トリミングされたイメージ領域を処理して、イメージ領域がオブジェクト クラスの 1 つまたは背景に属するものとして分類します。

% Specify the number of classes the network should classify.
numClassesPlusBackground = 2 + 1;

% Define new classfication layers
newLayers = [
    fullyConnectedLayer(numClassesPlusBackground, 'Name', 'rcnnFC')
    softmaxLayer('Name', 'rcnnSoftmax')
    classificationLayer('Name', 'rcnnClassification')
    ];

% Add new layers
lgraph = addLayers(lgraph, newLayers);

% Connect the new layers to the network. 
lgraph = connectLayers(lgraph, 'avg_pool', 'rcnnFC');

% Display the final R-CNN network. This can be trained using trainRCNNObjectDetector.
figure
plot(lgraph)
ylim([-5 16])

Fast R-CNN オブジェクト検出ネットワークの作成

この例は、上記のR-CNN オブジェクト検出ネットワークの作成の例に基づいています。ROI プーリング層と境界ボックス回帰層を追加して、事前学習済みの ResNet-50 ネットワークを Fast R-CNN オブジェクト検出ネットワークに変換します。その後、Fast R-CNN ネットワークは、trainFastRCNNObjectDetector を使用して学習させることができます。

R-CNN ネットワークの作成

まず、Fast R-CNN の基礎となる R-CNN ネットワークを作成します。R-CNN オブジェクト検出ネットワークの作成の例で、このコード セクションを詳細に説明しています。

% Load pretrained ResNet-50.
net = resnet50;
lgraph = layerGraph(net);

% Remove the the last 3 layers from ResNet-50. 
layersToRemove = {
    'fc1000'
    'fc1000_softmax'
    'ClassificationLayer_fc1000'
    };
lgraph = removeLayers(lgraph, layersToRemove);

% Specify the number of classes the network should classify.
numClasses = 2;
numClassesPlusBackground = numClasses + 1;

% Define new classfication layers.
newLayers = [
    fullyConnectedLayer(numClassesPlusBackground, 'Name', 'rcnnFC')
    softmaxLayer('Name', 'rcnnSoftmax')
    classificationLayer('Name', 'rcnnClassification')
    ];

% Add new layers.
lgraph = addLayers(lgraph, newLayers);

% Connect the new layers to the network. 
lgraph = connectLayers(lgraph, 'avg_pool', 'rcnnFC');

境界ボックス回帰層の追加

領域提案ボックスに適用する一連のボックス オフセットを学習するためのボックス回帰層を追加します。学習したオフセットによって、領域提案ボックスが元のグラウンド トゥルース境界ボックスに近くなるように変換されます。この変換により、Fast R-CNN の位置推定パフォーマンスが向上します。

ボックス回帰層は、全結合層とその後に続く R-CNN ボックス回帰層で構成されます。全結合層は、各クラスに対して、4 つのボックス オフセットのセットを出力するように設定されています。背景クラスは、背景境界ボックスが調整されていないため、除外されます。

% Define the number of outputs of the fully connected layer.
numOutputs = 4 * numClasses;

% Create the box regression layers.
boxRegressionLayers = [
    fullyConnectedLayer(numOutputs,'Name','rcnnBoxFC')
    rcnnBoxRegressionLayer('Name','rcnnBoxDeltas')
    ];

% Add the layers to the network
lgraph = addLayers(lgraph, boxRegressionLayers);

ボックス回帰層は通常、分類分岐が結合されているのと同じ層に結合されます。

% Connect the regression layers to the layer named 'avg_pool'.
lgraph = connectLayers(lgraph,'avg_pool','rcnnBoxFC');

% Display the classification and regression branches of Fast R-CNN.
figure
plot(lgraph)
ylim([-5 16])

ROI の最大プーリング層の追加

次の手順は、特徴抽出層として使用するネットワークの層を選択することです。この層は、プリーングされた領域の分類のために特徴量をプーリングする ROI の最大プーリング層に結合します。特徴抽出層の選択には、実証的評価が必要です。ResNet-50 の場合、一般的な特徴抽出層は、畳み込みの 4 番目のブロックの出力です。これは、activation40_relu という名前の層に対応します。

featureExtractionLayer = 'activation_40_relu';

figure
plot(lgraph)
ylim([30 42])

ROI 最大プーリング層を挿入するには、まず、特徴抽出層に結合されている層 res5a_branch2a および res5a_branch1 を切り離します。

% Disconnect the layers attached to the selected feature extraction layer.
lgraph = disconnectLayers(lgraph, featureExtractionLayer,'res5a_branch2a');
lgraph = disconnectLayers(lgraph, featureExtractionLayer,'res5a_branch1');

% Add ROI max pooling layer.
outputSize = [14 14]
outputSize = 1×2

    14    14

roiPool = roiMaxPooling2dLayer(outputSize,'Name','roiPool');

lgraph = addLayers(lgraph, roiPool);

% Connect feature extraction layer to ROI max pooling layer.
lgraph = connectLayers(lgraph, 'activation_40_relu','roiPool/in');

% Connect the output of ROI max pool to the disconnected layers from above.
lgraph = connectLayers(lgraph, 'roiPool','res5a_branch2a');
lgraph = connectLayers(lgraph, 'roiPool','res5a_branch1');

% Show the result after adding and connecting the ROI max pooling layer.
figure
plot(lgraph)
ylim([30 42])

最後に、ROI 入力層を ROI 最大プーリング層の 2 番目の入力に結合します。

% Add ROI input layer.
roiInput = roiInputLayer('Name','roiInput');
lgraph = addLayers(lgraph, roiInput);

% Connect ROI input layer to the 'roi' input of the ROI max pooling layer.
lgraph = connectLayers(lgraph, 'roiInput','roiPool/roi');

% Show the resulting faster adding and connecting the ROI input layer.
figure
plot(lgraph)
ylim([30 42])

これで、trainFastRCNNObjectDetector を使用してネットワークを学習させる準備が整いました。

Faster R-CNN オブジェクト検出ネットワークの作成

この例は、上記のFast R-CNN オブジェクト検出ネットワークの作成の例に基づいています。ROI プーリング層、境界ボックス回帰層、および領域提案ネットワーク (RPN) を追加して、事前学習済みの ResNet-50 ネットワークを Faster R-CNN オブジェクト検出ネットワークに変換します。その後、Faster R-CNN ネットワークは、trainFasterRCNNObjectDetector を使用して学習させることができます。

Fast R-CNN ネットワークの作成

まず、Faster R-CNN の基礎となる Fast R-CNN ネットワークを作成します。Fast R-CNN オブジェクト検出ネットワークの作成の例で、このコード セクションを詳細に説明しています。

% Load a pretrained ResNet-50.
net = resnet50;
lgraph = layerGraph(net);

% Remove the the last 3 layers. 
layersToRemove = {
    'fc1000'
    'fc1000_softmax'
    'ClassificationLayer_fc1000'
    };
lgraph = removeLayers(lgraph, layersToRemove);

% Specify the number of classes the network should classify.
numClasses = 2;
numClassesPlusBackground = numClasses + 1;

% Define new classification layers.
newLayers = [
    fullyConnectedLayer(numClassesPlusBackground, 'Name', 'rcnnFC')
    softmaxLayer('Name', 'rcnnSoftmax')
    classificationLayer('Name', 'rcnnClassification')
    ];

% Add new object classification layers.
lgraph = addLayers(lgraph, newLayers);

% Connect the new layers to the network. 
lgraph = connectLayers(lgraph, 'avg_pool', 'rcnnFC');

% Define the number of outputs of the fully connected layer.
numOutputs = 4 * numClasses;

% Create the box regression layers.
boxRegressionLayers = [
    fullyConnectedLayer(numOutputs,'Name','rcnnBoxFC')
    rcnnBoxRegressionLayer('Name','rcnnBoxDeltas')
    ];

% Add the layers to the network.
lgraph = addLayers(lgraph, boxRegressionLayers);

% Connect the regression layers to the layer named 'avg_pool'.
lgraph = connectLayers(lgraph,'avg_pool','rcnnBoxFC');

% Select a feature extraction layer.
featureExtractionLayer = 'activation_40_relu';

% Disconnect the layers attached to the selected feature extraction layer.
lgraph = disconnectLayers(lgraph, featureExtractionLayer,'res5a_branch2a');
lgraph = disconnectLayers(lgraph, featureExtractionLayer,'res5a_branch1');

% Add ROI max pooling layer.
outputSize = [14 14];
roiPool = roiMaxPooling2dLayer(outputSize,'Name','roiPool');
lgraph = addLayers(lgraph, roiPool);

% Connect feature extraction layer to ROI max pooling layer.
lgraph = connectLayers(lgraph, featureExtractionLayer,'roiPool/in');

% Connect the output of ROI max pool to the disconnected layers from above.
lgraph = connectLayers(lgraph, 'roiPool','res5a_branch2a');
lgraph = connectLayers(lgraph, 'roiPool','res5a_branch1');

領域提案ネットワーク (RPN) の追加

Faster R-CNN では、領域提案ネットワーク (RPN) を使用して領域提案を生成します。RPN は、"オブジェクト" または "背景" のクラス、および "アンカー ボックス" とも呼ばれる一連の事前定義された境界ボックス テンプレートのボックス オフセットを予測して領域提案を生成します。アンカー ボックスは、そのサイズを指定することで指定されます。一般的に、アンカー ボックスのサイズは、学習データセットに含まれるオブジェクトのスケールと縦横比に関する予備知識に基づいて決定されます。

アンカー ボックスを定義して regionProposalLayer を作成します。

% Define anchor boxes.
anchorBoxes = [
    16 16
    32 16
    16 32
    ];

% Create the region proposal layer.
proposalLayer = regionProposalLayer(anchorBoxes,'Name','regionProposal');

lgraph = addLayers(lgraph, proposalLayer);

RPN の畳み込み層を追加して、上記で選択した特徴抽出層に結合します。

% Number of anchor boxes.
numAnchors = size(anchorBoxes,1);

% Number of feature maps in coming out of the feature extraction layer. 
numFilters = 1024;

rpnLayers = [
    convolution2dLayer(3, numFilters,'padding',[1 1],'Name','rpnConv3x3')
    reluLayer('Name','rpnRelu')
    ];

lgraph = addLayers(lgraph, rpnLayers);

% Connect to RPN to feature extraction layer.
lgraph = connectLayers(lgraph, featureExtractionLayer, 'rpnConv3x3');

RPN 分類出力層を追加します。分類層では、各アンカーを "オブジェクト" または "背景" として分類します。

% Add RPN classification layers.
rpnClsLayers = [
    convolution2dLayer(1, numAnchors*2,'Name', 'rpnConv1x1ClsScores')
    rpnSoftmaxLayer('Name', 'rpnSoftmax')
    rpnClassificationLayer('Name','rpnClassification')
    ];
lgraph = addLayers(lgraph, rpnClsLayers);

% Connect the classification layers to the RPN network.
lgraph = connectLayers(lgraph, 'rpnRelu', 'rpnConv1x1ClsScores');

RPN 回帰出力層を追加します。回帰層では、各アンカー ボックスに対して 4 つのボックス オフセットを予測します。

% Add RPN regression layers.
rpnRegLayers = [
    convolution2dLayer(1, numAnchors*4, 'Name', 'rpnConv1x1BoxDeltas')
    rcnnBoxRegressionLayer('Name', 'rpnBoxDeltas');
    ];

lgraph = addLayers(lgraph, rpnRegLayers);

% Connect the regression layers to the RPN network.
lgraph = connectLayers(lgraph, 'rpnRelu', 'rpnConv1x1BoxDeltas');

最後に、分類および回帰特徴マップを領域提案層入力に結合し、ROI プーリング層を領域提案層出力に結合します。

% Connect region proposal network.
lgraph = connectLayers(lgraph, 'rpnConv1x1ClsScores', 'regionProposal/scores');
lgraph = connectLayers(lgraph, 'rpnConv1x1BoxDeltas', 'regionProposal/boxDeltas');

% Connect region proposal layer to roi pooling.
lgraph = connectLayers(lgraph, 'regionProposal', 'roiPool/roi');

% Show the network after adding the RPN layers.
figure
plot(lgraph)
ylim([30 42])

これで、trainFasterRCNNObjectDetector を使用してネットワークを学習させる準備が整いました。