深度学习-卷积神经网络CNN

案例-图像分类

网络结构: 卷积+BN+激活+池化

数据集介绍

CIFAR-10数据集5万张训练图像、1万张测试图像、10个类别、每个类别有6k个图像,图像大小32×32×3。下图列举了10个类,每一类随机展示了10张图片:

特征图计算

在卷积层和池化层结束后, 将特征图变形成一行n列数据, 计算特征图进行变化, 映射到全连接层时输入层特征为最后一层卷积层经池化后的特征图各维度相乘

具体流程-# Acc: 0.728

# 导包
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchsummary import summary
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor, Compose  # Compose: 数据增强(扩充数据集)
import time
import matplotlib.pyplot as plt
​
batch_size = 16
​
​
# 创建数据集
def create_dataset():torch.manual_seed(21)train = CIFAR10(root='data',train=True,transform=Compose([ToTensor()]))test = CIFAR10(root='data',train=False,transform=Compose([ToTensor()]))return train, test
​
​
# 创建模型
class ImgCls(nn.Module):# 定义网络结构def __init__(self):super(ImgCls, self).__init__()# 定义网络层:卷积层+池化层self.conv1 = nn.Conv2d(3, 16, stride=1, kernel_size=3)self.batch_norm_layer1 = nn.BatchNorm2d(num_features=16, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
​self.conv2 = nn.Conv2d(16, 32, stride=1, kernel_size=3)self.batch_norm_layer2 = nn.BatchNorm2d(num_features=32, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool2 = nn.MaxPool2d(kernel_size=2, stride=1)
​self.conv3 = nn.Conv2d(32, 64, stride=1, kernel_size=3)self.batch_norm_layer3 = nn.BatchNorm2d(num_features=64, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool3 = nn.MaxPool2d(kernel_size=2, stride=1)
​self.conv4 = nn.Conv2d(64, 128, stride=1, kernel_size=2)self.batch_norm_layer4 = nn.BatchNorm2d(num_features=128, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool4 = nn.MaxPool2d(kernel_size=2, stride=2)
​self.conv5 = nn.Conv2d(128, 256, stride=1, kernel_size=2)self.batch_norm_layer5 = nn.BatchNorm2d(num_features=256, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool5 = nn.MaxPool2d(kernel_size=2, stride=1)
​# 全连接层self.linear1 = nn.Linear(1024, 2048)self.linear2 = nn.Linear(2048, 1024)self.linear3 = nn.Linear(1024, 512)self.linear4 = nn.Linear(512, 256)self.linear5 = nn.Linear(256, 128)self.out = nn.Linear(128, 10)
​# 定义前向传播def forward(self, x):# 第1层: 卷积+BN+激活+池化x = self.conv1(x)x = self.batch_norm_layer1(x)x = torch.rrelu(x)x = self.pool1(x)
​# 第2层: 卷积+BN+激活+池化x = self.conv2(x)x = self.batch_norm_layer2(x)x = torch.rrelu(x)x = self.pool2(x)
​# 第3层: 卷积+BN+激活+池化x = self.conv3(x)x = self.batch_norm_layer3(x)x = torch.rrelu(x)x = self.pool3(x)
​# 第4层: 卷积+BN+激活+池化x = self.conv4(x)x = self.batch_norm_layer4(x)x = torch.rrelu(x)x = self.pool4(x)
​# 第5层: 卷积+BN+激活+池化x = self.conv5(x)x = self.batch_norm_layer5(x)x = torch.rrelu(x)x = self.pool5(x)
​# 将特征图做成以为向量的形式:相当于特征向量x = x.reshape(x.size(0), -1)  # 将3维特征图转化为1维向量(1, n)
​# 全连接层x = torch.rrelu(self.linear1(x))x = torch.rrelu(self.linear2(x))x = torch.rrelu(self.linear3(x))x = torch.rrelu(self.linear4(x))x = torch.rrelu(self.linear5(x))# 返回输出结果return self.out(x)
​
​
# 训练
def train(model, train_dataset, epochs):torch.manual_seed(21)loss = nn.CrossEntropyLoss()opt = optim.Adam(model.parameters(), lr=1e-4)for epoch in range(epochs):dataloader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)loss_total = 0iter = 0stat_time = time.time()for x, y in dataloader:output = model(x.to(device))loss_value = loss(output, y.to(device))opt.zero_grad()loss_value.backward()opt.step()loss_total += loss_value.item()iter += 1print(f'epoch:{epoch + 1:4d}, loss:{loss_total / iter:6.4f}, time:{time.time() - stat_time:.2f}s')torch.save(model.state_dict(), 'model/img_cls_model.pth')
​
​
# 测试
def test(valid_dataset, model, batch_size):# 构建数据加载器dataloader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False)
​# 计算精度total_correct = 0# 遍历每个batch的数据,获取预测结果,计算精度for x, y in dataloader:output = model(x.to(device))y_pred = torch.argmax(output, dim=-1)total_correct += (y_pred == y.to(device)).sum()# 打印精度print(f'Acc: {(total_correct.item() / len(valid_dataset))}')
​
​
if __name__ == '__main__':batch_size = 16device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 获取数据集train_data, test_data = create_dataset()
​# # 查看数据集# print(f'数据集类别: {train_data.class_to_idx}')# print(f'训练集: {train_data.data.shape}')# print(f'验证集: {test_data.data.shape}')# print(f'类别数量: {len(np.unique(train_data.targets))}')# # 展示图像# plt.figure(figsize=(8, 8))# plt.imshow(train_data.data[0])# plt.title(train_data.classes[train_data.targets[0]])# plt.show()
​# 实例化模型model = ImgCls().to(device)
​# 查看网络结构summary(model, (3, 32, 32), device='cuda', batch_size=batch_size)
​# 模型训练train(model, train_data, epochs=60)# 加载训练好的模型参数model.load_state_dict(torch.load('model/img_cls_model.pth'))model.eval()# 模型评估test(test_data, model, batch_size=16)   # Acc: 0.728
​

调整网络结构

第一次调整: 训练50轮, Acc: 0.71

第二次调整: 训练30轮, Acc:0.7351

第三次调整: batch_size=8, epoch=50 => Acc: 0.7644

# 导包
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader
from torchsummary import summary
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor, Compose  # Compose: 数据增强(扩充数据集)
import time
import matplotlib.pyplot as plt
​
batch_size = 16
​
​
# 创建数据集
def create_dataset():torch.manual_seed(21)train = CIFAR10(root='data',train=True,transform=Compose([ToTensor()]))test = CIFAR10(root='data',train=False,transform=Compose([ToTensor()]))return train, test
​
​
# 创建模型
class ImgCls(nn.Module):# 定义网络结构def __init__(self):super(ImgCls, self).__init__()# 定义网络层:卷积层+池化层self.conv1 = nn.Conv2d(3, 16, stride=1, kernel_size=3, padding=1)self.batch_norm_layer1 = nn.BatchNorm2d(num_features=16, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)
​self.conv2 = nn.Conv2d(16, 32, stride=1, kernel_size=3, padding=1)self.batch_norm_layer2 = nn.BatchNorm2d(num_features=32, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)
​self.conv3 = nn.Conv2d(32, 64, stride=1, kernel_size=3, padding=1)self.batch_norm_layer3 = nn.BatchNorm2d(num_features=64, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool3 = nn.MaxPool2d(kernel_size=2, stride=1)
​self.conv4 = nn.Conv2d(64, 128, stride=1, kernel_size=3, padding=1)self.batch_norm_layer4 = nn.BatchNorm2d(num_features=128, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool4 = nn.MaxPool2d(kernel_size=2, stride=1)
​self.conv5 = nn.Conv2d(128, 256, stride=1, kernel_size=3)self.batch_norm_layer5 = nn.BatchNorm2d(num_features=256, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True)self.pool5 = nn.MaxPool2d(kernel_size=2, stride=2)
​# 全连接层self.linear1 = nn.Linear(1024, 2048)self.linear2 = nn.Linear(2048, 1024)self.linear3 = nn.Linear(1024, 512)self.linear4 = nn.Linear(512, 256)self.linear5 = nn.Linear(256, 128)self.out = nn.Linear(128, 10)
​# 定义前向传播def forward(self, x):# 第1层: 卷积+BN+激活+池化x = self.conv1(x)x = self.batch_norm_layer1(x)x = torch.relu(x)x = self.pool1(x)
​# 第2层: 卷积+BN+激活+池化x = self.conv2(x)x = self.batch_norm_layer2(x)x = torch.relu(x)x = self.pool2(x)
​# 第3层: 卷积+BN+激活+池化x = self.conv3(x)x = self.batch_norm_layer3(x)x = torch.relu(x)x = self.pool3(x)
​# 第4层: 卷积+BN+激活+池化x = self.conv4(x)x = self.batch_norm_layer4(x)x = torch.relu(x)x = self.pool4(x)
​# 第5层: 卷积+BN+激活+池化x = self.conv5(x)x = self.batch_norm_layer5(x)x = torch.rrelu(x)x = self.pool5(x)
​# 将特征图做成以为向量的形式:相当于特征向量x = x.reshape(x.size(0), -1)  # 将3维特征图转化为1维向量(1, n)
​# 全连接层x = torch.relu(self.linear1(x))x = torch.relu(self.linear2(x))x = torch.relu(self.linear3(x))x = torch.relu(self.linear4(x))x = torch.rrelu(self.linear5(x))# 返回输出结果return self.out(x)
​
​
# 训练
def train(model, train_dataset, epochs):torch.manual_seed(21)loss = nn.CrossEntropyLoss()opt = optim.Adam(model.parameters(), lr=1e-4)for epoch in range(epochs):dataloader = DataLoader(train_dataset, shuffle=True, batch_size=batch_size)loss_total = 0iter = 0stat_time = time.time()for x, y in dataloader:output = model(x.to(device))loss_value = loss(output, y.to(device))opt.zero_grad()loss_value.backward()opt.step()loss_total += loss_value.item()iter += 1print(f'epoch:{epoch + 1:4d}, loss:{loss_total / iter:6.4f}, time:{time.time() - stat_time:.2f}s')torch.save(model.state_dict(), 'model/img_cls_model1.pth')
​
​
# 测试
def test(valid_dataset, model, batch_size):# 构建数据加载器dataloader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False)
​# 计算精度total_correct = 0# 遍历每个batch的数据,获取预测结果,计算精度for x, y in dataloader:output = model(x.to(device))y_pred = torch.argmax(output, dim=-1)total_correct += (y_pred == y.to(device)).sum()# 打印精度print(f'Acc: {(total_correct.item() / len(valid_dataset))}')
​
​
if __name__ == '__main__':batch_size = 8device = torch.device("cuda" if torch.cuda.is_available() else "cpu")# 获取数据集train_data, test_data = create_dataset()
​# # 查看数据集# print(f'数据集类别: {train_data.class_to_idx}')# print(f'训练集: {train_data.data.shape}')# print(f'验证集: {test_data.data.shape}')# print(f'类别数量: {len(np.unique(train_data.targets))}')# # 展示图像# plt.figure(figsize=(8, 8))# plt.imshow(train_data.data[0])# plt.title(train_data.classes[train_data.targets[0]])# plt.show()
​# 实例化模型model = ImgCls().to(device)
​# 查看网络结构summary(model, (3, 32, 32), device='cuda', batch_size=batch_size)
​# 模型训练train(model, train_data, epochs=50)# 加载训练好的模型参数model.load_state_dict(torch.load('model/img_cls_model1.pth', weights_only=True))model.eval()# 模型评估test(test_data, model, batch_size=16)   # Acc: 0.7644
​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/60885.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stm32——通用定时器时钟知识点

(该图来自小破站 铁头山羊老师的stm32标准库教学)

SobarQube实现PDF报告导出

文章目录 前言一、插件配置二、使用步骤1.新生成一个Token2.将拷贝的Token加到上文中执行的命令中3.查看报告 三、友情提示总结 前言 这篇博文是承接此文 .Net项目在Windows中使用sonarqube进行代码质量扫描的详细操作配置 描述如何导出PDF报告 众所周知,导出PDF功…

【数据结构】10.线索二叉树

一、线索二叉树的产生 采用先序、中序、后序三种方法遍历二叉树后都可以得到一个线性序列,序列上的每一个结点(除了第一个和最后一个)都有一个前驱和一个后继,但是,这个线性序列只是逻辑的概念,不是物理结…

如何合理设计一套springcloud+springboot项目中的各个微服务模块之间的继承关系的最优方案

文章目录 一、模块化设计所遵循的原则二、项目架构设计三、各个模块作用说明3.1 core 模块3.2 common 模块3.3 generatorcode模块3.4 business 模块3.5 web 模块3.6 admin 模块3.7 父pom 四、采用import引入SpringBoot 在springcloud微服务项目中经常用到多模块化的架构设计&am…

HarmonyOS4+NEXT星河版入门与项目实战--------开发工具与环境准备

文章目录 1、熟悉鸿蒙官网1、打开官网2、下载 DevEco Studio3、HarmonyOS 资源库4、开发指南与API 2、安装 DevEco Studio1、软件安装2、配置开发工具 1、熟悉鸿蒙官网 1、打开官网 百度搜索 鸿蒙开发者官网 点击进入开发者官网,点击开发,可以看到各种…

单元测试、集成测试、系统测试、验收测试、压力测试、性能测试、安全性测试、兼容性测试、回归测试(超详细的分类介绍及教学)

目录 1.单元测试 实现单元测试的方法: 注意事项: 2.集成测试 需注意事项: 实现集成测试的方法: 如何实现高效且可靠的集成测试: 3.系统测试 实现系统测试的方法: 须知注意事项: 4.验收测试 实现验…

Ubuntu24 上安装搜狗输入法

link 首先在终端中依次输入以下代码 sudo apt update sudo apt install fcitx 找到语言支持 在终端中依次输入 sudo cp /usr/share/applications/fcitx.desktop /etc/xdg/autostart/ sudo apt purge ibus 进入网页 搜狗输入法linux-首页​ shurufa.sogou.com/linux 找到刚才下…

FairyGUI和Unity联动(入门篇)

一、FairyGUI编辑器中 1.新建按钮、新建组件 编辑器中界面简易设计如下 2.文件-发布设置-发布路径:自己unity项目Resources所在的路径 二、Unity 使用代码展示UI using FairyGUI; using System.Collections; using System.Collections.Generic; using UnityEngi…

【Java知识】Java性能测试工具JMeter

一文带你了解什么是JMeter 概述JMeter的主要功能:JMeter的工作原理:JMeter的应用场景:JMeter的组件介绍: 实践说明JMeter实践基本步骤:JMeter实践关键点: JMeter支持哪些参数化技术?常见插件及其…

Redis的缓存穿透、缓存雪崩、缓存击穿问题及有效解决方案

目录 一、缓存穿透 1.简介 2.解决方案 3.修改前的代码 4.修改过后的代码 二、缓存雪崩 1.简介 2.解决方案 三、缓存击穿 1.简介 2.解决方案 3.用代码来实现互斥锁来解决缓存击穿 4.用代码来实现逻辑过期解决缓存击穿 四、缓存穿透和缓存击穿的区别 一、缓存穿透 …

CPU的性能指标总结(学习笔记)

CPU 性能指标 我们先来回顾下,描述 CPU 的性能指标都有哪些。 首先,最容易想到的应该是 CPU 使用率,这也是实际环境中最常见的一个性能指标。 用户 CPU 使用率,包括用户态 CPU 使用率(user)和低优先级用…

【go从零单排】Environment Variables环境变量

🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 在 Go 语言中,环境变量是用于配置程序行为的一种常见方式。它们可以用…

信捷PLC转以太网连接电脑方法

信捷XC/XD/XL等系列PLC如何上下载程序?可以选择用捷米特JM-ETH-XJ模块轻松搞定,并不需要编程,即插即用,具体看见以下介绍: 产品介绍 捷米特JM-ETH-XJ是专门为信捷PLC转以太网通讯面设计,可实现工厂设备信息化需求,对…

【golang-技巧】-线上死锁问题排查-by pprof

1.背景 由于目前项目使用 cgo golang 本地不能debug, 发生死锁问题,程序运行和期待不一致,通过日志排查可以大概率找到 阻塞范围,但是不能找到具体问题在哪里,同时服务器 通过k8s daemonset 部署没有更好的方式暴露端口 获取ppr…

AVL树的删除方法简单实现

看过前面的AVL树的介绍和插入方法实现AVL树了解并简单实现-CSDN博客,接着可以来学习删除方法的实现 目录 1.AVL树的删除 2.平衡因子调节 3.删除代码逻辑 4.AVL树的整体代码 1.AVL树的删除 因为AVL树也是二叉搜索树,可按照二叉搜索树的方式将节点删除…

ArcGIS的汉字(亚洲文本)垂直标注

01 需求说明 实现ArcGIS的汉字(亚洲文本的垂直标注)。 启用 Maplex 标注引擎。 在标注 工具条上单击标注管理器按钮 。 选中要进行标注的图层旁边的复选框。 选择图层下方的标注分类。 单击符号。 选中 CJK 字符方向复选框。 仅当字体有垂直的文本度…

飞凌嵌入式RK3576核心板已适配Android 14系统

在今年3月举办的RKDC2024大会上,飞凌嵌入式FET3576-C核心板作为瑞芯微RK3576处理器的行业首秀方案重磅亮相,并于今年6月率先量产发货,为客户持续稳定地供应,得到了众多合作伙伴的认可。 FET3576-C核心板此前已提供了Linux 6.1.57…

基于python的dlib库的人脸识别实现

1、环境搭建 基于dlib库的人脸识别环境配置需求如下: conda create -n dlibFace python3.6.4 conda activate dlibFacepip install dlib19.8.1 pip install opencv-python3.4.1.15 pip install tqdm 安装如下: 2、模块介绍 2.1 源代码下载 源代码点击:下载源代码 2.2 源码…

Ubuntu问题 -- 允许ssh使用root用户登陆

目的 新重装的系统, 普通用户可以使用ssh登陆服务器, 但是root不能使用ssh登陆 方法 vim 编辑ssh配置文件 sudo vim /etc/ssh/sshd_config找到 PermitRootLogin 这一行, 把后面值改成 yes 重启ssh sudo service sshd restart然后使用root账号登陆即可

DAY6 线程

作业1&#xff1a; 多线程实现文件拷贝&#xff0c;线程1拷贝一半&#xff0c;线程2拷贝另一半&#xff0c;主线程回收子线程资源。 代码&#xff1a; #include <myhead.h> sem_t sem1; void *copy1()//子线程1函数 拷贝前一半内容 {int fd1open("./1.txt",O…