《昇思 25 天学习打卡营第 11 天 | ResNet50 图像分类 》
《昇思 25 天学习打卡营第 11 天 | ResNet50 图像分类 》
活动地址:https://xihe.mindspore.cn/events/mindspore-training-camp
签名:Sam9029
计算机视觉-图像分类,很感兴趣
且今日精神颇佳,一个字,学啊
上一节(ResNet50 迁移学习)直接应用了 ResNet50 模型却没有解释概念
这一节解释,虽然提前去了解了,还是温习一下
ResNet 网络: ResNet50 网络是 2015 年由微软实验室的何恺明提出,获得 ILSVRC2015 图像分类竞赛第一名。主要的特征如下:
残差学习(最重要的概念):ResNet50 的核心思想是引入了“残差学习”框架。在深度网络中,如果层数太多,网络的训练可能会变得困难,因为每增加一层,网络的性能反而可能下降。残差学习通过添加跳过(skip connections)或快捷连接(shortcut connections)解决了这个问题,允许网络学习残差函数,而不是直接学习未映射的特征表示。
层叠结构:ResNet50 包含 50 层深的网络结构,这些层被组织成多个残差块(residual blocks)。每个残差块包含两个卷积层,后面跟着批量归一化(Batch Normalization)和 ReLU 激活函数。
批量归一化:ResNet50 在每个卷积层之后使用批量归一化,这有助于加速收敛速度,同时减少对初始化的敏感性。
恒等快捷连接:在每个残差块中,输入通过一个恒等快捷连接(identity shortcut connection)直接添加到块的输出。这保证了在网络训练过程中,梯度可以有效地流动到较浅的层。
性能:由于其设计,ResNet50 在多个标准数据集(如 ImageNet 和 COCO)上表现出色,成为了许多计算机视觉任务的基准模型。
意思是啥呢?
看完了也不是很懂,但只要明白一个概念,就是很厉害,比起传统的 卷积化神经网络模型,resNet50 性能和识别误差都更小。
传统的卷积神经网络都是将一系列的卷积层和池化层堆叠得到的,但当网络堆叠到一定深度时,就会出现退化问题。
ResNet 网络模型就提出了残差网络结构(Residual Network)来减轻退化问题,使用 ResNet 网络可以实现搭建较深的网络结构(突破 1000 层)
使用实践
学习完概念,当然少不了实践拉,这次使用 CIFAR-10数据集 来进行 图像分类的模型训练
下载数据集
from download import downloadurl = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/cifar-10-binary.tar.gz"download(url, "./datasets-cifar10-bin", kind="tar.gz", replace=True)
CIFAR-10 数据集主要是一些 airplane、automobile、bird、cat、deer、dog、frog、horse、ship、truck,可查看(datasets-cifar10-bin/cifar-10-batches-bin/batches.meta.text)
- 然后是一些 数据增强操作,略过
构建 ResNet50 网络模型
残差网络结构(Residual Network)是 ResNet 网络的主要亮点,ResNet 使用残差网络结构后可有效地减轻退化问题,实现更深的网络结构设计,提高网络的训练精度。
构建残差网络结构

这里的原理概念太难懂了,直接说主要特征和使用
残差网络结构主要由两种:
一种是 Building Block,适用于较浅的 ResNet 网络,如 ResNet18 和 ResNet34;
另一种是 Bottleneck,适用于层数较深的 ResNet 网络,如 ResNet50、ResNet101 和 ResNet152。
这一节使用 ResNet50 来构建 图像识别模型所以,我注重记录一下 Bottleneck 网络的构建
class ResidualBlock(nn.Cell):expansion = 4 # 最后一个卷积核的数量是第一个卷积核数量的4倍def __init__(self, in_channel: int, out_channel: int,stride: int = 1, down_sample: Optional[nn.Cell] = None) -> None:super(ResidualBlock, self).__init__()self.conv1 = nn.Conv2d(in_channel, out_channel,kernel_size=1, weight_init=weight_init)self.norm1 = nn.BatchNorm2d(out_channel)self.conv2 = nn.Conv2d(out_channel, out_channel,kernel_size=3, stride=stride,weight_init=weight_init)self.norm2 = nn.BatchNorm2d(out_channel)self.conv3 = nn.Conv2d(out_channel, out_channel * self.expansion,kernel_size=1, weight_init=weight_init)self.norm3 = nn.BatchNorm2d(out_channel * self.expansion)self.relu = nn.ReLU()self.down_sample = down_sampledef construct(self, x):identity = x # shortscuts分支out = self.conv1(x) # 主分支第一层:1*1卷积层out = self.norm1(out)out = self.relu(out)out = self.conv2(out) # 主分支第二层:3*3卷积层out = self.norm2(out)out = self.relu(out)out = self.conv3(out) # 主分支第三层:1*1卷积层out = self.norm3(out)if self.down_sample is not None:identity = self.down_sample(x)out += identity # 输出为主分支与shortcuts之和out = self.relu(out)return out
定义make_layer实现残差块的构建
这个函数的作用在于构建一个 由多个残差块组成的 网络层,是 ResNet 网络构建深度残差网络的基础
def make_layer(last_out_channel, block: Type[Union[ResidualBlockBase, ResidualBlock]],channel: int, block_nums: int, stride: int = 1):down_sample = None # shortcuts分支if stride != 1 or last_out_channel != channel * block.expansion:# 创建下采样层:down_sample = nn.SequentialCell([nn.Conv2d(last_out_channel, channel * block.expansion,# 使用1x1卷积进行通道数的调整和下采样, 紧接着是批量归一化层。kernel_size=1, stride=stride, weight_init=weight_init),nn.BatchNorm2d(channel * block.expansion, gamma_init=gamma_init)])layers = []layers.append(block(last_out_channel, channel, stride=stride, down_sample=down_sample))in_channel = channel * block.expansion# 循环创建剩余的残差块并添加到layers列表for _ in range(1, block_nums):layers.append(block(in_channel, channel))return nn.SequentialCell(layers)
定义 ResNet网络模型
最重要的步骤,定义 ResNet 模型类型函数
from mindspore import load_checkpoint, load_param_into_netclass ResNet(nn.Cell):def __init__(self, block: Type[Union[ResidualBlockBase, ResidualBlock]],layer_nums: List[int], num_classes: int, input_channel: int) -> None:super(ResNet, self).__init__()self.relu = nn.ReLU()# 第一个卷积层,输入channel为3(彩色图像),输出channel为64self.conv1 = nn.Conv2d(3, 64, kernel_size=7, stride=2, weight_init=weight_init)self.norm = nn.BatchNorm2d(64)# 最大池化层,缩小图片的尺寸self.max_pool = nn.MaxPool2d(kernel_size=3, stride=2, pad_mode='same')# 各个残差网络结构块定义self.layer1 = make_layer(64, block, 64, layer_nums[0])self.layer2 = make_layer(64 * block.expansion, block, 128, layer_nums[1], stride=2)self.layer3 = make_layer(128 * block.expansion, block, 256, layer_nums[2], stride=2)self.layer4 = make_layer(256 * block.expansion, block, 512, layer_nums[3], stride=2)# 平均池化层self.avg_pool = nn.AvgPool2d()# flattern层self.flatten = nn.Flatten()# 全连接层self.fc = nn.Dense(in_channels=input_channel, out_channels=num_classes)def construct(self, x):# // ... 省略return x
- 然后定义 _resnet 函数加载 使用 ResNet 网络模型类
- 再使用 _resnet 函数构建 resnet50 网络模型
def resnet50(num_classes: int = 1000, pretrained: bool = False):"""ResNet50模型"""resnet50_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/models/application/resnet50_224_new.ckpt"resnet50_ckpt = "./LoadPretrainedModel/resnet50_224_new.ckpt"return _resnet(resnet50_url, ResidualBlock, [3, 4, 6, 3], num_classes,pretrained, resnet50_ckpt, 2048)
模型训练
# 定义ResNet50网络
network = resnet50(pretrained=True)# 全连接层输入层的大小
in_channel = network.fc.in_channels
fc = nn.Dense(in_channels=in_channel, out_channels=10)
# 重置全连接层
network.fc = fc# 设置学习率
num_epochs = 5
lr = nn.cosine_decay_lr(min_lr=0.00001, max_lr=0.001, total_step=step_size_train * num_epochs,step_per_epoch=step_size_train, decay_epoch=num_epochs)
# 定义优化器和损失函数
# // ... 省略# 定义训练函数
def train(data_loader, epoch): //epoch 即 num_epoch# // ... 省略# 定义预测函数
def evaluate(data_loader):# // ... 省略# 开始循环训练
print("Start Training Loop ...")for epoch in range(num_epochs):curr_loss = train(data_loader_train, epoch) # 训练curr_acc = evaluate(data_loader_val) # 预测print("Epoch: [%3d/%3d], Average Train Loss: [%5.3f], Accuracy: [%5.3f]" % (epoch+1, num_epochs, curr_loss, curr_acc))# 保存当前预测准确率最高的模型# // ... 省略
使用 可视化模型 预测
定义 visualize_model 来检验我们训练的 ResNet 微调模型 在图像分类方面的效果
import matplotlib.pyplot as pltdef visualize_model(best_ckpt_path, dataset_val):num_class = 10 # 对狼和狗图像进行二分类net = resnet50(num_class)# 加载模型参数param_dict = ms.load_checkpoint(best_ckpt_path)ms.load_param_into_net(net, param_dict)# 加载验证集的数据进行验证data = next(dataset_val.create_dict_iterator())images = data["image"]labels = data["label"]# 预测图像类别output = net(data['image'])pred = np.argmax(output.asnumpy(), axis=1)# 图像分类classes = []with open(data_dir + "/batches.meta.txt", "r") as f:for line in f:line = line.rstrip()if line:classes.append(line)# 显示图像及图像的预测值plt.figure()for i in range(6):plt.subplot(2, 3, i + 1)# 若预测正确,显示为蓝色;若预测错误,显示为红色color = 'blue' if pred[i] == labels.asnumpy()[i] else 'red'plt.title('predict:{}'.format(classes[pred[i]]), color=color)picture_show = np.transpose(images.asnumpy()[i], (1, 2, 0))mean = np.array([0.4914, 0.4822, 0.4465])std = np.array([0.2023, 0.1994, 0.2010])picture_show = std * picture_show + meanpicture_show = np.clip(picture_show, 0, 1)plt.imshow(picture_show)plt.axis('off')plt.show()# 使用测试数据集进行验证
visualize_model(best_ckpt_path=best_ckpt_path, dataset_val=dataset_val)
模型的预测结果,由章节解释 5 次训练就可以达到 70% 的准确率,
Epoch: [ 5/ 5], Average Train Loss: [0.745], Accuracy: [0.742], 差不多由 74%
当然想要继续提升,所需要的训练次数就会成倍的上升,训练成本也会添加,好在教程有说,80 次的 epochs 下就能达到理想的预测效果,
所有我实际测试一下,看看 80 的 ecochs 准确率是多少
实际测试日志输出
- 从
10:42:29开始训练
# 第二次 5次训练时--就达到了 80%,多3次epoch 提升 10%
Epoch: [ 5/ 80], Average Train Loss: [0.516], Accuracy: [0.802]# 8次训练--达到了 81%,多3次epoch 提升 1%
Epoch: [ 8/ 80], Average Train Loss: [0.429], Accuracy: [0.817]# 8次训练--达到了 83%,多16次epoch 提升 3%, 这个提升就有些慢了,看来提升准确率很不容易
Epoch: [ 21/ 80], Average Train Loss: [0.211], Accuracy: [0.837]# 40次训练--达到了 84%,多35次epoch 提升 4%,预测一下 80次的时候会到90%,看可不可以,希望不要打脸
Epoch: [ 40/ 80], Average Train Loss: [0.077], Accuracy: [0.847]# 49-51次训练--准确率进行了 过山车 波动,下降之后又回升了
Epoch: [ 49/ 80], Average Train Loss: [0.056], Accuracy: [0.850]
Epoch: [ 50/ 80], Average Train Loss: [0.057], Accuracy: [0.847]
Epoch: [ 51/ 80], Average Train Loss: [0.052], Accuracy: [0.846]# --------------------------------------------------
Epoch: [ 80/ 80], Average Train Loss: [0.033], Accuracy: [0.849]
# --------------------------------------------------
#================================================================================
End of validation the best Accuracy is: 0.851, save the best ckpt file in ./BestCheckpoint/resnet50-best.ckpt# 呃,80次的epochs 准确率是 84%, 过程最高时 85%
给我整嘛了,还是有好多的东西都不懂,不过也是初略的了解到了在图像识别方面 ResNet 网络模型的应用和突出的优势
所有内容仅为个人理解,若有错误与遗漏还望各位大佬指正
#================================================================================
End of validation the best Accuracy is: 0.851, save the best ckpt file in ./BestCheckpoint/resnet50-best.ckpt
呃,80次的epochs 准确率是 84%, 过程最高时 85%
给我整嘛了,还是有好多的东西都不懂,不过也是初略的了解到了在图像识别方面 ResNet 网络模型的应用和突出的优势> 所有内容仅为个人理解,若有错误与遗漏还望各位大佬指正
相关文章:
《昇思 25 天学习打卡营第 11 天 | ResNet50 图像分类 》
《昇思 25 天学习打卡营第 11 天 | ResNet50 图像分类 》 活动地址:https://xihe.mindspore.cn/events/mindspore-training-camp 签名:Sam9029 计算机视觉-图像分类,很感兴趣 且今日精神颇佳,一个字,学啊 上一节&…...
实现多数相加,但是传的参不固定
一、情景 一般实现的加法和减法等简单的相加减函数的话。一般都是写好固定传的参数。比如: function add(a,b) {return a b;} 这是固定的传入俩个,如果是三个呢,有人说当然好办! 这样写不就行了! function add(a…...
Windows环境安装Redis和Redis Desktop Manager图文详解教程
版权声明 本文原创作者:谷哥的小弟作者博客地址:http://blog.csdn.net/lfdfhl Redis概述 Redis是一个开源的高性能键值对数据库,以其卓越的读写速度而著称,广泛用于数据库、缓存和消息代理。它主要将数据存储在内存中࿰…...
SQL Server 2022的组成
《SQL Server 2022从入门到精通(视频教学超值版)》图书介绍-CSDN博客 SQL Server 2022主要由4部分组成,分别是数据库引擎、分析服务、集成服务和报表服务。本节将详细介绍这些内容。 1.2.1 SQL Server 2022的数据库引擎 SQL Server 2022的…...
【大语言模型系列之Transformer】
🎥博主:程序员不想YY啊 💫CSDN优质创作者,CSDN实力新星,CSDN博客专家 🤗点赞🎈收藏⭐再看💫养成习惯 ✨希望本文对您有所裨益,如有不足之处,欢迎在评论区提出…...
操作系统-懒汉式单例模式
懒汉式单例模式的主要好处有以下几点: 1.资源利用效率高: 只有在第一次调用 getInstance() 方法时才创建实例对象,而不是在类加载时就创建。这可以节省系统资源。 2.延迟加载: 实例对象的创建被延迟到第一次使用时,可以减少系统启动时的资源消耗。 3.线程安全: 这种…...
设计模式探索:策略模式
1. 什么是策略模式(Strategy Pattern) 定义 策略模式(Strategy Pattern)的原始定义是:定义一系列算法,将每一个算法封装起来,并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而…...
提升效能:Symfony 性能优化实用指南
Symfony 是一个功能丰富的 PHP Web 框架,但在构建高性能应用程序时,开发者需要考虑多种性能优化策略。本文将探讨一系列实用的 Symfony 性能优化技巧,帮助开发者提高应用程序的响应速度和整体性能。 1. 了解 Symfony 缓存机制 Symfony 提供…...
1.pwn的汇编基础(提及第一个溢出:整数溢出)
汇编掌握程度 能看懂就行,绝大多数情况不需要真正的编程(shellcode题除外) 其实有时候也不需要读汇编,ida F5 通常都是分析gadget,知道怎么用, 调试程序也不需要分析每一条汇编指令,单步执行然后查看寄存器状态即可 但…...
迎接AI新时代:GPT-5即将登场的巨大变革与应用前瞻
迎接AI新时代:GPT-5即将登场的巨大变革与应用前瞻 💎1. GPT-5 一年半后发布:AI新时代的来临1.1 GPT-5的飞跃:从高中生到博士生 💎2. GPT-5的潜在应用场景💎2.1 医疗诊断和健康管理💎2.2 教育领域…...
封锁-封锁模式(共享锁、排他锁)、封锁协议(两阶段封锁协议)
一、引言 1、封锁技术是目前大多数商用DBMS采用的并发控制技术,封锁技术通过在数据库对象上维护锁来实现并发事务非串行调度的冲突可串行化 2、基于锁的并发控制的基本思想是: 当一个事务对需要访问的数据库对象,例如关系、元组等进行操作…...
跨境干货|最新注册Google账号方法分享
谷歌账号对做跨境外贸业务的人来说是刚需,目前来说大部分的海外社媒平台、工具都可以用谷歌账号来注册。但是仍然有很多朋友并不知道如何注册这个谷歌账号,今天就来给大家分享2个注册谷歌账号的方法,一个是手机号注册,一个是如何跳…...
MySQL第三天作业
一、在数据库中创建一个表student,用于存储学生信息 CREATE TABLE student( id INT PRIMARY KEY, name VARCHAR(20) NOT NULL, grade FLOAT ); 1、向student表中添加一条新记录 记录中id字段的值为1,name字段的值为"monkey"…...
网络安全应急处理流程
网络安全应急处理流程是指在发生网络安全事件时,组织应采取的一系列措施,以快速响应、控制、恢复和调查网络安全事件,确保业务连续性和数据安全。以下是一个详细的网络安全应急处理流程: 1. 准备阶段 目标:建立和维护…...
昇思25天学习打卡营第12天 | LLM原理和实践:MindNLP ChatGLM-6B StreamChat
1. MindNLP ChatGLM-6B StreamChat 本案例基于MindNLP和ChatGLM-6B实现一个聊天应用。 ChatGLM-6B应该是国内第一个发布的可以在消费级显卡上进行推理部署的国产开源大模型,2023年3月就发布了。我在23年6月份的时候就在自己的笔记本电脑上部署测试过,当…...
中英双语介绍加拿大多伦多(Toronto)
中文版 多伦多概述 多伦多(Toronto)是加拿大最大的城市,也是北美地区重要的经济、文化和金融中心。以下是对多伦多的详细介绍,包括其经济地位、金融中心、人口、地理位置、高等教育、移民政策、著名景点和居住的名人等方面的信息…...
【YOLOv9教程】如何使用YOLOv9进行图像与视频检测
《博主简介》 小伙伴们好,我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源,可关注公-仲-hao:【阿旭算法与机器学习】,共同学习交流~ 👍感谢小伙伴们点赞、关注! 《------往期经典推…...
Text2SQL提问中包括时间的实战方案
大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…...
点胶系统实战1-项目介绍
准备实战开发如下图的多轴点胶系统实战课程,内容设计界面开发、运动板块开发、任务管理、点胶的控制等。我们将和进入这个领域的初学者门一起进步。 有感兴趣的小伙伴,可以关注点赞,或评论区反馈你们的重点关注的内容,那些部分我…...
【MYSQL】InnoDB引擎为什么选可重复读作为默认隔离级别
InnoDB引擎为什么选可重复读作为默认隔离级别 一般的DBMS系统,默认都会使用读提交(Read-Comitted,RC)作为默认隔离级别,如Oracle、SQL Server等,而MySQL却使用可重复读(Read-Repeatable&#x…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
无人机侦测与反制技术的进展与应用
国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
