首先贴上开源地址:
https://aistudio.baidu.com/aistudio/projectdetail/852413
复现总结: 1.最初复现时需要突破的是模型的转换,从torch到paddle,模型重定义,但到最后,却发现这是最简单的部分。
2.想要训得快,训得好,那必须还得上预训练模型,从google drive 下载下来torch 版本,剔除掉k400得fc尾巴,接上新尾巴。然后进行模型的转换。果不其然,原来训很多个epoch训练集都无法达到0.5精度,用上转换后的预训练模型后,第一个epoch,训练集的acc就可以直线上升至0.7-0.8,loss也会很快下降到1.测试集第一次一般是50-70的准确率左右
与此同时,torch版本调通训出来得精度还是蛮高的,想要把这版模型转换成paddle模型,fc层需要转置操作,但是转换后eval的结果却出乎意料的低。这部分还是要再分析看看是什么导致的,理论上与训练模型的转换因为替换掉了尾巴,所以不存在fc转置带来的影响,而自己训好的模型虽然精度可达92.9,但是由于fc对齐的问题,导致转换不过来,就很懊恼~。
3.训练部分的代码包含的trick最多,也最难,下面我会把我找到trick和没有办法修改的trick列举出来。
4.torch训练总结,一开始我都是以paddle去做单卡训练的,后面我发现精度基本卡在86左右就已经极限了,与论文gap很大,所以我就开始把torch源码搞出来,去做验证。
通过观察torch版本的训练log发现,训练的trick起到了重要的作用,在模型在0,001的lr下能达到的极限就是85-87左右,当模型5次饱和后,修改lr,模型精度两个
epoch后出现了3个点以上的提升87-90(16F),因此这也促使我进一步去对齐训练中所用的tricks。可惜的是有部分tricks貌似不能在pd上实现。因此精度很难对齐也是正常的了。
5.难例挖掘,这部分已经做了分析,但是难例出现不规律。因此目前还没有针对性进行调优。
6.转换模型精度从float64-float32可能存在掉点。
Tricks 部分:
这里我主要介绍一下本文用到的训练技巧:
1.新的fc层初始化用xavier初始化
2.clip gradient防止梯度爆炸
3.optimizer设置采用sgd,momentum,nesterov,weight decay=5e-4添加正则化
4.梯度更新时,freeze 除了第一层以外的所有Bn weight和 bias
5.梯度更新时,将所有的weight lr mult设置为1(跟随lr),bias lr mult设置为2(2倍lr),这部分也是很迷,难道bias步子迈大了不容易扯蛋?
6.模型饱和精度时更新lr,当模型eval精度5次没有比最高精度高时,lr缩减10倍,这也是torch版本模型精度跃升的关键(torch上16F版本!然而我也这么做了可是精度太大跃升。
7.单次loss/4,scale down loss,平均四次做一次opt.minize(),这一次是minimize是四次总和。
没有实现的tricks:(遗留问题)
1.weight decay 的 decay mult weight设置为1,bias设置为2.可惜我在paddle 的opt类中没有找到这个变量
能找到的就这么多了。可能还有,但是时间有限只能做到这么多了。
in the end
这次复现对我意义重大,让我学到了很多,最主要的是技巧方面,当我看到原本基础训练无trick与用训练trick带来的精度提升,我真的感叹自己需要学的还是太多了。
这次收获良多。真的非常感谢baidu!
btw,如果有同学复现了高精度但是没有用这些train的tricks,那着实有点太幸运了。我训了得有60组paddle模型一直突破不了90.太惨辣
BTW
楼主求一波互粉
我在AI Studio上获得白银等级,点亮1个徽章,来互关呀~ https://aistudio.baidu.com/aistudio/personalcenter/thirdview/228138
我来围观了~
赞!
太赞了!
厉害呀!而且是在飞桨下实现的!
谢谢,有帮到你就好~
原来现在的模型还是需要逐层训练trick啊
请问 "data/classInd.txt" "data/trainlist01.txt" 是不是都没有放进项目里啊?
我手工生成了classInd.txt文件,trainlist是不是复现要求的一个数据表? 大约是总数据的多少? 我只是跑一下这个项目,自己划分几千个数据就ok了吧?
这篇训练的trick非常多,锁了bn层的更新和改变了weight 和bias的更新速度。不知道是什么理论依据
这篇训练的trick非常多,锁了bn层的更新和改变了weight 和bias的更新速度。不知道是什么理论依据
我看下,应该有的,如果没有的话你可以上git相对应的代码去下载这部分,很小很好下载的。train 和split 是9537
3783这么多
trainlist是对应train_split01.txt生成的一个包含对应pikcle的list。把UCF数据添加一下,解压然后根据notebook生成这个列表即可训练了
赞b( ̄▽ ̄)d
大赞!
只能先试试有什么用处,理论再补充了
推测锁定bn参数的目的会不会是保持更多的原数据分布信息?不能添加过多噪声
渐冻式训练是为了保持稳定吧。还是得有理论分析才好说
个人认为:作者冻结bn可能是因为作者认为预训练的k400模型已经训得比较完全了,对数据得分布认知已经体现在了bn得权重上,因此不需要调整bn,但是这个是不是需要建立在k400数据和ucf101数据的mean和std是一致得情况
我理解是,使用预训练模型最好是微调。充分利用网络前面各层训练好的特征提取器。大部分需要重新训练的是靠近输出端的分类网络层吧。所以权值是渐冻的
理解到位,但是代码细节是仅冻结网络除了输入和res3d部分的bn的weight及bias,没有冻结神经元的weight 和bias,并且把神经元的bias学习率调整到了基础学习率的2倍。