在计算机视觉领域,目标检测一直是最具挑战性的任务之一。Faster R-CNN作为两阶段检测器的经典代表,在精度和速度之间取得了很好的平衡。最近我在一个工业质检项目中,成功实现了基于TensorFlow的Faster R-CNN模型在自定义数据集上的训练,整个过程踩了不少坑,也积累了一些实战经验。
这个项目的核心目标是为生产线上的缺陷检测构建一个高精度的自动识别系统。与使用现成的COCO或VOC数据集不同,我们需要针对特定的工业零件和缺陷类型从头训练模型。通过本文,我将详细分享从数据准备到模型部署的全流程技术细节,特别是那些官方文档中没有明确说明的"坑"和解决方案。
在工业检测场景中,我们面对的主要挑战是:
经过对比测试,我们发现Faster R-CNN相比单阶段检测器(如SSD、YOLO)在以下方面表现更优:
工业场景的数据采集有几个特点需要特别注意:
我们采用的数据增强策略包括:
python复制def augment_image(image, boxes):
# 随机亮度调整(模拟光照变化)
image = tf.image.random_brightness(image, max_delta=0.2)
# 随机裁剪(保持至少一个完整目标)
image, boxes = random_crop(image, boxes, min_objects=1)
# 高斯噪声(模拟传感器噪声)
image = tf.image.random_jpeg_quality(image, 75, 95)
return image, boxes
推荐使用以下版本组合:
安装关键组件:
bash复制pip install tensorflow-gpu==2.4.0
pip install pycocotools # 用于评估指标计算
git clone https://github.com/tensorflow/models.git
cd models/research
protoc object_detection/protos/*.proto --python_out=.
export PYTHONPATH=$PYTHONPATH:`pwd`:`pwd`/slim
我们使用LabelImg进行标注,生成PASCAL VOC格式的XML文件,然后转换为TFRecord格式:
python复制def create_tf_example(annot_data):
# 读取图像二进制数据
with tf.io.gfile.GFile(annot_data['path'], 'rb') as fid:
encoded_jpg = fid.read()
# 构建特征字典
feature = {
'image/height': int64_feature(height),
'image/width': int64_feature(width),
'image/filename': bytes_feature(filename),
'image/source_id': bytes_feature(filename),
'image/encoded': bytes_feature(encoded_jpg),
'image/format': bytes_feature('jpeg'),
'image/object/bbox/xmin': float_list_feature(xmins),
'image/object/bbox/xmax': float_list_feature(xmaxs),
'image/object/bbox/ymin': float_list_feature(ymins),
'image/object/bbox/ymax': float_list_feature(ymaxs),
'image/object/class/text': bytes_list_feature(classes_text),
'image/object/class/label': int64_list_feature(classes),
}
return tf.train.Example(features=tf.train.Features(feature=feature))
重要提示:工业图像建议保持原始分辨率,不要过早下采样,否则会丢失微小缺陷特征
以faster_rcnn_resnet50_v1_640x640_coco17为例,需要调整的核心参数:
config复制model {
faster_rcnn {
num_classes: 6 # 根据实际类别数修改
image_resizer {
keep_aspect_ratio_resizer {
min_dimension: 640
max_dimension: 640
pad_to_max_dimension: true # 保持长宽比填充
}
}
first_stage_anchor_generator {
scales: [0.25, 0.5, 1.0, 2.0] # 针对小目标增加更小的anchor
aspect_ratios: [0.5, 1.0, 2.0]
}
}
}
train_config {
batch_size: 2 # 高分辨率图像需要减小batch
data_augmentation_options {
random_horizontal_flip {}
}
fine_tune_checkpoint: "pre-trained-model/ckpt-0"
fine_tune_checkpoint_type: "detection" # 固定特征提取器
num_steps: 50000
}
对于大规模数据集(10万+图像),建议采用多GPU训练:
bash复制# 单机多卡训练命令
python object_detection/model_main_tf2.py \
--pipeline_config_path=configs/faster_rcnn.config \
--model_dir=output/ \
--num_train_steps=50000 \
--alsologtostderr \
--num_workers=4 \
--worker_replicas=8
关键参数说明:
num_workers: 参数服务器数量worker_replicas: 实际GPU数量batch_size: 指单卡batch size工业场景更关注的指标:
评估命令:
bash复制python object_detection/model_main_tf2.py \
--pipeline_config_path=configs/faster_rcnn.config \
--model_dir=output/ \
--checkpoint_dir=output/ \
--eval_timeout=3600
问题1:小目标检测效果差
问题2:误检率高
python复制!python exporter_main_v2.py \
--input_type image_tensor \
--pipeline_config_path configs/faster_rcnn.config \
--trained_checkpoint_dir output/ \
--output_directory exported/
针对NVIDIA GPU的优化方案:
python复制from tensorflow.python.compiler.tensorrt import trt_convert as trt
conversion_params = trt.TrtConversionParams(
precision_mode='FP16',
max_workspace_size_bytes=1<<30
)
converter = trt.TrtGraphConverterV2(
input_saved_model_dir='exported/',
conversion_params=conversion_params
)
converter.convert()
converter.save('exported_trt/')
实测性能提升:
数据质量比数量更重要:我们通过精心筛选的5000张图像训练出的模型,比随机10万张数据的效果更好。关键是要确保标注一致性和缺陷多样性。
学习率策略很关键:工业数据集与COCO差异大,建议采用warmup+余弦退火:
config复制optimizer {
momentum_optimizer {
learning_rate {
cosine_decay_learning_rate {
learning_rate_base: 0.004
total_steps: 50000
warmup_learning_rate: 0.0001
warmup_steps: 2000
}
}
}
}
硬件选型建议:
持续学习策略:我们搭建了一个自动标注平台,将模型预测结果经质检员复核后自动加入训练集,实现模型性能的持续提升。