当前位置: 首页 > news >正文

搭建AlexNet神经网络,并搭建自己的图像分类训练和测试的模板,模板通用!!!均有详细注释。

本文任务:

1、构建AlexNet神经网络。

2、搭建图像分类训练和测试的通用模板。

3、训练出自己的模型。

4、验证模型效果。

论文地址:原文地址icon-default.png?t=O83Ahttp://papers.nips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf


目录

一、AlexNet神经网络介绍

1、网络结构

2、网络参数

3、Dropout操作

4、图像增强方法

5、LRN正则化(局部归一化)

6、总结

二、代码实现AlexNet神经网络 

1、构建AlexNet神经网络

2、搭建图像分类训练的通用模板

3、搭建图像分类测试的通用模板

4、训练出自己的模型

5、验证模型效果

三、调试好的源码


一、AlexNet神经网络介绍

1、网络结构

由八层组成:五个卷积层、两个全连接隐藏层、一个全连接层。

AlexNet使用ReLU而不是sigmoid作为其激活函数。

2、网络参数

3、Dropout操作

作用:为了防止神经网络过拟合,提高了模型准确度

4、图像增强方法

        水平翻转:增加数据集,防止过拟合。

        随机裁剪:大量增加数据集的量,防止过拟合,使网络更加健壮。

          PCA图像增强:增加数据集。

5、LRN正则化(局部归一化)

6、总结

二、代码实现AlexNet神经网络 

我的项目目录结构:

其中,fashion_data文件夹是我们的数据集,这个数据集是PyTorch中自带的数据集,大家直接运行我下面的model_train.py就可以自动下载,或者大家也可以自行下载,model文件夹是我用来存放训练好的模型的,这个大家可以自行设置存放路径。

以下代码均有详细注释,所以不在这里讲解。

1、构建AlexNet神经网络

     model.py

import torch
import torch.nn as nn
from torchsummary import summary
import torch.nn.functional as Fclass AlexNet(nn.Module):def __init__(self, num_classes=1000):super(AlexNet, self).__init__()self.model = nn.Sequential(nn.Conv2d(1, 96, kernel_size=11, stride=4), # 卷积操作nn.ReLU(), # 激活函数nn.MaxPool2d(kernel_size=3, stride=2), # 最大池化nn.Conv2d(96, 256, kernel_size=5, padding=2, stride=1),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2),nn.Conv2d(256, 384, kernel_size=3, padding=1, stride=1),nn.ReLU(),nn.Conv2d(384, 384, kernel_size=3, padding=1, stride=1),nn.ReLU(),nn.Conv2d(384, 256, kernel_size=3, padding=1, stride=1),nn.ReLU(),nn.MaxPool2d(kernel_size=3, stride=2),nn.Flatten(), # 平展操作nn.Linear(9216, 4096), # 线性nn.ReLU(),nn.Dropout(0.5), # 防止过拟合nn.Linear(4096, 4096),nn.ReLU(),nn.Dropout(0.5),nn.Linear(4096, 10))def forward(self, x):x = self.model(x)return xif __name__ == '__main__':device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')model = AlexNet()print(model)

2、搭建图像分类训练的通用模板

        model_train.py

import copy
import timeimport torch
from torch.utils.data import DataLoader
from torchvision import transforms
from torchvision.datasets import FashionMNIST
import numpy as np
import matplotlib.pyplot as plt
from model import AlexNet
import torch.utils.data as Data
import torch.nn as nn
import pandas as pd# 加载数据集
def train_val_data_process():train_data = FashionMNIST(root='./fashion_data',train=True,download=True,transform=transforms.Compose([transforms.Resize(size=227), transforms.ToTensor()]))# 划分数据集train_data, val_data = Data.random_split(train_data, [round(0.8 * len(train_data)), round(0.2 * len(train_data))])train_loader = Data.DataLoader(dataset=train_data, batch_size=128, shuffle=True, num_workers=0)val_loader = Data.DataLoader(dataset=val_data, batch_size=128, shuffle=True, num_workers=0)return train_loader, val_loader# 训练过程
def train_model_process(model, train_loader, val_loader, epochs):device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 定义优化器,使用Adam优化器,学习率为0.001optimizer = torch.optim.Adam(model.parameters(), lr=0.001)# 交叉熵损失函数loss_fn = nn.CrossEntropyLoss()# 将模型放入到训练设备当中model = model.to(device)# 复制当前模型的参数best_model_wts = copy.deepcopy(model.state_dict())# 初始化参数# 初始化精度best_acc = 0.0# 保存训练集loss值的列表train_loss_all = []# 保存验证集loss值的列表val_loss_all = []# 保存训练集精度的列表train_acc_all = []# 保存验证集精度的列表val_acc_all = []# 保存当前时间since = time.time()for epoch in range(epochs):print('Epoch {}/{}'.format(epoch + 1, epochs))print('-' * 10)# 初始化参数# 训练集train_loss = 0.0train_acc = 0.0# 验证集val_loss = 0.0val_acc = 0.0# 训练集的样本数量train_num = 0# 验证集的样本数量val_num = 0# 对每一个batch进行训练for step, (images, labels) in enumerate(train_loader):# 将特征和标签放到gpu中images, labels = images.to(device), labels.to(device)# 设置模型为训练模式model.train()# 将数据放入到模型当中,向前传播过程,输入为一个batch,输出为一个batch中对应的预测outputs = model(images)# 查找每一行中最大值对应的行标pre_labels = torch.argmax(outputs, dim=1)# 计算损失loss = loss_fn(outputs, labels)# 将梯度清0optimizer.zero_grad()# 反向传播计算loss.backward()# 根据网络反向传播的梯度信息来更新网络的参数,以起到降低loss函数计算值的作用optimizer.step()# 对损失函数进行累加train_loss += loss.item() * images.size(0)# 计算准确的数量train_acc += torch.sum(pre_labels == labels.data)# 当前用于训练的样本数量train_num += images.size(0)# 验证开始with torch.no_grad():for step, (images, labels) in enumerate(val_loader):# 将特征和标签放到gpu中images, labels = images.to(device), labels.to(device)# 设置模型为验证模式model.eval()# 前向传播outputs = model(images)# 查找每一行中最大值对应的行标pre_labels = torch.argmax(outputs, dim=1)# 计算损失loss = loss_fn(outputs, labels)# 对损失函数进行累加val_loss += loss.item() * images.size(0)# 计算准确的数量val_acc += torch.sum(pre_labels == labels.data)# 当前用于验证的样本数量val_num += images.size(0)# 计算每一次迭代的loss值和准确率train_loss_all.append(train_loss / train_num)train_acc_all.append(train_acc.double().item() / train_num)val_loss_all.append(val_loss / val_num)val_acc_all.append(val_acc.double().item() / val_num)# 打印出每轮的训练损失值和训练准确率print('{} Train Loss: {:.4f} Train Acc: {:.4f}'.format(epoch + 1, train_loss_all[-1], train_acc_all[-1]))# 打印出每轮的验证损失值和验证准确率print('{} Val Loss: {:.4f} Val Acc: {:.4f}'.format(epoch + 1, val_loss_all[-1], val_acc_all[-1]))# 寻找最高准确度的权重if val_acc_all[-1] > best_acc:best_acc = val_acc_all[-1]# 保存当前的最优参数best_model_wts = copy.deepcopy(model.state_dict())# 计算该轮次训练所花费的时间time_used = time.time() - sinceprint('训练和验证花费的时间:{:.0f}m{:.0f}s'.format(time_used // 60, time_used % 60))# 选择最优模型# 加载最优的模型参数torch.save(best_model_wts, './model/AlexNet_model.pth')# 训练过程的数据train_process = pd.DataFrame(data={'epoch': range(epochs),'train_loss_all': train_loss_all,'train_acc_all': train_acc_all,'val_loss_all': val_loss_all,'val_acc_all': val_acc_all})return train_process# 画图
def matplot_acc_loss(train_process):plt.figure(figsize=(12, 4))plt.subplot(1, 2, 1) # 一行两列的第一张图# loss图plt.plot(train_process['epoch'], train_process['train_loss_all'], 'ro-', label='train loss')plt.plot(train_process['epoch'], train_process['val_loss_all'], 'bs-', label='val loss')plt.legend()plt.xlabel('Epoch')plt.ylabel('Loss')plt.subplot(1, 2, 2) # 一行两列的第二张图plt.plot(train_process['epoch'], train_process['train_acc_all'], 'ro-', label='train acc')plt.plot(train_process['epoch'], train_process['val_acc_all'], 'bs-',label='val acc')plt.legend()plt.xlabel('Epoch')plt.ylabel('Accuracy')plt.show()if __name__ == '__main__':# 将模型实例化leNet = AlexNet()train_loader, val_loader = train_val_data_process()train_process = train_model_process(leNet, train_loader, val_loader, 20)matplot_acc_loss(train_process)

3、搭建图像分类测试的通用模板

    model_test.py

import torch
from torchvision import transforms
import torchvision
import torch.utils.data as Data
from torchvision.datasets import FashionMNIST
from model import AlexNet# 加载测试集
def test_val_data_process():test_data = FashionMNIST(root='./fashion_data',train=False,download=True,transform=transforms.Compose([transforms.Resize(size=227), transforms.ToTensor()]))test_loader = Data.DataLoader(dataset=test_data, batch_size=1, shuffle=True, num_workers=0)return test_loader# 开始测试模型
def test_model_process(model, test_loader):# 设置测试环境device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')# 将模型放入到gpu中model = model.to(device)# 初始化参数# 模型的测试精度test_accuracy = 0.0# 用来记录测试次数test_num = 0# 只进行前向传播,不计算梯度,从而节省内存,加快运算速度with torch.no_grad():for images, labels in test_loader:# 加载数据集到gpu中images, labels = images.to(device), labels.to(device)# 设置模型为评估模式model.eval()# 进行前向传播output = model(images)# 查找最大值对应的行标pred_lab = output.argmax(dim=1, keepdim=True)# 计算测试正确的数据个数test_accuracy += torch.sum(pred_lab == labels.data)# 计算测试样本总数test_num += images.size(0)# 计算准确率test_acc = test_accuracy.double() / test_numprint("测试的准确率为:",test_acc)return test_accif __name__ == '__main__':model = AlexNet()model.load_state_dict(torch.load('./model/AlexNet_model.pth'))test_loader = test_val_data_process()test_acc = test_model_process(model, test_loader)

4、训练出自己的模型

我们运行model_train.py文件,来进行模型的训练。

由于时间原因,我这里只训练了20轮,大家在实际运行时,可以把轮次设置的大一些,这样得到的模型效果会更好。

输出:

        结果可视化 

我使用的是gpu训练的,我的显卡是RTX4060Ti,训练了20轮,总花费是24分22秒,大家可以根据自己的显卡来设置训练的轮数和训练批次的大小。 

训练好的保存到了model文件夹下:

5、验证模型效果

接下来我们来使用我们上面训练好的模型来对验证数据集进行推理,为了节约时间,仅供测试,我们使用的测试数据集和上述训练数据集是一致的(实际操作中不要这样进行,推理使用的数据一般是未经过训练的),所以我们可以直接开始运行model_test.py来验证我们的模型效果。

可以看到,测试的准确率是91.57%,对于我们训练20轮次来说,效果还不错,那么我们整个训练,推理的过程就结束了,希望大家可以动手试一下,有问题请在评论区提问哦。

三、调试好的源码

我这边提供给大家一个我调试好的源码,方便新手进行训练、测试。

大家扫码关注公众号,回复关键字AlexNet源码即可获取。


http://www.mrgr.cn/news/56352.html

相关文章:

  • 【JavaEE】【IO】文件操作
  • 20 Shell Script输入与输出
  • 51单片机快速入门之 LCD1602 液晶显示屏2024/10/19
  • tracert和ping的区别
  • Marvell 利用 3nm 芯片使 PCIe Gen7 连接传速可达 128GT/s
  • Springboot项目
  • 平衡二叉树最全代码
  • 使用SpringBoot自定义注解+AOP+redisson锁来实现防接口幂等性重复提交
  • Java避坑案例 - 消除代码重复_模板方法与工厂模式的最佳实践
  • 【10月最新】植物大战僵尸杂交版即将新增【植物】内容介绍预告(附最新版本下载链接)
  • 23种设计模式具体实现方法
  • 点云数据介绍
  • SCANeR Studio 仿真数据获取和车辆座舱数据输入
  • 强心剂!EEMD-MPE-KPCA-LSTM、EEMD-MPE-LSTM、EEMD-PE-LSTM故障识别、诊断
  • 10.22学习
  • vue中实现css布局
  • 西门子 SMART PLC 扫码串口通讯
  • 【不要离开你的舒适圈】:猛兽才希望你落单,亲人总让你回家,4个维度全面构建舒适圈矩阵
  • Shell重定向输入输出
  • 数据库表的创建
  • 如何自定义一个自己的 Spring Boot Starter 组件(从入门到实践)
  • 算法的学习笔记—数组中的逆序对(牛客JZ51)
  • 安全测试概述和用例设计
  • Modbus协议缺陷(Modbus缺陷)(一次性可读取的寄存器数量有限、不支持寄存器位级写入操作)
  • 【C++】踏上C++学习之旅(三):“我“ 与 “引用“ 的浪漫邂逅
  • 每日算法一练:剑指offer——数组篇(3)