我有一个关于微调和迁移学习的一般性问题,这个问题是在我试图弄清楚如何让YOLO检测我的自定义对象(手)时产生的。
我为可能包含大量错误信息的长文道歉。如果有人有耐心阅读并帮助我解除困惑,我将不胜感激。
经过大量的谷歌搜索,我了解到许多人认为微调是迁移学习的一个子类,而其他人则认为它们是训练模型的两种不同方法。同时,人们区分了仅在自定义数据集上重新训练模型的最后一个分类器层与重新训练模型的其他层(甚至可能添加一个全新的分类器而不是重新训练?)。这两种方法都使用预训练模型。
我最后的困惑在这里:我按照这些指示:https://github.com/thtrieu/darkflow 使用darkflow训练tiny yolo,使用命令:
# 从yolo-tiny初始化yolo-new,然后在100%的GPU上训练网络:flow --model cfg/yolo-new.cfg --load bin/tiny-yolo.weights --train --gpu 1.0
但这里发生了什么?我猜我只重新训练了分类器,因为指示说要在配置文件的最后一层更改类别数量。但另一方面,也需要更改倒数第二层(一个卷积层)的滤波器数量。
最后,指示提供了一个替代训练的例子:# 完全初始化yolo-new并使用ADAM优化器训练它:flow --model cfg/yolo-new.cfg --train --trainer adam
我完全不明白这与迁移学习的不同方式有何关系。
回答:
如果你使用的是AlexeyAB的darknet仓库(不是darkflow),他建议通过在配置文件中设置此参数来进行微调而不是迁移学习:stopbackward=1
。
然后输入./darknet partial yourConfigFile.cfg yourWeightsFile.weights outPutName.LastLayer# LastLayer#
例如:
./darknet partial cfg/yolov3.cfg yolov3.weights yolov3.conv.81 81
它将创建yolov3.conv.81
并冻结下层,然后你可以使用权重文件yolov3.conv.81
进行训练,而不是原来的darknet53.conv.74
。
参考:https://github.com/AlexeyAB/darknet#how-to-improve-object-detection,https://groups.google.com/forum/#!topic/darknet/mKkQrjuLPDU