Python LeNetネットワークの説明とpytorchでの実装
1. LeNetの紹介
LeNetニューラルネットワークは、ディープラーニング三国志の一人で、CNN(Convolutional Neural Network)の父でもあるYan LeCunが提唱したものです。LeNetの構造はCNNの構造を確立し、畳み込み層、Pooling層、ReLU層など、現在ニューラルネットワークに見られるものの多くはLeNetのネットワーク構造に見られる。LeNetは1990年代に提案されたが、当時は大規模な学習データがなく、コンピュータのハードウェアの性能も低かったため、LeNetのニューラルネットワークは複雑な問題を扱うにはあまり有効ではなかった。LeNetのネットワーク構造は比較的単純であるが、ニューラルネットワークの入門的な学習に適しているに過ぎない。
2. LetNetネットワークモデル
LeNetネットワークモデルは、一般にLeNet-5と呼ばれており、このモデルを勉強していると、こんな絵を見たことがあるのではないでしょうか?
画像
この図も元の論文のモデル図なので、ちょっと見づらいかもしれませんが、次の図は、私がdrawioというソフトで作ったネットワークモデル図で、次のようなものです。
画像
訂正、上図の2層目のConv2dの結果は10になるはずですが、5と表記されています
畳み込みニューラルネットワークの基礎を学んだ方なら、この図がはっきり読めるはずだと思います。図の左上の計算の右側にも計算式が書いてありますが、上の図は入力形状と出力形状の各層について詳しく書き出しました。計算式とモデルの一般的な構造は、次の図も見てください(上下の図に一緒に対応すると、より分かりやすいと思います)。
LeNet-5のネットワークモデルは、畳み込み層、最大プーリング層、完全連結層、relu, softmax活性化関数を含むだけです。入力画像のサイズと各層の畳み込みカーネルの数、ステップサイズはすべてモデルによって設定されており、一般に任意に変更することはできないはずである。フラット化操作は、平坦化操作とも呼ばれる。完全連結層への入力は1つの特徴量と1次元のベクトルであることは周知の通りですが、畳み込みネットワークの特徴量から抽出された特徴行列は1次元ではなく、完全連結層に送られるべきものなので、1次元に平坦化するフラット化操作が必要なのです。
3. PytorchによるLeNetの実装
Pythonのコードは以下の通りです。
from torch import nn
import torch
import torch.nn.functional as F
'''
Notes:
1. LeNet is a 5-layer network
2. nn.ReLU(inplace=True) The parameter True is to modify the tensor passed down from the upper layer network Conv2d directly, which can save memory for computing and not to store other variables.
3. The dimensional annotations of this model omit the size of N(batch_size), i.e. input(3, 32, 32) -->input(N, 3, 32, 32)
4.nn.init.xavier_uniform_(m.weight)
Generate values with a uniform distribution, fill the input tensor or variable, and sample the values in the resulting tensor from U(-a, a)
where a = gain * sqrt( 2/(fan_in + fan_out))* sqrt(3),
gain is the optional scaling factor, default is 1
'fan_in' retains the magnitude of the variance of the weights in forward propagation, 'fan_out' retains the magnitude in backward propagation
5.nn.init.constant_(m.bias, 0)
Fill a constant 0 for all dimensional tensor
'''
class LeNet(nn.Module):
def __init__(self, num_classes=10, init_weights=False):
super(LeNet, self). __init__()
self.conv1 = nn.Conv2d(in_channels=3, out_channels=16, kernel_size=5, stride=1)
self.maxpool1 = nn.MaxPool2d(kernel_size=2, stride=2)
self.relu = nn.ReLU(True)
self.conv2 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=5, stride=1)
self.maxpool2 = nn.MaxPool2d(kernel_size=2, stride=2)
self.fc1 = nn.Linear(32 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, num_classes)
if init_weights:
self._initialize_weights()
def forward(self, x):
x = self.conv1(x) # input(3, 32, 32) output(16, 28, 28)
x = self.relu(x) # activation function
x = self.maxpool1(x) # output(16, 14, 14)
x = self.conv2(x) # output(32, 10, 10)
x = self.relu(x) # activation function
x = self.maxpool2(x) # output(32, 5, 5)
x = torch.flatten(x, start_dim=1) # output(32*5*5) N for batch_size
x = self.fc1(x) # output(120)
x = self.relu(x) # activation function
x = self.fc2(x) # output(84)
x = self.relu(x) # activation function
x = self.fc3(x) # output(num_classes)
return x
def _initialize_weights(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
nn.init.xavier_uniform_(m.weight)
if m.bias is not None:
nn.init.constant_(m.bias, 0)
elif isinstance(m, nn.Linear):
nn.init.xavier_uniform_(m.weight)
nn.init.constant_(m.bias, 0)
または
次のものは、自分自身のウェイトとオフセットを初期化せず、デフォルトの初期化を使用します。
import torch.nn as nn
import torch.nn.functional as F
import torch
class LeNet(nn.Module):
def __init__(self):
super(LeNet, self). __init__()
self.conv1 = nn.Conv2d(3, 16, 5)
self.pool1 = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(16, 32, 5)
self.pool2 = nn.MaxPool2d(2, 2)
self.fc1 = nn.Linear(32*5*5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = F.relu(self.conv1(x)) # output(16, 28, 28)
x = self.pool1(x) # output(16, 14, 14)
x = F.relu(self.conv2(x)) # output(32, 10, 10)
x = self.pool2(x) # output(32, 5, 5)
x = x.view(x.size(0), -1) # output(32*5*5)
x = F.relu(self.fc1(x)) # output(120)
x = F.relu(self.fc2(x)) # output(84)
x = self.fc3(x) # output(10)
return x
nn.Linearは完全連結層、最後の完全連結層以外は再アクティブ化する必要がある、デフォルトではパディング操作なし
nn.Conv2dは対応するパラメータの順番を覚えておく必要があります:
1.in_channels: チャンネル数または入力の深さ
2.out_channels: 出力のチャンネル数または深さ
3.kernel_size: コンボリューションカーネルの大きさ
4.stride:ステップサイズ、デフォルト1
5.パディング:パディングの大きさ、デフォルトは0
6.dilation: 拡張の大きさ、デフォルトは1、現在は使用されていない
7.グループ:グループの数、デフォルト1
8. bias: デフォルト True, boolean, バイアス値を使用するかどうか
9. padding_mode: デフォルトのパディングを0にする。
順番を覚えていなくても大丈夫ですが、パラメータ名は覚えておく必要があります
参考記事 LeNetネットワークモデルの学習と予測に関するpytorchの実装
以上、Python LeNetネットワークとpytorchの実装について詳しく説明しました。Python LeNetネットワークの実装に関するより詳しい情報は、BinaryDevelopの他の関連記事にもご注目ください
関連
-
[解決済み] ValueError : 閉じたファイルへのI/O操作
-
[解決済み】Python 2.7 : LookupError: unknown encoding: cp65001 [重複]。
-
[解決済み] フラスコパイソンボタン
-
[解決済み] theano をインポートすると AttributeError: module 'theano' has no attribute 'gof'.
-
[解決済み] anaconda-navigatorがアプリケーションのロードで立ち往生する
-
[解決済み] Python で Line2D を使って線を引く
-
[解決済み] PythonでPDFを特定のプリンタに無音印刷する
-
[解決済み] charが母音('a', 'e', 'i', 'o', または 'u')であれば真、そうでなければ偽を返す関数 isVowel(char) を定義する。
-
[解決済み] Cythonコンパイルエラー:動的モジュールにモジュールエクスポート関数が定義されていない
-
[解決済み] dict_keys' オブジェクトを取得すると、リストへのキャストにもかかわらずインデックスがサポートされない
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Python elifの構文が無効です【終了しました
-
ValueErrorを解決する。同一ラベルのシリーズオブジェクトしか比較できない
-
python draw bar chart error ValueError: shape mismatch: Objects cannot be broadcast to the single shape causes and solutions
-
[解決済み] Python 3 では、'map' 型のオブジェクトは len() を持ちません。
-
[解決済み] pandasのデータフレームで2つの列を要素ごとに分割する方法
-
[解決済み] OpenCV houghLinesP パラメータ
-
[解決済み] キーボード入力でタイムアウト?
-
[解決済み] Pycharmです。「インデックスへのファイルのスキャンに時間がかかる
-
[解決済み] Airflowで条件付きタスクを作成する方法
-
[解決済み] spyder python 変数エクスプローラを再度開く方法