LeNet-5の紹介
LeNet-5公式ウェブサイトリンク
畳み込みニューラルネットワークは、特別な多層ニューラルネットワークです。他のほとんどすべてのニューラルネットワークと同様に、それらはバックプロパゲーションアルゴリズムのバージョンを使用してトレーニングされます。それらの違いはアーキテクチャです。
畳み込みニューラルネットワークは、最小限の前処理でピクセル画像から直接視覚パターンを認識するように設計されています。
それらは、大きな変動性のあるパターン(手書き文字など)を認識でき、歪みや単純な幾何学的変換に対して堅牢です。
LeNet-5は、手書きおよび機械印刷された文字認識用に設計されています。
C1層は6つの畳み込みカーネル(6種類の局所特徴が抽出される)を持つ畳み込み層であり、カーネルサイズは5 * 5です
。S2層はプーリング層であり、ダウンサンプリング(面積:2 * 2)はネットワークを縮小しますトレーニングパラメータとモデル。過剰適合の程度。
C3レイヤーは2番目の畳み込みレイヤーで、16個の畳み込みカーネルを使用します。カーネルサイズ:5 * 5で特徴を抽出します
。S4レイヤーもプーリングレイヤー、面積:2 * 2
C5レイヤーは最後の畳み込みレイヤー、畳み込みカーネルサイズ:5 * 5畳み込みカーネルタイプ:120
最後に、完全に接続されたレイヤーを使用して、C5の120の特徴を分類し、最後に0〜9の確率を出力します。
LeNet-5が強力な理由は、当時の環境でのMNISTデータの認識率が99%に向上したためです。次のテストは、MNISTデータを使用して実行されます。
データセットを準備する
PytorchにはMNISTデータセットが含まれているため、ここで直接使用できます。DataLoaderを直接使用してデータを読み取ります。
トレーニングデータセット
train_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train=True, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=BATCH_SIZE, shuffle=True)
テストデータセット
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('data', train=False, transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=BATCH_SIZE, shuffle=True)
ネットワークを定義する
注:公式チュートリアルで定義されているネットワークには、32X32アクセスイメージが必要です。MNISTデータの画像サイズは28X28であるため、ここでは画像のサイズを変更しませんが、最初の線形レイヤーの入力フィーチャのサイズを変更します。
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
# 1 input image channel, 6 output channels, 5x5 square convolution
# kernel
self.conv1 = nn.Conv2d(1, 6, 5)
self.conv2 = nn.Conv2d(6, 16, 5)
# an affine operation: y = Wx + b
self.fc1 = nn.Linear(16 * 4 * 4, 120) # 4*4 from image dimension
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
# Max pooling over a (2, 2) window
x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2))
# If the size is a square, you can specify with a single number
x = F.max_pool2d(F.relu(self.conv2(x)), 2)
# x = F.relu(self.conv2(x))
x = torch.flatten(x, 1) # flatten all dimensions except the batch dimension
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
x = F.log_softmax(x, dim=1) # 计算log(softmax(x))
return x
トレーニングとテスト
ここではCPUトレーニングを使用しており、GPUを使用した場合の速度が速くなります。
#定义超参数
BATCH_SIZE=512
EPOCHS=20 # 总共训练批次
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 让torch判断是否使用GPU,建议使用GPU环境
#声明一个网络
model = Net()
#采用Adam优化器
optimizer = optim.Adam(model.parameters())
#开始训练
for epoch in range(1, EPOCHS + 1):
# 训练
model.train()
for batch_idx, (data, target) in enumerate(train_loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizer.step()
if(batch_idx+1)%30 == 0:
print('Train Epoch: {
} [{
}/{
} ({
:.0f}%)]\tLoss: {
:.6f}'.format(
epoch, batch_idx * len(data), len(train_loader.dataset),
100. * batch_idx / len(train_loader), loss.item()))
# 测试
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():
for data, target in test_loader:
data, target = data.to(device), target.to(device)
output = model(data)
test_loss += F.nll_loss(output, target, reduction='sum').item() # 将一批的损失相加
pred = output.max(1, keepdim=True)[1] # 找到概率最大的下标
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(test_loader.dataset)
print('\nTest set: Average loss: {
:.4f}, Accuracy: {
}/{
} ({
:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
トレーニング結果
トレインエポック:1 [14848/60000(25%)]ロス:0.796161
トレインエポック:1 [30208/60000(50%)]ロス:0.382039
トレインエポック:1 [45568/60000(75%)]ロス:0.258347
テストセット:平均損失:0.2065、精度:9400/10000(94%)
トレインエポック:2 [14848/60000(25%)]ロス:0.203479
トレインエポック:2 [30208/60000(50%)]ロス:0.107671
トレインエポック:2 [45568/60000(75%)]ロス:0.143290
テストセット:平均損失:0.1203、精度:9635/10000(96%)
トレインエポック:3 [14848/60000(25%)]ロス:0.130832
トレインエポック:3 [30208/60000(50%)]ロス:0.093064
トレインエポック:3 [45568/60000(75%)]ロス:0.097940
テストセット:平均損失:0.0878、精度:9731/10000(97%)
列車エポック:4 [14848/60000(25%)]損失:0.079764
列車エポック:4 [30208/60000(50%)]損失:0.092091
列車エポック:4 [45568/60000(75%)]損失:0.083679
テストセット:平均損失:0.0798、精度:9744/10000(97%)
列車エポック:5 [14848/60000(25%)]損失:0.081892
列車エポック:5 [30208/60000(50%)]損失:0.083289
列車エポック:5 [45568/60000(75%)]損失:0.068377
テストセット:平均損失:0.0642、精度:9789/10000(98%)
列車エポック:6 [14848/60000(25%)]損失:0.066107
列車エポック:6 [30208/60000(50%)]損失:0.089498
列車エポック:6 [45568/60000(75%)]損失:0.042199
テストセット:平均損失:0.0565、精度:9812/10000(98%)
列車エポック:7 [14848/60000(25%)]損失:0.043734
列車エポック:7 [30208/60000(50%)]損失:0.078332
列車エポック:7 [45568/60000(75%)]損失:0.054749
テストセット:平均損失:0.0545、精度:9827/10000(98%)
列車エポック:8 [14848/60000(25%)]損失:0.039079
列車エポック:8 [30208/60000(50%)]損失:0.057117
列車エポック:8 [45568/60000(75%)]損失:0.062051
テストセット:平均損失:0.0497、精度:9841/10000(98%)
列車エポック:9 [14848/60000(25%)]損失:0.087467
列車エポック:9 [30208/60000(50%)]損失:0.055735
列車エポック:9 [45568/60000(75%)]損失:0.030613
テストセット:平均損失:0.0450、精度:9853/10000(99%)
トレインエポック:10 [14848/60000(25%)]ロス:0.053619
トレインエポック:10 [30208/60000(50%)]ロス:0.048457
トレインエポック:10 [45568/60000(75%)]ロス:0.050112
テストセット:平均損失:0.0461、精度:9851/10000(99%)
列車エポック:11 [14848/60000(25%)]損失:0.026218
列車エポック:11 [30208/60000(50%)]損失:0.044744
列車エポック:11 [45568/60000(75%)]損失:0.044205
テストセット:平均損失:0.0429、精度:9860/1000(99%)
列車エポック:12 [14848/60000(25%)]損失:0.038024
列車エポック:12 [30208/60000(50%)]損失:0.032498
列車エポック:12 [45568/60000(75%)]損失:0.047964
テストセット:平均損失:0.0445、精度:9848/10000(98%)
列車エポック:13 [14848/60000(25%)]損失:0.027184
列車エポック:13 [30208/60000(50%)]損失:0.015675
列車エポック:13 [45568/60000(75%)]損失:0.021164
テストセット:平均損失:0.0434、精度:9858/10000(99%)
列車エポック:14 [14848/60000(25%)]損失:0.010554
列車エポック:14 [30208/60000(50%)]損失:0.050443
列車エポック:14 [45568/60000(75%)]損失:0.018514
テストセット:平均損失:0.0406、精度:9868/10000(99%)
列車エポック:15 [14848/60000(25%)]損失:0.019876
列車エポック:15 [30208/60000(50%)]損失:0.028926
列車エポック:15 [45568/60000(75%)]損失:0.062516
テストセット:平均損失:0.0361、精度:9882/10000(99%)
列車エポック:16 [14848/60000(25%)]損失:0.009616
列車エポック:16 [30208/60000(50%)]損失:0.017137
列車エポック:16 [45568/60000(75%)]損失:0.034604
テストセット:平均損失:0.0346、精度:9881/10000(99%)
列車エポック:17 [14848/60000(25%)]損失:0.014641
列車エポック:17 [30208/60000(50%)]損失:0.034391
列車エポック:17 [45568/60000(75%)]損失:0.006974
テストセット:平均損失:0.0362、精度:9873/10000(99%)
列車エポック:18 [14848/60000(25%)]損失:0.014653
列車エポック:18 [30208/60000(50%)]損失:0.023054
列車エポック:18 [45568/60000(75%)]損失:0.008639
テストセット:平均損失:0.0369、精度:9880/1000(99%)
列車エポック:19 [14848/60000(25%)]損失:0.026135
列車エポック:19 [30208/60000(50%)]損失:0.028519
列車エポック:19 [45568/60000(75%)]損失:0.023374
テストセット:平均損失:0.0428、精度:9867/10000(99%)
列車エポック:20 [14848/60000(25%)]損失:0.012330
列車エポック:20 [30208/60000(50%)]損失:0.023574
列車エポック:20 [45568/60000(75%)]損失:0.030578
テストセット:平均損失:0.0480、精度:9852/10000(99%)
正解率99%