当前位置:   article > 正文

Pytorch实现CNN:LeNet(附代码实现与讲解)_pytorch的lenet代码

pytorch的lenet代码

目录

一、准备MNIST数据集

 二、LeNet模型构建

三、完整代码


本篇博客教大家使用MNIST数据集基于Pytorch框架实现比较经典的一种卷积神经网络:LeNet。

运行环境:python 3.6.12,pytorch 1.6.0,torchvision 0.7.0

一、准备MNIST数据集

MNIST是一个非常经典的手写字数据库,官网网址请点击此处,需要的可自行下载。不过,Pytorch为我们提供了快速下载并加载MNIST数据集的方法,本博客采用此方法下载数据集,具体代码如下:

  1. from torchvision import datasets, transforms
  2. transform = transforms.Compose([transforms.ToTensor(),
  3. transforms.Normalize((0.1307,), (0.3081,))])
  4. # 读取测试数据,train=True读取训练数据;train=False读取测试数据
  5. # 下载完成后改为download=False
  6. trainset = datasets.MNIST('data', train=True, download=False, transform=transform)
  7. testset = datasets.MNIST('data', train=False, download=False, transform=transform)

其中transforms是图像数据预处理的方法。transforms.ToTensor()是将数据转化为Tensor对象,transforms.Normalize()是对数据进行归一化。具体用法可上网查找,或看官方手册。datasets.MNIST的第一个参数指定了数据集下载和存储的文件夹,可根据需要修改。train=True表示读取训练数据,train=False表示读取测试数据。download=False表示不下载MNIST数据集,因为博主已经下载过,所以是False,如果没有下载将其改为True,下载完成后改为False即可。transform=transform表示使用上面的数据预处理方法对MNIST数据集进行处理。

设置好相应参数之后(download=True),运行上述代码即可自动下载MNIST数据集,并保存到同目录下的data文件夹。

 二、LeNet模型构建

接下来构建LeNet模型。LeNet的网络结构如下图所示,一共7层。其中C1,C3,C5为卷积层,S2,S4为降采样层,F6为全连接层,还有一个输出层。网络结构比较简单,这里不进行具体分析,想要了解的可自行查找。

 具体代码如下:

  1. from torch import nn
  2. from torch.nn.functional import max_pool2d, relu
  3. class LeNet(nn.Module):
  4. def __init__(self):
  5. super(LeNet, self).__init__()
  6. self.Conv1 = nn.Conv2d(1, 6, 5)
  7. self.Conv2 = nn.Conv2d(6, 16, 5)
  8. self.Conv3 = nn.Linear(16 * 4 * 4, 120)
  9. self.fc1 = nn.Linear(120, 64)
  10. self.fc2 = nn.Linear(64, 10)
  11. def forward(self, x):
  12. x = max_pool2d(relu(self.Conv1(x)), kernel_size=2)
  13. x = max_pool2d(relu(self.Conv2(x)), kernel_size=2)
  14. x = x.view(-1, 16 * 4 * 4)
  15. x = relu(self.Conv3(x))
  16. x = relu(self.fc1(x))
  17. x = self.fc2(x)
  18. return x

定义了LeNet类,首先运行父类初的始化函数,并对LeNet的各个层进行了实现。然后定义了forward()函数,即前向传播。

接下来初始化LeNet,并设置使用CPU或GPU运行。使用交叉熵损失函数,Adam优化器,出示学习率设置为0.001。如果电脑有GPU则在GPU上运行,反之在CPU上运行。

  1. device = torch.device('cpu')
  2. if torch.cuda.is_available():
  3. device = torch.device("cuda:0")
  4. print('Training on GPU.')
  5. else:
  6. print('No GPU available, training on CPU.')
  7. lenet = LeNet().to(device)
  8. criterion = nn.CrossEntropyLoss()
  9. optimizer = torch.optim.Adam(lenet.parameters(), lr=1e-3)

接下来,使用Dataloader加载训练集。shuffle=True表示打乱数据顺序。

train_loader = DataLoader(trainset, batch_size=8, shuffle=True)

在上述工作完成后,开始对网络进行训练。设置epoch=5,使用enumetrate加载数据,并进行前向传播与反向传播。每一千个batch输出一次训练结果,如果训练损失低于1e-5,则保存模型并停止训练。

  1. epochs = 5
  2. for epoch in range(epochs):
  3. train_loss = 0.0
  4. for i, data in enumerate(train_loader, 0):
  5. inputs, labels = data
  6. outputs = lenet(inputs.to(device))
  7. loss = criterion(outputs, labels.to(device))
  8. optimizer.zero_grad()
  9. loss.backward()
  10. optimizer.step()
  11. train_loss += loss.item()
  12. if (i + 1) % 1000 == 0:
  13. print('Epoch: [{}/{}], Batch:{}, Loss:{:.5f}'.format(epoch + 1, epochs, i + 1, train_loss / (i + 1)))
  14. if (train_loss / (i + 1)) < 1e-5:
  15. torch.save(lenet.state_dict(), 'lenet.pt') # save model parameters to files
  16. print(
  17. 'Epoch [{}/{}], Batch:{}, Loss: {:.5f}'.format(epoch + 1, epochs, i + 1, train_loss / (i + 1)))
  18. print("The loss value is reached")
  19. break
  20. train_loss = 0.0

在训练完成后,使用测试集测试模型的泛华效果,避免过拟合。仍然使用Dataloader加载测试集。

test_loader = DataLoader(testset, batch_size=8, shuffle=False)

对测试模块进行完善,统计测试结果,并输出测试集准确率。

  1. total = 0.0
  2. correct = 0.0
  3. for data in test_loader:
  4. inputs, labels = data
  5. outputs = lenet(inputs.to(device))
  6. pred_labels = torch.argmax(outputs.data, 1)
  7. labels = labels.to(device)
  8. total += labels.size(0)
  9. correct += (pred_labels == labels).sum()

至此,数据集加载、模型的构建、训练与测试全部完成。

三、完整代码

完整代码如下。

  1. """
  2. pytorch实现LeNet
  3. """
  4. from torchvision import datasets, transforms
  5. import torch
  6. from torch import nn
  7. from torch.utils.data import DataLoader
  8. from torch.nn.functional import max_pool2d, relu, softmax
  9. class LeNet(nn.Module):
  10. def __init__(self):
  11. super(LeNet, self).__init__()
  12. self.Conv1 = nn.Conv2d(1, 6, 5)
  13. self.Conv2 = nn.Conv2d(6, 16, 5)
  14. self.Conv3 = nn.Linear(16 * 4 * 4, 120)
  15. self.fc1 = nn.Linear(120, 64)
  16. self.fc2 = nn.Linear(64, 10)
  17. def forward(self, x):
  18. x = max_pool2d(relu(self.Conv1(x)), kernel_size=2)
  19. x = max_pool2d(relu(self.Conv2(x)), kernel_size=2)
  20. x = x.view(-1, 16 * 4 * 4)
  21. x = relu(self.Conv3(x))
  22. x = relu(self.fc1(x))
  23. x = self.fc2(x)
  24. return x
  25. if __name__ == "__main__":
  26. transform = transforms.Compose([transforms.ToTensor(),
  27. transforms.Normalize((0.1307,), (0.3081,))])
  28. # 读取测试数据,train=True读取训练数据;train=False读取测试数据
  29. # 下载完成后改为download=False
  30. trainset = datasets.MNIST('data', train=True, download=False, transform=transform)
  31. testset = datasets.MNIST('data', train=False, download=False, transform=transform)
  32. device = torch.device('cpu')
  33. if torch.cuda.is_available():
  34. device = torch.device("cuda:0")
  35. print('Training on GPU.')
  36. else:
  37. print('No GPU available, training on CPU.')
  38. lenet = LeNet().to(device)
  39. criterion = nn.CrossEntropyLoss()
  40. optimizer = torch.optim.Adam(lenet.parameters(), lr=1e-3)
  41. epochs = 5
  42. train_loader = DataLoader(trainset, batch_size=8, shuffle=True)
  43. for epoch in range(epochs):
  44. train_loss = 0.0
  45. for i, data in enumerate(train_loader, 0):
  46. inputs, labels = data
  47. outputs = lenet(inputs.to(device))
  48. loss = criterion(outputs, labels.to(device))
  49. optimizer.zero_grad()
  50. loss.backward()
  51. optimizer.step()
  52. train_loss += loss.item()
  53. if (i + 1) % 1000 == 0:
  54. print('Epoch: [{}/{}], Batch:{}, Loss:{:.5f}'.format(epoch + 1, epochs, i + 1, train_loss / (i + 1)))
  55. if (train_loss / (i + 1)) < 1e-5:
  56. torch.save(lenet.state_dict(), 'lenet.pt') # save model parameters to files
  57. print(
  58. 'Epoch [{}/{}], Batch:{}, Loss: {:.5f}'.format(epoch + 1, epochs, i + 1, train_loss / (i + 1)))
  59. print("The loss value is reached")
  60. break
  61. train_loss = 0.0
  62. torch.save(lenet.state_dict(), 'lenet.pt') # save model parameters to files
  63. test_loader = DataLoader(testset, batch_size=8, shuffle=False)
  64. total = 0.0
  65. correct = 0.0
  66. for data in test_loader:
  67. inputs, labels = data
  68. outputs = lenet(inputs.to(device))
  69. pred_labels = torch.argmax(outputs.data, 1)
  70. labels = labels.to(device)
  71. total += labels.size(0)
  72. correct += (pred_labels == labels).sum()
  73. print('Accuracy on the test set: {:.2f}'.format(100 * correct / total))

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/194171
推荐阅读
相关标签
  

闽ICP备14008679号