TensorFlow 对象检测 api:使用预训练模型在训练中更改类数时的分类权重初始化
Posted
技术标签:
【中文标题】TensorFlow 对象检测 api:使用预训练模型在训练中更改类数时的分类权重初始化【英文标题】:TensorFlow object detection api: classification weights initialization when changing number of classes at training using pre-trained models 【发布时间】:2018-08-28 17:20:26 【问题描述】:我不仅想利用特征提取器预训练的权重,而且还想利用特征图层的分类器/定位预训练的权重,使用 TensorFlow 对象检测 API 来微调 TensorFlow 对象检测模型 (SSD)。当我的新模型与我用于微调检查点的预训练模型具有不同数量的类时,TensorFlow 对象检测 API 将如何处理分类权重张量?
当在 ML 对象检测模型(如 SSD)中微调预训练模型时,我不仅可以使用预训练权重初始化特征提取器权重,还可以初始化特征图的定位层权重和分类层权重,后者只选择预先训练的类权重,这样我就可以减少模型最初可以识别的类的数量(例如,从 90 个 MSCOCO 类到这 90 个类中的任何选择类,如仅汽车和行人等.)https://github.com/pierluigiferrari/ssd_keras/blob/master/weight_sampling_tutorial.ipynb 这就是在 keras 模型(即在 h5 文件中)中的完成方式,我也想在 Tensorflow 对象检测 API 中执行相同的操作。似乎在训练时我可以在配置 protobuf 文件中指定新模型将具有的类的数量,但是由于我是 API(和 tensorflow)的新手,所以我无法遵循源结构并了解如何在微调时处理该数字。我知道的大多数 SSD 模型只是忽略并初始化分类权重张量,以防预训练模型的类权重形状与新模型的分类权重形状不同,但我想保留必要的分类权重并对其进行训练。另外,我将如何在 API 结构中做到这一点? 谢谢!
【问题讨论】:
【参考方案1】:当我阅读代码时,我找到了负责的代码,如果新定义的模型和预训练模型之间的层形状匹配,它只会保留预训练模型的权重。所以如果我改变类的数量,分类器层的形状就会改变,并且不会保留预训练的权重。
https://github.com/tensorflow/models/blob/master/research/object_detection/utils/variables_helper.py#L133
【讨论】:
你好@Kazuya,“不保留预训练权重”是否还包括特征提取器预训练权重?非常感谢您提出这个问题,因为它也困扰着我!!! 嗨@willSapgreen,不,它不包括特征提取器预训练的权重。似乎当类数改变时,只有分类层的权重被初始化,而特征提取器和定位层的权重被保留,因为它们的形状不会根据类数而改变。 您好@Kazuya Hatta,感谢您的快速回复。我的另一个问题是在训练期间是否更新了分类层和特征提取器/定位层的权重?这就是我问这个问题的原因:ai.stackexchange.com/questions/6129/… @willSapgreen 是的,我认为它们已更新。关于您在 ai.stackexchange 中的问题,您是否将班级编号正确设置为 1,并正确制作了 tfrecord 文件?如果一切都按照文档完成并得到不合理的结果,另一种可能是您的数据没有正确注释 感谢您的反馈。我将仔细检查 tfrecord(从中提取图像数据)。另一个问题是根据您的经验,除了查看“总损失”和“mAP”之外,还有什么其他方法可以调试包的性能(例如检查分类层中的权重)?谢谢。以上是关于TensorFlow 对象检测 api:使用预训练模型在训练中更改类数时的分类权重初始化的主要内容,如果未能解决你的问题,请参考以下文章
Tensorflow 2 对象检测 API:Numpy 版本错误
Tensorflow 对象检测 API:TensorBoard 中损坏的训练图像
tensorflow利用预训练模型进行目标检测:预训练模型的使用