实践教程|卷积神经网络 C++ 从零开始实现

共 2680字,需浏览 6分钟

 ·

2022-02-26 23:29

↑ 点击蓝字 关注极市平台

作者丨山与水你和我@知乎
来源丨https://zhuanlan.zhihu.com/p/468100301
编辑丨极市平台

极市导读

 

目前搭建卷积神经网络(CNN)一般直接用Pytorch、Tensorflow等深度学习框架,很简单。但如果是手写反向传播过程,情况就比BP网络复杂多了,因为不仅仅是矩阵相乘。本文详解了作者从零开始用c++实现CNN的过程,附详细代码介绍。 >>加入极市CV技术交流群,走在计算机视觉的最前沿

目前搭建卷积神经网络(CNN)一般直接用 Pytorch、Tensorflow 等深度学习框架,很简单。但如果是手写反向传播过程,情况就比 BP 网络复杂多了,因为不仅仅是矩阵相乘。

目标是,从零开始实现 CNN。

刚开始,本人搜网上的卷积神经网络反向推导的相关博客,发现了几个问题:

  • 公式看的实在脑袋疼,不好理解,一大堆的 ,变量还特别多,最后自己实现才发现,卷积的时间复杂度还挺高,好几层 for;
  • 卷积层的反向传播,从输出回传的梯度 ,求输入的梯度 存在一个权重矩阵 rot180 的操作,而且还需要对梯度 填充 padding 的问题,见卷积神经网络(CNN)反向传播算法 - 刘建平Pinard - 博客园:https://www.cnblogs.com/pinard/p/6494810.html(刘建平老师的博客强烈推荐),如下
例子

这个例子没有错,但只是一种特殊情况,如果步长 stride 大于 1,就不仅仅是外围填充 0 了,还需要对 数 据之间也做填充 0,具体过程和转置卷积的前向过程一模一样。但即使真的可以这样做,写对了,做 padding 消耗也是很大的,假设 stride = 2,则大约有 的计算都是跟 0 做乘法,是无意义的计算,个人以为不可取,个人改用了其他思路。

后续一步步实现,遇到的也不仅仅这两个问题,一一克服,整个过程的关键就是——硬着头皮,老老实实写,别看公式

这也是本人一直以来的夙愿,终于实现。整个过程中,又回顾了一些 C++ 的坑与优化技巧,对卷积的前向以及后向过程和如何搭建深度学习流程有了更清晰的认识,收获颇丰。

提纲

卷积神经网络(一)tensor 定义:https://zhuanlan.zhihu.com/p/463673933

卷积神经网络(二)从图像到 tensor:https://zhuanlan.zhihu.com/p/468161119

卷积神经网络(三)ReLU 层:https://zhuanlan.zhihu.com/p/468161821

卷积神经网络(四)池化层:https://zhuanlan.zhihu.com/p/468163843

卷积神经网络(五)卷积层:https://zhuanlan.zhihu.com/p/468164733

卷积神经网络(六)Linear 线性层:https://zhuanlan.zhihu.com/p/468165951

卷积神经网络(七)搭建 CNN 网络结构:https://zhuanlan.zhihu.com/p/469475509

卷积神经网络(八)训练 CNN:https://zhuanlan.zhihu.com/p/468177334

代码

https://github.com/hermosayhl/CNN

环境

  1. Windows 11
  2. >=C++17(TDM GCC 10.3.0:https://jmeubank.github.io/tdm-gcc/download/
  3. OpenCV 4.5.2
  4. 构建工具 Cmake

数据集

采用的小型图像分类数据集,从 cat-dog-panda:https://www.kaggle.com/ashishsaxena2209/animal-image-datasetdog-cat-and-panda 数据集剔除 cat(cat 和 dog 相对比较难),然后又从 CUB-200 bird:http://www.vision.caltech.edu/visipedia/CUB-200.html 数据集中随机抽出 1000 张鸟类图像,凑成三分类的小型数据集。train : valid : test 比例 8:1:1。

网络模型

本人也不知道是什么网络结构,随便设计的(能跑就行),只有卷积层、最大池化层、ReLU 层、Softmax 层、Linear 全连接层,比 AlexNet 要简单,接受的输入大小是 224x224x3,输出 3 个值,经过 softmax 得到概率,损失函数是交叉熵,优化方法是 SGD 随机梯度下降,最终在测试集上大概可以达到 0.91 的准确率,不高,但至少跑通了。

后面虽然也写了 BatchNorm 层、DropOut 层,训练是没问题的,这俩的前向和反向传播都对,但 valid 和 test 阶段,过拟合了。。。按照网上诸多说法尝试,但都失败了,遗留问题。

后面还尝试了 Grad-CAM 可视化神经网络,实现跟论文里的细节些许不一样,例子如下,分类为 bird


公众号后台回复“数据集”获取30+深度学习数据集下载~

△点击卡片关注极市平台,获取最新CV干货
极市干货
数据集资源汇总:10个开源工业检测数据集汇总21个深度学习开源数据集分类汇总
算法trick目标检测比赛中的tricks集锦从39个kaggle竞赛中总结出来的图像分割的Tips和Tricks
技术综述:一文弄懂各种loss function工业图像异常检测最新研究总结(2019-2020)


CV技术社群邀请函 #

△长按添加极市小助手
添加极市小助手微信(ID : cvmart4)

备注:姓名-学校/公司-研究方向-城市(如:小极-北大-目标检测-深圳)


即可申请加入极市目标检测/图像分割/工业检测/人脸/医学影像/3D/SLAM/自动驾驶/超分辨率/姿态估计/ReID/GAN/图像增强/OCR/视频理解等技术交流群


每月大咖直播分享、真实项目需求对接、求职内推、算法竞赛、干货资讯汇总、与 10000+来自港科大、北大、清华、中科院、CMU、腾讯、百度等名校名企视觉开发者互动交流~


觉得有用麻烦给个在看啦~  
浏览 46
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报