- 数据预处理
-
通过PIL中的Image接口读取图像,并做一系列数据增强处理会更方便:多尺度resize,随机水平翻转,光照变化,对比度变化, mosic数据增强等。
-
1. 数据增强
-
多尺度resize:先预设一些resize尺寸,训练时做random挑选,计算输入图像的短边resize到该尺寸的ratio,再计算将图像长边按此ratio做缩放,是否会超过最大预设值(经验值1333),若超过,则按长边resize到1333的ratio做为最终ratio值,将图像和bbox做整体缩放。
-
随机水平翻转:flip的方式其实很多,水平/垂直翻转,任意角度rotate,如果不做rotate-bbox检测,比较make sense的数据增强方式就是对image/bbox同时做随机水平旋转。
-
光照变化
-
对比度变化
-
2. 数据归一化
-
将输入数据归一化到[0, 1]区间: x/255
-
将输入数据做标准化:(x - mean) / std
-
- 模型结构设计
-
模型结构总体分为backbone, neck, head三部分串接二层。backbone从轻量级mobileNet,squeezeNet, shuffleNet从偏重的resnet, resnext, DLA都可适配选择。neck部分可选的有FPN, PAN等。head就具体到特定的任务,检测head + 分类head。
-
1. backbone
-
2. neck
-
3. head
- 模型参数初始化
-
一个良好的模型参数初始化至关重要,这决定了你模型能否正常收敛,未正常初始化好的模型,在训练初期,会因为前向计算值过大或者过小,导致loss迅速变为nan,导致训练失败。模型初始化的经验大致分为如下几点:
-
1. 加载预训练模型
-
如果整体模型结构有一个预训练的模型,那是非常完美的,直接load_state_dict加载预训练权重,在自有数据集上做finetune任务,甚至你head部分如果layer比较多的话,可以freeze backbone和neck部分,只finetune head任务部分,效果也可以很好。如果是一个新修改建立的模型结构,backbone部分可以加载在imageNet数据集上预训练过的weight,这部分有现成的工作,pytorch官方提供了大量的此类预训练权重,可以直接wget下来,再load_state_dict, 记得在加载权重时,把strict设置为false,以免部分不一致,导致加载预训练权重失败的问题。
-
2. 正态分布初始化/常值初始化
-
对于特定的head部分,一般不一定有预训练的weight,我们可以使用正态分布初始化或者常值初始化的方式,来初始化任务head部分的权重。
-
nn.init.constant_(layer.bias, 0) #bias常值初始化偏置 nn.init.normal_(layer.weight, std=0.01) # 0均值,0.01标准差初始化权重
-
对于detection的分类head,可以借鉴的初始化方式如下:
-
pi = 0.01 b = -math.log((1-pi)/pi) nn.init.constant_(layer.bias, val=b) nn.init.normal_(layer.weight, std=0.01)
-
-
- loss计算
-
正负样本如何生成,分类和检测的loss计算,是模型收敛迭代的重头戏。
-
1. 生成预设anchor
-
2.生成训练正负样本
-
3. det与cls head loss计算
-
- 模型前向推理
-
1. 解码prediction生成bbox
-
2. nms去重框
-
- 模型效果评估
基于retinanet结构的detection训练推理分析
最新推荐文章于 2024-01-28 14:31:32 发布