pytorch官方demo(LeNet)

pytorch官方demo(Lenet)

1、首先,我们定义LeNet网络模型,构建的模型如下: 

model

import torch.nn as nn
import torch.nn.functional as F      #导入pytorch的两个包

 #在pytorch中搭建模型,首先定义一个类,类继承与nn.module这个父类
class LeNet(nn.Module):
    def __init__(self):              #定义初始化函数,在初始化过程中,搭建我们所使用的网络层结构
        super(LeNet, self).__init__()      #涉及到多继承,一般使用super函数
        self.conv1 = nn.Conv2d(3, 16, 5)    #按住ctrl键,鼠标左键点击函数,进入函数里面,输入的彩色图片,深度3,(输入的深度,卷积核个数也就是输出的深度,卷积核大小)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(16, 32, 5)
        self.pool2 = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(32*5*5, 120)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x):            #,forward函数定义正向传播的过程,x指的是输入的数据
        x = F.relu(self.conv1(x))    # 输入的数据先经过卷积层,再经过激活函数。input(3, 32, 32) output(16, 28, 28)
        x = self.pool1(x)            # 经过下采样,得到输出。output(16, 14, 14)
        x = F.relu(self.conv2(x))    # output(32, 10, 10)
        x = self.pool2(x)            # output(32, 5, 5)
        x = x.view(-1, 32*5*5)       # 全连接层将特征矩阵展平成一维向量。-1代表第一个维度batch,第二个维度为展平后节点的个数,自动推理output(32*5*5)
        x = F.relu(self.fc1(x))      # output(120)
        x = F.relu(self.fc2(x))      # output(84)
        x = self.fc3(x)              # output(10)
        return x


#输入测试网络模型的代码段
import torch            
input1 = torch.rand([32,3,32,32])
model = LeNet()
print(model)
output = model(input1)

输入代码段,运行这个网络模型,运行结果如下:

2、输入训练脚本:

train

import torch
import torchvision
import torch.nn as nn
from model import LeNet
import torch.optim as optim
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np


  #transform是对图像进行预处理的函数,normalize标准化函数
  #transforms.Compose方法将使用的预处理方法打包成为一个整体、
  #ToTensor将(H,W,C),像素值[0,255]转换成(C,H,W),(0,1)
transform = transforms.Compose(
     [transforms.ToTensor(),
      transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

    # 50000张训练图片
    # 第一次使用时要将download设置为True才会自动去下载数据集,将数据集下载到当前目录的data文件夹下
    #torchvision中的datasets下有很多的数据集
train_set = torchvision.datasets.CIFAR10(root='./data', train=True,
                                             download=False, transform=transform)

  #torch.utils.data.DataLoader将训练集导入进来,并且分成一个一个批次的,num_workers载入数据的线程数,window下必须设置成0
train_loader = torch.utils.data.DataLoader(train_set, batch_size=36,
                                            shuffle=True, num_workers=0)
#     # 10000张验证图片
#     # 第一次使用时要将download设置为True才会自动去下载数据集
val_set = torchvision.datasets.CIFAR10(root='./data', train=False,
                                        download=False, transform=transform)
val_loader = torch.utils.data.DataLoader(val_set, batch_size=10000  ,
                                            shuffle=False, num_workers=0)
val_data_iter = iter(val_loader)     #iter将val_loader转化为可迭代的迭代器
val_image, val_label = val_data_iter.next()     #通过next方法获取测试的图像和标签值,提取验证集

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')    #元组类型,值不可改变



net = LeNet()     #实例化模型
loss_function = nn.CrossEntropyLoss()       #定义损失函数和优化器,交叉熵损失,Adam优化器
optimizer = optim.Adam(net.parameters(), lr=0.001)   #parameters将LeNet所有可训练的参数都进行优化,lr学习率


for epoch in range(5):  # loop over the dataset multiple times,训练集迭代5次

    running_loss = 0.0   #累加训练中的损失
    for step, data in enumerate(train_loader, start=0):   #通过enumerate函数不仅返回每一批的数据data,还会返回data所对应的步数,从0开始
            # get the inputs; data is a list of [inputs, labels]
        inputs, labels = data    #将数据分离成对应的图像以及分类所对应的标签

        # zero the parameter gradients
        optimizer.zero_grad()        #历史梯度会累加,将历史损失梯度清零
         # forward + backward + optimize
        outputs = net(inputs)    #预测输出
        loss = loss_function(outputs, labels)   #计算损失
        loss.backward()     #将loss反向传播,参数更新
        optimizer.step()

            # print statistics
        running_loss += loss.item()    #累加损失
        if step % 500 == 499:    # print every 500 mini-batches,每隔500步计算一次损失
            with torch.no_grad():      #在接下来的过程中,不计算每个节点的误差损失梯度,不使用这个函数会占用更多的内存资源
                outputs = net(val_image)  # [batch, 10] 正向传播
                predict_y = torch.max(outputs, dim=1)[1]    #输出的最大的index,最可能是哪个类别,在维度1也就是十个类别去寻找

                #通过值是否相等torch.eq()和求和函数sum()求预测对了多少样本,在tensor中计算,得到的是tensor,通过item()方法拿到数值,再除以测试样本的数目得到准确率
                accuracy = torch.eq(predict_y, val_label).sum().item() / val_label.size(0)

                print('[%d, %5d] train_loss: %.3f  test_accuracy: %.3f' %
                        (epoch + 1, step + 1, running_loss / 500, accuracy))    #每500步求一个平均损失
                running_loss = 0.0   #下一次500步迭代的过程中损失从0开始

print('Finished Training')

save_path = './Lenet.pth'     #设置保存路径
torch.save(net.state_dict(), save_path)    #通过torch.save将网络中所有参数保存,保存的路径是save_path



# if __name__ == '__main__':
#     main()

训练结果如下:

3、输入预测脚本:

predict

import torch
import torchvision.transforms as transforms
from PIL import Image   #,导入PIL的image模块,PIL模块载入图像

from model import LeNet


def main():
    transform = transforms.Compose(
        [transforms.Resize((32, 32)),
         transforms.ToTensor(),
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])   #预处理,将图像大小设置为32*32,并且将其转化为tensor,标准化处理

    classes = ('plane', 'car', 'bird', 'cat',
               'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

    net = LeNet()    #实例化LeNet

    net.load_state_dict(torch.load('Lenet.pth'))     #通过 net.load_state_dict载入刚刚保存的权重文件

    im = Image.open('2.jpeg')   #image模块载入图像
    im = transform(im)  # 预处理之后得到一个[C, H, W]的格式
    im = torch.unsqueeze(im, dim=0)  # [N, C, H, W],torch.unsqueeze增加一个新的维度

    with torch.no_grad():         #不需要求损失梯度
        outputs = net(im)
        predict = torch.max(outputs, dim=1)[1].data.numpy()    #找到最大值对应的index
    print(classes[int(predict)])       #将index传入到类别当中
    #     predict = torch.softmax((outputs,dim=1)
    # print(predict)
if __name__ == '__main__':
    main()


从网上随机下载一个类别中的图片,使用此模型进行预测,预测的结果如下:

 从结果的值,预测的类别是ship

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值