继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Pytorch入门实战一:LeNet神经网络实现 MNIST手写数字识别

蝴蝶不菲
关注TA
已关注
手记 244
粉丝 81
获赞 379

记得第一次接触手写数字识别数据集还在学习TensorFlow,各种sess.run(),头都绕晕了。自从接触pytorch以来,一直想写点什么。曾经在2017年5月,Andrej Karpathy发表的一片Twitter,调侃道:l've been using PyTorch a few months now, l've never felt better, l've more energy.My skin is clearer. My eye sight has improved。确实,使用pytorch以来,确实感觉心情要好多了,不像TensorFlow那样晦涩难懂。迫不及待的用pytorch实战了一把MNIST数据集,构建LeNet神经网络。话不多说,直接上代码!

复制代码

import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets,transforms
import torchvision
from torch.autograd import Variable
from torch.utils.data import DataLoader
import cv2
class LeNet(nn.Module):   
 def __init__(self):      
   super(LeNet, self).__init__()       
    self.conv1 = nn.Sequential(         
       nn.Conv2d(1, 6, 3, 1, 2),      
             nn.ReLU(),         
                nn.MaxPool2d(2, 2)      
                  )        
                  self.conv2 = nn.Sequential(     
                         nn.Conv2d(6, 16, 5),    
                                 nn.ReLU(),     
                                        nn.MaxPool2d(2, 2)     
                                           )       
                                            self.fc1 = nn.Sequential(            nn.Linear(16 * 5 * 5, 120),            nn.BatchNorm1d(120),            nn.ReLU()        )        self.fc2 = nn.Sequential(            nn.Linear(120, 84),            nn.BatchNorm1d(84),#加快收敛速度的方法(注:批标准化一般放在全连接层后面,激活函数层的前面)            nn.ReLU()        )        self.fc3 = nn.Linear(84, 10)    #         self.sfx = nn.Softmax()    def forward(self, x):        x = self.conv1(x)        x = self.conv2(x)        #         print(x.shape)        x = x.view(x.size()[0], -1)        x = self.fc1(x)        x = self.fc2(x)        x = self.fc3(x)        #         x = self.sfx(x)        return xdevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')batch_size = 64LR = 0.001Momentum = 0.9# 下载数据集train_dataset = datasets.MNIST(root = './data/',                              train=True,                              transform = transforms.ToTensor(),                              download=False)test_dataset =datasets.MNIST(root = './data/',                            train=False,                            transform=transforms.ToTensor(),                            download=False)#建立一个数据迭代器train_loader = torch.utils.data.DataLoader(dataset = train_dataset,                                          batch_size = batch_size,                                          shuffle = True)test_loader = torch.utils.data.DataLoader(dataset = test_dataset,                                         batch_size = batch_size,                                         shuffle = False)#实现单张图片可视化# images,labels = next(iter(train_loader))# img  = torchvision.utils.make_grid(images)# img = img.numpy().transpose(1,2,0)# # img.shape# std = [0.5,0.5,0.5]# mean = [0.5,0.5,0.5]# img = img*std +mean# cv2.imshow('win',img)# key_pressed = cv2.waitKey(0)net = LeNet().to(device)criterion = nn.CrossEntropyLoss()#定义损失函数optimizer = optim.SGD(net.parameters(),lr=LR,momentum=Momentum)epoch = 1if __name__ == '__main__':    for epoch in range(epoch):        sum_loss = 0.0        for i, data in enumerate(train_loader):            inputs, labels = data            inputs, labels = Variable(inputs).cuda(), Variable(labels).cuda()            optimizer.zero_grad()#将梯度归零            outputs = net(inputs)#将数据传入网络进行前向运算            loss = criterion(outputs, labels)#得到损失函数            loss.backward()#反向传播            optimizer.step()#通过梯度做一步参数更新            # print(loss)            sum_loss += loss.item()            if i % 100 == 99:                print('[%d,%d] loss:%.03f' % (epoch + 1, i + 1, sum_loss / 100))                sum_loss = 0.0    #验证测试集    net.eval()#将模型变换为测试模式    correct = 0    total = 0    for data_test in test_loader:        images, labels = data_test        images, labels = Variable(images).cuda(), Variable(labels).cuda()        output_test = net(images)        # print("output_test:",output_test.shape)        _, predicted = torch.max(output_test, 1)#此处的predicted获取的是最大值的下标        # print("predicted:",predicted.shape)        total += labels.size(0)        correct += (predicted == labels).sum()    print("correct1: ",correct)    print("Test acc: {0}".format(correct.item() / len(test_dataset)))#.cpu().numpy()

复制代码

本次识别手写数字,只做了1个epoch,train_loss:0.250,测试集上的准确率:0.9685,相当不错的结果。

https://img4.mukewang.com/5c7b31ec0001abbf04680292.jpg

 

作者:泽积

原文出处:https://www.cnblogs.com/shenpings1314/p/10463647.html  

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP