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

深度学习训练营_第P3周_天气识别

  • 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
  • 🍦 参考文章:Pytorch实战 | 第P3周:彩色图片识别:天气识别
  • **🍖 原作者:K同学啊|接辅导、项目定制**␀

本次实验有两个新增任务:

  1. 测试集准确度达95%
  2. 调用模型识别图片
    我训练完直接在测试集里选了几张图识别,界面的title第一行是label,第二行是预测结果,如图,效果不错
    ps:想输出图片还需加入一个逆解原图的函数,因为读入时直接用transforms将数据集归一化了

在这里插入图片描述
关于准确度:

  • 直接将K同学的模型改成nn.Sequential()连接后,准确度已经达到了94.2%,目前不是很理解原因,在我目前的理解,在前向传播时连接模型应该和Sequential是等价的
  • 将激活函数由RELU改为SILU后测试集准确度在86%附近不再提升,如图
    在这里插入图片描述
  • 将原模型最后只有一个全连接层改为两个全连接层
    在lr=1e-4,epoch=20时,准确度在一直增加,可以看出这时训练20次还不够,我的理解是因为此时比上次的参数多了一层,所以更加难训练。效果如图:

在这里插入图片描述

  • 此时我想将上次的学习率增大,是否可以快点达到理想水平?于是设置lr=1e-2,由于给的太大了,训练后期开始震荡,如图:
    在这里插入图片描述

  • 自己瞎设计了一个模型,效果一般,也没有达到95%(后面就转到云服务器训练了,电脑显卡一般,训练要等半天)
    在这里插入图片描述

  • 模仿残差块,想融合低维和高维数据一起预测,但准确度只有88%左右(理论知识不足,模型也只会凭感觉设计的结果。。。)
    记录一下这个模型吧
    在这里插入图片描述

代码:

import torch
import torch.nn as nn
import torchvision.transforms as transforms
import torchvision
from torchvision import transforms, datasets
import os, PIL, pathlib, random
import torch.nn.functional as F
from torchinfo import summary
import matplotlib.pyplot as plt
import numpy as npdevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("device:" + str(device))data_dir = './data/'
data_dir = pathlib.Path(data_dir)
data_paths = list(data_dir.glob('*'))
classeNames = [str(path).split("\\")[1] for path in data_paths]
print(classeNames)total_datadir = './data/'# 串联多个图片变换操作,进行图像预处理
train_transforms = transforms.Compose([transforms.Resize([224, 224]),  # 将输入图片resize成统一尺寸transforms.ToTensor(),  # 将PIL Image或numpy.ndarray转换为tensor,并归一化到[0,1]之间transforms.Normalize(  # 标准化处理-->转换为标准正太分布(高斯分布),使模型更容易收敛mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])])  # 其中 mean=[0.485,0.456,0.406]与std=[0.229,0.224,0.225] 从数据集中随机抽样计算得到的total_data = datasets.ImageFolder(total_datadir, transform=train_transforms)  # root:数据集地址,数据集内每个类别再单独一个文件夹,类别文件夹内才是图片train_size = int(0.8 * len(total_data))
test_size = len(total_data) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(total_data, [train_size, test_size])  # 按8:2随机将数据集划分为训练集和测试集# 参数
batch_size = 32
nc = 10
learn_rate = 1e-2
epochs = 20train_dl = torch.utils.data.DataLoader(train_dataset,batch_size=batch_size,shuffle=True,num_workers=0)  # 用多线程(nw>0)会导致print()函数多次输出
test_dl = torch.utils.data.DataLoader(test_dataset,batch_size=batch_size,shuffle=True,num_workers=0)class Model(nn.Module):def __init__(self):super(Model, self).__init__()conv1 = nn.Conv2d(3, 12, 5)bn1 = nn.BatchNorm2d(12)conv2 = nn.Conv2d(12, 12, 5)bn2 = nn.BatchNorm2d(12)pool = nn.MaxPool2d(2, 2)conv4 = nn.Conv2d(12, 24, 5)bn4 = nn.BatchNorm2d(24)conv5 = nn.Conv2d(24, 24, 5)bn5 = nn.BatchNorm2d(24)fc1 = nn.Linear(24 * 50 * 50, 1000)fc2 = nn.Linear(1000, len(classeNames))self.m = nn.Sequential(conv1, bn1, nn.ReLU(),conv2, bn2, nn.ReLU(),pool,conv4, bn4, nn.ReLU(),conv5, bn5, nn.ReLU(),pool,nn.Flatten(),fc1, fc2)def forward(self, x):output = self.m(x)return output# 将归一化的数据集逆解出原图,并转化成numpy格式
def de_normalize(image, mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]):mean = torch.as_tensor(mean)std = torch.as_tensor(std)if mean.ndim == 1:mean = mean.view(-1, 1, 1)if std.ndim == 1:std = std.view(-1, 1, 1)image = image * std + mean  # 由image=(x-mean)/std可知,x=image*std+meanimage = image.numpy().transpose(1, 2, 0)  # 从tensor转为numpy,并由(C,H,W)变为(H,W,C)image = np.around(image * 255)  # 对数据恢复并进行取整image = np.array(image, dtype=np.uint8)  # 矩阵元素类型由浮点数转为整数return image# 训练
def train(dataloader, model, loss_fn, optimizer):size = len(dataloader.dataset)  # 训练集的大小,一共60000张图片num_batches = len(dataloader)  # 批次数目,1875(60000/32)train_loss, train_acc = 0, 0  # 初始化训练损失和正确率for X, y in dataloader:  # 获取图片X及其标签yX, y = X.to(device), y.to(device)# 前向传播,计算预测误差# 注:这里会触发Module的forward回调函数,调用上面的Model类的forward(),从而进行前向传播pred = model(X)  # 网络输出预测值# 计算网络输出(预测值)和真实值之间的差距,targets为真实值,计算二者差值即为损失# 返回的loss是一个张量loss = loss_fn(pred, y)# 反向传播optimizer.zero_grad()  # grad属性归零loss.backward()  # 反向传播,backward()会一层层的反向传播计算每层的每个w的梯度值,并保存到该w的.grad属性中,并在下一步step()更新optimizer.step()  # 每一步自动更新 前面已经把model的参数传给了opt,所以此处调用更新就会更新model的参数# 记录acc与losstrain_acc += (pred.argmax(1) == y).type(torch.float).sum().item()  # train_acc: 训练集准确度train_loss += loss.item()train_acc /= sizetrain_loss /= num_batchesreturn train_acc, train_loss# 测试函数和训练函数大致相同,但是由于不进行梯度下降对网络权重进行更新,所以不需要传入优化器
def test(dataloader, model, loss_fn):size = len(dataloader.dataset)  # 测试集的大小,一共10000张图片num_batches = len(dataloader)  # 批次数目,313(10000/32=312.5,向上取整)test_loss, test_acc = 0, 0# 当不进行训练时,停止梯度更新,节省计算内存消耗# (pytorch默认会对含张量的操作自动求导)with torch.no_grad():  # 表示张量的计算过程中无需计算梯度for imgs, target in dataloader:imgs, target = imgs.to(device), target.to(device)# 计算losstarget_pred = model(imgs)loss = loss_fn(target_pred, target)test_loss += loss.item()test_acc += (target_pred.argmax(1) == target).type(torch.float).sum().item()test_acc /= sizetest_loss /= num_batchesreturn test_acc, test_lossmodel = Model().to(device)  # 将模型转移到GPU中
loss_fn = nn.CrossEntropyLoss()  # 多分类问题-->交叉熵损失函数
opt = torch.optim.SGD(model.parameters(), lr=learn_rate)  # 随机梯度下降def main():train_loss = []train_acc = []test_loss = []test_acc = []for epoch in range(epochs):# trainmodel.train()epoch_train_acc, epoch_train_loss = train(train_dl, model, loss_fn, opt)# testmodel.eval()epoch_test_acc, epoch_test_loss = test(test_dl, model, loss_fn)# 记录数据,用于最后画曲线train_acc.append(epoch_train_acc)train_loss.append(epoch_train_loss)test_acc.append(epoch_test_acc)test_loss.append(epoch_test_loss)template = ('Epoch:{:2d}, Train_acc:{:.1f}%, Train_loss:{:.3f}, Test_acc:{:.1f}%,Test_loss:{:.3f}')print(template.format(epoch + 1, epoch_train_acc * 100, epoch_train_loss, epoch_test_acc * 100, epoch_test_loss))plt.figure()for i in range(20):# 原图数据img, label = test_dataset[i]npimg = de_normalize(img)# 预测img = img.unsqueeze(0)  # 升维,否则不能输入模型img = img.to(device)  # 传入GPU,因为前面模型是建在GPU内的pred = model(img)  # model前向传播,返回的是一个张量index = torch.argmax(pred)  # 取置信度最大的# plt显示plt.subplot(2, 10, i + 1)plt.title(classeNames[label] + "\n" + classeNames[index])  # 第一行是real 第二行是predplt.imshow(npimg)plt.axis('off')plt.show()plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号plt.rcParams['figure.dpi'] = 100  # 分辨率epochs_range = range(epochs)plt.figure(figsize=(12, 3))plt.subplot(1, 2, 1)plt.plot(epochs_range, train_acc, label='Training Accuracy')plt.plot(epochs_range, test_acc, label='Test Accuracy')plt.legend(loc='lower right')plt.title('Training and Validation Accuracy')plt.subplot(1, 2, 2)plt.plot(epochs_range, train_loss, label='Training Loss')plt.plot(epochs_range, test_loss, label='Test Loss')plt.legend(loc='upper right')plt.title('Training and Validation Loss')plt.show()if __name__ == '__main__':main()

相关文章:

深度学习训练营_第P3周_天气识别

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍦 参考文章:Pytorch实战 | 第P3周:彩色图片识别:天气识别**🍖 原作者:K同学啊|接辅导、项目定制**␀ 本次实验有两个新增任务&…...

“华为杯”研究生数学建模竞赛2006年-【华为杯】C题:维修线性流量阀时的内筒设计问题(附获奖论文及matlab代码)

赛题描述 油田采油用的油井都是先用钻机钻几千米深的孔后,再利用固井机向四周的孔壁喷射水泥砂浆得到水泥井管后形成的。固井机上用来控制砂浆流量的阀是影响水泥井管质量的关键部件,但也会因磨损而损坏。目前我国还不能生产完整的阀体,固井机仍依赖进口。由于损坏的内筒已…...

数据结构:带环单链表基础OJ练习笔记(leetcode142. 环形链表 II)(leetcode三题大串烧)

目录 一.前言 二.leetcode160. 相交链表 1.问题描述 2.问题分析与求解 三.leetcode141. 环形链表 1.问题描述 2.代码思路 3.证明分析 下一题会用到的重要小结论: 四.leetcode142. 环形链表 II 1.问题描述 2.问题分析与求解 Judgecycle接口&#xf…...

数模美赛如何找数据 | 2023年美赛数学建模必备数据库

2023美赛资料分享/思路答疑群:322297051 欧美相关统计数据(一般美赛这里比较多) 1、http://www.census.gov/ 美国统计局(统计调查局或普查局)官方网站 The Census Bureau Web Site provides on-line access to our …...

SSTI漏洞原理及渗透测试

模板引擎(Web开发中) 是为了使 用户界面 和 业务数据(内容)分离而产生的,它可以生成特定格式的文档, 利用模板引擎来生成前端的HTML代码,模板引擎会提供一套生成HTML代码的程序,之后…...

【算法基础】高精度除法

👦个人主页:Weraphael ✍🏻作者简介:目前是C语言 算法学习者 ✈️专栏:【C/C】算法 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…...

optimizer.zero_grad(), loss.backward(), optimizer.step()的理解及使用

optimizer.zero_grad,loss.backward,optimizer.step用法介绍optimizer.zero_grad():loss.backward():optimizer.step():用法介绍 这三个函数的作用是将梯度归零(optimizer.zero_grad())&#x…...

融资、量产和一栈式布局,这家Tier 1如此备战高阶智驾决赛圈

作者 | Bruce 编辑 | 于婷从早期的ADAS,到高速/城市NOA,智能驾驶的竞争正逐渐升级,这对于车企和供应商的核心技术和产品布局都是一个重要的考验。 部分智驾供应商已经在囤积粮草,响应变化。 2023刚一开年,智能驾驶领域…...

centos7.8安装oralce11g

文章目录环境安装文件准备添加用户操作系统环境配置解压安装问题解决创建用户远程连接为了熟悉rman备份操作,参照大神的博客在centos中安装了一套oracle11g,将安装步骤记录如下环境安装文件准备 这里准备一台centos7.8 虚拟机 配置ip 192.168.18.100 主…...

【蓝桥杯集训·每日一题】AcWing 3956. 截断数组

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴一维前缀和一、题目 1、原题链接 3956. 截断数组 2、题目描述 给定一个长度为 n 的数组 a1,a2,…,an。 现在,要将该数组从中间截断,得到三个非空子…...

万丈高楼平地起:Linux常用命令

目录 系统管理命令 man命令 ls命令 cd命令 useradd命令 passwd命令 free命令 whoami命令 ps命令 date命令 pwd命令 shutdown命令 文件目录管理命令 touch命令 cat命令 mkdir命令 rm命令 cp命令 mv命令 find命令 more指令 less指令 head指令 tail指令 …...

Linux(Linux的连接使用)

连接Linux我们一般使用CRT或者Xshell工具进行连接使用。 如CRT使用SSH的方式 输出主机,账户,密码那些就可以连接上了。 Linux系统是一个文件型操作系统,有一句话说Linux的一切皆是文件。Linux系统的启动大致有下面几个步骤 Linux系统有7个运…...

Unity中画2D图表(2)——用XChart包绘制散点分布图 + 一条直线方程

散点图用于显示关系。 对于 【相关性】 ,散点图有助于显示两个变量之间线性关系的强度。 对于 【回归】 ,散点图常常会添加拟合线。 举例1:你可以展示【年降雨量】与【玉米亩产量】的关系 举例2:你也可以分析各个【节假日】与【大…...

Go 排序包 sort

写在前面的使用总结: 排序结构体 实现Len,Less,Swap三个函数 package main import ( "fmt" "sort") type StuScore struct { name string score int } type StuScores []StuScore func (s StuScores) Len(…...

Java Email 发HTML邮件工具 采用 freemarker模板引擎渲染

Java Email 发HTML邮件工具 采用 freemarker模板引擎 1.常用方式对比 Java发送邮件有很多的实现方式 第一种&#xff1a;Java 原生发邮件mail.jar和activation.jar <!-- https://mvnrepository.com/artifact/javax.mail/mail --> <dependency><groupId>jav…...

CNI 网络流量分析(六)Calico 介绍与原理(二)

文章目录CNI 网络流量分析&#xff08;六&#xff09;Calico 介绍与原理&#xff08;二&#xff09;CNIIPAM指定 IP指定非 IPAM IPCNI 网络流量分析&#xff08;六&#xff09;Calico 介绍与原理&#xff08;二&#xff09; CNI 支持多种 datapath&#xff0c;默认是 linuxDa…...

短视频标题的几种类型和闭坑注意事项

目录 短视频标题的几种类型 1、悬念式 2、蹭热门式 3、干货式 4、对比式方法 5、总分/分总式方法 6、挑战式方式 7、启发激励式 8、讲故事式 02注意事项 1、避免使用冷门、生僻词汇 标题是点睛之笔&#xff0c;核心是视频内容 短视频标题的几种类型 1、悬念式 通过…...

操作系统——1.操作系统的概念、定义和目标

目录 1.概念 1.1 操作系统的种类 1.2电脑的组成 1.3电脑组成的介绍 1.4操作系统的概念&#xff08;定义&#xff09; 2.操作系统的功能和目标 2.1概述 2.2 操作系统作为系统资源的管理者 2.3 操作系统作为用户和计算机硬件间的接口 2.3.1用户接口的解释 2.3.2 GUI 2.3.3接…...

【html弹框拖拽和div拖拽功能】原生html页面引入vue语法后通过自定义指令简单实现div和弹框拖拽功能

前言 这是html版本的。只是引用了vue的语法。 这是很多公司会出现的一种情况&#xff0c;就是原生的页面&#xff0c;引入vue的语法开发 这就导致有些vue上很简单的功能。放到这里需要转换一下 以前写过一个vue版本的帖子&#xff0c;现在再加一个html版本的。 另一个vue版本…...

2023新华为OD机试题 - 计算网络信号(JavaScript) | 刷完必过

计算网络信号 题目 网络信号经过传递会逐层衰减,且遇到阻隔物无法直接穿透,在此情况下需要计算某个位置的网络信号值。 注意:网络信号可以绕过阻隔物 array[m][n] 的二维数组代表网格地图,array[i][j] = 0代表 i 行 j 列是空旷位置;array[i][j] = x(x 为正整数)代表 i 行 …...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

多模态图像修复系统:基于深度学习的图片修复实现

多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...