Main Content

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

resnetLayers

2 次元残差ネットワークの作成

R2021b 以降

    説明

    lgraph = resnetLayers(inputSize,numClasses) は、inputSize で指定されたイメージ入力サイズおよび numClasses で指定されたクラス数をもつ 2 次元残差ネットワークを作成します。残差ネットワークは、ブロックのスタックで構成されます。各ブロックには深層学習層が含まれています。このネットワークには、入力イメージのカテゴリカル ラベルの予測に適したイメージ分類層が含まれています。

    3 次元残差ネットワークを作成するには、resnet3dLayers を使用します。

    lgraph = resnetLayers(___,Name=Value) は、前述の構文に含まれるいずれかの入力引数を指定する 1 つ以上の名前と値の引数を使用して、残差ネットワークを作成します。たとえば、InitialNumFilters=32 は、最初の畳み込み層で 32 個のフィルターを指定します。

    すべて折りたたむ

    ボトルネック アーキテクチャをもつ残差ネットワークを作成します。

    imageSize = [224 224 3];
    numClasses = 10;
    
    lgraph = resnetLayers(imageSize,numClasses)
    lgraph = 
      LayerGraph with properties:
    
         InputNames: {'input'}
        OutputNames: {'output'}
             Layers: [177x1 nnet.cnn.layer.Layer]
        Connections: [192x2 table]
    
    

    ネットワークを解析します。

    analyzeNetwork(lgraph)

    このネットワークは、ResNet-50 残差ネットワークと等価です。

    カスタムのスタック深さを使用して ResNet-101 ネットワークを作成します。

    imageSize = [224 224 3];
    numClasses = 10;
    
    stackDepth = [3 4 23 3];
    numFilters = [64 128 256 512];
    
    lgraph = resnetLayers(imageSize,numClasses, ...
        StackDepth=stackDepth, ...
        NumFilters=numFilters)
    lgraph = 
      LayerGraph with properties:
    
         InputNames: {'input'}
        OutputNames: {'output'}
             Layers: [347x1 nnet.cnn.layer.Layer]
        Connections: [379x2 table]
    
    

    ネットワークを解析します。

    analyzeNetwork(lgraph)

    イメージを分類するための残差ネットワークを作成して学習を行います。

    関数 digitTrain4DArrayDatadigitTest4DArrayData を使用して、インメモリ数値配列として数字データを読み込みます。

    [XTrain,YTrain] = digitTrain4DArrayData;
    [XTest,YTest] = digitTest4DArrayData;

    残差ネットワークを定義します。この数字データには 28×28 ピクセルのイメージが含まれているため、それより小さなフィルターを使用して残差ネットワークを構成します。

    imageSize = [28 28 1];
    numClasses = 10;
    
    lgraph = resnetLayers(imageSize,numClasses, ...
        InitialStride=1, ...
        InitialFilterSize=3, ...
        InitialNumFilters=16, ...
        StackDepth=[4 3 2], ...
        NumFilters=[16 32 64]);

    モーメンタム項付き確率的勾配降下法の既定の設定にオプションを設定します。最大エポック数を 5 に設定し、初期学習率 0.1 で学習を開始します。

    options = trainingOptions("sgdm", ...
        MaxEpochs=5, ...
        InitialLearnRate=0.1, ...
        Verbose=false, ...
        Plots="training-progress");

    ネットワークに学習をさせます。

    net = trainNetwork(XTrain,YTrain,lgraph,options);

    テスト データの予測精度を評価することによって、ネットワーク性能をテストします。関数 classify を使用して、各テスト イメージのクラス ラベルを予測します。

    YPred = classify(net,XTest);

    精度を計算します。精度は、ネットワークが正しく予測するラベルの割合です。

    accuracy = sum(YPred == YTest)/numel(YTest)
    accuracy = 0.9956
    

    カスタム学習ループを使用して残差ネットワークに学習させるには、まずネットワークを dlnetwork オブジェクトに変換します。

    残差ネットワークを作成します。

    lgraph = resnetLayers([224 224 3],5);

    分類層を削除します。

    lgraph = removeLayers(lgraph,"output");

    入力層を、Normalization"none" に設定された新しい入力層に置き換えます。入力層にゼロ中心正規化または z スコア正規化を使用するには、imageInputLayerMean プロパティに空でない値を指定しなければなりません。たとえば Mean=sum(XTrain,4) を指定します。ここで、XTrain は入力データを含む 4 次元配列です。

    newInputLayer = imageInputLayer([224 224 3],Normalization="none");
    lgraph = replaceLayer(lgraph,"input",newInputLayer);

    dlnetwork に変換します。

    dlnet = dlnetwork(lgraph)
    dlnet = 
      dlnetwork with properties:
    
             Layers: [176x1 nnet.cnn.layer.Layer]
        Connections: [191x2 table]
         Learnables: [214x3 table]
              State: [106x3 table]
         InputNames: {'imageinput'}
        OutputNames: {'softmax'}
        Initialized: 1
    
      View summary with summary.
    
    

    入力引数

    すべて折りたたむ

    ネットワークの入力イメージのサイズ。次のいずれかとして指定します。

    • [height, width] の形式の 2 要素ベクトル。

    • [height, width, depth] の形式の 3 要素ベクトル。ここで、depth はチャネル数です。RGB イメージの場合は depth を 3 に設定し、グレースケール イメージの場合は 1 を設定します。マルチスペクトル イメージおよびハイパースペクトル イメージの場合、depth をチャネル数に設定します。

    height および width の値は initialStride * poolingStride * 2D 以上でなければなりません。ここで、D はダウンサンプリング ブロックの数です。引数 InitialStride を使用して、初期ストライドを設定します。InitialPoolingLayer"none" に設定されている場合、プーリング ストライドは 1 になり、そうでない場合は 2 になります。

    データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    イメージ分類ネットワークのクラス数。1 より大きい整数として指定します。

    データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    名前と値の引数

    オプションの引数のペアを Name1=Value1,...,NameN=ValueN として指定します。ここで、Name は引数名で、Value は対応する値です。名前と値の引数は他の引数の後に指定しなければなりませんが、ペアの順序は重要ではありません。

    例: InitialFilterSize=[5,5],InitialNumFilters=32,BottleneckType="none" は、初期フィルター サイズを 5×5 ピクセルに指定し、32 個の初期フィルターと、ボトルネック コンポーネントをもたないネットワーク アーキテクチャを指定します。

    最初の層

    すべて折りたたむ

    最初の畳み込み層のフィルター サイズ。次のいずれかとして指定します。

    • 正の整数。フィルターの高さと幅は同じになります。たとえば、5 を指定すると、高さが 5、幅が 5 のフィルターが生成されます。

    • [height, width] の形式の 2 要素ベクトル。たとえば、初期フィルター サイズとして [1 5] を指定すると、高さが 1、幅が 5 のフィルターが生成されます。

    例: InitialFilterSize=[5,5]

    データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    最初の畳み込み層のフィルター数。正の整数として指定します。初期フィルター数は、残差ネットワークに含まれる最初の畳み込み層の出力におけるチャネル (特徴マップ) の数を決定します。

    例: InitialNumFilters=32

    データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    最初の畳み込み層のストライド。次として指定します。

    • 正の整数。ストライドの高さと幅は同じになります。たとえば、3 を指定すると、高さが 3、幅が 3 のストライドが生成されます。

    • [height, width] の形式の 2 要素ベクトル。たとえば、初期ストライドとして [1 2] を指定すると、高さが 1、幅が 2 のストライドが生成されます。

    ストライドは、入力を垂直方向および水平方向に走査するステップ サイズを定義します。

    例: InitialStride=[3,3]

    データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    最初の残差ブロックの前に使用する最初のプーリング層。次のいずれかとして指定します。

    • "max" — 最初の残差ブロックの前に最大プーリング層を使用します。詳細については、maxPooling2dLayer を参照してください。

    • "average" — 最初の残差ブロックの前に平均プーリング層を使用します。詳細については、averagePooling2dLayer を参照してください。

    • "none" — 最初の残差ブロックの前にプーリング層を使用しません。

    例: InitialPoolingLayer="average"

    データ型: char | string

    ネットワーク アーキテクチャ

    すべて折りたたむ

    残差ブロックのタイプ。次のいずれかとして指定します。

    • "batchnorm-before-add" — 残差ブロックの加算層の前にバッチ正規化層を追加します[1]

    • "batchnorm-after-add" — 残差ブロックの加算層の後にバッチ正規化層を追加します[2]

    引数 ResidualBlockType は、標準残差ブロックおよびダウンサンプリング残差ブロックにおけるバッチ正規化層の位置を指定します。詳細については、詳細を参照してください。

    例: ResidualBlockType="batchnorm-after-add"

    データ型: char | string

    ブロックのボトルネックのタイプ。次のいずれかとして指定します。

    • "downsample-first-conv" — ダウンサンプリング残差ブロックの最初の畳み込み層でダウンサンプリングを実行するボトルネック残差ブロックを使用します。ストライドは 2 を使用します。ボトルネック残差ブロックは、チャネルの次元をダウンサンプリングするための 1 行 1 列の層、3 行 3 列の畳み込み層、およびチャネルの次元をアップサンプリングするための 1 行 1 列の層の 3 つの畳み込み層で構成されています。

      最後の畳み込み層におけるフィルター数は、最初の 2 つの畳み込み層におけるフィルター数の 4 倍になります。詳細については、NumFilters を参照してください。

    • "none" — ボトルネック残差ブロックを使用しません。残差ブロックは、2 つの 3 行 3 列の畳み込み層で構成されています。

    ボトルネック残差ブロックは、3 行 3 列の畳み込みの前に 1 行 1 列の畳み込みを実行し、チャネル数を 4 分の 1 に減らします。ボトルネック ブロックがあるネットワークとボトルネック ブロックがないネットワークの計算量は同程度ですが、残差結合で伝播される特徴の合計数は、ボトルネック ユニットを使用する場合の方が 4 倍多くなります。そのため、ボトルネックを使用するとネットワークの効率が向上します[1]。各残差ブロックの層の詳細については、詳細を参照してください。

    例: BottleneckType="none"

    データ型: char | string

    各スタックに含まれる残差ブロックの数。正の整数のベクトルとして指定します。たとえば、スタックの深さが [3 4 6 3] の場合、ネットワークには、それぞれ 3 つのブロック、4 つのブロック、6 つのブロック、3 つのブロックから成る 4 つのスタックが含まれます。

    引数 NumFilters を使用して、各スタックの畳み込み層のフィルターの数を指定します。StackDepth の値には、NumFilters の値と同じ数の要素が含まれていなければなりません。

    例: StackDepth=[9 12 69 9]

    データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    各スタックに含まれる畳み込み層のフィルターの数。正の整数のベクトルとして指定します。

    • BottleneckType"downsample-first-conv" に設定した場合、各スタックの各ブロックに含まれる最初の 2 つの畳み込み層には、いずれも NumFilters の値で設定された数のフィルターが含まれています。最後の畳み込み層は、最初の 2 つの畳み込み層の 4 倍の数のフィルターをもちます。

      たとえば、NumFilters[4 5] に設定し、BottleneckType"downsample-first-conv" に設定したとします。最初のスタックでは、各ブロックに含まれる最初の 2 つの畳み込み層は 4 つのフィルターをもち、各ブロックに含まれる最後の畳み込み層は 16 個のフィルターをもちます。2 番目のスタックでは、各ブロックに含まれる最初の 2 つの畳み込み層は 5 つのフィルターをもち、最後の畳み込み層は 20 個のフィルターをもちます。

    • BottleneckType"none" に設定した場合、各スタックに含まれる畳み込み層には、NumFilters の値で設定された数のフィルターが含まれています。

    NumFilters の値には、StackDepth の値と同じ数の要素が含まれていなければなりません。

    NumFilters の値は、最初の残差ブロックに含まれる残差結合上の層を決定します。次のいずれかの条件が満たされた場合、残差結合上に畳み込み層が存在します。

    • BottleneckType="downsample-first-conv" (既定) および InitialNumFilters が、NumFilters に含まれる最初の要素数の 4 倍に等しくない。

    • BottleneckType="none" および InitialNumFilters が、NumFilters に含まれる最初の要素に等しくない。

    各残差ブロックの層の詳細については、詳細を参照してください。

    例: NumFilters=[32 64 126 256]

    データ型: single | double | int8 | int16 | int32 | int64 | uint8 | uint16 | uint32 | uint64

    データが入力層を通じて順伝播されるたびに適用するデータ正規化。次のいずれかとして指定します。

    • "zerocenter" — 平均を減算します。この平均は学習時に計算されます。

    • "zscore" — 平均値を減算し、標準偏差で除算します。この平均と標準偏差は学習時に計算されます。

    例: Normalization="zscore"

    データ型: char | string

    出力引数

    すべて折りたたむ

    残差ネットワーク。layerGraph オブジェクトとして返されます。

    詳細

    すべて折りたたむ

    残差ネットワーク

    残差ネットワーク (ResNets) は深層ネットワークの一種で、"残差結合" ("スキップ" 結合または "ショートカット" 結合とも呼ばれる) をもつ基本ブロックで構成されます。この結合を使用すると、入力が主分岐の畳み込みユニットをスキップすることができ、ネットワーク内によりシンプルなパスを実装することができます。残差結合によって、パラメーターの勾配がネットワークの出力層からより初期の層へとよりスムーズに流れるようになり、学習の初期の段階で勾配が消えてしまうという問題を軽減することができます。

    残差ネットワークの構造には柔軟性があります。主なコンポーネントは、"残差ブロック" 内に組み込まれた残差結合です。残差ブロックのグループは "スタック" と呼ばれます。ResNet アーキテクチャは、初期層、それに続く残差ブロックを含むスタック、および最終層で構成されています。ネットワークは次の 3 種類の残差ブロックをもちます。

    • 初期残差ブロック — このブロックは、最初のスタックの開始点に出現します。初期残差ブロックの残差結合に含まれる層は、ブロックが活性化サイズを保持するか、ダウンサンプリングを行うかを決定します。

    • 標準残差ブロック — このブロックは、各スタック内の最初のダウンサンプリング残差ブロックの後に複数回出現します。標準残差ブロックは活性化サイズを保持します。

    • ダウンサンプリング残差ブロック — このブロックは、各スタックの開始点に 1 回出現します。ダウンサンプリング ブロックの最初の畳み込みユニットは、係数 2 で空間次元をダウンサンプリングします。

    標準的なスタックは、ダウンサンプリング残差ブロックと、それに続く m 個の標準残差ブロック (m は 1 以上) をもちます。最初のスタックは、初期残差ブロックで始まる唯一のスタックです。

    Diagram showing N stacks connected in series.

    初期残差ブロック、標準残差ブロック、ダウンサンプリング残差ブロックには、"ボトルネック" ブロックまたは非ボトルネック ブロックを使用できます。ボトルネック残差ブロックは、3 行 3 列の畳み込みの前に 1 行 1 列の畳み込みを実行し、チャネル数を 4 分の 1 に減らします。ボトルネック ブロックがあるネットワークとボトルネック ブロックがないネットワークの計算量は同程度ですが、残差結合で伝播される特徴の合計数は、ボトルネック ユニットを使用する場合の方が 4 倍多くなります。そのため、ボトルネック ブロックを使用するとネットワークの効率が向上します。

    各ブロック内部の層は、設定するブロックのタイプとオプションによって決まります。

    ブロックの層

    名前最初の層初期残差ブロック標準残差ブロック (BottleneckType="downsample-first-conv")標準残差ブロック (BottleneckType="none")ダウンサンプリング残差ブロック最後の層
    説明

    残差ネットワークは、以下の順序で並んだ以下の層で始まります。

    オプションのプーリング層を設定するには、引数 InitialPoolingLayer を使用します。

    初期残差ブロックの主分岐は、標準残差ブロックと同じ層をもちます。

    InitialNumFilters および NumFilters の値は、残差結合上の層を決定します。次のいずれかの条件が満たされた場合、残差結合は、[1,1] のフィルターおよび [1,1] のストライドがある畳み込み層をもちます。

    • BottleneckType="downsample-first-conv" (既定) および InitialNumFilters が、NumFilters に含まれる最初の要素数の 4 倍に等しくない。

    • BottleneckType="none" および InitialNumFilters が、NumFilters に含まれる最初の要素に等しくない。

    ResidualBlockType"batchnorm-before-add" に設定されている場合、残差結合にはバッチ正規化層も含まれます。

    ボトルネック ユニットをもつ標準残差ブロックには、以下の層が以下の順序で含まれます。

    標準ブロックには、前のブロックの出力から加算層への残差結合が含まれます。

    加算層の位置を設定するには、引数 ResidualBlockType を使用します。

    ボトルネック ユニットをもたない標準残差ブロックには、以下の層が以下の順序で含まれます。

    標準ブロックには、前のブロックの出力から加算層への残差結合が含まれます。

    加算層の位置を設定するには、引数 ResidualBlockType を使用します。

    ダウンサンプリング残差ブロックは (ボトルネックがある、またはボトルネックがない) 標準ブロックと同じですが、残差結合上の最初の畳み込み層と加算層に [2,2] のストライドをもちます。

    残差結合上の層は、ResidualBlockType の値によって決まります。

    • ResidualBlockType"batchnorm-before-add" に設定されている場合、2 番目の分岐には、[1,1] のフィルター、[2,2] のストライド、および batchNormalizationLayer をもつ convolution2dLayer が含まれます。

    • ResidualBlockType"batchnorm-after-add" に設定されている場合、2 番目の分岐には、[1,1] のフィルター、[2,2] のストライドをもつ convolution2dLayer が含まれます。

    ダウンサンプリング ブロックは、入力の高さと幅を半分にし、チャネルの数を増やします。

    残差ネットワークは、以下の順序で並んだ以下の層で終了します。

    可視化の例

    Initial layers of a residual network.

    ボトルネックをもたず、加算層の前にバッチ正規化層があるネットワークの初期残差ブロックの例。

    Example of an initial residual block in a residual network.

    ボトルネックをもち、加算層の前にバッチ正規化層があるネットワークの標準残差ブロックの例。

    Example of a standard residual block in a residual network with bottleneck units.

    ボトルネックをもたず、加算層の前にバッチ正規化層があるネットワークの標準残差ブロックの例。

    Example of a standard residual block in a residual network without bottleneck units.

    ボトルネックをもたず、加算層の前にバッチ正規化層があるネットワークのダウンサンプリング残差ブロックの例。

    Example of a downsampling residual block in a residual network without bottleneck units.

    Final layers of a residual network.

    畳み込み層と全結合層の重みを初期化するには、He 重み初期化メソッドを使用します[3]。詳細については、convolution2dLayer を参照してください。

    ヒント

    • 小さなイメージを扱うには、InitialPoolingLayer オプションを "none" に設定し、初期プーリング層を削除してダウンサンプリングの量を減らします。

    • 残差ネットワークには、通常、ResNet-"X" という名前が付けられています。ここで、"X" はネットワークの "深さ" です。ネットワークの深さは、入力層から出力層までのパスにある逐次畳み込み層または全結合層の最大数として定義されます。ネットワークの深さを計算するには、次の関数を使用できます。

      depth = {1+2i=1Nsi+1       If no bottleneck1+3i=1Nsi+1            If bottleneck     ,

      ここで、si はスタック i の深さです。

      深さが同じネットワークに異なるネットワーク アーキテクチャを使用できます。たとえば、ボトルネックをもつ (またはもたない) ResNet-14 アーキテクチャを作成できます。

      resnet14Bottleneck = resnetLayers([224 224 3],10, ...
      StackDepth=[2 2], ...
      NumFilters=[64 128]);
      
      resnet14NoBottleneck = resnetLayers([224 224 3],10, ...
      BottleneckType="none", ...
      StackDepth=[2 2 2], ...
      NumFilters=[64 128 256]);
      ボトルネック アーキテクチャと非ボトルネック アーキテクチャの間の関係は、ボトルネックをもつネットワークとボトルネックをもたないネットワークの深さの違いにも現れています。
      resnet50Bottleneck = resnetLayers([224 224 3],10);
      
      resnet34NoBottleneck = resnetLayers([224 224 3],10, ... 
      BottleneckType="none");
      

    参照

    [1] He, Kaiming, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. “Deep Residual Learning for Image Recognition.” Preprint, submitted December 10, 2015. https://arxiv.org/abs/1512.03385.

    [2] He, Kaiming, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. “Identity Mappings in Deep Residual Networks.” Preprint, submitted July 25, 2016. https://arxiv.org/abs/1603.05027.

    [3] He, Kaiming, Xiangyu Zhang, Shaoqing Ren, and Jian Sun. "Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification." In Proceedings of the 2015 IEEE International Conference on Computer Vision, 1026–1034. Washington, DC: IEEE Computer Vision Society, 2015.

    拡張機能

    バージョン履歴

    R2021b で導入