谈谈Darknet53为啥这么难训练

 在我使用Imagenet2012对Darknet53进行预训练的时候,往往训练到一半,就会出现过拟合,导致无法继续向下训练,尝试了很多方法,最后发现问题出现在下图红框的部分。

得出这个结论是因为当我使用Resnet中,包含有下采样作用的 BTNK1结构代替了上面红框里的卷积层后,模型变得可以训练了。

表现在代码里:

原代码:

class ResidualBlock(Module):def __init__(self, in_channels):super(ResidualBlock, self).__init__()self.conv1 = Conv2d(in_channels=in_channels, out_channels=in_channels // 2, kernel_size=1, stride=1, padding=0)self.bn1 = BatchNorm2d(in_channels // 2)self.conv2 = Conv2d(in_channels // 2, in_channels, 3, 1, 1)self.bn2 = BatchNorm2d(in_channels)def forward(self, x):y = self.conv1(x)y = self.bn1(y)y = leaky_relu(y)y = self.conv2(y)y = self.bn2(y)y = leaky_relu(y) + xreturn y

修改后的代码:

class ResidualBlock(Module):def __init__(self, in_channels, hidden_channels, shortcut=False, stride=1):super(ResidualBlock, self).__init__()self.conv1 = Conv2dBnLeakyReLU(in_channels, hidden_channels, 1, 1, 0)self.conv2 = Conv2dBnLeakyReLU(hidden_channels, hidden_channels * 4, 3, stride, 1)# self.conv3 = Conv2dBnLeakyReLU(hidden_channels, hidden_channels * 4, 1, 1, 0)self.shortcut = Conv2dBnLeakyReLU(in_channels, hidden_channels * 4, 1, stride, 0) if shortcut else Nonedef forward(self, x):if self.shortcut is None:return x + self.conv2(self.conv1(x))else:return self.shortcut(x) + self.conv2(self.conv1(x))

 原模型代码:

class Darknet53(Module):def __init__(self, init_weights=True, num_classes=1000):super(Darknet53, self).__init__()self.conv1 = Conv2dBnLeakyReLU(3, 32, 3, 1, 1)self.conv2 = Conv2dBnLeakyReLU(32, 64, 3, 2, 1)self.residual_block1 = ResidualBlock(64)self.conv3 = Conv2dBnLeakyReLU(64, 128, 3, 2, 1)self.residual_block2 = Sequential(*([ResidualBlock(128)] * 2))self.conv4 = Conv2dBnLeakyReLU(128, 256, 3, 2, 1)self.residual_block3 = Sequential(*([ResidualBlock(256)] * 8))self.conv5 = Conv2dBnLeakyReLU(256, 512, 3, 2, 1)self.residual_block4 = Sequential(*([ResidualBlock(512)] * 8))self.conv6 = Conv2dBnLeakyReLU(512, 1024, 3, 2, 1)self.residual_block5 = Sequential(*([ResidualBlock(1024)] * 4))self.avg_pool = AdaptiveAvgPool2d(1)self.fn = Linear(1024, num_classes)if init_weights:self._initialize_weights()

修改后的模型代码:

class Darknet53(Module):def __init__(self, init_weights=True, num_classes=1000):super(Darknet53, self).__init__()self.conv1 = Conv2dBnLeakyReLU(3, 32, 3, 1, 1)# self.conv2 = Conv2dBnLeakyReLU(32, 64, 3, 2, 1)self.conv2 = ResidualBlock(32, 16, shortcut=True, stride=2)self.residual_block1 = ResidualBlock(64, 16)# self.conv3 = Conv2dBnLeakyReLU(64, 128, 3, 2, 1)self.conv3 = ResidualBlock(64, 32, shortcut=True, stride=2)self.residual_block2 = Sequential(*([ResidualBlock(128, 32)] * 2))# self.conv4 = Conv2dBnLeakyReLU(128, 256, 3, 2, 1)self.conv4 = ResidualBlock(128, 64, shortcut=True, stride=2)self.residual_block3 = Sequential(*([ResidualBlock(256, 64)] * 8))# self.conv5 = Conv2dBnLeakyReLU(256, 512, 3, 2, 1)self.conv5 = ResidualBlock(256, 128, shortcut=True, stride=2)self.residual_block4 = Sequential(*([ResidualBlock(512, 128)] * 8))# self.conv6 = Conv2dBnLeakyReLU(512, 1024, 3, 2, 1)self.conv6 = ResidualBlock(512, 256, shortcut=True, stride=2)self.residual_block5 = Sequential(*([ResidualBlock(1024, 256)] * 4))self.avg_pool = AdaptiveAvgPool2d(1)self.fn = Linear(1024, num_classes)if init_weights:self._initialize_weights()

于是有了大胆的猜测,Darknet相比Resnet,因为中间的下采样卷积层没有残差结构连接,所以模型实际上是被分割了,小loss很难向后传播到模型头部,所以会逐渐倾向于用尾部的几层网络来拟合数据,刚好Darknet的尾部很重,所以模型会逐渐走向过拟合,


以下内容就是发牢骚,但我真的好气呀,明明这么信任它。



熟悉YOLO系列的同学应该都知道,Darknet53是YOLOv3的主干网络,本人乘着暑假也在学习YOLO,从1学到了3,基本上都会用代码复现一遍,和作者所说的效果过基本吻合以后再开始新的篇章,直到遇上了Darknet53,按照作者的话说,Darknet53在ImageNet2012上的效果堪比Resnet152,而速度几乎是Resnet的2两倍。才看到这句话,我是不信的,人家Resnet152比你怎么说也多了近100层,你说这效果差不多,那Resnet家族不是很尴尬,这家人以后还怎么混是吧。但一想,YOLOv3也是久经考验的老同志了,要是数据造假,那不是早就被拖出来游街了,奈何网上又找不到相关的资料,那就自己上手训练吧。

Darknet53的网络并不复杂,用pytorch不用半个小时就搭建好了,上数据,开炼。

本人只有一张游戏显卡,为了速度上了混合精度,懒得调参,优化器用了Adam,100个epoch差不多也跑了一整天。

一看效果,在train上Top1 acc到了80,而在val上有65。这可比论文里的77.2差远了,可能是开了混合精度造成的损失?关了试一试吧,好,又是两天过去了,这次再val上的Top1 acc到了68,步子迈进了一步,可还是离77.2差了一截,难道是Adam的锅,那换SGDM再来!没想到,噩梦开始了。

自从换上SGDM,val的指标没有再突破过50,val在上升一定数值后就会逐步下降,毫无疑问,过拟合了。

batchsize小了?上梯度累计,不行!

weight_decay大了?换!,1e-4,1e-3,1e-2,1e-1,1...不行!

学习率设置大了?上指数衰减,上余弦衰减,上重启机制,全都失败。

找github看别人的代码,一行行对比,没什么区别。

怀疑过激活函数,怀疑过batchnorm,统统没用!!!

impossible!‘质子’干扰了实验。

啥都怀疑过,就是没怀疑过是网络本身的问题,毕竟有人复现过,当然都没说100%,github的同学跑出的数据是75,那也比咱强。

直到前前后后快半个月,所有能想到的方案我都试过后,一切的矛头都指向了Darknet53本身,它怎么就那么爱背答案。

砍,把后面的残差块砍掉一半。

可它死性不改,就是背。

明明Resnet50和它的层数差不多,但人家就没那么爱过拟合,到底是哪里出问题了。

抱着这个疑问,那就一点点测。

把Resnet的三层残差结构给他,不行!

把Resnet顶部的7X7卷积给他,不行!

直到!直到!直到!把Resnet用来代替池化层的BTNK1给它。

动了,它动了!问题找到了,是连接残差块的卷积层,它阻塞了loss向深度回传,在加上Darknet53很重的脚,所以只能走向过拟合。

这里面还出现了一个有意思的现象,在大学习率阶段,这种过拟合并不会太明显,但当学习率开始衰减,那么网络就会开始走向灭亡,这可能是由于在学习率较大时,loss还能有部分穿过残差块之间的间隙,而学习率逐步衰减,网络就只能靠底部的神经元进行学习了。

最后就只剩一个疑问,github上那些跑到75+的代码究竟用了什么魔法喂!。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医药大数据案例分析

二、功能 (1)流量分析 (2)经营状态分析 (3)大数据可视化系统 配置tomcat vim /root/.bash_profile添加以下内容: export CATALINA_HOME/opt/tomcat export PATH P A T H : PATH: PATH:CATALIN…

leetcode一天一题-第1天

为了增加自己的代码实战能力,希望通过刷leetcode的题目,不断提高自己,增加对代码的理解,同时开拓自己的思维方面。 题目名称:两数之和 题目编号:1 题目介绍: 给定一个整数数组 nums 和一个整数…

【算法与数据结构】队列的实现详解

文章目录 📝队列的概念及结构🌠 队列的顺序实现🌉初始化🌠入队🌉出队🌠获取队列首元素🌉获取队列尾部元素🌠获取队列中有效元素个数🌉 队列是否为空🌠查看队列…

Django框架的全面指南:从入门到高级【第128篇—Django框架】

Django框架的全面指南:从入门到高级 Django是一个高效、功能强大的Python Web框架,它被广泛用于构建各种规模的Web应用程序。无论是初学者还是有经验的开发人员,都可以从入门到掌握Django的高级技巧。在本指南中,我们将带你逐步了…

十三届试题B(山)

这天小明正在学数数。 他突然发现有些正整数的形状像一座“山”,比如 123565321 、 145541 ,它们左右对称(回文)且数位上的数字先单调不减,后单调不增。 小明数了很久也没有数完,他想让你告诉他在区间[2022…

YOLOv5目标检测学习(5):源码解析之:推理部分dectet.py

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、导入相关包与路径、模块配置1.1 导入相关的python包1.2 获取当前文件的相对路径1.3 加载自定义模块1.4 总结 二、执行主体的main函数所以执行推理代码&…

【易语言】夸克网盘通用一键转存工具

这标题很熟悉吧,没错,之前是用python写的。 然而py编译的exe好像兼容性贼差,好几个人跟我反馈闪退、卡死。 所以用易语言重写了一下。 主要更新了读取数据库链接的功能,设置好一定的时间范围,就相当于是可以每日更新链…

盘点9款AI论文写作神器,轻松写出高质量论文

0. 未来百科 未来百科,是一个全球最大的 AI 产品导航网站 —— 为发现全球优质 AI 工具而生 。目前已 聚集全球 10000优质 AI 工具产品 ,旨在帮助用户发现全球最好的 AI 工具,同时为研发 AI 垂直应用的创业公司提供展示窗口,迎接…

全国自然保护区生态功能区分布数据

自然保护区,是指对有代表性的自然生态系统、珍稀濒危野生动植物物种的天然集中分布区、有特殊意义的自然遗迹等保护对象所在的陆地、陆地水体或者海域,依法划出一定面积予以特殊保护和管理的区域。 【分级】按事权划分原则,我国自然保护区分为…

05-ESP32-S3-IDF USART

ESP32-S3 IDF USART详解 USART简介 USART是一种串行通信协议,广泛应用于微控制器和计算机之间的通信。USART支持异步和同步模式,因此它可以在没有时钟信号的情况下(异步模式)或有时钟信号的情况下(同步模式&#xff…

【LLMs+小羊驼】23.03.Vicuna: 类似GPT4的开源聊天机器人( 90%* ChatGPT Quality)

官方在线demo: https://chat.lmsys.org/ Github项目代码:https://github.com/lm-sys/FastChat 官方博客:Vicuna: An Open-Source Chatbot Impressing GPT-4 with 90% ChatGPT Quality 模型下载: https://huggingface.co/lmsys/vicuna-7b-v1.5 | 所有的模…

Redirect相应重定向无法访问WEB-INF下的静态资源,可以跳到外部资源(比如www.baidu.com)

相应重定向无法访问WEB-INF目录下静态资源,WEB-INF目录下静态资源受保护。 访问外部资源 访问Servlet5.do,就跳到百度页面