第一次用PyTorch跑Faster R-CNN时,我花了整整三天时间在环境配置上。最坑的是当时没注意PyTorch版本问题,用1.6版本跑0.4的老代码,报错信息看得我怀疑人生。后来才发现,不同版本的PyTorch对CUDA、CUDNN的依赖天差地别。
强烈建议使用以下组合:
安装PyTorch时一定要指定版本:
bash复制conda install pytorch==1.0.0 torchvision==0.2.1 cuda100 -c pytorch
遇到过最奇葩的报错是"ImportError: torch.utils.ffi is deprecated",这是因为新版PyTorch移除了FFI模块。解决方法很简单——换用pytorch-1.0分支的代码:
bash复制git clone -b pytorch-1.0 --single-branch https://github.com/jwyang/faster-rcnn.pytorch.git
很多教程只教用VOC2007数据集,但实际项目中我们总要处理自己的数据。这里有个大坑:VOC格式要求图片名必须是6位数字(比如000001.jpg),但我们的原始图片可能是任意命名。用这个Python脚本批量重命名:
python复制import os
from PIL import Image
img_dir = 'your_images_folder'
for idx, img_name in enumerate(os.listdir(img_dir)):
new_name = f"{idx:06d}.jpg"
img = Image.open(os.path.join(img_dir, img_name))
img.save(os.path.join('JPEGImages', new_name))
Annotations文件夹的XML文件也要对应修改。建议用labelImg工具标注,它会自动生成符合VOC标准的XML。我遇到过标注框越界导致的"assert(boxes[:,2]>=boxes[:,0]).all()"错误,解决方法是在生成XML时检查坐标是否超出图片宽高:
python复制# 在标注工具的输出代码里加上边界检查
xmax = min(xmax, image_width-1)
ymax = min(ymax, image_height-1)
第一次训练时GPU显存直接炸了,后来发现batch_size不能超过4(我的显卡是RTX 2080 Ti)。如果出现CUDA out of memory,试试这些参数组合:
bash复制CUDA_VISIBLE_DEVICES=0 python trainval_net.py \
--dataset pascal_voc \
--net res101 \
--bs 2 \ # 关键参数!显存不够就调小
--nw 4 \ # dataloader线程数
--lr 0.001 \
--cuda
致命陷阱:缓存文件冲突!当你更换数据集后,一定要删除data/cache下的voc_2007_trainval_gt_roidb.pkl,否则程序会傻傻地加载旧数据索引。我在这栽过跟头,训练时一直报KeyError:'width',就是因为缓存没清理。
官方代码的默认学习率可能不适合你的数据。我的经验是:
在lib/model/config.py里有几个隐藏参数很关键:
python复制__C.TRAIN.RPN_POSITIVE_OVERLAP = 0.7 # 建议调低到0.5-0.6
__C.TRAIN.RPN_NEGATIVE_OVERLAP = 0.3 # 建议调高到0.4
修改检测类别时要注意两个地方必须同步改:
有个骚操作可以提升小目标检测效果——修改anchor尺寸。在lib/model/config.py中找到:
python复制__C.ANCHOR_SCALES = [8,16,32] # 改为[4,8,16]检测小物体更灵敏
技巧1:用–vis参数实时查看训练效果
bash复制python trainval_net.py --vis --cuda
这会在data/vis文件夹生成检测效果图,方便随时监控训练质量。
技巧2:冻结底层网络加速训练
在trainval_net.py的109行附近添加:
python复制for param in net.Conv_base.parameters():
param.requires_grad = False # 冻结卷积层
技巧3:自动保存测试结果到Excel
在test_net.py的预测循环后添加:
python复制import pandas as pd
results = []
for box, score in zip(boxes, scores):
results.append({'x1':box[0],'y1':box[1],'x2':box[2],'y2':box[3],'score':score})
pd.DataFrame(results).to_excel('det_results.xlsx')
坑1:验证集效果突然暴跌
可能原因:学习率太高导致模型震荡。解决方案:
python复制torch.nn.utils.clip_grad_norm_(model.parameters(), 10.0)
坑2:预测框全部挤在图片角落
典型症状:loss_rpn_loc一直很高。这是anchor设置不合理导致的,检查:
坑3:训练时GPU利用率波动大
通常是因为数据加载瓶颈。试试这些优化:
python复制self._roidb = self.gt_roidb() # 改为
self._roidb = cache.cache(self.gt_roidb)
训练好的模型可以用torch.jit.trace加速:
python复制model.eval()
example = torch.rand(1, 3, 600, 800).cuda()
traced_model = torch.jit.trace(model, example)
traced_model.save('fasterrcnn_jit.pt')
实测发现,用半精度推理能提升30%速度:
python复制with torch.cuda.amp.autocast():
detections = model(im_data, im_info)
如果是部署到生产环境,建议转ONNX格式:
python复制torch.onnx.export(model,
(im_data, im_info),
"fasterrcnn.onnx",
opset_version=11)
最后提醒:别用OpenCV的dnn模块加载PyTorch模型!我测试发现其NMS实现与原生代码有差异,会导致漏检。推荐用libtorch部署,保持前后处理一致性。