此项目github地址为https://github.com/yshuqiao/steelDetect,码云地址为https://gitee.com/yang_shuqiao/steelDetect
mmdetection原本工具使用
- 此项目建立在https://github.com/open-mmlab/mmdetection的基础上,其中标题Getting Started下有些链接比较概括
- 首先按这个网址的方法进行安装https://github.com/open-mmlab/mmdetection/blob/master/docs/get_started.md
- 然后可以看一下官方的这个使用教程,里面也有些链接https://github.com/open-mmlab/mmdetection/blob/master/docs/get_started.md
- 主要是用
python tools/train.py config_path --work_dir checkpoint_save_path
来进行训练 - 可以用test.py来获取mAP指标,即
python tools/test.py config_path checkpoint_path --eval bbox
- 画loss曲线图可以用
python tools/analyze_logs.py plot_curve xxx.log.json --keys loss --legend loss
- 获取网络的浮点运算量可以用
python tools/get_flops.py config_path --shape 200
python tools/coco_error_analysis.py result.json output_dir --ann GT.json
可以用来分析误差,
test.py如果设置--out参数则一般是通过single_gpu_test生成后缀为.pkl的pickle文件,但根据里面这段代码,可以看到mmdetection/mmdet/datasets/coco.py文件的evaluate函数可以通过if args.format_only: dataset.format_results(outputs,**kwargs)
result_files, tmp_dir = self.format_results(results, jsonfile_prefix)
来生成.json后缀的结果,
那么运行python tools/test.py config_path checkpoint_path --format-only --eval-options jsonfile_prefix = "/home/yshuqiao/mmdetection/tools/results/regnet"
则可生成后缀为.json的结果文件regnet.json从而可以用coco_error_analysis.py来分析误差。
tools文件夹下另增的脚本
- coco2GTjson.py可以用来把coco格式标注文件转化为GTjson文件,后续可以用visualizeGTandPredict.py来可视化图片上的真实标注框。
- defect_nums.py可以统计coco格式标注文件中各类缺陷的个数。
- inference-me.py可以用来生成结果的json文件,后续可用visualizeGTandPredict.py来可视化图片上的预测框。
在mmdetection基础上修改的地方
resnet.py | regnet.py | schedule_1x.py |
---|---|---|
se | cbam | cosineAnnealing |
1.resnet.py中增加SE通道注意力
主要是在resnet.py里面添加SELayer类:
class SELayer(nn.Module):
def __init__(self,channel,reduction=16):
super(SELayer,self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Sequential(
nn.Linear(channel,channel//reduction,bias=False),
nn.ReLU(inplace=True),
nn.Linear(channel//reduction,channel,bias=False),
nn.Sigmoid()
)
def forward(self,x):
b,c,_,_ = x.size()
y = self.avg_pool(x).view(b,c)
y = self.fc(y).view(b,c,1,1)
return x*y.expand_as(x)
并在Bottleneck模块类中添加self.se参数,在其中的forward函数里添加:
if self.se:
se_block = SELayer(self.planes)
out = se_block(out)
Bottleneck类中也能看到,如果加入generalized_attention模块(Transformer)这样的插件的话,会插入到Bottleneck中第一个卷积层conv1(卷积核大小为3x3,紧接着BN层和relu)和第二个卷积层conv2之间。
2.regnet.py中增加CBAM混合注意力,可以参考https://zhuanlan.zhihu.com/p/99261200
在类中添加self.se参数(其Bottleneck类会调用resnext.py中的Bottleneck,而resnext.py中的Bottleneck继承了resnet.py的Bottleneck)和self.cbam参数,
如果self.cbam为True,则初始化ChannelAttention类和SpatialAttention类,相应地,在前传函数forward中的最后一个阶段后面添加cbam。
而如果self.se为True,则对第三阶段和第四阶段的残差层传入self.se=True的参数值,使残差层中每一个Bottleneck的残差支路末尾,即在与恒等映射支路相加之前添加SE模块。
3.把schedule_1x.py中的step学习率衰减策略改为cosineAnnealing学习率衰减策略。
根据https://github.com/open-mmlab/mmdetection/blob/master/docs/tutorials/customize_runtime.md,即把
lr_config = dict(
policy='step',
warmup='linear', # 可改为余弦退火算法
warmup_iters=500, # 在初始的500次迭代中学习率逐渐增加
warmup_ratio=0.001, # 起始的学习率
step=[8, 11] # 在第8和11个epoch时降低学习率,可调成step=[16, 19]
)
改为
lr_config = dict(
policy='CosineAnnealing',
warmup='linear',
warmup_iters=1000,
warmup_ratio=1.0/10,
min_lr_ratio=1e-5,
)
其他
- 模型可视化工具Netron
- 对mmdetection的解读: GiantPandaCV公众号中【MMDetection 超全专栏】、OpenMMLab | 轻松掌握 MMDetection 整体构建流程(一)、MMDETECTION最小复刻版(五):YOLOV5转化内幕
- 根据需要调整config文件(以faster_rcnn_r50_fpn_1x_coco.py为例):
-
coco格式数据的制作与配置修改:对后缀为xml的voc格式的数据标签,可以通过脚本(可查找CSDN博客或知乎相关参考)转换成后缀为json的coco格式的;若自己制作数据集,可用labelimg或labelme,也是可以通过脚本转化成coco格式;
可以通过对数据标签的统计分析得到数据集目标的数量、长宽比、面积分布等信息;通过脚本划分数据集为训练集和测试集,对训练集的数据增强可以参考https://github.com/maozezhong/CV_ToolBox;
配置文件中,需要调整coco_detection.py中的data_root,img_scale,samples_per_gpu(batchsize);mmdet/datasets/coco.py里面的类别名称CLASSES,另外可设iou_thrs=[5]。 -
学习率设置与否使用预训练模型:schedule_1x.py中如果优化器用了SGD,那么一般设置学习率lr=gpu_nums·0.00125·samples_per_gpu;default_runtime.py中可以设置load_from=预训练模型,其中预训练模型可以由项目首页的Benchmark and model zoo标题中点击Faster R-CNN,跳转到https://github.com/open-mmlab/mmdetection/tree/master/configs/faster_rcnn选择下载。
-
目标类别数、显示各类mAP、tensorboard的使用:faster_rcnn_r50_fpn.py中要把num_classes设置成目标类别数;如果要验证模型效果的时候显示各类目标的mAP,那么要在mmdet/datasets/coco.py的evaluate函数中设置classwise=True;
若要使用tensorboard查看模型训练过程中loss变化,应在default_runtime.py中去掉dict(type='TensorboardLoggerHook')
的注释,并安装tensorboard包,然后在命令终端中输入tensorboard --logdir=work_dir/
,就可以在浏览器打开http://localhost:6006/查看。 -
模型其他配置参数的调整或替换:anchor_generator的scales,ratios和strides;img_norm_cfg中的mean和std;骨干网络或特征金字塔的替换;train_cfg里的rcnn里的sampler的type可用改为OHEMSampler;
roi_head里面loss_bbox可以改为CIoULoss并设置reg_decoded_bbox=True
,loss_cls可以改为FocalLoss,其参数设置为:loss_cls=dict( type='FocalLoss', use_sigmoid=True, gamma=2.0, alpha=0.25, loss_weight=1.0),
配置文件中单引号的名称可以copy来在pycharm此项目中搜索,例如'CrossEntropyLoss'和'FocalLoss',能找到相应的定义且可能找到可替换的部件。
-
mmdetection重点关注的文件夹是configs(含各种配置文件)、mmdet(含各种模型组件)和tools(含训练测试等主要工具),
大致可以认为mmdetection中有一个大管家,tools中的脚本是主函数,通过把config配置文件中的参数读到给大管家,把数据和模型(mmdet提供模型结构等)放到大管家;大管家用统一训练测试管道输出评价结果;
可以重点关注这些py文件:mmdet/models/detectors/two_stage.py、mmdet/models/roi_heads/standard_roi_heads.py、mmdet/models/dense_heads/rpn_head.py以及
训练信息相关:从tools/train.py文件ctrl点击train_detector可进入mmdet/apis/train.py,看到tran_detector函数底下有runner.run(data_loaders, cfg.workflow, cfg.total_epochs)
,
再Ctrl点击run可进入所安装的包的内部文件/home/yshuqiao/anaconda/envs/open-mmlab/lib/python3.7/site-packages/mmcv/runner/epoch_based_runner.py,
其中可以看到run函数下面有epoch_runner(data_loaders[i],**kargs)
实则调用了train函数中的self.run_iter(data_batch,train_mode=True)
,另外还用到了logger.info
,但是找不到打印训练的loss和acc等信息的输出处,
倒是只在mmdet/datasets/coco.py中看到print_log(log_msg, logger=logger)
,或许是epoch_based_runner.py中的val函数通过run_iter中的val_step间接地调用了tests/test_data/test_dataset.py中的test_dataset_evaluation函数或是tools/test.py或tools/eval_metric.py,
很大可能是与tests/test_data/test_dataset.py中_build_demo_runner的val_step以及test_evaluation_hook函数有关,而test_evaluation_hook函数中evalhook.evaluate = MagicMock()
Ctrl点击evaluate可以进入mmdet/core/evaluation/eval_hooks.py中的evaluate函数,
其中eval_res = self.dataloader.dataset.evaluate(results, logger=runner.logger, **self.eval_kwargs)
中evaluate对应coco的则为coco_dataset.evaluate,而对应自己定义的数据集则调用相应的evaluate函数;另外在mmdet/apis/train.py中还有这一句eval_hook = DistEvalHook if distributed else EvalHook
,Ctrl点击EvalHook也能跳转到mmdet/core/evaluation/eval_hooks.py。
至于不同版本的mmdetection(tags),可以在github项目左上角下拉选择;ctrl+F可以在指定github项目中搜索关键字,方便查找一些模型结构相关的py文件。 -
关于深度学习说两句:机器学习中主要了解矩阵、概率等相关概念;卷积神经网络中可以把卷积核与滤波器联系起来(吴恩达的深度学习教程b站上有);其他要学习了解Linux、Cuda、Anaconda、pytorch的操作使用。
-
除了faster RCNN,yolov5、efficientdet、fcos、centernet可以去了解一下,其中fcos使用了atss自适应采样,centernet是无锚框的检测算法;
跑通一个网络主要关注:数据的预处理和结果评价、模型结构、优化器配置等,看代码过程中除了debug,可用print来看各个环节输出的张量形状。
-