《南溪的目标检测学习笔记》CNN调参笔记

1 🙏致谢

感谢赵老师的教导!
感谢张老师的指导!

2 参考资料

【GitHub】《Deep Learning Tuning Playbook from Google》

公众号“AI算法工程师Future”提供了中文资源:
【十万行代码模版+调参书+代码示例】链接: https://pan.baidu.com/s/1M9JHp2kVjC9uYgSQW9XPYg?pwd=aay2 提取码: aay2

3 ⏰训练时长要求: < 4days

在调参时,我们需要注意,训练的时间不能超过4天;

3 🚀超参数速查表

# 图像预处理
图像尺寸预处理(same_paddingletterbox
# 特征归一化
mean&std
(mean&std在样本增广之后进行计算)
# 编码encode
位置编码
Shape编码
# 载入数据
bs:批处理的数据个数
(bs在确定loss函数之后确定)
# principles
act: 激活函数
weights_init: 参数初始化
# Backbone
input_channels_bn: 输入通道归一化(~)
# neck
步长设置
# loss函数
loss_scale: loss函数缩放因子(准备进行实验)
不同loss目标的对数权重
# 训练策略
base_lr: 基础学习率(leanring rate linear scaling)
piecewise_decay: 使用Piecewise-Decay的学习率策略(~)


# 后处理
nms:使用NMS算法
~:表示暂时缺省


# 数据增广参数

3.1 HPS超参数

缩放因子loss_scale
loss权重s_map s_offset s_shape
优化器权重衰减weight_decay
优化器RM系数beta1 beta2
学习率lr

4 参数调整时间表

5.1 第一轮更新——QMV

建立简单的初始模型,
使用QMV模式进行调参,QMV = 100

5.2 第二轮更新——RSR

RSR: Randomly selected review, 从训练集中随机选取多个数据进行评测。
对训练集进行针对性调参,
使用RSR模式进行调参,RANDOM_SAMPLE_NUM = 3000=3k,这个参数是我调试出来的,如果小于这个参数,评测值会十分不稳定;

5 实验配置说明

val_data_mode: 模型验证的数据模式。

6 快速实验

7.1 特征提取模块EMA

我们使用以下方式来探索性实验,
抽象能力:指标度量(mAP)
保持能力:L2度量

7 图像预处理

输入分辨率:640x640像素
参数设置: 为了保持最大的信息量,根据COCO数据集尺寸最大的图像来进行设置;

暂停使用letterbox

经过实验发现,letterbox640目前还没有same_padding效果好,参见exp_lb640_2021-04-21_193450

8 特征归一化——mead&std

调参阶段:样本增广之后进行调整;
备注:特征归一化对加快收敛是有效果的,这个已经经过实验证明了,实验结果如图所示,
在这里插入图片描述

这里我们使用的特征归一化方法还是沿用的吴恩达教授在《Machine Learning》课程中使用的归一化方法,也就是“mead&std特征归一化”;
关于均值和标准差的计算,请参考《南溪的目标检测学习笔记》——特征归一化(mead&std)》

9 样本增广

调参阶段:在第二轮更新的最后进行调整;

9.1 随机IoU限定裁减:MinIoURandomCrop

MinIoURandomCrop在MMDet中有参考实现:MinIoURandomCrop

9.2 随机翻转:RandomFlip

RandomFlip在MMDet中有参考实现:RandomFlip

Record1:TTFNet去掉RandomFlip分数降到0.342

去掉RandomFlip的配置如图所示,
在这里插入图片描述

10 Batchsize调整的尽量大

首先batchsize的原因是这种调参是最简单的,基本上没有什么成本,只需要把网络重新训练就行了,而且这种方法一般都会很有效,因为当batchsize变大时,此时每个batch的样本的分布有更大的可能会接近训练集整体的分布,也就是说,当前的batch会更具有代表性,从而不会因为少数样本的偏差,而影响局部最优解的收敛路径;
一次看的更多,选择才会更有全局意识,才会更加理智嘛;
如果一次只看到很少量的样本,难免选择梯度的前进方向的时候,就会出现偏离,从而产生Zigzag现象呢;
(我们在MTCNN模型上,通过调大batchsize实现了召回率的提升)

11 Backbones和设计原则

7.1 权重初始化

权重初始化会影响模型的收敛速度,目前使用的是trunc_normal,其对照实验结果如下,
在这里插入图片描述

7.1 输入通道归一化 (input_channels_bn)

回顾:当时设计input_channels_bn主要是感觉可以使用BN来对输入图像通道进行learnable的分布归一化;
后来试了一下,发现没有什么明显的效果;
现在暂时停用

12 Neck设计

由于步长搜索的代价较大,我们暂时使用已有网络的步长设计,目前使用的是yolov5x的SPP步长;

13 Head设计

13.1 设计说明

Head部分需要神经元具有足够的复杂性——以应对不同回归分支的差异性

在调参时,我们发现有时候offset的编码设计较为复杂的时候,shape-target的回归也会“下降困难”的现象(loss_shape较高,而且很难下降),我们猜测这是由于Head部分的神经结构较为简单,使得难以对不同分支的目标空间进行有效地曲化,所以Head部分的神经元需要具有足够的复杂性

尽量保证head部分算子的连续性

之前在实验的时候发现,将sigmoid函数替换为H-Sigmoid函数,模型的收敛会变慢,所以我们要在head部分要尽量使用连续性强的算子,而减少使用类似于H-Sigmoid这样具有不可导点的算子;

不要使用BN层

Head模块中不要使用BN层,会使得网络收敛变慢,(可能是由于热点图的稀疏性引起的);
备注:

  • CascadeRcnn-Cbr200vd(来自PaddleDetection)在head设计中没有使用BN层,其代码截图如下
    在这里插入图片描述

13.2 range_norm_act

SoftSkim

对sigmoid函数进行改进,代码如下:

(x.sigmoid()-0.1)*1.2
# 经过这样的处理之后,张量的值域为(-0.12,1.08)包含[0,1]

初步测试了一下,效果不好,原因我也不是很清楚,我猜测是乘上正数因子会导致梯度优化的不稳定;

HeatSkim

不要使用heat_skim,试了一下感觉没有什么用,heat_skim暂时停用
备注:

# HeatSkim代码
(x.sigmoid()-0.1)*1.2.clamp(min=0, max=1)
# 对张量值进行扩展之后,再用.clamp函数规范化到[0,1]区间

14 loss函数

14.1 loss缩放因子ls(#)

ls#:该参数暂时缺省,因为在调参时,我发现该参数过于不稳定;
待服务器配置升级之后,再提高迭代次数,继续进行实验;
猜想:不稳定的原因可能是因为使用了Adam优化算法,导致优化过程对缩放因子ls不敏感。
调参方法:七星连珠法

14.2 权重更新

Decay值:0.99

14.3 备注

14.3.1 KLDivLoss使用问题(Deprecated)

文档示例代码错误

我们在前期实验的时候发现,nn.KLDivLoss官方文档的代码是有问题的:官方的示例代码会报错;该问题已经在PyTorch的Github上提交[issue]
修改如下所示:

import torch
import torch.nn as nn
import torch.nn.functional as F

kl_loss = nn.KLDivLoss(reduction="batchmean")
# input should be a distribution in the log space
input = F.log_softmax(torch.randn(3, 5, requires_grad=True), dim=-1)
# Sample a batch of distributions. Usually this would come from the dataset
# 在softxmax操作中加上了dim参数
target = F.softmax(torch.rand(3, 5), dim=-1)
output = kl_loss(input, target)

log_target = F.log_softmax(torch.rand(3, 5), dim=-1)
# output = kl_loss(input, log_target, log_target=True)
# log_target=True应该放在module的构造函数中,
kl_loss = nn.KLDivLoss(log_target=True, reduction="batchmean")
output = kl_loss(input, log_target) # 在计算时不用在声明log_target参数
KLDivLoss的loss会出现负数

我在实验的时候发现使用KLDivLoss会出现负数,感觉这个torch函数十分不稳定,于是我们暂时将其deprecate。

11 训练策略

10.1 学习率lr

lr的形象比喻

lr可以看作是小球的半径;

调整方法

lr = 0.001 0.003 0.01 0.03 0.1 0.3 1 3 10
这里的参数值是符合指数函数的增长规律的,可以参考我的博文《CNN——学习率LR的参考值范围是符合指数函数的增长规律的》
调参方法:七星连珠法

10.2 优化器optimizer

optimizer算法列表:
AdamW算法(used by Swin-Transformer-Object-Detection

10.2.1 学习率调节策略

10.2.1.1 Warmup(Disabled)

南溪笔记:尽管yolov5s在训练时使用了Warmup策略,南溪认为这种策略是没有什么道理的,我们将优化球比作一个自由下落的过程,在开始的时候,由于阻力比较小,这时候“下落的引力”占主导,对应学习率肯定是很大的,所以感觉用Warmup并不是十分合适;

Note
我们尝试了Warmup策略,会使模型在初期收敛缓慢;

实验记录:

2020.06.06:
	config-warmup:	0.000310
	config-plain:	0.010725

可以看到不使用Warmup策略进行训练,收敛会更快一些;

12 后处理方法

先通过训练获得权重之后,再来对后处理算法进行调参;

13 问题描述

13.1 从第二个epoch开始loss就一直保持不变,不在下降

原因分析:

  1. 学习率较大,导致梯度向量在斜坡两侧不断来回碰撞,难以继续下降到达底部,
    解决方案: 可以尝试降低学习率lr;

13.2 train集的loss不断下降,而val集的loss最终与训练集loss相差很大

出现了过拟合现象
原因分析:

  1. 如果验证集loss最后只是反复震荡,而没有出现下降的现象, 说明模型在一定程度上很好地利用了训练集的数据,分类边界有一定的过拟合,但并没有对验证loss产生很大影响;说明根本原因还是train集的分布无法很好地表征val集数据的分布,换句话说,训练集与验证集的分布存在较大的差异性;
    解决方案: 可以尝试降低学习率lr;
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值