pytorch实现卷积神经网络(MNIST,99%准确率)

导入相关的库

import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor

导入数据

training_data = datasets.MNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)


test_data = datasets.MNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)

 We pass the as an argument to . This wraps an iterable over our dataset, and supports automatic batching, sampling, shuffling and multiprocess data loading. Here we define a batch size of 256, i.e. each element in the dataloader iterable will return a batch of 64 features and labels.

batch_size = 256

# Create data loaders.
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print(f"Shape of X [N, C, H, W]: {X.shape}")
    print(f"Shape of y: {y.shape} {y.dtype}")
    break
Shape of X [N, C, H, W]: torch.Size([256, 1, 28, 28])
Shape of y: torch.Size([256]) torch.int64

使用GPU计算

device = "cuda" if torch.cuda.is_available() else "cpu"
print(f"Using {device} device")
Using cuda device

卷积层尝试解决这两个问题。一方面,卷积层保留输入形状,使图像的像素在高和宽两个方向上的相关性均可能被有效识别;另一方面,卷积层通过滑动窗口将同一卷积核与不同位置的输入重复计算,从而避免参数尺寸过大。

卷积神经网络就是含卷积层的网络。本节里我们将介绍一个早期用来识别手写数字图像的卷积神经网络:LeNet 。这个名字来源于LeNet论文的第一作者Yann LeCun。LeNet展示了通过梯度下降训练卷积神经网络可以达到手写数字识别在当时最先进的结果。这个奠基性的工作第一次将卷积神经网络推上舞台,为世人所知。LeNet的网络结构如下图所示。

不过我们使用改进版的卷积神经网络

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv = nn.Sequential(
            nn.Conv2d(1, 32, 5), # in_channels, out_channels, kernel_size
            nn.ReLU(),
            nn.MaxPool2d(2, 2), # kernel_size, stride
            nn.Conv2d(32, 64, 5),
            nn.ReLU(),
            nn.MaxPool2d(2, 2)
        )
        self.fc = nn.Sequential(
            nn.Linear(64*4*4, 128),
            nn.ReLU(),
            nn.Dropout(0.5),
            nn.Linear(128, 64),
            nn.ReLU(),
            nn.Dropout(0.5),
            nn.Linear(64, 10)
        )
    def forward(self, img):
        feature = self.conv(img)
        output = self.fc(feature.view(img.shape[0], -1))
        return output
model = LeNet().to(device)
model
LeNet(
  (conv): Sequential(
    (0): Conv2d(1, 32, kernel_size=(5, 5), stride=(1, 1))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
    (3): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1))
    (4): ReLU()
    (5): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (fc): Sequential(
    (0): Linear(in_features=1024, out_features=128, bias=True)
    (1): ReLU()
    (2): Dropout(p=0.5, inplace=False)
    (3): Linear(in_features=128, out_features=64, bias=True)
    (4): ReLU()
    (5): Dropout(p=0.5, inplace=False)
    (6): Linear(in_features=64, out_features=10, bias=True)
  )
)
loss_fn = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters())

def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    model.train()
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)

        # Compute prediction error
        pred = model(X)
        loss = loss_fn(pred, y)

        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if batch % 100 == 0:
            loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")


def test(dataloader, model, loss_fn):
    size = len(dataloader.dataset)
    num_batches = len(dataloader)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

编写训练循环

epochs = 10
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model, loss_fn)
print("Done!")
Epoch 1
-------------------------------
loss: 2.308621  [    0/60000]
loss: 0.505998  [25600/60000]
loss: 0.268082  [51200/60000]
Test Error: 
 Accuracy: 96.4%, Avg loss: 0.117353 

Epoch 2
-------------------------------
loss: 0.329561  [    0/60000]
loss: 0.254944  [25600/60000]
loss: 0.189128  [51200/60000]
Test Error: 
 Accuracy: 98.1%, Avg loss: 0.065033 

Epoch 3
-------------------------------
loss: 0.152760  [    0/60000]
loss: 0.204619  [25600/60000]
loss: 0.112943  [51200/60000]
Test Error: 
 Accuracy: 98.4%, Avg loss: 0.057176 

Epoch 4
-------------------------------
loss: 0.137523  [    0/60000]
loss: 0.149151  [25600/60000]
loss: 0.111854  [51200/60000]
Test Error: 
 Accuracy: 98.6%, Avg loss: 0.046431 

Epoch 5
-------------------------------
loss: 0.102964  [    0/60000]
loss: 0.076728  [25600/60000]
loss: 0.107589  [51200/60000]
Test Error: 
 Accuracy: 98.9%, Avg loss: 0.035916 

Epoch 6
-------------------------------
loss: 0.126341  [    0/60000]
loss: 0.068162  [25600/60000]
loss: 0.081467  [51200/60000]
Test Error: 
 Accuracy: 98.9%, Avg loss: 0.038968 

Epoch 7
-------------------------------
loss: 0.130671  [    0/60000]
loss: 0.110663  [25600/60000]
loss: 0.087696  [51200/60000]
Test Error: 
 Accuracy: 99.0%, Avg loss: 0.032638 

Epoch 8
-------------------------------
loss: 0.083890  [    0/60000]
loss: 0.135233  [25600/60000]
loss: 0.082023  [51200/60000]
Test Error: 
 Accuracy: 99.0%, Avg loss: 0.036280 

Epoch 9
-------------------------------
loss: 0.150658  [    0/60000]
loss: 0.068766  [25600/60000]
loss: 0.094734  [51200/60000]
Test Error: 
 Accuracy: 99.1%, Avg loss: 0.036989 

Epoch 10
-------------------------------
loss: 0.191105  [    0/60000]
loss: 0.152277  [25600/60000]
loss: 0.091440  [51200/60000]
Test Error: 
 Accuracy: 99.0%, Avg loss: 0.032618 

Done!

你可能感兴趣的:(深度学习,pytorch,cnn,深度学习)