前言
在前端领域,目前不断地有 design2code 工具涌现。即给定视觉稿识别出里面的元素并将其转换成代码。它们底层技术都离不开深度学习中的「目标检测」。最近有幸接触到这块的内容,实践下来发现深度学习也并不那么的高深莫测,这里用一篇文章带大家快速入门目标检测技术。并提供一个 开箱即P . 7 @ E U l 6 d用 的目标检测框架。
「【划重点!!】l h u R ~ i目标检测通俗地来说就是识别出给定视图中的物体,并将其定位。」
准备
团队这边的目标检测是基于 tensorflow 提供的 object detection API 。整个训练的过程可以简要概括为训练集的准备和训练k J f。
训_ . Z $ X n m 0 T练集准备:
- 人工标注图片,并转成K + 2 w xml 格式
- 将 xml 转成 tf 能识别的x U X 2 } E X数据格式即 tfrecord
训练过程:
- 配置训练参数,这里需要配置目e J {标检测算法类型目标类别数量训练步长训y R $练部署训练集路径模型输出路径*以及可以基于前人训练好的模型微调
- 基于 slim 模块实现模型训练
过程
环境配置
我们需 v 3 M f } K要准备好 python 的环境。系统内置的 python 一般为 2.7.x ,而训练需要的版本为 3+ 。这里推荐使用 pyenv 进行 python 的版本控制与切换。
$ brew install pyenv
$ brew install pyenv-virtua6 f o g b vlenv
$ pye/ t {nv virtualenv 3.6.5 <your-project-name>
$ pyen9 / Q 8 J f g hv activate <your-project-name>
环境配置完成后,就可以着手开始我们的训练了。
训练集准备
首先我们需要准备 大量 的训练集,可- B g . } {以针对自己的需求手动标注。我们用的是 labelImg 这个 python 工具。
(PS:如果只是k s q - @ | i l #想体验下目标检测过程,可以从V A F / s网上下载已经标注好的训练集和测试集。
本文的测试范例用的是扑克牌训练集,来源于 github 上的大佬 >>> 仓库地址:https://github.com/EdjeElectronics/TT / 2 . g b H - ~e! v } onsorFlow-Objectn y 6-DO 9 Setection-API-Tutorial-Train-Multiple-Objects-Windows-10 。)
labelImg 安装使用具体参考文档。简要步R h v M x骤如下:
# 基于上步切换到python3环境
# 安装
$ pip install labelImg
# 启动
$ labelImg
手动[ b c ~ V S a X框选出目标,并储存为 xml 文件。
最后会得到 image 和对应的 xml(annotations) 两个目录。(建议分目录存储)
训练配置
tf object detection API 已经为我们准备了部分已经训练好的模型。 我们可以对基于它w r A . 7 1 @们做fine-tuning(微调)从R n @而来训练我们的模型 。
Tensorflow detection model z| w a _ hoo:https://github.com/tensorflow/models/blob/master/research/ob@ _ Oject_detection/g3doc/detection_mG o Zodel_zoo.mk $ = ^ L fd
这里包含了 SSD/Faster RCNN/RCNN 等目标检测常用算法,比较遗憾的是没有 Yolo 的。如果有一定深度学习基础的同学可以基于 tf 训K x m练自己的 Yolo 模型。
先看一下目录的基本结构
- resourc0 _ Y I 8 ~ /esM m l K:文件转换、? 0 s p训练、模型导出目标代码
- config:配置文件,包括labee ` pl_map 和 算法配置文件
- modelu S b:fine_tuning模型
- object_detection:tf ob3 3 Wject detection api
- slim:tf sS t & p % k W ilim目标代码
- train_assets:训练集
- train_data:训练: 9 & S h过程中输出的文件
1、O . t J ;将xml转成tfrecord
在使用 labelImg 标注后我们会得到p : n ; ? M image 和对应 xml 两份文件,要进行^ q f Q训练还需要将其转换成 tf 能识别的 tfrecord 格式文件) 1 ; 4 e 9 x 4 h。
tfi e { f object detection 已经提供了相应的文件转换 API 。
tf/models中目标代y & A o ! B i !码路径 >>> object_detection/dataset_toolsw o g ~ s B =/create_pascal_tf_record.py
上面提供的框架中已经将其处理好了
# 根目录下调用
$ python resources/convert.py
这时候就能得到 train.record 文件。
2k 4 u t j J (、将slim路径添加到PATH中
这一步框架# K @ . (已经处理了,可以忽略,了解即可。
$ export PYTHONPATH=$PYTHONPATH:V ` N r b\'pk # % ^ % [wd\':\'pwd\E Z h v y { H O j'/slim
3、模型选用
模型指的是用以fine-tuning的7 s & & ~ ^ I ] K由前人训练好的模型。可以在上面的 model zoo 选择下载。这里采用的是 SSD 。上图 model 目录。
4、文件配置
训练前我们需要配置检测目标的类别,在 config/label_map 中定义
# config/label_map.pi . 8 ] A P | btxt
item {
id: 1
name: \'nine\y t y'
}
item {
id: 2
name: \'ten\'
}
...more
同时需要配置算法文件(下载 fine_tuning 模型后对其xxx.config文件进行参数调整)重点配置如下
model {
ssd {
num_classes: 6a 1 L : W | r #用以目标| S . . S ~ r检测的类别数量
box_coder {...}
fi[ F N = One_tune_checkpoint: \"\" #本地& A J 0 ]fine_tuning模型路径
nub X H m C 9 0 mm_steps: 10000 #训练步长
}
train_input_reader: {
tf_record_input_reader {
input_path: \"\" #tfrecord文件路径
}
label_map_path: \"\" #本地label_map路径
}
完成配置后,在根目录中调用以下命令
$ python resources/train.py
我们这o ^ u 6 s边使用的训练 api 是 tfC G , ^/model/object$ R D J Z 9_detection/legacy/train.py , tf/model/object_detection/mD q M w 9 % K T Iodel_main 也可以提供相应的功能,但是在使用 cpu 训练下会报错,于是换成了 legacy/train 。
如果看到以下输出就说明已经成功进行模型训练了。
这里的step指的是当前训练的步数,loss指当前函数损失值,loss越小x q 9,B f # c C ! H说明模型越接近准确。
同时可以使用 tf 提供的命令行工具 tensorboard 实时查看训练结果。
$ tensorboard --logdirZ p - ( M A Q Z=train_data/ssd
这里可以看到, losses 波动特别大,显然这Z ] l 7 .个模型训练得不是特别好。这里等后面模型调优我们再来讲W ( g [ F。
模% ] : O 1型导出
如果看到如下输出,说明模型已经训练完成。
我们此时需要对训练s G Q U完成的数据进行模型导出。 tf object detea s dction 也提供了相应的 api ,具体文件路径是 tf/model/object` t ` L o U_detection/export_inference_graph.py 。
使用提供的框架可以直接调用
$ python resources/export.py
正常的话会得5 d } :到如下结构的文件,其中 frozn_inX P i k w _ference_graph.pb 就是训练所得的模型了。
预测
在得到了训练好的模型之后,我们就能用m r x它对我们的0 , l m E s X视图进行目标检测了。
预测这边 tf 提供的目标代码是 tf/model/object_detecti? ~ J d 5 +on/objectm L { u e b_detection_tutorial.py| r r可以自行参考,根据自己需求改写。^ u v & * . r H
也可以在框架代码根目录下执y N N * H e , * 行
$ python resources/detection.py
完成后会在 train_detections/ssd 目录下生成被标记好的预测图。
评估
单看上图,我们的预测结果还是准确的,那对于目标物体模糊或S D u者被_ { [ & ~ B s遮挡的情况呢?我们单纯跑一张图预测的话其实还不足以评估模型的准确性,所以 tf 也提供了相应模型评估的函数。
具体可以参考 tf/model/object_detey ) v b & 3ction/legacy/eval
也可以在框架代码 valid_assets/ 下配置测试集,包括 images 和对应的 xml 。完成之后需要:
- 将 xml 转成 tfrecord
- 配置算法文件 xxx.config
evj @ N h ~ 3 0al_confz f : M _ig: {
num_examples: 67 # 测试集数量
# Note: The below line limits the evaluation process to 10 evaluation= u W a p ] k fs.
# Remove the below line to evaluate indefinitely.
max_evals: 1 # 评估次数,1* [ P次即可
}
eval_input_reader: {
tf_record_ino _ U I !put_reader {
input_path: \"\" # valid tfrecord文件路径
}
label_map_path: \"\" # label_map路径
shuffle: false
num_readers: 1
}
配置完成后在根目录下依次执行
$ python resources/co& z : L _ & R _ ~nvert.py valid
$1 l ( D I c * python resources/eval.py
控制台会输出该模型下每个类7 $ F别的检测准确率。
微调
如果训练出的模型准确率不是很高,我们需要对配置进行微u V |调。这里主要可以通C g P & ) = 2过改变步长、算法、 batch_size 等方式。
算法
目标检测I z I C L ` S的明星算法是 SSD/Faster RCNN/YOLO
步长
步长指训练迭代的总长度,可以通过 tensorboard 实时观测。Y R步长设置过大可能会带来过7 2 ^ % w拟合的问题,设置不够则会是欠拟合。
batch_r } | csize
batch_size 指一次迭代使用的样本数量。如果训练集足够小,可以使用全数据集。而对于大数据集,可以使用一个适中的 batch_size 或者走向另一个极端就是每次只, 0 Y # 3 9 O训练一个样本,即 batchT e (_Size = 1。
对于 ssd 算法来说,使用小的 batcQ ^ Jh_size 貌似会造成 losses 波动大的情况而迟迟达不到一个稳定的 losses 值。