最近在做智能车人工智能组的线上赛,赛题分为两个:一个是人流密度检测,另一个是红绿灯识别,我在小队中的任务是做第二部分,红绿灯识别。一开始的时候建立模型的时选用的是SSD_Mobilenet_v1模型,权重也是预训练好的默认权重,我们只需要直接在预训练的基础上训练自己的数据集,得到新的权重,然后用该权重进行预测即可。
本项目所用数据集为VOC格式,所需要的原材料为:jpg+xml。
构建方法参考我的文章:使用(jpg + xml)制作VOC数据集
#根据自己的目录解压'PaddleDetection完整环境压缩包'
%cd ~
!unzip data/data23099/ppdet.zip
#根据自己的路径解压制作好的数据集'VOC_smartcar.zip'
!unzip /home/aistudio/data/data22499/VOC_smartcar.zip
#根据自己的路径选择PaddleDection配置python环境变量
%env PYTHONPATH=/home/aistudio/PaddleDetection-release-0.2
#运行creat_list.py为数据集创建object_xxx.txt
%cd PaddleDetection-release-0.2/
!python dataset/voc/create_list.py
#执行train.py,开始训练,更多参数请查看train.py文件,并在末尾进行个性化设置
!python -u tools/train.py -c configs/ssd/ssd_mobilenet_v1_voc.yml --use_tb=True --eval
其实这步不做也可以,因为在train,py执行的时候,会默认将模型的权重导出到output_dir,这个可以在训练过程的报告中找到。
#导出模型
!python -u tools/export_model.py -c configs/ssd/ssd_mobilenet_v1_voc.yml
其实和上一步一样,不做可以,因为在train,py执行的时候,每次迭代到一定数量后,会自动进行评估操作,这个也可以在训练过程的报告中找到。
#评估模型
!python -u tools/eval.py -c configs/ssd/ssd_mobilenet_v1_voc.yml
#执行infer.py,开始训练,更多参数请查看infer.py文件,并在末尾进行个性化设置
!python -u tools/infer.py -c configs/ssd/ssd_mobilenet_v1_voc.yml --infer_dir dataset/voc/VOCdevkit --output_dir output/test_result
在configs文件夹中找到所用模型的yml文件:ssd_mobilenet_v1_voc.yml,可以根据自己的需求进行相应的调整。
配置自定义数据集时在uml文件中找到TrainReader、EvalReader和TestReader下的dataset中的anno_path、dataset_dir,根据自己的VOC数据集的路径进行配置,注意:如果对相对路径使用不熟练,建议最好使用绝对路径!绝对路径肯定不会错;如果在不会用相对路径的情况下,强行使用相对路径,会导致很多路径相关的bug,带来很多不必要的麻烦。
可调参数:
具体参数调节参考文档:PaddleDetcion高级使用教程-数据处理模块
architecture: SSD
pretrain_weights: https://paddlemodels.bj.bcebos.com/object_detection/ssd_mobilenet_v1_coco_pretrained.tar
use_gpu: true
max_iters: 28000
snapshot_iter: 2000
log_smooth_window: 1
metric: VOC
map_type: 11point
save_dir: output
weights: output/ssd_mobilenet_v1_voc/model_final
# 2(label_class) + 1(background)
num_classes: 21
SSD:
backbone: MobileNet
multi_box_head: MultiBoxHead
output_decoder:
background_label: 0
keep_top_k: 200
nms_eta: 1.0
nms_threshold: 0.45
nms_top_k: 400
score_threshold: 0.01
#超参数调节
MobileNet:
norm_decay: 0.
conv_group_scale: 1
conv_learning_rate: 0.1
extra_block_filters: [[256, 512], [128, 256], [128, 256], [64, 128]]
with_extra_blocks: true
MultiBoxHead:
aspect_ratios: [[2.], [2., 3.], [2., 3.], [2., 3.], [2., 3.], [2., 3.]]
base_size: 300
flip: true
max_ratio: 90
max_sizes: [[], 150.0, 195.0, 240.0, 285.0, 300.0]
min_ratio: 20
min_sizes: [60.0, 105.0, 150.0, 195.0, 240.0, 285.0]
offset: 0.5
#学习率
LearningRate:
schedulers:
- !PiecewiseDecay
milestones: [10000, 15000, 20000, 25000]
values: [0.001, 0.0005, 0.00025, 0.0001, 0.00001]
#优化器
OptimizerBuilder:
optimizer:
momentum: 0.0
type: RMSPropOptimizer
regularizer:
factor: 0.00005
type: L2
##训练-数据处理模块的名称统一为TrainReader;
##PaddleDetection的yml配置文件中,使用!直接序列化模块实例(可以是函数、类等);
#dataset下需要序列化数据源实例,如COCODataSet、VOCDataSe和自定义的XXXDataSet;
#inputs_def的具体定义与使用请参考模型技术文档
#Reader的参数可选择性配置,如未在yml配置文件中定义,则会选取各参数在源码中的默认值。
TrainReader:
inputs_def:
image_shape: [3, 300, 300]
fields: ['image', 'gt_bbox', 'gt_class']
dataset:
!VOCDataSet
#anno_path: trainval.txt
anno_path: /home/aistudio/PaddleDetection-release-0.2/dataset/voc/trainval.txt
dataset_dir: /home/aistudio/PaddleDetection-release-0.2/dataset/voc
#如果是用自己的数据集,要把默认的标签改成false
use_default_label: false
#使用各种单图像数据增强算子的列表,文档地址:https://paddledetection.readthedocs.io/advanced_tutorials/READER.html#%E6%95%B0%E6%8D%AE%E5%A2%9E%E5%BC%BA%E7%AE%97%E5%AD%90
sample_transforms:
- !DecodeImage
#从图像文件或内存buffer中加载图像,格式为BGR、HWC格式,如果设置to_rgb=True,则转换为RGB格式。
to_rgb: true
- !RandomDistort
#随机扰动图片亮度、对比度、饱和度和色相
brightness_lower: 0.875
brightness_upper: 1.125
is_order: true
- !RandomExpand
#原理同ExpandImage,以随机比例与角度对图像进行裁剪、缩放和翻转
fill_value: [127.5, 127.5, 127.5]
- !RandomCrop
#原理同CropImage,以随机比例与IoU阈值进行处理
allow_no_crop: false
- !NormalizeBox {}
- !ResizeImage
#根据特定的插值方式调整图像大小
interp: 1
target_size: 300
use_cv2: false
- !RandomFlipImage
#随机水平翻转图像
is_normalized: true
- !Permute {}#对图像的通道进行排列并转为BGR格式。假如输入是HWC顺序,通道C上是RGB格式,设置channel_first=True,将变成CHW,设置to_bgr=True,通道C上变成BGR格式。
- !NormalizeImage
#对图像像素值进行归一化,如果设置is_scale=True,则先将像素值除以255.0,像素值缩放到到[0-1]区间。
is_scale: false
mean: [127.5, 127.5, 127.5]
std: [127.502231, 127.502231, 127.502231]
#批数据大小(图像个数/batch)
batch_size: 32
#是否随机打乱数据集中图像排序,默认False
shuffle: true
#是否删除最后一个batch的数据,默认False
drop_last: true
#数据读取中使用多进程的数量
worker_num: 8
#多进程/多线程缓冲队列的大小,队列中每个元素为一个batch的数据
bufsize: 16
#数据读取中是否使用多进程
use_process: true
#评估-数据处理模块的名称统一为EvalReader;
#在评估配置中,数据增强需要去除各种含有随机操作的数据处理算子与操作。
EvalReader:
inputs_def:
image_shape: [3, 300, 300]
fields: ['image', 'gt_bbox', 'gt_class', 'im_shape', 'im_id', 'is_difficult']
dataset:
!VOCDataSet
anno_path: /home/aistudio/PaddleDetection-release-0.2/dataset/voc/test.txt
dataset_dir: /home/aistudio/PaddleDetection-release-0.2/dataset/voc
#如果是用自己的数据集,要把默认的标签改成false
use_default_label: false
sample_transforms:
- !DecodeImage
to_rgb: true
- !NormalizeBox {}
- !ResizeImage
interp: 1
target_size: 300
use_cv2: false
- !Permute {}
- !NormalizeImage
is_scale: false
mean: [127.5, 127.5, 127.5]
std: [127.502231, 127.502231, 127.502231]
batch_size: 32
worker_num: 8
bufsize: 32
use_process: True
#推理-数据处理模块的名称统一为TestReader;
#在推理配置中dataset的数据源一般都设置为ImageFolder数据源。ImageFolder可以指定图片的文件夹地址,将读取该文件夹下的所有图片。
TestReader:
inputs_def:
image_shape: [3,300,300]
fields: ['image', 'im_id', 'im_shape']
dataset:
!ImageFolder
anno_path: /home/aistudio/PaddleDetection-release-0.2/dataset/voc/anno.txt
#如果是用自己的数据集,要把默认的标签改成false
use_default_label: false
sample_transforms:
- !DecodeImage
to_rgb: true
- !ResizeImage
interp: 1
max_size: 0
target_size: 300
use_cv2: false
- !Permute {}
- !NormalizeImage
is_scale: false
mean: [127.5, 127.5, 127.5]
std: [127.502231, 127.502231, 127.502231]
batch_size: 1
在train.py中自定义扩展功能:
具体参数调节参考官方文档:PaddleDetcion高级使用教程-数据处理模块
#可添加的功能后缀,可以直接更改default即可
if __name__ == '__main__':
parser = ArgsParser()
parser.add_argument(
"-r",
"--resume_checkpoint",
default=None,
type=str,
help="Checkpoint path for resuming training.")
parser.add_argument(
"--fp16",
action='store_true',
default=False,
help="Enable mixed precision training.")
parser.add_argument(
"--loss_scale",
default=8.,
type=float,
help="Mixed precision training loss scale.")
parser.add_argument(
"--eval",
action='store_true',
default=True,
help="Whether to perform evaluation in train")
parser.add_argument(
"--output_eval",
default=None,
type=str,
help="Evaluation directory, default is current directory.")
parser.add_argument(
"--use_tb",
type=bool,
default=True,
help="whether to record the data to Tensorboard.")
parser.add_argument(
'--tb_log_dir',
type=str,
default="tb_log_dir/scalar",
help='Tensorboard logging directory for scalar.')
FLAGS = parser.parse_args()
main()
如果读者觉得好,跟着博主做出了项目,不要忘了点个赞哦~