pytorch搭建LeNet网络实现图像分类器

这篇具有很好参考价值的文章主要介绍了pytorch搭建LeNet网络实现图像分类器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、定义LeNet网络模型

pytorch 中的卷积、池化、输入输出层中参数的含义与位置,可参考下图:
pytorch搭建LeNet网络实现图像分类器

1,卷积 Conv2d

常用的卷积(Conv2d)在pytorch中对应的函数是

# in_channels:输入特征矩阵的深度。如输入一张RGB彩色图像,那in_channels=3
# out_channels:输入特征矩阵的深度。也等于卷积核的个数,使用n个卷积核输出的特征矩阵深度就是n
# kernel_size:卷积核的尺寸。可以是int类型,如3 代表卷积核的height=width=3,也可以是tuple类型如(3, 5)代表卷积核的height=3,width=5
# stride:卷积核的步长。默认为1,和kernel_size一样输入可以是int型,也可以是tuple类型
# padding:补零操作,默认为0。可以为int型如1即补一圈0,如果输入为tuple型如(2, 1) 代表在上下补2行,左右补1列。
torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros')

经卷积后的输出层尺寸计算公式为:
pytorch搭建LeNet网络实现图像分类器
例如:当定义 Conv2d(3, 16, 5) 和 input(3, 32, 32),步长 S 为 1,P 为0时,此时卷积核尺度 F 为5,W 为32,计算得到 output(16, 28, 28)

2,池化 MaxPool2d

最大池化(MaxPool2d)在 pytorch 中对应的函数是:

MaxPool2d(kernel_size, stride)

3,Tensor的展平:view()

注意到,在经过第二个池化层后,数据还是一个三维的Tensor (32, 5, 5),需要先经过展平后(3255)再传到全连接层:

  x = self.pool2(x)            # 第二个池化层 output(32, 5, 5)
  x = x.view(-1, 32*5*5)       # 展平 output(32*5*5)
  x = F.relu(self.fc1(x))      # 传到全连接层 output(120)

4,全连接 Linear

全连接(Linear)在 pytorch 中对应的函数是:

Linear(in_features, out_features, bias=True)

5,代码:定义 LeNet 网络模型

model.py

# 定义LeNet网络模型
import torch.nn as nn
import torch.nn.functional as F

class LeNet(nn.Module):                  # 继承于nn.Module这个父类
    def __init__(self):                  # 初始化网络结构
        super(LeNet, self).__init__()    # 多继承需用到super函数
        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)

    def forward(self, 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)       # 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

二、训练并保存网络参数

1,数据预处理

ToTensor:把输入的图像数据为 shape (H x W x C) in the range [0, 255] 转化为 shape (C x H x W) in the range [0.0, 1.0],同时将 image 和 numpy 输入格式转化为 tensor
Normalize:标准化

transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

2,数据集

用的是CIFAR10数据集,是 pytorch 自带的一个很经典的图像分类数据集,一共包含 10 个类别的 RGB 彩色图片。
pytorch搭建LeNet网络实现图像分类器
注意:第一次运行程序,需要下载数据集到本地,所以第一次运行训练集下载时download=True为True,下载完成后改为False。测试集的加载则不用变化。

3,代码

名词 定义
epoch 对训练集的全部数据进行一次完整的训练,称为 一次 epoch
batch 由于硬件算力有限,实际训练时将训练集分成多个批次训练,每批数据的大小为 batch_size
iteration 或 step 对一个batch的数据训练的过程称为 一个 iteration 或 step
# 加载数据集并训练,训练集计算loss,测试集计算accuracy,保存训练好的网络参数
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
import time

# 数据预处理
transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

# 导入、加载训练集
# 导入50000张训练图片
train_set = torchvision.datasets.CIFAR10(root='./data',      # 数据集存放目录
                                        train=True,          # 表示是数据集中的训练集
                                        download=False,       # 第一次运行时为True,下载数据集,下载完成后改为False
                                        transform=transform) # 预处理过程
# 加载训练集,实际过程需要分批次(batch)训练                                        
train_loader = torch.utils.data.DataLoader(train_set,      # 导入的训练集
                                           batch_size=50,  # 每批训练的样本数
                                           shuffle=False,  # 是否打乱训练集
                                           num_workers=0)  # 使用线程数,在windows下设置为0

# 导入测试集
# 导入10000张测试图片
test_set = torchvision.datasets.CIFAR10(root='./data', 
                                        train=False,    # 表示是数据集中的测试集
                                        download=False,transform=transform)
# 加载测试集
test_loader = torch.utils.data.DataLoader(test_set, 
                                          batch_size=10000, # 每批用于验证的样本数
                                          shuffle=False, num_workers=0)
# 获取测试集中的图像和标签,用于accuracy计算
test_data_iter = iter(test_loader)
test_image, test_label = test_data_iter.next()

#训练过程
net = LeNet()                                       # 定义训练的网络模型
loss_function = nn.CrossEntropyLoss()               # 定义损失函数为交叉熵损失函数 
optimizer = optim.Adam(net.parameters(), lr=0.001)  # 定义优化器(训练参数,学习率)

for epoch in range(5):  # 一个epoch即对整个训练集进行一次训练
    running_loss = 0.0	# 累加过程中的损失
    time_start = time.perf_counter()
    
    for step, data in enumerate(train_loader, start=0):   # enumerate遍历训练集,可以同时返回 data 和 step对应下标,start表示从0下标开始遍历
        inputs, labels = data 	# 获取训练集的图像和标签
        optimizer.zero_grad()   # 清除历史损失梯度
        
        # forward + backward + optimize
        outputs = net(inputs)  				  # 正向传播
        loss = loss_function(outputs, labels) # 计算损失
        loss.backward() 					  # 反向传播
        optimizer.step() 					  # 优化器更新参数

        # 打印耗时、损失、准确率等数据
        running_loss += loss.item()
        if step % 1000 == 999:    # print every 1000 mini-batches,每1000步打印一次
            with torch.no_grad(): # 在以下步骤中(验证过程中)不用计算每个节点的损失梯度,防止内存占用
                outputs = net(test_image) 				 # 测试集传入网络(test_batch_size=10000),output维度为[10000,10]
                predict_y = torch.max(outputs, dim=1)[1] # 以output中值最大位置对应的索引(标签)作为预测输出
                accuracy = (predict_y == test_label).sum().item() / test_label.size(0)
                
                print('[%d, %5d] train_loss: %.3f  test_accuracy: %.3f' %  # 打印epoch,step,loss,accuracy
                      (epoch + 1, step + 1, running_loss / 500, accuracy))
                
                print('%f s' % (time.perf_counter() - time_start))        # 打印耗时
                running_loss = 0.0

print('Finished Training')

# 保存训练得到的参数
save_path = './Lenet.pth'
torch.save(net.state_dict(), save_path)

三、图像分类测试

使用训练并保存好的网络参数,从数据集外找一张图像进行分类测试文章来源地址https://www.toymoban.com/news/detail-496411.html

# 导入包
import torch
import torchvision.transforms as transforms
from PIL import Image
from model import LeNet

# 数据预处理
transform = transforms.Compose(
    [transforms.Resize((32, 32)), # 首先需resize成跟训练集图像一样的大小
     transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])    # 数据标准化

# 导入要测试的图像
im = Image.open('./car.jpg').convert('RGB')    # 若图像为4通道,则用 convert('RGB') 转化为3通道,否则 transform 会报错
im = transform(im)  # [C, H, W]
im = torch.unsqueeze(im, dim=0)  # 对数据增加一个新维度,因为tensor的参数是[batch, channel, height, width] 

# 实例化网络,加载训练好的模型参数
net = LeNet()
net.load_state_dict(torch.load('Lenet.pth'))

# 预测
classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
with torch.no_grad():
    outputs = net(im)
    predict = torch.max(outputs, dim=1)[1].data.numpy()    # 找出最大概率的下标
	predicts = torch.softmax(outputs , dim=1)    # 所有分类的预测概率
print(classes[int(predict)])
print(predicts)

到了这里,关于pytorch搭建LeNet网络实现图像分类器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • pytorch搭建AlexNet网络实现花分类

    使用Dropout的方式在网络正向传播过程中随机失活一部分神经元,以减少过拟合 对其中的卷积层、池化层和全连接层进行分析 1,Conv1 注意:图片中用了两块GPU并行计算,上下两组图结构一样。 输入:input_size = [224, 224, 3] 卷积层: kernels = 48 * 2 = 96 组卷积核 kernel_size = 11 paddi

    2024年02月09日
    浏览(37)
  • CNN经典网络模型(一):LeNet简介及代码实现(PyTorch超详细注释版)

    一、开发背景 二、网络结构 三、模型特点 四、代码实现 1. model.py 2. train.py 3. predict.py 四、参考内容 Lenet 是一系列网络的合称,包括 Lenet1 - Lenet5,由 Yann LeCun 等人 在1990年《Handwritten Digit Recognition with a Back-Propagation Network》中提出,是卷积神经网络的开山之作,也是将深度学

    2024年02月08日
    浏览(40)
  • 深度学习应用篇-计算机视觉-图像分类[2]:LeNet、AlexNet、VGG、GoogleNet、DarkNet模型结构、实现、模型特点详细介绍

    LeNet是最早的卷积神经网络之一 [1] ,其被提出用于识别手写数字和机器印刷字符。1998年,Yann LeCun第一次将LeNet卷积神经网络应用到图像分类上,在手写数字识别任务中取得了巨大成功。算法中阐述了图像中像素特征之间的相关性能够由参数共享的卷积操作所提取,同时使用

    2024年02月08日
    浏览(42)
  • 项目实战解析:基于深度学习搭建卷积神经网络模型算法,实现图像识别分类

    随着人工智能的不断发展,深度学习这门技术也越来越重要,很多人都开启了学习机器学习,本文将通过项目开发实例,带领大家从零开始设计实现一款基于深度学习的图像识别算法。 学习本章内容, 你需要掌握以下基础知识: Python 基础语法 计算机视觉库(OpenCV) 深度学习

    2024年02月03日
    浏览(60)
  • MATLAB算法实战应用案例精讲-【图像处理】图像分类模型-LeNet&AlexNet&VGG

    目录 LeNet  模型介绍 模型结构 模型实现 模型特点 模型指标  Ale

    2024年02月13日
    浏览(52)
  • 使用Pytorch实现图像花朵分类

    代码的介绍在这个链接里面,这篇博客主要是为了带着大家通过实践的方式熟悉一下代码的使用,并且了解相关功能。 这里我提供了一个花朵数据集,里面总共有十个类别的花朵作为本次实验的数据集。 我们下载代码和数据集到本地,然后我们在下图创建一个名字为dataset的

    2023年04月08日
    浏览(40)
  • 度学习pytorch实战六:ResNet50网络图像分类篇自建花数据集图像分类(5类)超详细代码

    1.数据集简介、训练集与测试集划分 2.模型相关知识 3.model.py——定义ResNet50网络模型 4.train.py——加载数据集并训练,训练集计算损失值loss,测试集计算accuracy,保存训练好的网络参数 5.predict.py——利用训练好的网络参数后,用自己找的图像进行分类测试 1.自建数据文件夹

    2024年02月09日
    浏览(40)
  • Pytorch:搭建卷积神经网络完成MNIST分类任务:

    2023.7.18 MNIST百科: MNIST数据集简介与使用_bwqiang的博客-CSDN博客 数据集官网:MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges 数据集将按以图片和文件夹名为标签的形式保存:  代码:下载mnist数据集并转还为图片  训练代码: 测试代码: 分类正确率不错:

    2024年02月17日
    浏览(43)
  • 【Pytorch】计算机视觉项目——卷积神经网络CNN模型识别图像分类

    在上一篇笔记《【Pytorch】整体工作流程代码详解(新手入门)》中介绍了Pytorch的整体工作流程,本文继续说明如何使用Pytorch搭建卷积神经网络(CNN模型)来给图像分类。 其他相关文章: 深度学习入门笔记:总结了一些神经网络的基础概念。 TensorFlow专栏:《计算机视觉入门

    2024年02月05日
    浏览(53)
  • 【图像分类】【深度学习】【轻量级网络】【Pytorch版本】ShuffleNet_V1模型算法详解

    ShuffleNet_V1是由旷视科技的Zhang, Xiangyu等人在《ShuffleNet: An Extremely Efficient Convolutional Neural Network for Mobile Devices【CVPR-2018】》【论文地址】一文中提出的模型,是一种采用了逐点组卷积和通道混洗的轻量级CNN网络,在保持精度的同时大大降低了计算成本。 一般的卷积是全通道卷

    2024年01月20日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包