一.理解fast-rcnn到faster-rcnn的结构
如果不理解faster-rcnn的结构就去看代码是不可能看懂的,faster-rcnn是在fast-rcnn的基础上改进的。
那么我们就先从fast-rcnn开始
(文字是跟着图片描述的)
1. 选择性搜索Selective Search(SS)在图片中获得大约2000个候选框,使用的方法是Selective Search(SS)(Region Proposa)
2. 用vgg16 前五个阶段是conv + relu + pooling的多层的卷积网络得到一些特征映射(Feature Map)
3. 得到feature map,根据之前RoI框选择出对应的区域(既可以理解为将feature map映射回原图像)
4.通过ROI Pooling得到固定大小的特征,再把这些特征输入全连接层4096。
5.最后是21和84的两个全连接层(这两个全连接层是并列的,不是前后关系),前者是分类的输出,代表每个region proposal属于每个类别(21类)的得分,后者是回归的输出,代表每个region proposal的四个坐标。
6.最后是两个损失层,分类的是softmaxWithLoss,输入是label和分类层输出的得分;回归的是SmoothL1Loss,输入是回归层的输出和target坐标及weight。
7.最后对每个类别采用NMS(non-maximun suppression)
(下面这个图细分了fast-rcnn的构造)
(下面这个是损失部分的)
接下来是faster-rcnn的结构理解
(下面这个是faster-rcnn的结构图)
faster-rcnn就是在fast-rcnn的基础上用RPN替换掉Selective Search来生成ROI(注意图中的 区域建议 是虚线的)
RPN网络输入的特征图经过RPN网络得到区域建议和区域得分,并对区域得分采用非极大值抑制【阈值为0.7】,输出其Top-N得分的区域建议给RoI池化层
(了解到这里就可以理解代码了,其余的不详解结构,给出几个网站有兴趣的可以看看:
https://www.cnblogs.com/zyly/p/9247863.html
https://www.cnblogs.com/zyly/p/9246418.html
https://www.cnblogs.com/CZiFan/p/9903518.html
https://blog.csdn.net/shenxiaolu1984/article/details/51036677
https://blog.csdn.net/gentelyang/article/details/80469553
)
二.代码解读
给出github代码链接:https://github.com/endernewton/tf-faster-rcnn
这个tf-faster-rcnn代码想要训练起来一定要花大量的时间去解决问题,非常有耐心才可以(这里不教解决bug,自己上网查进行解决)。
一般代码都有demo文件,让你初步运行查看结果和测试环境。
安装
1.在设置脚本中更新-arch以匹配GPU
cd tf-faster-rcnn/lib
# Change the GPU architecture (-arch) if necessary
vim setup.py
2.构建Cython模块
make clean
make
cd ..
3.安装Python COCO API。代码要求API访问COCO dataset
cd data
git clone https://github.com/pdollar/coco.git
cd coco/PythonAPI
make
cd ../../..
5.下载模型
./data/scripts/fetch_faster_rcnn_models.sh
4.创建一个文件夹和一个软链接来使用预训练的模型
NET=res101
TRAIN_IMDB=voc_2007_trainval+voc_2012_trainval
mkdir -p output/${NET}/${TRAIN_IMDB}
cd output/${NET}/${TRAIN_IMDB}
ln -s ../../../data/voc_2007_trainval+voc_2012_trainval ./default
cd ../../..
在路径下:tf-faster-rcnn-master/output/res101/voc_2007_trainval+voc_2012_trainval/default/ 我们可以看到如下模型
我们也从这里开始:
在目录tf-faster-rcnn-master下运行:
GPU_ID=0
CUDA_VISIBLE_DEVICES=${GPU_ID} ./tools/demo.py
一般来说是可以运行的但失败了呢?不要紧,接下来看代码,理解了代码就可以解决问题
(没必要的代码我并没有放进来)
demo.py
因为代码的跳转问题,图文讲述特别麻烦,我接下来按照这个main进行跳转
if __name__ == '__main__':
cfg.TEST.HAS_RPN = True # 将RPN用于提案
args = parse_args()
# model path
demonet = args.demo_net
dataset = args.dataset
# 模型路径
tfmodel = os.path.join('../output', demonet, DATASETS[dataset][0], 'default', NETS[demonet][0])
if not os.path.isfile(tfmodel + '.meta'):
raise IOError(('{:s} not found.\nDid you download the proper networks from '
'our server and place them properly?').format(tfmodel + '.meta'))
# set config
tfconfig = tf.ConfigProto(allow_soft_placement=True)
tfconfig.gpu_options.allow_growth = True
# init session
sess = tf.Session(config=tfconfig)
# load network
if demonet == 'vgg16':
net = vgg16()
elif demonet == 'res101':
net = resnetv1(num_layers=101)
else:
raise NotImplementedError
net.create_architecture("TEST", 21,
tag='default', anchor_scales=[8, 16, 32])
saver = tf.train.Saver()
# 加载模型
saver.restore(sess, tfmodel)
print('Loaded network {:s}'.format(tfmodel))
# 验证图片集
im_names = ['000456.jpg', '000542.jpg', '001150.jpg', '001763.jpg', '004545.jpg']
for im_name in im_names:
print('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
print('Demo for data/demo/{}'.format(im_name))
# 验证函数进入
demo(sess, net, im_name)
# 保存图片
plt.savefig(im_name)
plt.show()
parse_args()跳转
def parse_args():
"""Parse input arguments."""
parser = argparse.ArgumentParser(description='Tensorflow Faster R-CNN demo')
parser.add_argument('--net', dest='demo_net', help='Network to use [vgg16 res101]',
choices=NETS.keys(), default='res101')
parser.add_argument('--dataset', dest='dataset', help='Trained dataset [pascal_voc pascal_voc_0712]',
choices=DATASETS.keys(), default='pascal_voc_0712')
args = parser.parse_args()
return args
可以看到网络(net)用的是res101,数据集(dataset)用的是pascal_voc_0712.
(注意,没用到数据集,只是拼接路径用到pascal_voc_0712)
CLASSES = ('__background__',
'aeroplane', 'bicycle', 'bird', 'boat',
'bottle', 'bus', 'car', 'cat', 'chair',
'cow', 'diningtable', 'dog', 'horse',
'motorbike', 'person', 'pottedplant',
'sheep', 'sofa', 'train', 'tvmonitor')
NETS = {'vgg16': ('vgg16_faster_rcnn_iter_70000.ckpt',), 'res101': ('res101_faster_rcnn_iter_110000.ckpt',)}
DATASETS = {'pascal_voc': ('voc_2007_trainval',), 'pascal_voc_0712': ('voc_2007_trainval+voc_2012_trainval',)}
CLASSES : 是数据的类别名称
NETS : 是使用的网络,这里有vgg16 、res101 代码中还提供了mobile、res50、res152,也可以使用,也提供了相应的模型下载链接https://drive.google.com/drive/folders/0B1_fAEgxdnvJSmF3YUlZcHFqWTQ下载后解压放到tf-faster-rcnn-master/output/res101/voc_2007_trainval+voc_2012_trainval/default/ 路径,根据相应的进行修改代码,即可使用不同的模型
DATASETS :这里是使用相应的数据,提供我们下载的模型中有使用, voc_2007_trainval+voc_2012_trainval和coco_2014_train+coco_2014_valminusminival数据的,没有voc_2007_trainval的模型,毕竟数据越大对验证越好,这里有两种格式voc和coco的数据,代码中只提供了voc数据的模型,如果要用到coco的自行修改。
用pascal_voc代表使用数据voc_2007_trainval ( 在我们训练自己的数据的时候使用这个比较方便)
这里使用pascal_voc_0712代表使用数据voc_2007_trainval+voc_2012_trainval (当然这里只代表模型是用这个数据集进行训练的,现在还不用提供数据集)