ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

CV算法复现(分类算法1/6):LeNet5

2020-12-30 20:31:48  阅读:260  来源: 互联网

标签:LeNet5 nn train self torch 算法 val import CV


致谢:霹雳吧啦Wz:https://space.bilibili.com/18161609

目录

致谢:霹雳吧啦Wz:https://space.bilibili.com/18161609

1 本次要点

1.1 Python库语法

1.2 Pytorch框架语法

2 环境

3 网络结构

4 代码结构

4.1 model.py

4.2 utils.py

4.3 train.py

4.4 test.py


1 本次要点

1.1 Python库语法

  1. PIL 和 numpy 中维度顺序:H*W*C
  2. enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。如
  3. with:上下文管理器。with 语句适用于对资源进行访问的场合,相当于try….except….finlally,确保使用过程中不管是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。
  4. :解决多层继承中可能出现的一些问题。使用多继承时,一般要用此函数。

1.2 Pytorch框架语法

  1. pytorch 中 tensor 维度顺序:C*H*W
  2. optimizer.zero_grad():每计算一次batch后,要将历史梯度清零,防止累加。

  3. item():得到元素张量里面的元素值。(将张量值变为可计算的值?)
  4. #不计算损失和梯度。(节省内存和计算量)

 

2 环境

  • win10,GPU 1060 3G
  • pytorch 1.4
  • Python 3.6

3 网络结构

4 代码结构

  • model.py
  • utils.py
  • train.py
  • test.py
  • data(存放cifar数据集:需要解压,不能更改压缩包名字)
  • 1.jpg(测试图)

4.1 model.py

import torch.nn as nn
import torch.nn.functional as F

class LeNet(nn.Module):
    def __init__(self): #初始化函数
        super(LeNet, self).__init__() #super解决多层继承中可能出现的一些问题。使用多继承,一般要用此函数。
        self.conv1 = nn.Conv2d(3, 6, 5)
        self.pool1 = nn.MaxPool2d(2, 2)
        self.conv2 = nn.Conv2d(6, 16, 5)
        self.pool2 = nn.MaxPool2d(2, 2)
        self.fc1 = nn.Linear(16*5*5, 120) #输入要展平成1维向量(16通道,每通道5*5特征图)
        self.fc2 = nn.Linear(120, 84)
        self.fc3 = nn.Linear(84, 10)

    def forward(self, x): #x代表输入的数据
        x = F.relu(self.conv1(x)) # input(3, 32, 32) output(6, 28, 28)
        x = self.pool1(x)         # output(6, 14, 14)
        x = F.relu(self.conv2(x)) # output(16, 10, 10)
        x = self.pool2(x)         # output(16, 5, 5)
        x = x.view(-1, 16*5*5)    # output(16*5*5 = 400)
        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([2, 3, 32, 32]) #B C H W
# print(input1)

# model = LeNet()
# print(model)

# output = model(input1)
# print(output)

4.2 utils.py

import torchvision.transforms as transforms

transform_train = transforms.Compose(
    [transforms.ToTensor(), #将数据转为tensor,维度顺序c*h*w, 值归一化[0,1]
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 再对数据进行标准化]
)

transform_test = transforms.Compose(
    [transforms.Resize((32, 32)),
     transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]
)

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

4.3 train.py

import torch
import torchvision
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms

import matplotlib.pyplot as plt 
import numpy as np 

from utils import clases_cifar10, transform_train
from model import LeNet


# 1 加载训练集(5万),预处理,打乱顺序并分割成一批批的batch
train_data = torchvision.datasets.CIFAR10(root='M:/CV_data/cifar-10/', train=True,
                                        download=False, transform=transform_train)
# win系统下num_work要设为0.
train_loader = torch.utils.data.DataLoader(train_data, batch_size=32,
                                            shuffle=True, num_workers=0)

# 2 加载验证集(1万),预处理,打乱顺序并分割成1个batch
val_data = torchvision.datasets.CIFAR10(root='M:/CV_data/cifar-10/', train=False,
                                        download=False, transform=transform_train)
val_loader = torch.utils.data.DataLoader(val_data, batch_size=10000,
                                            shuffle=False, num_workers=0)
#创建迭代器对象(每次调用.next(),就会自动迭代集合中下一个元素,由于val集batch就1个,所以调用一次.next()就全部取完了)
val_data_iter = iter(val_loader)
val_images, val_labels = val_data_iter.next()


# 3 初始化模型,损失函数,优化器
net = LeNet()
loss_function = nn.CrossEntropyLoss()
optimizer = optim.Adam(net.parameters(), lr=0.001)

# 4 开始训练
for epoch in range(5):
    running_loss = 0.0 #累加损失

    for step, data in enumerate(train_loader, start=0): #遍历训练数据,并返回当前index
        inputs, labels = data
        # 每计算一次batch, 将历史梯度清零,防止累加。
        optimizer.zero_grad()
        # forward backward optimize
        outputs = net(inputs)
        loss = loss_function(outputs, labels)
        loss.backward()
        optimizer.step() # 参数更新

        # 打印训练过程信息
        running_loss += loss.item() # item()得到元素张量里面的数值
        if step % 500 == 499:
            with torch.no_grad():#不计算损失和梯度。(节省内存和计算量)
                outputs = net(val_images) #[batch=10000, 10]
                predict_y = torch.max(outputs, dim=1)[1]
                accuracy = (predict_y == val_labels).sum().item() / val_labels.size(0)

                print('[%d, %5d] train_loss: %.3f val_accuracy: %.3f' %
                        (epoch + 1, step + 1, running_loss / 500, accuracy))
                running_loss = 0.0

# 5 保存模型
print("finished training")
save_path = './Lenet.pth'
torch.save(net.state_dict(), save_path)

输出

4.4 test.py

import torch
from PIL import Image
from model import LeNet
from utils import clases_cifar10, transform_test

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

im = Image.open('1.jpg')
im = transform_test(im) # [c, h, w]
im = torch.unsqueeze(im, dim=0) # [n, c, h, w]

with torch.no_grad(): # 此句可以不要,但大批量测试时,必须加此句,节省内存和计算量。
    outputs = net(im) # 输出值谁最大,预测的就是谁
    predict = torch.softmax(outputs, dim=1) # 将值转换成预测概率
    print(predict)
    max_index = torch.max(predict, dim=1)[1].data.numpy() # 返回一个1*1数组。
    print(clases_cifar10[int(max_index)]) # 打印对应的便签

输出

 

标签:LeNet5,nn,train,self,torch,算法,val,import,CV
来源: https://blog.csdn.net/weixin_42118657/article/details/111410650

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有