training fpnssd

以epoch为单位,计算整个epoch的loss函数和时间。batch size=32或者64,现在程序中设置的batch size=8,每进行一个step需要0.30s,如果训练数据集中包含9600张图片,batch size=32,一个epoch中包含300个step,1秒进行一次step,则300秒一个epoch,5min一个epoch,一小时12个epoch,一般训练过程会跑200-300个epoch,则24小时之后会跑到288个epoch。

训练网络模型常用两种optimizer/学习方法:

(1)Adam:学习率   1e-3

(2)带有momentum项的SGD:通常要对超参数进行调节,如learning_rate,经验值如下:①epoch=0~120/150,learning_rate=0.1,②epoch=120~160,learning_rate=0.01, ③epoch=160~200,learning_rate=0.001

在最开始训练的时候,需要采用大的学习率,只要更新后的权值参数不是NaN(not a number)就可以无限增大学习率,就是说,较大的学习率会使得模型参数更新后的数值超出了float类型数据的表示范围,就会报 not a number。对于softmax输出的类别置信度,很有可能输出的数值会特别小,这时候求classification_loss时,很可能会出现超出float浮点数表示的范围,如-numpy.log(0.0000000001),则会导致无法继续训练,这时候通常会加入一个smooth项,如-numpy.log(0.0000000001+0.00001)。出现这种问题(not a number)解决办法通常是:①将学习率调小②看classification loss中是否有平滑项。

 

loss函数在接近局部最优值附近再迭代训练,可能会发生震荡(比如在epoch=150到epoch=200之间loss函数都在某个值附近震荡)。这个时候应减小学习率(乘以0.1),可以使在接近最优值附近的loss迅速下降。

loss=classification_loss+localization_loss

要对loss函数进行大致计算,知道最开始的loss值是多大,达到一定的训练准确率之后的loss值又是多大。比如,最开始进行训练时,分类网络可能是对21个类别进行随机猜测,将当前样本分类成每个类别(包括是正确的类别)的概率是1/21=0.05,则平均的分类损失是 -numpy.log(0.05)=2.99,而如果是希望达到90.0%的准确率,则loss=-numpy.log(0.90)=0.105,

localization_loss=

在default boxes(没有调整之前的)中根据IOU值找到的一些正样本肯定都是与ground truth很近的样本,则四个坐标的loss都接近于0。

计算出编码之后的ground truth值后,再与FPNSSD模型的输出值相比较计算出差值,再对差值取smooth L1,其实对于localization loss,误差差值是0.1就已经是很大的误差了,因为正样本的default boxes就在ground truth boxes附近,因为差值的分母处除以了宽度(对于坐标x),则说明default boxes的x坐标(经过网络预测后的输出)距离ground truth 的x坐标很远。可以假设初始的坐标损失较大,但是可能也就在0.1量级,再进行smoothL1计算,得到0.01,则loss函数值并不会太大。

实际上并不是loss函数越小,模型的测试准确率/评估准确率越高,而且在实验过程中,很多情况下,找到的使得测试准确率较小的模型参数并不是使loss函数最小的模型,这可能是由于训练数据集中的图片数量过少,发生了过拟合overfit。

要会直接根据loss函数的数值判断当前训练模型性能的好坏。loss函数的数值则需要根据loss的公式定义来看,loss的定义决定了最优的loss值大概在什么数值范围。

如果的值设定的很大,比如100,则loss函数的最优值可能不需要达到0.001/0.01的数量级就已经是最优的了。

对于当前的loss值所得到的网络模型参数进行评估,计算测试的mAP,

pytorch中的可视化工具:tensorboard,或打印print loss函数值进行调试,

 

用pretrained model在FPNSSD512上训练时,开始的时候loss=12,cls_loss=3(accuracy=1/21=0.05),loc_loss=12-3=9。模型的分类输出是经过softmax函数作用后,故分类输出的值域在(0,1),但是localization却只是经过卷积之后的输出,输出至于范围未知,所以可能会产生较大的loss值。

 

test/evaluate评估时间会比训练时间短很多,这是因为train阶段有前向传播(一次卷积计算)和反向传播(两次卷积计算),而评估阶段只有前向传播,没有反向传播和梯度计算,训练时间0.3s,评估时间0.1s,则可能是差2倍的卷积时间。

batch size的大小和学习率的调整都会对于网络模型的loss函数是否收敛有影响:

(1)batch size:并不是越大越好,如果每个step中是使用的整个训练数据集中的所有训练样本,即full batch SGD,则训练效果并不一定会比mini-batch SGD好,因为在训练过程中需要对训练数据引入一定的随机性。batch size=1则也会使学习的信息过少,并不准确。比如训练数据集合中共有9,000张图片,batch size=30,在每一次epoch时,先将这9000张图片进行随机打乱,然后每个step中按顺序取出30张图片进行训练,下一次的epoch时,还要对这9000张训练图片再随机打乱一次,每个step中取出batch size张图片进行训练, 故而每进行一次epoch前,都要对训练数据集进行随机重排。对于物体检测的应用,batch size 一般不会取值太小,batch size=32/64,但是对于全卷积网络的应用如语义分割,batch size的取值可能只能取1,这是因为,全卷积网络通常是网络层次很深且输出图像分辨率与输入图像相等,无法降低图像的分辨率,故而训练这样的网络非常消耗显存,如果取batch size=2,很有可能就run out of memory,batch size的取值很大程度上取决于显卡的显存,这个时候为了增大batch size,最好的方法就是使用多个GPU并行,如果一张显卡只能容纳batch size=2,则如果有8张显卡,就可以将batch size设置成16。

对于物体检测问题,如果一个GPU能容纳16张图片,有4块GPU,则可以将batch size设置成64。

当batch size 设置成8后,如果采用多个GPU并行,则会将8张图片分成两块4张图片(即使4张图片远远没能占满一个GPU的显存)。每块GPU前向传播、训练,计算出4张图片的loss 关于当前模型参数的loss之后,再计算梯度,第二块GPU将所计算的梯度传回第一块GPU,这将会导致第一块GPU的显存占用率比第二块GPU更高(约400M),因为第一块GPU需要对第二块GPU传回的梯度进行平均,平均完之后,更新模型参数,再将更新后的模型参数分发给第二块GPU(数据分发),两个GPU之间使用了高速连接设备,所以数据传输速度很快。要注意的是,多个GPU并行的情况下,多个GPU实现的是同一个batch size中的图像数据的训练,因为多个GPU在同一时间的模型参数是相同的(共享模型参数),如果认为是每个GPU上运行一个batch size的数据,训练过程中,是需要当前batch size训练完成更新模型参数后,才能进行下一个batch size的训练,则这样另一块GPU需要空闲等待当前GPU训练完成并将模型参数传到这个GPU,才能开始这个batch size的训练,这样相当于没有并行,所以多个GPU之间并行一定是对于同一个batch size的数据进行平均分配。

保存模型或者大型数据集到  data    ssddata文件夹下,不要再保存到home目录下。

 

task:

1. 打印损失函数信息的时候最好分别打印出classification_loss和localization_loss.观察训练到了什么程度。如果对于测试数据集,classification_loss=0.1,则说明mean accuracy=90%,这对于模型而言是远远不够的,因为它是密集估计且使用了hard example mining策略,故而需要mean accuracy=95%,即loss=0.04左右才行

2.learning rate调节的经验值   

看优秀的代码怎么修改学习率     模仿优秀风格的代码 多看代码

①epoch=0~120/150,learning_rate=0.1,②epoch=120~160,learning_rate=0.01, ③epoch=160~200,learning_rate=0.001

在第120个epoch后开始评估模型性能,打印出loss函数,选择几个较小的loss函数所对应的模型,对测试数据集进行评估,可视化一些包围框

模型训练的最好效果必然是在②③阶段出来,不会再①中出来

把网络和测试数据集作为输入,对模型进行评估,torchcv/evaluations/voc_eval.py

loss小于某个阈值(如0.2)之后,调用voc_eval.py对模型进行评估

如果评估的速度很快,就可以把评估模块集成到train.py

需要保留接近10种模型参数,不能只保存一个loss最小的模型参数

经常出现这种情况,不是最小的loss使得测试准确率最高

3.把batch size的数值调大,重新训练     batch size=20

4.把网络模型的结构打印出来

5.跑通ship detection,读取数据代码

6.重现torchcv 中的fpn性能 80.%精确重现准确率 (精确性能)

 

pytorch中集成了tensorflow中的tensorboard,在代码中加入一些变量,可以实现可视化(用图形展示);

杀死程序     

ps -ef|grep python  打印当前所有的正在运行的python程序的进程号

找到想要杀死的python程序进程号,手动删除

 

在后台运行程序,(关上电脑或者断开网络连接,程序可能中断)

python 1.py &

 

 

FPNSSD512-resnet50实践经验总结;

1.使用SGD学习方法,初始学习率不能设置成太大,我开始设置成0.1,经过7.8个batch的参数更新之后,计算得到的loc_loss和cls_loss都特别大(nan,inf),导致训练崩溃,这时候要调小出事的学习率,之前跑过将初始学习率设置成0.001的训练,发现训练过程十分缓慢,每个batch的损失函数变化很小,因此将初始学习率设置成0.01,注意模型的参数是每个batch size更新一次,不是每个epoch更新一次

2.关于初始的损失函数数值的解释:loc_loss:0.08,cls_loss=12,因为正样本都是与ground truthIOU值很大的anchor boxes,故而经过编码之后计算出的回归损失会很小,(localization loss只对正样本进行计算)接近于0,而分类损失是对于正样本以及hard negative mining策略得到的负样本进行计算的,程序中采用的是将困难样本挖掘的数量是正样本数量的3倍,开始可以认为分类器是对于voc数据集的21个类别进行随机猜测,正确类别的概率也是1/21=0.05,-numpy.log(0.05)=2.99,用N表示正样本数量,负样本数量为3N,classification_loss=(N*2.99+3N*2.99)/N=4*2.99=12

3.batch size的值可以尽量设置大,只要程序不崩溃,而num_worker表示的是(在使用一块或者多块GPU的情况下)多块GPU加载数据使用的总进程数,num_worker的经验值一般设置8-12,如果设置的太大会引起进程堵塞。batch size的数值并不一定要设置成2的整数次幂。

 

训练网络模型的目的在于使得模型的测试准确率提高,而不是使loss函数很小,而且loss函数换一个公式定义后,它的数值又会不一样,所以可以在训练的epoch过程中,训练到达一定的程度后,每隔固定的epoch数量,就计算模型参数在测试数据集上的准确率,打印出来,从而判断模型的测试准确率,因为并不一定是loss值越小准确率越高的。

 

 

 

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值