anchor_target_layer层其他部分解读
inds_inside = np.where(
(all_anchors[:, 0] >= -self._allowed_border) &
(all_anchors[:, 1] >= -self._allowed_border) &
(all_anchors[:, 2] < im_info[1] + self._allowed_border) & # width
(all_anchors[:, 3] < im_info[0] + self._allowed_border) # height
)[0] # keep only inside anchors
anchors = all_anchors[inds_inside, :]
这部分代码是把所有anchor中超过了图片边界部分的anchor去掉,即论文中说的cross-boundary anchors
# fg label: for each gt, anchor with highest overlap
labels[gt_argmax_overlaps] = 1 # fg label: above threshold IOU
labels[max_overlaps >= cfg.TRAIN.RPN_POSITIVE_OVERLAP] = 1
这部分代码是把和gt-roi有最大iou的anchor和与任何gt-roi iou大于0.7的anchor的label置为1,即前景。这和论文中所说的是一样的。
if cfg.TRAIN.RPN_CLOBBER_POSITIVES:
# assign bg labels last so that negative labels can clobber positives
labels[max_overlaps < cfg.TRAIN.RPN_NEGATIVE_OVERLAP] = 0
把和所有gt-roi iou都小于0.3的achor的label置为0
# label: 1 is positive, 0 is negative, -1 is dont care
labels = np.empty((len(inds_inside), ), dtype=np.float32)
labels.fill(-1)
这是label的初始化的代码,所有的label都置为-1
所以总的来看,label分为3类,一类是0,即背景label;一类是1,即前景label;另一类既不是前景也不是背景,置为-1。论文中说只有前景和背景对训练目标有用,这种-1的label对训练没用。
# subsample positive labels if we have too many
num_fg = int(cfg.TRAIN.RPN_FG_FRACTION * cfg.TRAIN.RPN_BATCHSIZE)
fg_inds = np.where(labels == 1)[0]
if len(fg_inds) > num_fg: #从所有label为1的anchor中选择128个,剩下的anchor的label全部置为-1
disable_inds = npr.choice(
fg_inds, size=(len(fg_inds) - num_fg), replace=False)
labels[disable_inds] = -1 # subsample negative labels if we have too many
num_bg = cfg.TRAIN.RPN_BATCHSIZE - np.sum(labels == 1)#这里num_bg不是直接设为128,而是256减去label为1的个数,这样如果label为1的不够,就用label为0的填充,这个代码实现很巧
bg_inds = np.where(labels == 0)[0]
if len(bg_inds) > num_bg: #将没被选择作为训练的anchor的label置为-1
disable_inds = npr.choice(
bg_inds, size=(len(bg_inds) - num_bg), replace=False)
labels[disable_inds] = -1
#print "was %s inds, disabling %s, now %s inds" % (
#len(bg_inds), len(disable_inds), np.sum(labels == 0))
论文中说从所有anchor中随机选取256个anchor,前景128个,背景128个。注意:那种label为-1的不会当前景也不会当背景。
这两段代码是前一部分是在所有前景的anchor中选128个,后一部分是在所有的背景achor中选128个。如果前景的个数少于了128个,就把所有的anchor选出来,差的由背景部分补。这和fast rcnn选取roi一样。
这是论文中rpn的loss函数:

这个loss函数和fast rcnn中的loss函数差不多,所以在计算的时候是每个坐标单独进行smoothL1计算,所以参数Pi*和Nreg必须弄成4维的向量,并不是在论文中的就一个数值
bbox_inside_weights = np.zeros((len(inds_inside), 4), dtype=np.float32)
bbox_inside_weights[labels == 1, :] = np.array(cfg.TRAIN.RPN_BBOX_INSIDE_WEIGHTS) bbox_outside_weights = np.zeros((len(inds_inside), 4), dtype=np.float32)
if cfg.TRAIN.RPN_POSITIVE_WEIGHT < 0:
# uniform weighting of examples (given non-uniform sampling)
num_examples = np.sum(labels >= 0)
positive_weights = np.ones((1, 4)) * 1.0 / num_examples
negative_weights = np.ones((1, 4)) * 1.0 / num_examples
else:
assert ((cfg.TRAIN.RPN_POSITIVE_WEIGHT > 0) &
(cfg.TRAIN.RPN_POSITIVE_WEIGHT < 1))
positive_weights = (cfg.TRAIN.RPN_POSITIVE_WEIGHT /
np.sum(labels == 1))
negative_weights = ((1.0 - cfg.TRAIN.RPN_POSITIVE_WEIGHT) /
np.sum(labels == 0))
bbox_outside_weights[labels == 1, :] = positive_weights
bbox_outside_weights[labels == 0, :] = negative_weights
bbox_inside_weights实际上指的就是Pi*,bbox_outside_weights指的是Nreg。
论文中说如果anchor是前景,Pi*就是1,为背景,Pi*就是0。label为-1的,在这个代码来看也是设置为0,应该是在后面不会参与计算,这个设置为多少都无所谓。
Nreg是进行标准化操作,就是取平均。这个平均是把所有的label 0和label 1加起来。因为选的是256个anchor做训练,所以实际上这个值是1/256。
值得注意的是,rpn网络的训练是256个anchor,128个positive,128个negative。但anchor_target_layer层的输出并不是只有256个anchor的label和坐标变换,而是所有的anchor。其中_unmap函数就很好体现了这一点。那训练的时候怎么实现训练这256个呢?实际上,这一层的4个输出,rpn_labels是需要输出到rpn_loss_cls层,其他的3个输出到rpn_loss_bbox,label实际上就是loss function前半部分中的Pi*(即计算分类的loss),这是一个log loss,为-1的label是无法进行log计算的,剩下的0、1就直接计算,这一部分实现了256。loss function后半部分是计算bbox坐标的loss,Pi*,也就是bbox_inside_weights,论文中说了activated only for positive anchors,只有为正例的anchor才去计算坐标的损失,这是Pi*是1,其他情况都是0
bbox_inside_weights = np.zeros((len(inds_inside), 4), dtype=np.float32)
bbox_inside_weights[labels == 1, :] = np.array(cfg.TRAIN.RPN_BBOX_INSIDE_WEIGHTS)
这段代码也体现了这个思想,所以这也实现了256。
可以这样去理解:anchor_target_layer输出的是所有anchor的label,bbox_targets。但真正进行了loss计算的只有那256个anchor。可以看下面这个loss函数,i是anchor的下标,这个i计算是计算了所有的anchor的,但只有那256个才真正改变了loss值,其他的都是0。

_unmap函数:因为all_anchors裁减掉了2/3左右,仅仅保留在图像内的anchor。这里就是将其复原作为下一层的输入了,并reshape成相应的格式。
anchor_target_layer层其他部分解读的更多相关文章
- anchor_target_layer层解读
总结下来,用generate_anchors产生多种坐标变换,这种坐标变换由scale和ratio来,相当于提前计算好.anchor_target_layer先计算的是从feature map映射到原 ...
- Tensorflow-slim 学习笔记(二)第一层目录代码解读
通过阅读代码来学习,一向时最直接快速的.本章将讲解slim的第一层目录tensorflow/tensorflow/contrib/slim/python/slim的代码. 本层代码主要包括learni ...
- OSI七层协议大白话解读
参考链接:https://www.cnblogs.com/zx125/p/11295985.html 国际标准化组织(ISO)制定了osi七层模型,iso规定了各种各样的协议,并且分了7层 应用层 应 ...
- proposal_layer.py层解读
proposal_layer层是利用训练好的rpn网络来生成region proposal供fast rcnn使用. proposal_layer整个处理过程:1.生成所有的anchor,对ancho ...
- caffe︱ImageData层、DummyData层作为原始数据导入的应用
Part1:caffe的ImageData层 ImageData是一个图像输入层,该层的好处是,直接输入原始图像信息就可以导入分析. 在案例中利用ImageData层进行数据转化,得到了一批数据. 但 ...
- 数据通讯与网络 第五版第24章 传输层协议-UDP协议部分要点
24.1 介绍 本章节主要集中于传输层协议的解读,图24.1展示TCP.UDP.SCTP在TCP\IP协议栈的位置 24.1.1 服务(Service) 每个协议都提供不同的服务,所以应该合理正确的使 ...
- ERNIE代码解析
原创作者 |疯狂的Max ERNIE代码解读 考虑到ERNIE使用BRET作为基础模型,为了让没有基础的NLPer也能够理解代码,笔者将先为大家简略的解读BERT模型的结构,完整代码可以参见[1]. ...
- v87.01 鸿蒙内核源码分析 (内核启动篇) | 从汇编到 main () | 百篇博客分析 OpenHarmony 源码
本篇关键词:内核重定位.MMU.SVC栈.热启动.内核映射表 内核汇编相关篇为: v74.01 鸿蒙内核源码分析(编码方式) | 机器指令是如何编码的 v75.03 鸿蒙内核源码分析(汇编基础) | ...
- BiLSTM-CRF模型中CRF层的解读
转自: https://createmomo.github.io/ BiLSTM-CRF模型中CRF层的解读: 文章链接: 标题:CRF Layer on the Top of BiLSTM - 1 ...
随机推荐
- BZOJ3160【万径人踪灭】 【FFT】
..恩 打了四五遍 不会也背出来了.. BZOJ3160 [听说时限紧?转C++的优势么?] 上AC代码 fft /*Problem: 3160 User: cyz666 Language: C++ ...
- AppDomain加载与释放dll
AppDomain加载与释放dll 几年前写过同名随笔,但今天应不大适用了.但还有几个朋友留言关注,我重新发布相关代码. 首先我们的目的就是运行期间更新dll,并应用dll.这个过程需要应用 AppD ...
- Tinkoff Challenge - Elimination Round C. Mice problem(模拟)
传送门 题意 给出一个矩形的左下角和右上角的坐标,给出n个点的初始坐标和运动速度和方向,询问是否存在一个时间使得所有点都在矩形内,有则输出最短时间,否则输出-1 分析 对于每个点如果运动过程中都不在矩 ...
- WinXP下如何安装及御载MySQL服务
一.安装及御载MySQL服务点击开始->运行,输入services.msc启动服务功能,如果发现以前安装过mysql,但是突然发现MySQL服务不见了,此时可以手动安装MySQL服务. 进入my ...
- ibatais.net 连接 mysql 最全配置写法
1.安装环境: 1. vs2013 (vs开发工具) 2. mysql 5.7.10.0 (安装的mysql 数据库版本) https://dev.mysql.com/doc/ ...
- ObjectARX2012错误1 fatal error C1083: 无法打开包括文件:“arxHeaders.h”: No such file or directory; fatal error C1083: 无法打开包括文件:“map”: No such file or directory
问题1:fatal error C1083: 无法打开包括文件:“arxHeaders.h”: No such file or directory: 解决办法:这个问题很明显,是因为没有在工程属性里包 ...
- 贪心 CodeForces 124B Permutations
题目传送门 /* 贪心:全排列函数使用,更新最值 */ #include <cstdio> #include <algorithm> #include <cstring& ...
- yii2 设置多个入口文件
在web下希望加个core.php的后台入口,但因为权限问题,总是会跳转到index.php
- UWP Windows10开发更新磁贴和动态更新磁贴
下面将介绍两种方式如何在windows10 uwp开发中如何更新应用磁贴: 实际上windows的磁贴就是用xml实现的,你只需要创建相应格式的xml就可以实现动态磁贴了 一,手动更新磁贴 二,轮询更 ...
- Java 线程实例 刷碗烧水和倒计时
线程——烧水刷碗和倒计时实例 (一)烧水刷碗 刷碗的同时烧水:下面是碗的程序: 下面是烧水的程序:在水的实现类中,调用了Thread线程,让烧水刷碗同时进行. 注意:刷碗2s一次,烧水10s (二)1 ...