2、pytorch官方demo(Lenet)

前言

记录一下自己学习的过程,内容主要来自于B站的一位up主,在此非常感谢他无私的奉献精神。看到他的视频请一键三连!


这里有些关于pycharm使用的小技巧

  • 在我们想查看某个函数的定义的时候,我们可以ctrl +鼠标左键快速查看。
  • 如果我们想要查看详细的定义,直接移步pytorch 官网查看详细文档:https://pytorch.org/docs/stable/index.html

pytorch官网教程:https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html

1 model.py

自己思考的一些点:

  • if __name__ == '__main__'的作用就是条件判断语句,当我们直接运行脚本的时候,__name__的值为__main__,当被当成模块去import的时候,__name__的值为该脚本的名称。下面我们举个详细的例子。
    当我们直接执行demo.py的时候。
    在这里插入图片描述
    在这里插入图片描述
    当我们import demo到一个新的demo0中去执行的时候结果如下,此时__name__的值不等于__main__,所以if __name__ == '__main__'后的语句就不会执行。
    在这里插入图片描述
    在这里插入图片描述

  • 我们将dataset输入到DataLoader中返回的是对应的是imagelabel。所以后面代码从train_loader中提取出来的data才会有imagelabel

import torch.nn as nn
import torch.nn.functional as f


class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, 5)
        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)  # 10代表自己的分类类别个数

    def forward(self, x):
        x = f.relu(self.conv1(x))  # input(3, 32, 32) output(16, 28, 28)
        x = self.pool1(x)  # input(16, 28, 28) output(16, 14, 14)
        x = f.relu(self.conv2(x))  # input(16, 14, 14) output(32, 10,10)
        x = self.pool2(x)  # input(32, 10,10) output(32, 5, 5)
        x = x.view(-1, 32 * 5 * 5)  # 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

2 train.py

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


def main():
    #     # 一些预处理操作
    transform = transforms.Compose(
        [transforms.ToTensor(),
         transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])
    # 定义训练集
    train_set = torchvision.datasets.CIFAR10(root='./data', train=True,
                                             transform=transform, download=True)
    # 定义训练数据加载器
    train_loader = torch.utils.data.DataLoader(dataset=train_set, batch_size=64,
                                               shuffle=True, num_workers=0)
    # 定义验证集
    val_set = torchvision.datasets.CIFAR10(root='./data', train=False,
                                           download=False, transform=transform)
    # 定义验证数据加载器
    val_loader = torch.utils.data.DataLoader(val_set, batch_size=5000,
                                             shuffle=False, num_workers=0)

    val_data_iter = iter(val_loader)
    val_image, val_label = next(val_data_iter)

# classes = ('plane', 'car', 'bird', 'cat',
#            'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
# 查看4张图像
# def imshow(img):
#     img = img / 2 + 0.5  # unnormalize
#     npimg = img.numpy()
#     plt.imshow(np.transpose(npimg, (1, 2, 0)))
#     plt.show()
#
# imshow(torchvision.utils.make_grid(val_image))
# # print labels
# print(' '.join(f'{classes[val_label[j]]:5s}' for j in range(4)))

    # 实例化我们的网络,并且定义我们使用的损失函数和优化器
    net = LeNet()
    loss_function = torch.nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(net.parameters(), lr=0.001)


    # 开始训练
    for epoch in range(5):

        running_loss = 0.0
        # enumerate会返回一个两个值,第一个值是索引。
        for step, data in enumerate(train_loader, start=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()
            optimizer.step()

            # print statistics
            running_loss += loss.item()
            if step % 500 == 499:  # print every 500 mini-batches
                with torch.no_grad():
                    outputs = net(val_image)  # [batch, 10]

                    # 返回最大值索引
                    predict_y = torch.max(outputs, dim=1)[1]
                    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))
                    running_loss = 0.0

    print('Finished Training')
    save_path = './Lenet.pth'
    torch.save(net.state_dict(), save_path)

if __name__ == '__main__':
    main()

3 predict

import torch
import torchvision.transforms as transforms
from PIL import Image

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))])

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

    net = LeNet()
    net.load_state_dict(torch.load('Lenet.pth'))

    im = Image.open(r'C:\Users\QYB\Desktop\1.jpg')  # [H, W, C]
    im = transform(im)  # [C, H, W]
    im = torch.unsqueeze(im, dim=0)  # [N, C, H, W]

    with torch.no_grad():
        outputs = net(im)

        predict = torch.max(outputs, dim=1)[1].numpy()
    print("这张图片是:",classes[int(predict)])

        # 使用softmax输出概率
        # predict = torch.softmax(outputs, dim=1)


if __name__ == '__main__':
    main()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值