入门培训2:算法训练说明



  • 算法训练说明文档


    目录

    在开始本教程前,我们假设用户已阅读鲲云雨人V3板卡使用指南,并已熟悉开发套件的基本原理和操作方式。

    在本教程中,我们将介绍算法的基础知识,并展示如何使用用户自己的数据训练一个目标检测算法。用户所得的模型将作为下一步Plumber使用指南的输入,使用编译器对于算法进行解析、转化和硬件加速。

    目标检测是机器学习领域里的经典问题,目标是对于图片中的物体进行定位及分类,其中物体的位置通过提供一个矩形框的左上角和右下角坐标返回。以人脸识别为例,输入一张图片,目标检测的结果为图中所有人脸的位置,和人脸的类别(类别为1,只需要区别人脸1和非人脸0)。

    检测完成后的实际效果如下:
    face.png

    深度学习算法在目标检测领域已有比较成熟的应用,主要框架分为One-Shot DetectorTwo-Shot Detector两种。One-Shot相对于Two-Shot在基本保持相同精度的情况下,速度大幅提升,更加实用于工业级应用。
    本教程中从采用经典的Single-Shot Multibox Detector(SSD),具体原理可以参照:
    https://arxiv.org/abs/1512.02325。

    本教程代码基于github的第三方实现进行了一些修改,更多的说明请参照:
    https://github.com/balancap/SSD-Tensorflow

    0. 算法训练提前准备:

    1. 包含GPU的主机或服务器
      深度学习算法通常需要较长时间(几个小时或者几天)进行学习,实用CPU进行算法训练需要花费更长的时间,建议用户使用GPU。
    2. 训练数据及标注
      数据是深度学习的基础,我们通常将深度学习视为一个黑盒算法,深度学习网络通过不断尝试去拟合输入数据来实现模型训练的目标。对于物体检测问题,用户需要提供被检测物体在图中的位置和对应的类别。

    算法训练需要在CPU或者GPU中进行安装GPU请使用GPU版本:

    sudo docker run --runtime=nvidia --name plumber -dti brucvv/plumber
    

    无GPU安装使用CPU版本:

    sudo docker run --name plumber -dti brucvv/plumber:cpu_1.2
    

    1. 数据准备

    本步骤将用户输入的原始图像及标注,转化为Tensorflow框架使用的record数据格式。

    示例
    在路径/app/detection下运行

    ./script/1_run_convert.sh
    

    参数示例

    --dataset_name=数据库名 
    --dataset_dir=训练数据根目录 
    --output_dir=转换后数据存储路径 
    --shuffle=True(是否打乱数据顺序,默认打乱)
    

    运行完成后在目标目录生成三个文件,xxx为数据库名dataset_name

    • xxx.record
    • xxx.INFO
    • xxx.json三个文件

    本代码中假设数据和数据标注文件(img_label.txt)在同一文件夹下(示例中数据库文件夹为/app/imagetxt/,其中包含19张图像,标注了图像中的人脸位置)。

    数据标注文件格式如下:

    图像名  \
    图像中物体数量  \
    物体1:物体1对应的label_id  \
    2(预定义字段)  \
    左上角x坐标  y坐标 \
    右下角x坐标 y坐标  \
    ……
    物体N:物体N对应的label_id  \
    2(预定义字段)  \
    左上角x坐标  y坐标 \
    右下角x坐标 y坐标  \
    

    其中x为图像宽方向,y为图像高方向。

    示例

    1530697831_1.jpg 2 face:1 2 414.0 207.0 536.0 304.0 face:1 2 234.0 207.0 398.0 390.0 
    

    用户可自己定义数据类型,并编写对应的数据转换代码。

    注意: 数据标注文件img_label.txt中仅标注了一张人脸位置,因此训练出来的算法将只检测图像中的一张人脸。用户可以将此作为练习,尝试将新的人脸位置添加到标注文件中,以实现同一张图片中多张人脸的检测功能。

    2. 模型训练

    使用Tensorflow框架进行模型训练。

    示例
    在路径/app/detection下运行

    ./script/2_run_training.sh
    

    参数列表

    --train_dir = 训练所得模型的存储目录
    --dataset_name = 数据库名 (与步骤1数据准备中一致)
    --dataset_dir = 训练数据根目录 (与步骤1数据准备中一致)
    --model_name = 模型结构定义(在nets中对应添加,并在nets_factory中注册)
    --save­_summaries_secs = summary存储间隔秒数
    --save_interval_secs = 模型snapshot存储间隔描述
    --batch_size = 根据实际GPU现存调整,如出现CUDA_OUT_OF_MEMORY减小batch_size
    

    该步骤中最重要的步骤为网络模型的定义model_name, 模型定义文件处于nets文件夹中。

    注意

    • 一般来讲数据越多,标记错误越少,模型训练得到的效果越好。示例中只提供19张图像用于训练,仅仅用来测试总体流程,测试时请使用训练的图片来验证正确性。
    • 训练过程需要较长时间,通常为几个小时。可通过观察训练的loss和train_dir中是否存储了对应的ckpt文件为参照,决定是否执行后续步骤。

    下面给出一个实际训练中的例子

    INFO:tensorflow:global_step/sec: 0
    INFO:tensorflow:global step 10: loss = 83.2801 (0.059 sec/step)
    INFO:tensorflow:Recording summary at step 14.
    INFO:tensorflow:global step 20: loss = 70.6828 (0.195 sec/step)
    INFO:tensorflow:global step 30: loss = 72.3244 (0.215 sec/step)
    INFO:tensorflow:global step 40: loss = 69.1671 (0.239 sec/step)
    ... ...
    INFO:tensorflow:global step 5010: loss = 0.1913 (0.245 sec/step)
    INFO:tensorflow:global step 5020: loss = 0.2235 (0.251 sec/step)
    INFO:tensorflow:global step 5030: loss = 0.2603 (0.239 sec/step)
    INFO:tensorflow:Saving checkpoint to path model.ckpt #已存储模型中间结果
    

    随着训练的进行,loss会逐渐降低,当较长时间loss只出现小幅数值波动,但总体不下降时,可视为模型训练完成(收敛)。

    注意:

    • 本示例中由于图像数量很小,非常容易收敛,loss会降到非常低。一般二分类的训练中(训练样本数量级为10k+),loss数值将至4~6时训练基本完成。

    3. 模型测试

    读取步骤2中得到的模型,使用GPU测试模型训练的效果。

    示例
    在路径/app/detection下运行

    ./script/3_run_test.sh
    

    参数列表

    --_model_key = 模型结构定义(与步骤二保持一致)
    --_model_path = 训练所得模型的存储目录(与步骤二中train_dir保持一致)
    --_img_path = 输入图片路径
    --_out_img_path = 输出图片路径(默认)
    --num_classes = 测试类别数
    

    注意:类别数=识别类别总数+1,e.g., 训练样本中包含行人和车辆两种物体,则类别数=3。

    4. 生成后处理参数

    生成后续板卡推演需要的后处理参数文件(SSD中Anchor相关参数),关于Anchor的概念可以参考Faster-RCNN算法
    示例
    在路径/app/detection下运行

    ./script/4_gen_PostParam.sh
    
    python post_gen.py   模型结构定义(与步骤二保持一致)   后处理参数输出目录
    

    5. 导出推演模型

    将模型训练得到的结果固化为pb文件。.pb文件适合部署在推理终端中运行,在Tensorflow中.pb保存着模型网络的结构和变量名,还保存了所有变量的值。

    示例
    在路径/app/detection下运行

    ./script/5_run_truncate_model.sh
    
    python export_inference_graph.py   模型结构定义   训练所得模型的存储目录   输出模型目录
    

    该步骤输出为后续编译步骤的输入,目的在于移除tensorflow图中的训练节点。