从论文到测试:Facebook Detectron开源项目初探

机器之心专栏

作者:陈惠婵


从 RCNN 到 Faster RCNN,再到最近的 FPN 和获得 ICCV Best Paper 的 Mask RCNN,深度学习在物体检测中以绝对优势从众多机器学习算法中脱引而出。大家对 Facebook 的计算机视觉研究项目的开源期盼已久,经过 1 年多的漫长等待,今天 Facebook 终于开源了 Detectron,Detectron 开源项目使用 caffe2 和 python 接口。实现了 10 多篇计算机视觉最新的成果。下面我们简单介绍一下 Detectron 所实现的论文。并且对 Detectron 进行初次测试,我们会在随后的博客中更新我们自己测试得到的 Detectron 训练模型和速度标准。


Fast RCNN、Faster RCNN、RFCN、FPN、RetinaNet


Detectron 实现了物体检测的标准模型,并且添加了 Feature Pyramid Network 和 RetinaNet 等 state-of-the-art 的物体检测模型。FPN 是 two-stage 检测的 state-of-the-art,RetinaNet 是 one-stage 的 best-performing 模型,并且也是 ICCV 的 best student paper。


ResNet,ResNeXt


Detectron 实现了 Residual Network 和 ResNeXt 等基础的神经网络结构。ResNext 使用 depthwise convolution 的技术大大降低了参数,并且保证了分类结果。

 



Human-object Interaction Detection


物体检测可以得到 bounding box 如图(a),Human-object interaction 通过预测不同的 bounding box 之间的概率密度可以学习不同 bounding box 之间的关系。如图(c),人和刀之间的关系是切(cut)。




Mask RCNN


Mask RCNN 通过改进 Faster RCNN 可以实现 7 FPS 的 instance segmentation 和关键点检测,并且超过当时的所有方法。Mask RCNN 在 COCO 和 CITYSCAPES 数据集上面取得了好的结果。Mask RCNN 的示意图如下。

 



Training Imagenet in one hour


本篇论文发现了 large batch 可以大大的提升分类网络的收敛速度,通过把 batch size 从 256 提升到 8192,将训练时间从几周降低到了 1 个小时,大大提升了神将网络的训练速度。


CVPR 2018 投稿论文:Learning to segment everything


收集 mask rcnn 的标注十分昂贵,在 cityscapes 上面一张图的标注需要 1 个小时。这篇论文提出了 weight transfer 的办法来分割所有的物体,免去了收集分割数据的巨大时间和金钱耗费。本篇论文使用 bounding box detection branch 的权重来预测 mask branch 的权重来实现此目的。


Non Local Neural Convolution


Convolution Neural Network 只能够传递邻域的信息,本篇论文参照 non local means 和 self attention 的方法设计出了 non local convolution,从而能够捕捉到非邻域的信息。如下图,中心点可以捕捉到非邻域的重要信息。

 



Detectron 框架初探


要使用 Detectron 框架需要安装 caffe2,caffe2 的安装请参照 caffe2 官网。然后参照 INSTALL.md 安装 Detectron,Detectron 提供了方便的测试和添加 op 功能。添加 op 具体参照 test_zero_even_op.py。


Detectron 框架包含 config,demo,lib,tests 和 tools 等文件夹。Config 包含着各个模型的训练和测试参数,lib 是 detectron 的核心文件夹,例如 data loader,model builder,operator definition 和 utils(学习率等非核心函数)。


Detectron 安装


Caffe2 安装,参照网址 https://caffe2.ai/docs/getting-started.html?platform=ubuntu&configuration=compile


核心命令:


  1. git clone --recursive https://github.com/caffe2/caffe2.git && cd caffe2

  2. make && cd build && sudo make install

  3. python -c 'from caffe2.python import core' 2>/dev/null && echo "Success" || echo "Failure"



Detectron 安装,参照 https://github.com/facebookresearch/Detectron/blob/master/INSTALL.md


Detectron 测试


使用 Mask RCNN FPN ResNet 50 进行测试,命令如下:


  1. CUDA_VISIBLE_DEVICES=3 python tools/train_net.py --cfg configs/getting_started/tutorial_1gpu_e2e_faster_rcnn_R-50-FPN.yaml OUTPUT_DIR /tmp/detectron-output



在 Titan X 上面测试速度:


  1. INFO infer_simple.py: 111: Processing demo/16004479832_a748d55f21_k.jpg -> /tmp/detectron-visualizations/16004479832_a748d55f21_k.jpg.pdf

  2. INFO infer_simple.py: 119: Inference time: 1.402s

  3. INFO infer_simple.py: 121:  | im_detect_bbox: 1.329s

  4. INFO infer_simple.py: 121:  | misc_mask: 0.034s

  5. INFO infer_simple.py: 121:  | im_detect_mask: 0.034s

  6. INFO infer_simple.py: 121:  | misc_bbox: 0.005s

  7. INFO infer_simple.py: 124:  \ Note: inference on the first image will be slower than the rest (caches and auto-tuning need to warm up)

  8. INFO infer_simple.py: 111: Processing demo/18124840932_e42b3e377c_k.jpg -> /tmp/detectron-visualizations/18124840932_e42b3e377c_k.jpg.pdf

  9. INFO infer_simple.py: 119: Inference time: 0.411s

  10. INFO infer_simple.py: 121:  | im_detect_bbox: 0.305s

  11. INFO infer_simple.py: 121:  | misc_mask: 0.058s

  12. INFO infer_simple.py: 121:  | im_detect_mask: 0.044s

  13. INFO infer_simple.py: 121:  | misc_bbox: 0.004s

  14. INFO infer_simple.py: 111: Processing demo/24274813513_0cfd2ce6d0_k.jpg -> /tmp/detectron-visualizations/24274813513_0cfd2ce6d0_k.jpg.pdf

  15. INFO infer_simple.py: 119: Inference time: 0.321s

  16. INFO infer_simple.py: 121:  | im_detect_bbox: 0.264s

  17. INFO infer_simple.py: 121:  | misc_mask: 0.034s

  18. INFO infer_simple.py: 121:  | im_detect_mask: 0.018s

  19. INFO infer_simple.py: 121:  | misc_bbox: 0.005s

  20. INFO infer_simple.py: 111: Processing demo/33823288584_1d21cf0a26_k.jpg -> /tmp/detectron-visualizations/33823288584_1d21cf0a26_k.jpg.pdf

  21. INFO infer_simple.py: 119: Inference time: 0.722s

  22. INFO infer_simple.py: 121:  | im_detect_bbox: 0.515s

  23. INFO infer_simple.py: 121:  | misc_mask: 0.127s

  24. INFO infer_simple.py: 121:  | im_detect_mask: 0.072s

  25. INFO infer_simple.py: 121:  | misc_bbox: 0.007s

  26. INFO infer_simple.py: 111: Processing demo/17790319373_bd19b24cfc_k.jpg -> /tmp/detectron-visualizations/17790319373_bd19b24cfc_k.jpg.pdf

  27. INFO infer_simple.py: 119: Inference time: 0.403s

  28. INFO infer_simple.py: 121:  | im_detect_bbox: 0.292s

  29. INFO infer_simple.py: 121:  | misc_mask: 0.067s

  30. INFO infer_simple.py: 121:  | im_detect_mask: 0.038s

  31. INFO infer_simple.py: 121:  | misc_bbox: 0.006s



Detectron 框架训练


 在 COCO 数据集上面使用 FPN ResNet50 进行 Faster RCNN 训练


使用命令 :


  1. CUDA_VISIBLE_DEVICES=3 python tools/train_net.py     --cfg configs/getting_started/tutorial_1gpu_e2e_faster_rcnn_R-50-FPN.yaml     OUTPUT_DIR /tmp/detectron-output



输出如下:


  1. Namespace(cfg_file='configs/getting_started/tutorial_1gpu_e2e_faster_rcnn_R-50-FPN.yaml', multi_gpu_testing=False, opts=['OUTPUT_DIR', '/tmp/detectron-output'], skip_test=False)

  2. INFO train_net.py: 188: Training with config:

  3. INFO train_net.py: 189: {'BBOX_XFORM_CLIP': 4.1351665567423561,

  4. 'CLUSTER': {'ON_CLUSTER': False},

  5. 'DATA_LOADER': {'NUM_THREADS': 4},

  6. 'DEDUP_BOXES': 0.0625,

  7. 'DOWNLOAD_CACHE': '/tmp/detectron-download-cache',

  8. 'EPS': 1e-14,

  9. 'EXPECTED_RESULTS': [],

  10. 'EXPECTED_RESULTS_ATOL': 0.005,

  11. 'EXPECTED_RESULTS_EMAIL': '',

  12. 'EXPECTED_RESULTS_RTOL': 0.1,

  13. 'FAST_RCNN': {'MLP_HEAD_DIM': 1024,

  14.               'ROI_BOX_HEAD': 'fast_rcnn_heads.add_roi_2mlp_head',

  15.               'ROI_XFORM_METHOD': 'RoIAlign',

  16.               'ROI_XFORM_RESOLUTION': 7,

  17.               'ROI_XFORM_SAMPLING_RATIO': 2},

  18. 'FPN': {'COARSEST_STRIDE': 32,

  19.         'DIM': 256,

  20.         'EXTRA_CONV_LEVELS': False,

  21.         'FPN_ON': True,

  22.         'MULTILEVEL_ROIS': True,

  23.         'MULTILEVEL_RPN': True,

  24.         'ROI_CANONICAL_LEVEL': 4,

  25.         'ROI_CANONICAL_SCALE': 224,

  26.         'ROI_MAX_LEVEL': 5,

  27.         'ROI_MIN_LEVEL': 2,

  28.         'RPN_ANCHOR_START_SIZE': 32,

  29.         'RPN_ASPECT_RATIOS': (0.5, 1, 2),

  30.         'RPN_MAX_LEVEL': 6,

  31.         'RPN_MIN_LEVEL': 2,

  32.         'ZERO_INIT_LATERAL': False},

  33. 'MATLAB': 'matlab',

  34. 'MEMONGER': True,

  35. 'MEMONGER_SHARE_ACTIVATIONS': False,

  36. 'MODEL': {'BBOX_REG_WEIGHTS': (10.0, 10.0, 5.0, 5.0),

  37.           'CLS_AGNOSTIC_BBOX_REG': False,

  38.           'CONV_BODY': 'FPN.add_fpn_ResNet50_conv5_body',

  39.           'EXECUTION_TYPE': 'dag',

  40.           'FASTER_RCNN': True,

  41.           'KEYPOINTS_ON': False,

  42.           'MASK_ON': False,

  43.           'NUM_CLASSES': 81,

  44.           'RPN_ONLY': False,

  45.           'TYPE': 'generalized_rcnn'},

  46. 'MRCNN': {'CLS_SPECIFIC_MASK': True,

  47.           'CONV_INIT': 'GaussianFill',

  48.           'DILATION': 2,

  49.           'DIM_REDUCED': 256,

  50.           'RESOLUTION': 14,

  51.           'ROI_MASK_HEAD': '',

  52.           'ROI_XFORM_METHOD': 'RoIAlign',

  53.           'ROI_XFORM_RESOLUTION': 7,

  54.           'ROI_XFORM_SAMPLING_RATIO': 0,

  55.           'THRESH_BINARIZE': 0.5,

  56.           'UPSAMPLE_RATIO': 1,

  57.           'USE_FC_OUTPUT': False,

  58.           'WEIGHT_LOSS_MASK': 1.0},

  59. 'NUM_GPUS': 1,

  60. 'OUTPUT_DIR': '/tmp/detectron-output',

  61. 'PIXEL_MEANS': array([[[ 102.9801,  115.9465,  122.7717]]]),

  62. 'RESNETS': {'NUM_GROUPS': 1,

  63.             'RES5_DILATION': 1,

  64.             'STRIDE_1X1': True,

  65.             'TRANS_FUNC': 'bottleneck_transformation',

  66.             'WIDTH_PER_GROUP': 64},

  67. 'RETINANET': {'ANCHOR_SCALE': 4,

  68.               'ASPECT_RATIOS': (0.5, 1.0, 2.0),

  69.               'BBOX_REG_BETA': 0.11,

  70.               'BBOX_REG_WEIGHT': 1.0,

  71.               'CLASS_SPECIFIC_BBOX': False,

  72.               'INFERENCE_TH': 0.05,

  73.               'LOSS_ALPHA': 0.25,

  74.               'LOSS_GAMMA': 2.0,

  75.               'NEGATIVE_OVERLAP': 0.4,

  76.               'NUM_CONVS': 4,

  77.               'POSITIVE_OVERLAP': 0.5,

  78.               'PRE_NMS_TOP_N': 1000,

  79.               'PRIOR_PROB': 0.01,

  80.               'RETINANET_ON': False,

  81.               'SCALES_PER_OCTAVE': 3,

  82.               'SHARE_CLS_BBOX_TOWER': False,

  83.               'SOFTMAX': False},

  84. 'RFCN': {'PS_GRID_SIZE': 3},

  85. 'RNG_SEED': 3,

  86. 'ROOT_DIR': '/home/huichan/caffe2/detectron',

  87. 'RPN': {'ASPECT_RATIOS': (0.5, 1, 2),

  88.         'RPN_ON': True,

  89.         'SIZES': (64, 128, 256, 512),

  90.         'STRIDE': 16},

  91. 'SOLVER': {'BASE_LR': 0.0025,

  92.            'GAMMA': 0.1,

  93.            'LOG_LR_CHANGE_THRESHOLD': 1.1,

  94.            'LRS': [],

  95.            'LR_POLICY': 'steps_with_decay',

  96.            'MAX_ITER': 60000,

  97.            'MOMENTUM': 0.9,

  98.            'SCALE_MOMENTUM': True,

  99.            'SCALE_MOMENTUM_THRESHOLD': 1.1,

  100.            'STEPS': [0, 30000, 40000],

  101.            'STEP_SIZE': 30000,

  102.            'WARM_UP_FACTOR': 0.3333333333333333,

  103.            'WARM_UP_ITERS': 500,

  104.            'WARM_UP_METHOD': u'linear',

  105.            'WEIGHT_DECAY': 0.0001},

  106. 'TRAIN': {'ASPECT_GROUPING': True,

  107.           'AUTO_RESUME': True,

  108.           'BATCH_SIZE_PER_IM': 256,

  109.           'BBOX_THRESH': 0.5,

  110.           'BG_THRESH_HI': 0.5,

  111.           'BG_THRESH_LO': 0.0,

  112.           'CROWD_FILTER_THRESH': 0.7,

  113.           'DATASETS': ('coco_2014_train',),

  114.           'FG_FRACTION': 0.25,

  115.           'FG_THRESH': 0.5,

  116.           'FREEZE_CONV_BODY': False,

  117.           'GT_MIN_AREA': -1,

  118.           'IMS_PER_BATCH': 2,

  119.           'MAX_SIZE': 833,

  120.           'PROPOSAL_FILES': (),

  121.           'RPN_BATCH_SIZE_PER_IM': 256,

  122.           'RPN_FG_FRACTION': 0.5,

  123.           'RPN_MIN_SIZE': 0,

  124.           'RPN_NEGATIVE_OVERLAP': 0.3,

  125.           'RPN_NMS_THRESH': 0.7,

  126.           'RPN_POSITIVE_OVERLAP': 0.7,

  127.           'RPN_POST_NMS_TOP_N': 2000,

  128.           'RPN_PRE_NMS_TOP_N': 2000,

  129.           'RPN_STRADDLE_THRESH': 0,

  130.           'SCALES': (500,),

  131.           'SNAPSHOT_ITERS': 20000,

  132.           'USE_FLIPPED': True,

  133.           'WEIGHTS': u'/tmp/detectron-download-cache/ImageNetPretrained/MSRA/R-50.pkl'},

  134. 'USE_NCCL': False,

  135. 'VIS': False,

  136. 'VIS_TH': 0.9}

  137. I0123 13:14:38.367794 36482 context_gpu.cu:325] Total: 311 MB

  138. INFO train_net.py: 330: Loading dataset: ('coco_2014_train',)

  139. loading annotations into memory...

  140. Done (t=15.17s)

  141. creating index...

  142. index created!

  143. INFO roidb.py:  49: Appending horizontally-flipped training examples...

  144. INFO roidb.py:  51: Loaded dataset: coco_2014_train

  145. INFO roidb.py: 135: Filtered 1404 roidb entries: 165566 -> 164162

  146. INFO roidb.py:  67: Computing bounding-box regression targets...

  147. INFO roidb.py:  69: done

  148. INFO roidb.py: 191: Ground-truth class histogram:

  149. INFO roidb.py: 195: 0__background__: 0

  150. INFO roidb.py: 195: 1        person: 363358

  151. INFO roidb.py: 195: 2       bicycle: 9824

  152. INFO roidb.py: 195: 3           car: 61106

  153. INFO roidb.py: 195: 4    motorcycle: 11944

  154. INFO roidb.py: 195: 5      airplane: 7656

  155. INFO roidb.py: 195: 6           bus: 8642

  156. INFO roidb.py: 195: 7         train: 6316

  157. INFO roidb.py: 195: 8         truck: 14094

  158. INFO roidb.py: 195: 9          boat: 14912

  159. INFO roidb.py: 195: 10 traffic light: 18248

  160. INFO roidb.py: 195: 11  fire hydrant: 2632

  161. INFO roidb.py: 195: 12     stop sign: 2744

  162. INFO roidb.py: 195: 13 parking meter: 1666

  163. INFO roidb.py: 195: 14         bench: 13482

  164. INFO roidb.py: 195: 15          bird: 14226

  165. INFO roidb.py: 195: 16           cat: 6598

  166. INFO roidb.py: 195: 17           dog: 7534

  167. INFO roidb.py: 195: 18         horse: 9304

  168. INFO roidb.py: 195: 19         sheep: 12916

  169. INFO roidb.py: 195: 20           cow: 11196

  170. INFO roidb.py: 195: 21      elephant: 7760

  171. INFO roidb.py: 195: 22          bear: 1806

  172. INFO roidb.py: 195: 23         zebra: 7316

  173. INFO roidb.py: 195: 24       giraffe: 7186

  174. INFO roidb.py: 199:          total: 1195680

  175. INFO train_net.py: 334: 164162 roidb entries

  176. INFO net.py:  54: Loading from: /tmp/detectron-download-cache/ImageNetPretrained/MSRA/R-50.pkl

  177. I0123 13:16:41.699045 36482 net_dag_utils.cc:118] Operator graph pruning prior to chain compute took: 0.000500389 secs

  178. I0123 13:16:41.699774 36482 net_dag.cc:61] Number of parallel execution chains 340 Number of operators = 632

  179. INFO loader.py: 232:   [62/64]

  180. INFO detector.py: 434: Changing learning rate 0.000000 -> 0.000833 at iter 0

  181. json_stats: {"accuracy_cls": 0.000000, "eta": "2 days, 6:05:39", "iter": 0, "loss": 5.814330, "loss_bbox": 0.008809, "loss_cls": 4.863443, "loss_rpn_bbox_fpn2": 0.000000, "loss_rpn_bbox_fpn3": 0.000000, "loss_rpn_bbox_fpn4": 0.002576, "loss_rpn_bbox_fpn5": 0.264878, "loss_rpn_bbox_fpn6": 0.000000, "loss_rpn_cls_fpn2": 0.455301, "loss_rpn_cls_fpn3": 0.091068, "loss_rpn_cls_fpn4": 0.022299, "loss_rpn_cls_fpn5": 0.105955, "loss_rpn_cls_fpn6": 0.000000, "lr": 0.000833, "mb_qsize": 64, "mem": 3253, "time": 3.245656}

  182. json_stats: {"accuracy_cls": 0.940430, "eta": "8:29:26", "iter": 20, "loss": 1.839182, "loss_bbox": 0.071032, "loss_cls": 0.897934, "loss_rpn_bbox_fpn2": 0.077837, "loss_rpn_bbox_fpn3": 0.005068, "loss_rpn_bbox_fpn4": 0.014110, "loss_rpn_bbox_fpn5": 0.013995, "loss_rpn_bbox_fpn6": 0.000000, "loss_rpn_cls_fpn2": 0.425642, "loss_rpn_cls_fpn3": 0.099356, "loss_rpn_cls_fpn4": 0.034078, "loss_rpn_cls_fpn5": 0.019162, "loss_rpn_cls_fpn6": 0.000000, "lr": 0.000900, "mb_qsize": 64, "mem": 3267, "time": 0.509616}



Memory 占用如下:



 

总结


Detecrton 框架给予 caffe2 和 python 接口,caffe2 对 Multi-GPU 和分布式训练提供了很好的支持,GPU 现存的利用率也大大提升,并且对很多 state-of-the-art 的方法提供了很好的 baseline 实现。相信 Detectron 框架会在未来的 computer vision 领域大放异彩。


安装小提示 1:


  1. >>> import caffe2

  2. >>> from caffe2.python import core

  3. Traceback (most recent call last):

  4.  File "<stdin>", line 1, in <module>

  5.  File "caffe2/python/core.py", line 24, in <module>

  6.    from past.builtins import basestring

  7. ImportError: No module named past.builtins

  8. >>> quit()



方法: sudo pip install future


安装小提示 2:


caffe2 安装之后需要将 caffe2 添加到 PYTHONPATH 和 LD_LIBRARY_PATH 路径

nano ~/.bashrc


输入:


  1. export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

  2. export PYTHONPATH=$PYTHONPATH:/home/huichan/caffe2/caffe2/build

  3. source ~/.bashrc




工程FAIRMask R-CNN目标检测
171
MUMOPro
中山大学・个人
先mark一下