全手写resnet50,分分钟识别“十二生肖“图片

简介: 全手写resnet50神经网络,终于运行正常了。

大家好啊,我是董董灿。

前天,我完全手写的算法,并手搭的神经网络,终于成功的识别出一张图片。

成功地识别出来猫,意味着我搭建的整个流程跑通了。

这个流程主要包括了以下几个步骤:

  • 图片导入
  • 图片预处理:裁减、缩放、归一化
  • 输入手写的 Resnet50 中,进行推理,输出 1000 个分类得分
  • 从分类文件中查找得分最大的索引对应的类别

虽然流程通了,但是识别一张图片要耗时 40 分钟!这推理速度,简直就是龟速。

忍不了,于是我优化了一波,识别一张图片的耗时直接从40分钟降到1分多钟。

接着我从百度图片中下载了 12 张动物图片 — 组成十二生肖。

输入给了我手写的神经网络,希望它能正确的识别出来,顺便也测试一下网络的鲁棒性。

下面是十二生肖图片的识别结果,至于怎么优化的,在文章最后会有介绍。

image.png
image.png

子鼠,识别结果为 mink — 水貂,识别错误,扣一分。

不过这个老鼠是不是有那么点像水貂?

image.png
image.png

丑牛,识别为 ox - 公牛,识别正确!加一分。
而且还是公牛,是根据上翘的尾巴做的区分吗?

image.png
image.png

寅虎,识别为 tiger - 老虎,识别正确!加一分。

这萌萌的老虎特征这么明显,要是识别错,那可以下班了。

image.png
image.png

卯兔,识别为 hare - 野兔,识别正确!加一分。

这站立的姿势,警觉地竖起的耳朵,野兔无疑了。

image.png
image.png
image.png

辰龙,识别成 harp - 竖琴,识别错误,不减分。

神经网络识别不出来龙,真的不怪神经网络,因为它的类比分类里就没有中国龙这一类。

不过识别成竖琴的话,看这弯曲的身形,还确实是有点神似。

image.png
image.png

巳蛇,识别为 garter snake - 袜带蛇,识别正确!加一分。
虽然我不知道什么事袜带蛇,但它说是,就是了。

image.png
image.png

午马,识别成 Mexican hairless - 墨西哥无毛犬,识别错误,减一分。
这个不应该的。

是不是因为这匹马身上太光滑,没有马儿们标志性的鬃毛么? 但是那飘逸的尾巴,也能说明问题啊。

image.png
image.png

未羊,识别成 ram - 公羊,算是识别正确吧。

我感觉识别出是绵羊更好一些。

image.png
image.png

申猴,识别出 macaque - 猕猴,识别正确,加一分。

看这身形和毛发,这么像猕猴桃,是猕猴了!

image.png

酉鸡,识别出 cock - 公鸡,识别正确,加一分。这个是送分题。

image.png
image.png

戌狗,识别出 Samoyed - 萨摩耶,识别正确,加一分。

这一身雪白的气质,小萨独有。

image.png
image.png

亥猪,识别出 hog - 猪,识别正确,加一分。

二师兄小时候,还是很可爱的。

优化完神经网络之后,识别这 12 张图片,总共花了十来分钟。

十二生肖,共 12 种动物类别,剔除“龙”这一项,因为模型分类中没有,其他11个分类,有两个识别错误,分别是老鼠识别成了水貂,骏马识别成了墨西哥无毛犬。

整体识别成功率 81%,还算不错。

网络优化

下面说一下我是如何将这个网络推理一张图片的耗时,从 40 分钟一张,优化到 1 分钟一张的。

在最开始的版本中,整个推理过程,消耗的 90% 的时间集中在卷积运算中。

尤其是卷积运算中的乘累加部分。

在第一版手写卷积算法时,我为了完全展示卷积的运算逻辑,采用了最原始的多层循环,也就造成了现在的龟速卷积从零手写Resnet50实战—手写龟速卷积。
image.png

这种多重循环的写法,时间复杂度O(N^6),简直是没法忍受的。

于是,我针对卷积的乘累加运算,做了一个简单优化。

向量内积代替标量循环

优化方法也很简单:将最内层的循环乘累加替换成向量内积。

卷积的这种优化方法,在编译器或者指令优化场合很常见:尽可能用向量指令代替循环标量运算。

基本原理就是:原来一个时钟周期只可以计算一次循环的一个标量,而现在一个时钟周期可以计算一个向量。

在 python 的应用代码中,也可以这么做,利用 numpy 提供的 vdot 函数,直接对两个数组做向量内积。
然后加到一个数值上完成累加。

基本就下面一条语句搞定。

acc += np.vdot(img[hi_index][wi_index], weight[co_][kh_][kw_])

就这一点改动,整个网络的推理性能,便从原来的 40 分钟,直接降到了 1 分钟。

好啦,这篇文章就到这。欢迎关注本系列文章。

====================================================

最近在尝试不借助任何第三方库,从零手写 Resnet50 的算法并搭建网络,完成一张图片的推理,正确识别一张图片出来。

这是一个很好地图片识别入门实践项目,可以写到简历上,并且亮瞎面试官双眼的那种哦。

如果你感兴趣,欢迎一起参与。

项目内容:

  • 从零手写 Resnet50 中的所有基础算法 - 已完成
  • 从零搭建 Resnet50 的网络结构,将深入理解残差结构 - 已完成
  • 完成一整图片的正确推理 - 已完成
  • 对手写卷积算法进行优化(x86 CPU),提升推理性能 - 进行中
  • 采用异构编程方式完成推理加速(GPU + cuda kernel)

希望项目可以顺利完成。 欢迎关注同名公众号 @董董灿是个攻城狮,获取最新项目进展和好玩的算法文章。

相关文章
|
8月前
|
机器学习/深度学习 网络架构 计算机视觉
YOLOv5改进 | 检测头篇 | 利用DBB重参数化模块魔改检测头实现暴力涨点 (附代码 + 详细修改教程)
YOLOv5改进 | 检测头篇 | 利用DBB重参数化模块魔改检测头实现暴力涨点 (附代码 + 详细修改教程)
366 3
|
3月前
|
机器学习/深度学习 JSON 算法
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-Seg模型进行图像分割的完整流程,包括图像分割的基础知识、YOLOv5-Seg模型的特点、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。通过实例代码,指导读者从自定义数据集开始,直至模型的测试验证,适合深度学习领域的研究者和开发者参考。
1070 3
实例分割笔记(一): 使用YOLOv5-Seg对图像进行分割检测完整版(从自定义数据集到测试验证的完整流程)
|
7月前
|
人工智能 计算机视觉 Python
【超详细】【YOLOV8使用说明】一套框架解决CV的5大任务:目标检测、分割、姿势估计、跟踪和分类任务【含源码】(1)
【超详细】【YOLOV8使用说明】一套框架解决CV的5大任务:目标检测、分割、姿势估计、跟踪和分类任务【含源码】
【超详细】【YOLOV8使用说明】一套框架解决CV的5大任务:目标检测、分割、姿势估计、跟踪和分类任务【含源码】(1)
|
3月前
|
机器学习/深度学习 JSON 算法
语义分割笔记(二):DeepLab V3对图像进行分割(自定义数据集从零到一进行训练、验证和测试)
本文介绍了DeepLab V3在语义分割中的应用,包括数据集准备、模型训练、测试和评估,提供了代码和资源链接。
406 0
语义分割笔记(二):DeepLab V3对图像进行分割(自定义数据集从零到一进行训练、验证和测试)
|
3月前
|
机器学习/深度学习 算法 PyTorch
目标检测实战(五): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程)
本文详细介绍了使用YOLOv5-7.0版本进行目标检测的完整流程,包括算法介绍、环境搭建、数据集准备、模型训练、验证、测试以及评价指标。YOLOv5以其高精度、快速度和模型小尺寸在计算机视觉领域受到广泛应用。
1174 0
目标检测实战(五): 使用YOLOv5-7.0版本对图像进行目标检测完整版(从自定义数据集到测试验证的完整流程)
|
7月前
|
计算机视觉
【超详细】【YOLOV8使用说明】一套框架解决CV的5大任务:目标检测、分割、姿势估计、跟踪和分类任务【含源码】(2)
【超详细】【YOLOV8使用说明】一套框架解决CV的5大任务:目标检测、分割、姿势估计、跟踪和分类任务【含源码】
|
8月前
|
存储 传感器 编解码
CVPR 2023 最全分割类论文整理:图像/全景/语义/实例分割等【附PDF+代码】
CVPR 2023 最全分割类论文整理:图像/全景/语义/实例分割等【附PDF+代码】
1159 1
|
机器学习/深度学习 PyTorch 算法框架/工具
使用PyTorch构建卷积GAN源码(详细步骤讲解+注释版) 02人脸图片生成 上
使用PyTorch构建卷积GAN源码(详细步骤讲解+注释版) 02人脸图片生成 上
|
机器学习/深度学习 PyTorch 算法框架/工具
使用PyTorch构建卷积GAN源码(详细步骤讲解+注释版) 02人脸图片生成下
生成器的结构应与鉴别器相逆,因此生成器不再使用卷积操作,而是使用卷积的逆向操作,我们称之为转置卷积(transposed convolution)。
|
机器学习/深度学习 PyTorch 算法框架/工具
使用PyTorch构建GAN生成对抗网络源码(详细步骤讲解+注释版)01 手写字体识别
生成对抗网络(GAN)是一种用于生成新的照片,文本或音频的模型。它由两部分组成:生成器和判别器。生成器的作用是生成新的样本,而判别器的作用是识别这些样本是真实的还是假的。两个模型相互博弈,通过不断调整自己的参数来提高自己的能力。生成器希望判别器错误地认为其生成的样本是真实的,而判别器希望能正确地识别生成器生成的样本是假的。最终,生成器会学到如何生成逼真的样本,而判别器会学到如何区分真假样本。

热门文章

最新文章