深度学习-卷积神经网络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 = 0
        iter = 0
        stat_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 += 1
        print(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 = 16
    device = 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 = 0
        iter = 0
        stat_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 += 1
        print(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 = 8
    device = 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
​

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

PHP Switch 语句

<?php switch (expression) {case value1:// 代码块1break;case value2:// 代码块2break;// 更多的 case 语句default:// 如果没有匹配的值&#xff0c;输出这一行 } ?> $color 表示自己的颜色&#xff0c;需要switch循环找到对应的值。 case value : 表示对应的值&am…

Python Plotly 库使用教程

Python Plotly 库使用教程 引言 数据可视化是数据分析中至关重要的一部分&#xff0c;它能够帮助我们更直观地理解数据、发现潜在的模式和趋势。Python 提供了多种数据可视化库&#xff0c;其中 Plotly 是一个功能强大且灵活的库&#xff0c;支持交互式图表的创建。与静态图表…

ubuntu:20.04安装协议逆向工具netzob

创建容器 docker run -d --name ubuntu_env ubuntu:20.04 /bin/bash -c "while true; do sleep 1; done" 63a8f5cf5431a930671ff0e7bb2b667adf001efb05fd7261da244879d2699bec 进入容器 PS E:\src> docker exec -it ubuntu_env /bin/bash 安装常用工具 apt upda…

H3C NX30Pro刷机教程-2024-11-16

H3C NX30Pro刷机教程-2024-11-16 ref: http://www.ttcoder.cn/index.php/2024/11/03/h3c-nx30pro亲测无需分区备份 路由器-新机初始化设置路由器登录密码telnet进入路由器后台 刷机上传uboot到路由器后台在Windows环境下解压后的软件包中打开 tftpd64.exe在NX30Pro环境下通过以…

什么是嵌入式?

目录 一、什么是嵌入式 二、嵌入式系统的特点 &#xff08;一&#xff09;专用性与隐蔽性 &#xff08;二&#xff09;高可靠性与实时性 &#xff08;三&#xff09;资源固定与小型化 三、嵌入式系统的发展历史 &#xff08;一&#xff09;20 世纪 60 年代早期雏形 &am…

学习大数据DAY62 指标计算

客户需求 第一张汇总报表需要的指标 - 决策报表 汇总表 每次计算只有一天的记录 - 大 BOSS: - 全部会员数 新增会员数 - 有效会员数 有效会员占比 - 流失会员数: 倒推一年含一年无消费记录的会员 - 净增有效会员数 - 会员消费级别分类人数 (A >2000 B >1000 < …

快速上手 Vue 3 的高效组件库Element Plus

目录 前言1. 什么是组件&#xff1f;2. 安装与引入 Element Plus2.1 安装 Element Plus2.2 在 main.js 中引入 Element Plus 3. 使用 Element Plus 组件3.1 组件的基本使用3.2 控制组件状态 4. 常用组件实例解析4.1 表单与输入框4.2 表格与分页 5. 组件库的扩展性结语 前言 在…

自动驾驶车载SoC设计功能安全

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所有人的看法和评价都是暂时的&#xff0c;只有自己的经历是伴随一生的&#xff0c;几乎所有的担忧和畏惧…

【开源免费】基于Vue和SpringBoot的私人健身与教练预约管理系统(附论文)

本文项目编号 T 618 &#xff0c;文末自助获取源码 \color{red}{T618&#xff0c;文末自助获取源码} T618&#xff0c;文末自助获取源码 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息…

【项目实战】基于 LLaMA-Factory 通过 LoRA 微调 Qwen2

【项目实战】基于 LLaMAFactory 通过 LoRA 微调 Qwen2 一、项目介绍二、环境准备1、环境准备2、安装LLaMa-Factory3、准备模型数据集3.1 模型准备3.2 数据集准备 三、微调1、启动webui2、选择参数3、训练 四、测试五、总结 一、项目介绍 LLaMA-Factory是一个由北京航空航天大学…

《Probing the 3D Awareness of Visual Foundation Models》论文解析——多视图一致性

一、论文简介 论文讨论了大规模预训练产生的视觉基础模型在处理任意图像时的强大能力&#xff0c;这些模型不仅能够完成训练任务&#xff0c;其中间表示还对其他视觉任务&#xff08;如检测和分割&#xff09;有用。研究者们提出了一个问题&#xff1a;这些模型是否能够表示物体…

C++ | Leetcode C++题解之第565题数组嵌套

题目&#xff1a; 题解&#xff1a; class Solution { public:int arrayNesting(vector<int> &nums) {int ans 0, n nums.size();for (int i 0; i < n; i) {int cnt 0;while (nums[i] < n) {int num nums[i];nums[i] n;i num;cnt;}ans max(ans, cnt);…

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-04

计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-04 目录 文章目录 计算机前沿技术-人工智能算法-大语言模型-最新研究进展-2024-11-04目录1. Alopex: A Computational Framework for Enabling On-Device Function Calls with LLMs摘要&#xff1a;研究背景&…

智能运维:提升效率与响应速度的关键能力

在当今这个信息化高速发展的时代&#xff0c;运维工作的重要性日益凸显。一个高效、智能的运维系统不仅能够确保企业IT环境的稳定运行&#xff0c;还能在出现问题时迅速响应&#xff0c;最小化业务中断的影响。本文将深入探讨现代运维系统应具备的关键能力&#xff0c;包括告警…

Linux 下网络套接字(Socket) 与udp和tcp 相关接口

文章目录 1. socket常见API2 sockaddr结构体及其子类1. sockaddr结构体定义&#xff08;基类&#xff09;2. 子类 sockaddr_in结构体用于(IPv4)3 子类 sockaddr_un(Unix域套接字)4. 总结画出其结构体 3.实现一个简单的tcp Echo 服务器和客户端(cpp&#xff09;3.1 客户端3.2 服…

IPv6基础知识

IPv6是由IEIF提出的互聯網協議第六版&#xff0c;用來替代IPv4的下一代協議&#xff0c;它的提出不僅解決了網絡地址資源匱乏問題&#xff0c;也解決了多種接入設備接入互聯網的障礙。IPv6的地址長度為128位&#xff0c;可支持340多萬億個地址。如下圖&#xff0c;3ffe:1900:fe…

24首届数证杯(流量分析部分)

目录 流量分析 流量分析 1、分析网络流量包检材&#xff0c;写出抓取该流量包时所花费的秒数?(填写数字&#xff0c;答案格式:10) 3504相加即可 2、分析网络流量包检材&#xff0c;抓取该流量包时使用计算机操作系统的build版本是多少? 23F793、分析网络流量包检材&#x…

Linux(CentOS)安装达梦数据库 dm8

CentOS版本&#xff1a;CentOS 7&#xff0c;查看操作系统版本信息&#xff0c;请查阅 查看Linux内核版本信息 达梦数据库版本&#xff1a;dm8 一、获取 dm8 安装文件 1、下载安装文件 打开达梦官网&#xff1a;https://www.dameng.com/ 下载的文件 解压后的文件 2、上传安…

vue-i18n下载完报错

解决方法&#xff1a; 这是i18n版本太高了&#xff0c;与当前VUE版本不谦容&#xff1b; 查看版本&#xff1a;npm view vue-i18n versions 选择其中一个低版本&#xff0c;不要太低的 npm install vue-i18n7.3.22.可以删掉依赖包重新下载试试 报错类似如下&#xff1a; 1…/…

Docker环境搭建Cloudreve网盘服务(附shell脚本一键搭建)

Docker搭建Cloudreve Cloudreve介绍&#xff1a; Cloudreve 是一个基于 ThinkPHP 框架构建的开源网盘系统&#xff0c;旨在帮助用户以较低的成本快速搭建起既能满足个人也能满足企业需求的网盘服务。Cloudreve 支持多种存储介质&#xff0c;包括但不限于本地存储、阿里云OSS、…