我完全手写的Resnet50网络,终于把猫识别出来了

news2024/11/18 10:32:19

大家好啊,我是董董灿。

经常看我文章的同学,可能知道最近我在做一个小项目——《从零手写Resnet50实战》。

从零开始,用最简单的程序语言,不借用任何第三方库,完成Resnet50的所有算法实现和网络结构搭建,最终将下面这只猫识别出来。

图片

不幸的是,在刚搭建完网络之后,就试着运行了一下自己的神经网络,识别结果是错的

没办法,只能用 torch 搭了一个官方的网络,和我手写的神经网络,一层一层进行结果比对,然后调试(从零手写Resnet50实战——利用 torch 识别出了虎猫和萨摩耶)。

幸运的是,在经过一个数据一个数据对比之后,我的神经网络。

出猫了!

它竟然真的将猫识别出来了!


我的神经网络出猫现场

在从1000个分类得分中,将最大值的索引(第282号)挑出来之后,查询分类文件,便得到了分类结果:tiger cat

这个网络我没用 softmax。

因为 softmax 的作用是将结果“大的变得更显著,小的变得更微弱”,并不会改变结果的相对大小。

我直接从最后一个全连接层的输出,去找了最大值索引。

softmax的作用可以参考softmax原理。

过程记录

识别出猫的过程,说难也不是太难,说简单但又有不少坑。

最难的在于出猫失败,查找原因的过程,是真的一层一层的进行结果对比。

好在我封装了一个对比函数,能帮助我在重要的网络节点,验证我的网络是否正确。

下面是出猫全流程记录。

首层 Conv2d + 第一个 BatchNorm2d + MaxPool 验证正确。

第一个 Layer 验证正确,共 10 个 Conv2d。

第二个 Layer 验证正确,共 13 个 Conv2d。

第三个 Layer 验证正确,共 19 个 Conv2d。

第四个 Layer 验证正确,共10个卷积。

AvgPool 和 FC 层也都验证正确。

整个验证过程还是挺痛苦的,但是看着一层层的打出来“succ”(success的缩写,说明和官方结果是一致的),还是很有成就感,并且挺治愈的。

下面简单说一下

我在出猫过程中遇到的那些坑

保存权值文件 layout 搞错

torch 默认的图片数据摆放格式是 NCHW,而我习惯写算法的方式是NHWC。

因此,在前期将图片导出时,没有考虑自己算法实现的习惯,而是将权值直接 flatten之后保存了。

结果就是,再将权值从文件中读入内存参与运算时,数据读取不正确。结果肯定是错的。

意识到这一点之后,因为我算法都已经写好,而且不想改了,于是,将保存权值的逻辑,在 flatten 之前,添加了一个 transpose 操作,将权值从NCHW 转为 NHWC,然后保存。

BatchNorm2d 的均值和方差使用错误

BatchNorm2d的算法实现有多种,特别需要注意的是需要区分该算法是在训练时用的还是推理时用的。

训练和推理时用的BatchNorm2d虽然公式是一样的,但实现方式却大不一样。

主要区别在于:

  • 训练时均值和方差需要根据本次的数据进行实时计算

  • 推理是使用的均值和方差是模型保存好的参数,在 torch 模型中,分别为 BatchNorm2d.running_mean 和 BatchNorm2d.running_var。

而我在最开始的算法实现时,均值和方差是自己手算的(对应的训练过程),而没有使用模型保存的均值和方差。

结果便是每层BatchNorm算出来的结果都差一点,这一点误差在层与层之间传递,导致到最后的识别结果中,误差被放大。

正是因为这个误差被逐层放大,就把猫识别成了一个水桶

残差结构问题

上一篇文章从零手写Resnet50实战——利用 torch 识别出了虎猫和萨摩耶分析残差结构可能会有问题。

实际验证残差结构没问题,就是一个简单地加法。

有问题的是上一层的BatchNorm2d,计算错误了。

那为什么计算错了,当时的分析仍然能和官方的计算结果对上呢?

是因为当时的官方计算忘了一个 model.eval() 调用。该调用会告诉模型运行在推理模式而不是训练模式。

而如果我不调用,显然用的训练模式,恰巧的 BatchNorm2d 的第一次实现,手算均值和方差,就对应了训练模式的算法。

于是结果刚好对上了,但这样最终识别的图片分类肯定还是错误的。

基本就遇到了这3个问题,在把这3个问题解决了之后,整个预测过程运行了大约40分钟,猫就被顺理成章的预测出来了。

于是,项目的第一阶段,就这么完成了。

下面会开启本项目的第二阶段——神经网络性能优化。

  • 用C++ 重新实现一遍所有算法:因为C++性能要比 python 手写的算法性能好很多

  • 重点优化卷积的性能:目前40多分钟有将近39分钟的实践花在了卷积上

  • 使用C++实现的版本争取在数秒内完成一张图片的推理

因为本次有2/3的坑都是BatchNorm算法引起的,后面会写一篇BatchNorm算法的文章,欢迎继续关注。

出猫,看起来也很简单。

欢迎持续关注本博主文章和本系列,一起从零开始,学算法,做实践项目。
这是一个可以写到简历上,亮瞎面试官双眼的项目哦

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

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

相关文章

SOS大规模敏捷开发项目管理完整版(Scrum of Scrums)

Scrum of Scrums是轻量化的规模化敏捷管理模式,Leangoo领歌可以完美支持Scrum of Scrums多团队敏捷管理。 Scrum of Scrums的场景 Scrum of Scrums是指多个敏捷团队共同开发一个大型产品、项目或解决方案。Leangoo提供了多团队场景下的产品路线图规划、需求管理、…

2023首场亚马逊云科技行业峰会,医疗与生命科学年度盛会精彩先行

从实验室扩展到真实世界,从前沿技术探索到医疗生命科学行业的快速创新实践,亚马逊云科技不断地通过数字化助力医疗和生命科学的行业创新。由上海徐汇区科委指导,上海枫林集团作为支持单位,亚马逊云科技主办的2023亚马逊云科技医疗…

如何评估小程序开发费用:从项目规模到技术需求

作为一种越来越受欢迎的移动应用,小程序的开发费用是许多企业和个人考虑的重要因素之一。但是,要确定小程序开发费用并不是一件容易的事情,因为它涉及到多个因素,从项目规模到技术需求。 项目规模 小程序开发的费用通常与项目规…

docker-Dockerfile文件使用配置、自定义构建镜像、docker build

Dockerfile使用 docker build构建新的镜像参数解释 Dockerfile格式基础格式FROMCOPYADDRUNCMDENTRYPOINTENVARGVOLUMEEXPOSEWORKDIRUSERHEALTHCHECKONBUILDLABEL 命令摘要 docker build构建新的镜像 命令:docker build -t some-content-nginx . 参数解释 docker …

2023团体程序设计天梯赛--正式赛

L1-1 最好的文档 有一位软件工程师说过一句很有道理的话:“Good code is its own best documentation.”(好代码本身就是最好的文档)。本题就请你直接在屏幕上输出这句话。 输入格式: 本题没有输入。 输出格式: 在…

Pytorch的几种常用优化器

文章目录 AdagradSGDRMSpropAdamAdamW Adagrad Adagrad是一种可以自动调节每个参数更新的梯度的优化器,也可以做到在梯度平缓时走的步长大,在梯度小时走的步长小,从而防止loss出现剧烈震荡的情况。这里默认你已知道了他的原理了,…

SpringBoot自动配置原理详解

1 前言 之前也写过一篇类似的文章,但是当时理解的并不是很深入,所以一直想重新写,但是一直没有时间,就拖到了现在。这篇文章可能会很长,因为在讲解自动配置的过程中还会衍生出其他一些重要的知识点,我也会…

2023文本定位模型选型调研

背景 时间点:2023年03月 场景:做一个通用型的多种证件解析服务 需求:调研一种又新又快的定位模型。要求:1)支持倾斜的文字,可以是4点定位或分割法后获取box,但不能是2点的定位;2&…

2023.4.23第五十次周报

目录 前言 文献阅读:基于ARIMA-WOA-LSTM模型的空气污染物预测 背景 ARIMA-WOA-LSTM模型 思路 主要贡献 积分移动平均自回归 (ARIMA) 鲸鱼优化算法 搜索超参数 CEEMDAN 结论 LSTM-Kriging 主要目标 理论猜想 问1&#xff1a…

如何申请百度地图开发者AK和基本使用,并解决Uncaught ReferenceError: BMapGL is not defined的错误

文章目录 1. 文章引言2. 申请AK3. 使用AK4. 解决BMapGL is not defined的错误5. 文末总结 1. 文章引言 今天在学习amis框架中的地理位置(LocationPicker)的组件,如下图所示: 关于amis的更多了解,可以参考博文:百度低代码amis框架的…

适合学生的平价蓝牙耳机有哪些?学生平价蓝牙耳机推荐

随着蓝牙耳机的使用越来越频繁,近几年也出现了很多优质的蓝牙耳机,不仅有着超高的性价比,而且使用体验也有了很大的突破。接下来,我来给大家推荐几款适合学生使用的平价蓝牙耳机,可以当个参考。 一、南卡小音舱Lite2蓝…

Java基础--->基础部分(1)

文章目录 Java语言特点JVM、JRE和JDK的关系什么是字节码?采用字节码的好处是什么?面向对象面向对象的三大特征:封装,继承,多态关键字抽象类和接口特点和区别和equals的区别String、StringBuffer、StringBuilder异常 Ja…

中医脉诊仪:结合传统与现代技术的诊断工具

一、引言 随着科技的不断发展,医学领域也取得了举世瞩目的进步。中医作为一种古老的医学体系,始终保持着其独特的魅力。脉诊作为中医诊断的重要方法之一,历经千年的发展和传承,如今在现代科技的助力下,诞生了中医脉诊…

PostgreSQL标准复制方案

集群拓扑 假设我们使用4单元的标准配置:主库,同步从库,延迟备库,远程备库,分别用字母M,S,O,R标识。 M:Master, Main, Primary, Leader, 主库,权威数据源。S: Slave, Secondary, Standby, Sync…

CTFSHOW web入门——web37

过滤了flag,即c中不能有flag字段。 include包含变量c,因此可以利用文件包含漏洞,让变量c变成php代码,然后通过include函数执行。可以使用data协议获取flag.php文件中的内容 data://协议 通常可以用来执行PHP代码 data://text/pl…

FFmpeg PCM 编码 AAC

1. 概要说明与流程图 1.1 概要: 1) FFmpeg 已经废弃了 AV_SAMPLE_FMT_S16 格式 PCM 编码 AAC,也就是说如果使用 FFmpeg 自带的 AAC 编码器,必须做音频的重采样(重采样为:AV_SAMPLE_FMT_FLTP),否则AAC编码是失败的。 2) 传输 PCM 数据时,采取截取缓存机制,解决接收数据包…

8 年开发告诉你,API 是什么?如何看懂 API 文档

API 指的是应用程序编程接口,它是应用程序之间通信的一种方式,允许应用程序之间相互交互和传输数据。 API 文档是编写 API 的开发人员所提供的用户使用说明,通常包括 API 的用途、参数、请求示例、返回格式等信息,以便开发人员使用…

使用ltp进行三元组提取的实战代码

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

Bugzilla详解

Bugzilla详解 引言 Bugzilla是一种开源的缺陷管理系统,用于跟踪软件开发过程中的缺陷、错误和问题。它提供了一个集中化的平台,允许开发团队、测试团队和用户报告和跟踪软件中的缺陷,以便及时发现、修复和验证这些问题。 Bugzilla的作用和用…

前端学习--Ajax(2) form表单

一、form表单 组成&#xff1a;表单标签、表单域&#xff08;采集信息&#xff09;、表单按钮&#xff08;提交&#xff09; 1.1 <form>的属性 action -- 向何处发送表单数据 如果不写默认是当前页面url target -- 在何处打开action的url _blank 在新窗口打开 _self …