代码来自https://github.com/ruotianluo/pytorch-faster-rcnn
除了nms, roi_pooling, roi_align三部分用cuda完成,其他部分都是基于pytorch完成的。
首先看一下整个文件结构(二级):
├── data
│ ├── demo
│ ├── imgs
│ └── scripts
├── experiments
│ ├── cfgs
│ ├── logs
│ └── scripts
├── lib
│ ├── datasets
│ ├── layer_utils
│ ├── make.sh
│ ├── model
│ ├── nets
│ ├── nms
│ ├── roi_data_layer
│ └── utils
└── tools
├── convert_from_tensorflow_mobile.py
├── convert_from_tensorflow.py
├── convert_from_tensorflow_vgg.py
├── demo_all_bboxes.py
├── demo.ipynb
├── demo.py
├── _init_paths.py
├── reval.py
├── test_net.py
└── trainval_net.py
主要函数都在/lib文件夹下,train和test的脚本用bash完成,在/experiments文件夹下,数据集默认存储在/data下。
下面看一下/lib文件夹的结构:
lib/
├── datasets 主要包括imdb类以及对VOC,COCO两种数据集的包装解析,可以在此基础上自定义数据集
├── layer_utils 主要包括对proposal和anchor的操作,以及roi的两个cuda实现
├── make.sh
├── model 主要负责
├── nets
├── nms
├── roi_data_layer
└── utils
重点解析/lib/net/networks.py定义的Network类:
class Network(nn.Module):
#首先来看Network类的函数:
1. train_step(self, blobs, train_op) 以及 train_step_with_summary(self, blobs, train_op)
这是两个直接被/lib/model/train_val.py中SolverWrapper类 调用的函数,在每个iter中调用一次。
train_op 传入的是 optimizer,在SolverWrapper类的construct_graph()中,定义为SGD,momentum由/lib/model/config.py定义,
事实上,几乎所有的hyperparameter都在该文件中定义。
主要来看blobs这个参数:
向前追溯,blobs=self.data_layer.forward()
我们来看看data_layer是什么:
self.data_layer = RoIDataLayer(self.roidb, self.imdb.num_classes)
from roi_data_layer.layer import RoIDataLayer
再来到/lib/roi_data_layer/layer.py:
这里定义了一个类RoIDataLayer,该类的主要功能类似一个dataloader,需要注意有几个参数,_cur表示当前的roidb序号(有一点困惑,难道不应该是imdb?),
真正返回的值实际上是调用了另一个函数get_minibatch(minibatch_db,self._num_classes)
好吧,get_minibatch.py 还是在/lib/roi_data_layer/minibatch.py 里面:
这个函数的功能更像是对roidb的内容进行了包装:
### layer_utils
def proposal_layer(rpn_cls_prob, rpn_bbox_pred, im_info, cfg_key, _feat_stride, anchors, num_anchors):
input:
1. rpn_cls_prob
rpn_cls_prob = rpn_cls_prob_reshape.view_as(rpn_cls_score).permute(0, 2, 3, 1) # batch * h * w * (num_anchors * 2)
rpn_bbox_pred