1. 从零开始搭建船舶检测环境
第一次接触YOLOv3和TensorFlow/Keras时,我花了两周时间才把环境搭好。现在回想起来,其实只要掌握几个关键点,半小时就能搞定。先说说我的硬件配置:一台搭载RTX 2080 Ti的台式机,32GB内存。不过别担心,就算你用笔记本的GTX 1060也能跑起来,只是训练速度会慢些。
必备软件清单:
- Python 3.6(千万别用3.7+,会有各种兼容性问题)
- CUDA 9.0 + cuDNN 7.0(这是TensorFlow 1.12.0的黄金搭档)
- TensorFlow-gpu 1.12.0
- Keras-gpu 2.2.4
安装时最容易踩坑的是CUDA版本。我有次装了CUDA 10.0,结果训练时疯狂报错。后来发现TensorFlow 1.x对CUDA版本极其敏感,必须严格匹配。建议用conda创建虚拟环境:
conda create -n ship_detection python=3.6 conda install tensorflow-gpu=1.12.0 keras-gpu=2.2.4数据集方面,SeaShips绝对是船舶检测的标杆数据集。它包含6类船舶(货轮、邮轮等)的3000+张标注图片,每张都有精确的bounding box。下载后建议按7:2:1的比例划分训练集、验证集和测试集。我试过其他划分方式,发现这个比例在防止过拟合方面表现最好。
2. 数据预处理实战技巧
原始数据就像未经雕琢的玉石,处理得当才能发挥最大价值。我的预处理流程分为四步:
第一步:标注格式转换SeaShips默认是PASCAL VOC格式,但YOLOv3需要特定的txt格式。每个txt文件对应一张图片,内容格式为:
类别索引 x_center y_center width height这些坐标都是相对图片宽高的归一化值(0-1之间)。用这个Python脚本可以快速转换:
def convert(size, box): dw = 1./size[0] dh = 1./size[1] x = (box[0] + box[1])/2.0 y = (box[2] + box[3])/2.0 w = box[1] - box[0] h = box[3] - box[2] x = x*dw w = w*dw y = y*dh h = h*dh return (x,y,w,h)第二步:数据增强策略船舶检测有个特点——目标通常只占画面的10%-30%。为此我设计了特殊的数据增强组合:
- 随机水平翻转(概率0.5)
- 色彩抖动(HSV空间调整幅度±30%)
- 随机裁剪(保留至少60%的船舶区域)
这个组合使mAP提升了约7个百分点。注意不要用旋转增强,船舶在真实场景中很少出现倒置情况。
3. YOLOv3模型调优全记录
拿到baseline模型后,我进行了三轮优化:
第一轮:锚框(anchor)优化默认的9个anchor是基于COCO数据集设计的,对船舶检测并不友好。用k-means重新聚类后,得到更适合船舶形状的新anchor:
10,13, 16,30, 33,23, 30,61, 62,45, 59,119, 116,90, 156,198, 373,326修改yolov3.cfg中的anchors参数后,召回率从82%提升到89%。
第二轮:损失函数改进原版的YOLOv3使用简单的MSE损失,我替换为Focal Loss来解决正负样本不平衡问题:
def focal_loss(y_true, y_pred): gamma = 2.0 alpha = 0.25 pt = tf.where(tf.equal(y_true, 1), y_pred, 1 - y_pred) return -alpha * tf.pow(1. - pt, gamma) * tf.log(pt)第三轮:训练策略调整采用分阶段训练法:
- 冻结darknet53层,用1e-3学习率训练50轮
- 解冻全部层,用1e-4学习率微调100轮
- 最后用1e-5学习率精调20轮
配合ReduceLROnPlateau回调,当验证loss停滞时自动降低学习率。最终在测试集上达到95.66%的mAP。
4. 模型轻量化与部署实战
在港口实际部署时,发现原版YOLOv3的检测速度只有15FPS,无法满足实时需求。于是进行了三步优化:
第一步:通道剪枝通过分析卷积核的L1范数,移除了30%的冗余通道。具体操作:
pruning_params = { 'pruning_schedule': sparsity.PolynomialDecay( initial_sparsity=0.30, final_sparsity=0.70, begin_step=2000, end_step=8000) }第二步:量化训练采用TensorFlow的量化感知训练(QAT),将模型从FP32转为INT8:
converter = tf.lite.TFLiteConverter.from_keras_model(model) converter.optimizations = [tf.lite.Optimize.DEFAULT] tflite_quant_model = converter.convert()体积缩小4倍,速度提升2.3倍。
第三步:TensorRT加速在Jetson Xavier上部署时,使用TensorRT进一步优化:
trtexec --onnx=yolov3.onnx --fp16 --batch=8 --saveEngine=yolov3.engine最终在1080p视频上达到45FPS的实时检测速度,满足港口监控需求。