当前位置:   article > 正文

关于最新版本GPU下pytorch实现卷积神经网络实现手写数字识别的代码_pytorch gpu手写数字

pytorch gpu手写数字

最全的卷积神经网络实现手写数字识别,由于版本的更新,好多函数被替代或简化,本文是根据最新版本的GPU11.0的pytorch撰写的卷积神经网络实现手写数字识别。欢迎大家借鉴。

 

  1. import torch
  2. import torch.nn as nn
  3. import torch.nn.functional as F
  4. import torch.optim as optim
  5. from torchvision import datasets, transforms
  6. import torchvision
  7. from torch.autograd import Variable
  8. from torch.utils.data import DataLoader
  9. import matplotlib.pyplot as plt
  10. ####定义卷积神经网络
  11. #nn.Module,是专门为神经网络设计的模块接口
  12. class CNN(nn.Module): #(相当于定义一个类)
  13. def __init__(self):
  14. #调用父类初始化函数(父类就是nn.Module)
  15. super(CNN, self).__init__()
  16. #一个有序的容器,神经网络模块将按照传入的顺序依次添加到计算图中执行,
  17. self.conv1 = nn.Sequential(
  18. #二卷积层,输入通道数是1,输出通道数是16,即16个卷积核
  19. nn.Conv2d(1, 6, 5, 1, 2), #1是一个通道即黑白图片,彩色图像是36是输出通道数,按自己需求决定,没有固定值
  20. #BatchNorm2d是卷积网络中防止梯度消失或爆炸的函数,参数是卷积的输出通道数 (28*28-5+2*2)/1+1=784=28*28
  21. nn.BatchNorm2d(6),
  22. nn.ReLU(),
  23. # 卷积后的图像大小:28*28*16,16为深度
  24. nn.MaxPool2d(2, 2))
  25. # 池化后的图像大小:14*14*16
  26. self.conv2 = nn.Sequential(
  27. nn.Conv2d(6, 16, 5),
  28. nn.BatchNorm2d(16),
  29. nn.ReLU(),
  30. #卷积后的图像大小:14*14*32,32为深度
  31. nn.MaxPool2d(2, 2))
  32. #池化后的图像大小:7*7*32
  33. self.fc1 = nn.Sequential(
  34. nn.Linear(16 * 5 * 5, 120),
  35. nn.BatchNorm1d(120),
  36. nn.ReLU())
  37. self.fc2 = nn.Sequential(
  38. nn.Linear(120, 84), ##这里需要计算,其他不需要, W2=(W1-F+2P)/S+1
  39. nn.BatchNorm1d(84),
  40. nn.ReLU(),
  41. nn.Linear(84, 10))
  42. # 最后的结果一定要变为 10,因为数字的选项是 0 ~ 9
  43. def forward(self, x):
  44. x = self.conv1(x)
  45. x = self.conv2(x)
  46. x = x.view(x.size()[0], -1) #为了适应全连接层的要求,将多维度的Tensor展平成一维,一行n列
  47. x = self.fc1(x)
  48. x = self.fc2(x)
  49. return x
  50. ####训练网络
  51. batch_size = 64 #批处理的图片个数
  52. learning_rate = 1e-2 #学习率,梯度下降算法的参数
  53. num_epochs = 20 #全部训练集使用的次数
  54. #下载数据后需要将格式转换成Tensor,且进行标准化
  55. data_tf = transforms.Compose([transforms.ToTensor(), transforms.Normalize([0.5], [0.5])])
  56. ####下载数据集,位置放在本文件的父文件夹下的data文件夹里面
  57. train_dataset = datasets.MNIST(root='./data', train=True, transform=data_tf, download=True)
  58. test_dataset = datasets.MNIST(root='./data', train=False, transform=data_tf)
  59. #DataLoader的作用是每个epoch的时候,对数据进行重新打乱,即重新分组,随机抽出一部分作为训练,每次的训练集都不一样
  60. train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
  61. #对于测试集来说不需要进行从新分组
  62. test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)
  63. ##看看train_loader中的随机抽取图片
  64. for data,target in train_loader:
  65. for i in range(4):
  66. plt.figure()
  67. # print(target[i])
  68. plt.imshow(train_loader.dataset.data[i].numpy())
  69. #如果cuda存在话,divice=‘cuda:0,否则是'cpu'
  70. device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
  71. net = CNN().to(device) #放到GPU上运行,net就是类的实例化
  72. # 损失函数使用交叉熵
  73. criterion = nn.CrossEntropyLoss()
  74. # 优化函数使用 Adam 自适应优化算法
  75. optimizer = optim.Adam(
  76. net.parameters(),
  77. lr=learning_rate,
  78. )
  79. epoch = 1
  80. net.train() #形成训练期间形成的网络,必加这句话
  81. if __name__ == '__main__':
  82. for epoch in range(num_epochs):
  83. sum_loss = 0.0
  84. for i, data in enumerate(train_loader): # enumerate:提取序号和元素,i是序号,data是元素
  85. inputs, labels = data
  86. inputs, labels = Variable(inputs).cuda(), Variable(labels).cuda()
  87. # 根据pytorch中的backward()函数的计算,当网络参量进行反馈时,梯度是被积累的而不是被替换掉;
  88. # 但是在每一个batch时毫无疑问并不需要将两个batch的梯度混合起来累积,因此这里就需要每个batch设置一遍zero_grad 了
  89. # 将梯度初始化为零
  90. optimizer.zero_grad() #在反向传播之前要将梯度归零
  91. ##net(inputs),即model(images)即等价于module.forward(images) 也就是将数据放到网络中去。
  92. outputs = net(inputs) #将数据传入网络进行前向运算,相当于调用forward函数,net.forward(),建立计算图
  93. loss = criterion(outputs, labels) #得到损失函数 ,相当于求出他两个的距离差距。
  94. loss.backward() #反向传播
  95. optimizer.step() #通过梯度做一步参数更新 主要对学习率自动的进行调整
  96. # print(loss)
  97. sum_loss += loss.item()
  98. if i % 100 == 99: #每100次显示一下损失情况
  99. print('[%d,%d] loss:%.03f' %
  100. (epoch + 1, i + 1, sum_loss / 100))
  101. sum_loss = 0.0
  102. #测试模型
  103. net.eval() #将模型变换为测试模式,为了固定BN和dropout层,使得偏置参数不随着发生变化,预测之前都要加上这句。
  104. correct = 0
  105. total = 0
  106. for data_test in test_loader:
  107. images, labels = data_test
  108. images, labels = Variable(images).cuda(), Variable(labels).cuda()
  109. output_test = net(images)
  110. #函数返回两个tensor,第一个是每行的最大值,第二个是每行最大值的索引,因为softmax函数最大值是1
  111. _, predicted = torch.max(output_test, 1) #找出最大的概率,意思就是这张图片倾向于这个类
  112. total += labels.size(0)
  113. correct += (predicted == labels).sum() #预测结果是否等于目标
  114. print("correct1: ", correct)
  115. print("Test acc: {0}".format(correct.item() /
  116. len(test_dataset)))

 

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

闽ICP备14008679号