数据标注及格式转换之后,就可以开始模型训练,不过要先对其他的一些必备文件进行说明。
1、label_map文件
此文件是记录数据集中物体类别及其编号的,用于后面的检测模型中的classification部分,可以参考raccoon检测模型的label_map文件,如果类别比较多,就继续往后面加 item 就好。
item {
id: 1
name: 'raccoon'
}
2、finetune checkpoint
Tensorflow提供了一些预训练的模型(Model Zoo),供大家下载下来,之后进行迁移学习,即训练自己的模型时使用预训练模型来进行参数初始化。比如下载 ssd_mobilenet_v1_coco,解压缩之后目录如下:
这里model.ckpt三个文件是之后要在config文件设置时调用的,提前说一下,在接下来要说的config文件设置部分,config文件可以是这里的pipeline.config文件,不一定要去官网提供的config文件集中下载。
3、模型训练的配置文件 —— Config文件
模型训练所需要调整的一些关键参数放在config文件中,代码运行时会自己从config文件中读取相关的参数,之后进行模型训练。Tensorflow github给出了很多的config文件。config文件的整体结构如下:
model { *** //网络结构及相关超参数的设置
}
train_config: {*** //反向传播的方法选择及相关参数设置
}
train_input_reader: {*** //训练集数据的地址设置
}
eval_config: {*** //模型测试时的参数设置
}
eval_input_reader: {*** //测试集数据的地址设置
}
如果你对你要使用的深度学习模型不熟悉,比如ssd的结构,fast rcnn的结构不熟悉,先不要对config文件进行大量调参。但是有几项是必须要更改的, 下面以ssd_mobilenet_v1_pets.config为例进行说明:
(1) model/ssd 中的 num_classes
num_classes: 37
// 37改为自己的数据集中物体的类别数,比如数据集中只标注了猫,那就将37改为1.
(2) train_input_reader 和 eval_input_reader
train_input_reader: {
tf_record_input_reader {
input_path: "PATH_TO_BE_CONFIGURED_TFRECORD_FILE"
// "PATH_TO_BE_CONFIGURED_TFRECORD_FILE"替换为训练集生成的tfrecord文件的路径
}
label_map_path: "PATH_TO_BE_CONFIGURED_LABEL_MAP_PBTXT"
//"PATH_TO_BE_CONFIGURED_LABEL_MAP_PBTXT"替换为物体类别的label_map文件的路径,
}
eval_input_reader: {
tf_record_input_reader {
input_path: "PATH_TO_BE_CONFIGURED_TFRECORD_TEST"
//"PATH_TO_BE_CONFIGURED_TFRECORD_TEST"替换为测试集生成的tfrecord文件的路径
}
label_map_path: "PATH_TO_BE_CONFIGURED_LABEL_MAP_PBTXT"
// 这里的"PATH_TO_BE_CONFIGURED_LABEL_MAP_PBTXT" 和前面
// 的"PATH_TO_BE_CONFIGURED_LABEL_MAP_PBTXT"替换一样
shuffle: false
num_readers: 1
# eval_epochs: 10 在最新的tensorflow model中训练的话,这一条要去掉,否则会出现OutOfRange Error,
# 这是因为tf.estimator.train_and_evaluate是为了分布式而设计的,
# 而现在的训练终止条件只接受max_steps,所以不要写eval_epochs,
# 这个的意思是在训练多少epochs后停止,与max_steps冲突。
}
(3)如果你想在跑代码的时候每隔30分钟保存一次模型,那就对train_config进行如下设置:
train_config: {
keep_checkpoint_every_n_hours:0.5 // 添加这一行,其他时间可以自行调整
batch_size: 24
optimizer {
rms_prop_optimizer: {
learning_rate: {
exponential_decay_learning_rate {
initial_learning_rate: 0.004
decay_steps: 800720
decay_factor: 0.95
}
}
momentum_optimizer_value: 0.9
decay: 0.9
epsilon: 1.0
}
}
如果你还想设置最多保存多少个模型文件,还可以进一步修改代码部分。如果你git下来的models版本不太新,在object detection文件中应该有trainer.py文件,修改该文件的第361行的max_to_keep=1000,则在后期训练模型时,会自动保存最新的1000个模型。如果git的是最新的models版本,我还没来及找到怎么调整这个参数,大家可以自行挖代码。
(4)finetune
fine_tune_checkpoint: "PATH_TO_BE_CONFIGURED/model.ckpt"
// "PATH_TO_BE_CONFIGURED/model.ckpt"替换为下载到的预训练模型的地址,最后就是写
//model.ckpt,具体的还有meta,index,data什么的,这些都不用写,写model.ckpt就可以
// 解析到具体的三个文件了。
from_detection_checkpoint: true
// 如果不想用迁移学习,也就是不用预训练的模型进行参数初始化,这里的true改为false即可.
(5)此配置文件还包含数据增强的手段
详细数据增强可参见Preprocessor.proto,或者此处的讨论
4、接下来就可以跑代码了,在models/research 目录下运行如下命令:
python object_detection/train.py --logtostderr
--pipeline_config_path="自己填自己的config文件路径,类似D:/dataset/pipeline.config"
--train_dir="自己填自己想将tf跑出来的模型存储在哪里比如D:/dataset/OutModel"
如果你git的tensorflow models版本比较新,可能需要如下代码:
python object_detection/model_main.py --logtostderr
--pipeline_config_path="自己填自己的config文件路径,类似D:/dataset/pipeline.config"
--train_dir="自己填自己想将tf跑出来的模型存储在哪里比如D:/dataset/OutModel"
其实差不多。如果你对 --logtostderr 感兴趣,可以参考我在stack overflow的提问,如果你真对此有疑问,说明你和我一样完全不懂linux,不过这都不重要。
之后在train_dir中就可以看到很多文件,大概是下图的样子:
5、边训练边测试 eval
由于边训练,会不断产生训练输出的模型,所以可以基于此来看一下模型在测试集上的表现,具体是运行如下代码:
python object_detection/eval.py --logtostderr
--pipeline_config_path="自己填自己的config文件路径,需要和train时的设置相同"
--checkpoint_dir="自己填自己想将tf跑出来的模型存储在哪里了,其实就是train时的train_dir"
--eval_dir="自己填自己想将tf跑出来的测试结果存储在哪里比如D:/dataset/evalDir"
eval_dir中的文件格式大概是这样的:
还可以继续在另一个终端中运行如下命令来可视化tensorflow训练的模型在测试集上的表现:
tensorboard --logdir "自己写eval_dir的地址" --port=8008
后面的–port=8008是自定义网络端口的,这样你就可以打开在不同端口打开不同的tensorboard视图。接着在浏览器中打开网址:localhost:8008即可看到如下界面。
Scalar部分是一些损失值和准确率的可视化,注意左上角的 Show data download links,点开之后就可以下载损失值和准确率的数据了,这里不再给出过多解释。
Image部分展示的在测试集图片上的画框结果,而且支持同一张图片上顺序模型的输出结果的查看,不再展示,大家自行跑代码看吧。
Graph部分是整个网络的模型结构,eval时的graph比较好看,train部分产生的Graph太分散。
其他的按钮大家自己调着玩一下。
6、ckpt文件转化为frozen_graph
由上面的图可以看出,tensorflow训练得到的模型model.ckpt有三个文件:.meta, .index, .data.
大概来讲,.meta 文件是网络的图结构,.index是一个表结构,存储tensor名称及其对应data的存储路径(貌似是这样的), .data是网络中的变量的值。具体参见此博客。其他的一些介绍的资源:
Tensorflow学习笔记-模型保存与加载
Tensorflow加载预训练模型和保存模型
但是我们这里要说的是模型的固化,就是将上面的三个文件搞成一个文件,freeze_graph,也就是将模型固化,具体讲就是将训练数据和模型固化成pb文件。可以参考以下资料
TensorFlow: How to freeze a model and serve it with a python API
tensorflow将训练好的模型freeze,即将权重固化到图里面,并使用该模型进行预测
How to freeze a graph in Tensorflow
官方代码
具体操作是运行如下代码:
python object_detection/export_inference_graph.py
--input_type image_tensor
--pipeline_config_path "你的config文件的路径"
--trained_checkpoint_prefix
"你想转化的model.ckpt文件路径,比如D:/trainDir/model.ckpt-31626"
--output_directory "你想把转化后的模型存到哪里?比如D:/train_pb"
之后,会产生如下文件,其中的frozen_inference_graph.pb就是转化之后的模型:
7、模型应用
参考此文件,注意修改labels和ckpt文件路径。或者参考这个说明最后模型应用的代码。