[PyTorch]畳み込みニューラルネットワーク

畳み込みニューラルネットワーク

畳み込みニューラルネットワークは、もともとコンピュータビジョン関連の問題を解決するために設計されましたが、現在では画像やビデオの分野だけでなく、音声信号などの時系列信号の処理にも使用されています。

この記事では、主に畳み込みニューラルネットワークの基本原理とPyTorchを使用して畳み込みニューラルネットワークを実装することに焦点を当てています。

1.開発コンテキスト

ここに画像の説明を挿入

2.畳み込みニューラルネットワーク

畳み込みニューラルネットワークも最初に画像問題を解決するために提案されたので、その概念を説明するとき、私たちはしばしば画像問題を例として使用します。

(1)まとめ

1.完全に接続されたネットワークの問題

  • 完全に接続されたニューラルネットワーク:完全に接続された層のみを含むニューラルネットワーク2つの層ごとにすべてのノードがペアで接続されます

①膨大な量のパラメータ

例えば、200x200の画像に対して隠れ層のニューロンの次数が10に設定され、入力された。4ヶ月、200x200x10の合計次へ接続層の全体構造。4つのパラメータ重み付け。
psここでは、次のことを前提としています。画像入力の場合、ピクセルレベルの処理が使用されます。つまり、各入力レイヤーユニットがピクセルブロックを処理します。

②トレーニングには時間がかかります

パラメータの数が非常に多いため、バックプロパゲーションを実行するときのトレーニング効率は低くなります。

③オーバーフィット

また、パラメータの数が膨大であるため、ラベル付けされたデータと比較してパラメータの数が多すぎるため、モデルトレーニングの程度の過剰適合の問題が発生しやすくなります。

2.畳み込みニューラルネットワークの小さなトリック

①ローカル接続

各畳み込み操作は、小さな画像の処理のみを担当し、結果を次のグリッドに転送します。

同じことが200x200の入力画像のためのものである。ローカル接続の下で、隠れ層の各ユニットのみ画像における4x4のローカル画像に接続されている。このとき、パラメータの数だけ4x4x10ある4 = 1.6×10 5であり、完全に接続されたレイヤーと比較して3桁減少しました。
ここに画像の説明を挿入

②ウェイトシェアリング

  • 議論し、私たちにローカル接続すれば、n個のニューロンが隠された層であり、そして各ニューロンているだけのローカルMXMイメージに接続され、前の層、そして我々は持っているだろうメートルN・2重みパラメータをという考えの下重量の共有、私たちは聞かせて、各ニューロンが同じMXMパラメータを持っているので、どんな隠されたユニットの数nは、我々は唯一メートルもありません2重みパラメータをこの層に

【エッセンス】
たたみ込み層は、たたみ込み演算の結果を引き受けるために使用されます。たたみ込み演算のコアはたたみ込みカーネルです。たたみ込みカーネルの機能は、新しい画像を取得するための特定のフィルタリング後の元の画像に対応します。

新しい画像のすべてのピクセルは、この一般的な畳み込みカーネルによって取得されます。畳み込み層の各ユニットは、新しい各画像のピクセルを格納するために使用されるため、各ユニットに関連付けられた重みパラメーターは同じである必要があります。

ps畳み込みの具体的な知識については、ブログ投稿「Wu Enda Deep Learningcnn」を参照してください。
[畳み込みカーネルと機能]
畳み込みレイヤーには複数の異なる畳み込みカーネルを含めることができ、各畳み込みレイヤーは元の画像の特徴を抽出するのと同じです。出てくる、
それはコンボリューションカーネルを添加することによって達成することができるので、実用的なアプリケーションでは、我々は、複数の特徴を抽出する必要があるかもしれません

3.畳み込みニューラルネットワークの一般的な構造

  • 一般的な畳み込みネットワークは、畳み込み層、プーリング層、完全に接続された層、およびSoftmax層で構成されます。

【畳み込み層】この層の各ノードの入力は、前層のニューラルネットワークの小片であり、ニューラルネットワークの各小片を表示してより詳細な分析を行うことで、より高度な抽象化機能を取得します。

[プーリングレイヤー]このレイヤーのネットワークは、3次元マトリックスの深さを変更しません(たとえば、RGB画像の長さと幅は画像のサイズを反映し、深さは3チャネルです)。行列のサイズを小さくします。本質的に、このレイヤーは高解像度の画像を低解像度の画像に変換します。

[完全に接続されたレイヤー]畳み込みとプーリングを複数回実行した後、畳み込みニューラルネットワークは1つから2つの完全に接続されたレイヤーを接続して、最終結果を提供します。

[Softmax層]は分類問題に使用されます。つまり、対応する活性化関数と目的関数が選択されます。

ローカル接続、重みの共有、およびプーリングレイヤーのダウンサンプリングにより、パラメーターの量が減り、トレーニングの複雑さが減り、過剰適合のリスクが減ります。同時に、畳み込みニューラルネットワークには、変換に対するある程度の抵抗が与えられます。変形、およびスケール。変性により、モデルの一般化能力が向上します。

(2)畳み込み層

1.基礎知識

畳み込み層ニューラルネットワーク構造の最も重要な部分は、畳み込みカーネル(カーネル)またはフィルター(フィルター)とも呼ばれます。畳み込みカーネルは、ニューラルネットワークの現在の層のサブノード行列をニューラルネットワークの次の層に変換します。ネットワーク。ノード行列の。
ここに画像の説明を挿入

上図によると、畳み込みニューラルネットワークと畳み込み演算および構造を使用する場合、最も重要なことは、畳み込みカーネルの関連パラメーターとニューロンの関連設定を理解することです。

  • 畳み込みカーネルのサイズ(畳み込みカーネルの長さと幅)は手動で指定され、ニューラルネットワークの現在のレイヤーの子ノード行列のサイズは畳み込みカーネルのサイズです。
  • 畳み込みカーネルの(処理)深さは、現在の層のニューラルネットワークノード行列の深さと一致しています。

畳み込みカーネルの深さはデフォルトで同じであることが多いことに注意してください。入力される現在のレイヤー行列が3次元であっても、2つのパラメーターの長さと幅を手動で指定するだけで済みます。

一般的に、畳み込みカーネルのサイズを3x3と5x5とします。
上の図では、入力画像に対応する行列が左側に示され、そのサイズは3x32x32です。
したがって、たたみ込みカーネルを5x5とすると、各たたみ込みカーネルのサイズは実際には3x5x5である必要があり、たたみ込み層の各ニューロン(上の図の右側の領域の小さな楕円)は、入力データの3x5x5領域の重みを持ちます。合計75個のウェイト。

psは、PyTorchのデータサイズの記述順序に注意を払う必要があります。

  • 上の図の右側の領域に示されているように、畳み込みカーネルの数、つまり畳み込みレイヤーの出力深度には、5つの畳み込みカーネルに対応する合計5つのニューロンがあります。畳み込みカーネルの数と使用されるフィルターの数は同じです。
  • ステップ長、スライドステップ長は、畳み込み演算中に毎回移動されるピクセル数です。

スライディングコンボリューションの操作により、出力データは一般的に少なくなります。

  • 境界パディングには、必要に応じてさまざまなパディングモードがあります。すべてのパディングが0の場合、入力データのサイズが同じであることを確認します。パディング値が0より大きい場合、畳み込み操作中に境界情報が失われないようにすることができます。

【畳み込み計算式】畳み込み演算
後の出力サイズを次式で計算すると、
W '= floor((W − F + 2 P)/ S + 1)W' = floor((W-F + 2P) / S + 1)W=f l o o r WF+2 P / S+1

その中で、floorは整数除去操作を表し、Wは入力データのサイズを表し、Fは畳み込み層の畳み込みカーネルのサイズを表し、Sはステップサイズを表し、Pはゼロパディングの数を表します。


2.PyTorchでの呼び出しPyTorchには特別にパッケージ化された畳み込みカーネルモジュールがあります。nn.Conv2d()
その正式なパラメータ構造は次のとおりです。

nn.Conv2d(in_channels,out_channels,kernel_size,stride = 1,padding = 0,dilation = 1,groups = 1,bias = True)
  • in_channels:入力データ本体の深さ。入力データのサイズによって決まります。
  • out_channels:出力データボリュームの深さ。通常、選択したコアの数によって決まります。
  • kernel_size:畳み​​込みカーネルのサイズ;正方形の畳み込みカーネルが使用された場合、1つの数値のみが渡されました;非正方形の畳み込みカーネルが渡された場合、タプルが渡されました
  • stride:スライドステップ長、デフォルトは1
  • padding:境界上のパディングの数0
  • dilation:データ本体のスペース間隔を入力します
  • groups:入力データ本体と出力データ本体の関係の深さ
  • bias:オフセットを示します
'''
对PyTorch中的卷积核的调用示例
'''
#方形卷积核,等长的步长
m = nn.Conv2d(16,33,3,stride = 2)

#非方形卷积核,非登场的步长和边界填充
m = nn.Conv2d(16,33,(3,5),stride = (2,1),padding = (4,2))

#非方形卷积核,非登场的步长、边界填充和空间间隔
m = nn.Conv2d(16,33,(3,5),stride = (2,1),padding = (4,2),dilation = (3,1))

#进行卷积运算
input = autograd.Variable(torch.randn(20,16,50,100))
output = m(input)

(3)プーリング層

通常、プーリング層は畳み込み層の後に挿入されます。ニューラルネットワークのこの層には次の機能があります。

  • ネットワークのスペースサイズを徐々に縮小します
  • ネットワーク内のパラメータの数を減らします
  • コンピューティングリソースの使用を減らす
  • モデルの過剰適合を効果的に制御する

プーリングレイヤーには、通常、最大プーリングと平均プーリングの2つの計算方法があり、前者は[最大値]計算を使用し、後者は[平均値]計算を使用します。以下では、例として最大プーリングを使用して説明します。

1.計算プロセス
プーリングレイヤーは、データの長さと幅のディメンションのみをダウンサンプリングし、モデルの深さは変更しません。

入力データの深度スライスを入力として受け取り、ウィンドウを連続的にスライドさせます。最大プーリングの計算原理では、これらのウィンドウの最大値が出力結果として使用されます。
ここに画像の説明を挿入
プーリングレイヤーはどのくらい効果的ですか?

  • 画像の特徴には局所的な不変性があります。つまり、ダウンサンプリング後に取得された縮小画像は、その特徴を失うことはありません。

これに基づいて、画像が縮小された後に畳み込み演算が実行され(いわゆる畳み込み演算は、設計カーネルを使用して画像の特性を抽出することである)、畳み込み演算の時間を短縮することができる。

  • 一般的に使用されるプーリングスキーム(プーリングサイズは2x2、スライドステップサイズは2)を使用すると、画像のダウンサンプリングでは実際に元の画像の75%が失われ、その大部分が画像を保持するように選択され、ノイズが発生する可能性があります。また、削除されます。

2.PyTorchでの呼び出し

二つの異なるプーリングスキームが存在するため、同様に、対応があるnn.MaxPool2dとはnn.AvgPool2d

nn.MaxPool2d(kernel_size,stride = None,padding = 0,dilation = 1,
return_indices = False,ceil_mode = False)
  • 関連するパラメーターについては、畳み込み層の説明を参照してください。
  • return_indices:最大値の添え字を返すかどうか
  • ceil_model:レイヤー構造の代わりに正方形を使用する

同様に、選択したプーリングサイズが正方形の場合は、数値を渡すだけで済みます。それ以外の場合は、タプルを渡す必要があります。

3.古典的な畳み込みニューラルネットワーク

1. LeNet

LeNetは、1988年にYannLeCun教授が論文「文書認識に適用された勾配ベースの学習」で提案したLeNet-5を具体的に指します。これはデジタル認識問題にうまく適用された最初の畳み込みニューラルネットワークでした。

LeNet-5モデルには、合計7つの層があります(2つの畳み込み層、2つのプーリング層、2つの完全に接続された層、および出力層)
ここに画像の説明を挿入

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet,self).__init__()
        self.conv1 = nn.Conv2d(3,6,5)
        self.conv2 = nn.Conv2d(6,16,5)
        self.fc1 = nn.Linear(16*5*5,120)
        self.fc2 = nn.Linear(120,84)
        self.fc3 = nn.Linear(84,10)

    def forward(self,x):
        out = F.relu(self.conv1(x))
        out = F.max_pool2d(out,2)
        out = F.relu(self.con2(out))
        out = F.max_pool2d(out,2)
        out = out.view(out.size(0),-1)
        out = F.relu(self.fc1(out))
        out = F.relu(self.fc2(out))
        out = self.fc3(out)
        return out

2. AlexNet

2012年にヒルトンの学生であるAlexKrizhevskyによって提案されたこの構造は、Relu、Dropout、LRNなどの手法をうまく適用しました。

AlexNetモデルの構造図を以下に示します。当時の計算能力の制約から、並列計算には2つのGPUを使用していたため、構造図は少し複雑に見えます。
ここに画像の説明を挿入
以下に、単一のGPU計算の同等のモデル構造図を示します。

AlexNet全体には、5つの畳み込み層、3つのプーリング層、および3つの完全に接続された層が含まれています。
その中で、畳み込み層と完全接続層の両方にReLU層が含まれ、完全接続層ではドロップアウト層も使用されます。

ここに画像の説明を挿入

class AlexNet(nn.Module):
    def __init__(self,num_classes):
        super(AlexNet,self).__init__()
        self.features = nn.Sequential(
          nn.Conv2d(3,96,kernel_size = 11,stride = 4,padding = 2),
          nn.ReLU(inplace = True),
          nn.MaxPool2d(kernel_size = 3,stride = 2),
          nn.Conv2d(64,256,kernel_size = 5,padding = 2),
          nn.ReLU(inplace = True),
          nn.MaxPool2d(kernel_size = 3,stride = 2),
          nn.Conv2d(192,384,kernel_size = 3,padding = 1),
          nn.ReLU(inplace = True),
          nn.Conv2d(384,256,kernel_size = 3,padding = 1),
          nn.ReLU(inplace = True),
          nn.Conv2d(256,256,kernel_size = 3,padding = 1),
          nn.ReLU(inplace = True),
          nn.MaxPool2d(kernel_size = 3,stride = 2),
        )
        self.classifier = nn.Sequential(
             nn.Dropout(),
             nn.Linear(256*6*6,4096),
             nn.ReLU(inplace = True),
             nn.Dropout(),
             nn.Linear(4096,4096),
             nn.ReLU(inplace = True),
             nn.Linear(4096,num_classes)
         )
         def forward(self,x):
             x = self.features(x)
             x = x.view(x.size(0),256*6*6)
             x = self.classifier(x)
             return x

おすすめ

転載: blog.csdn.net/kodoshinichi/article/details/109680213