Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请问一下边框回归模型的计算方式是怎么来的 #1

Open
Ostnie opened this issue May 17, 2018 · 5 comments
Open

请问一下边框回归模型的计算方式是怎么来的 #1

Ostnie opened this issue May 17, 2018 · 5 comments

Comments

@Ostnie
Copy link

Ostnie commented May 17, 2018

我在看RCNN论文时就是没看懂边框回归这一块应该如何实现,我现在最大的疑问是您代码的边框回归为什么会产生五个值,第一个表示什么?这个我在作者的论文中完全没有看到,能不能解释一下

以及,为什么边框回归的训练数据是用的4096维的特征数据,按说不应该就是这些区域的图片信息么?
image

@zceng
Copy link

zceng commented May 25, 2018

最近,我在研究RCNN论文,对于你的这两个问题其实可以在论文的 Appendix C.Bounding-box regression 中找到。

  1. 针对第一个问题,为什么边框回归得到的是五个值。

首先,后四个值(第2个值到第5个值)表示当前的边框与真实目标边框的误差,分别表示边框中心的偏差率($t_x,t_y$)和边框宽高的偏差率($t_w,t_h$)。这些偏差率是真实偏差值与当前边框宽高的比值,具体可见论文Appendix C,这里贴出论文的部分截图:
image
其中,$(P_x,P_y,P_w,P_h)$ 表示当前的边框,$(G_x,G_y,G_w,G_h)$表示真实目标边框。

其次,边框框回归得到的第一个值,是表示该当前边框与真实目标边框是否十分接近。如果很接近(即偏差小),则采用后四位的偏差率;否则,舍弃后四位的值,即当前边框与真实边框相差太大,不适合估计进一步估计真实边框位置。对于这一接近程度的描述,是设置阈值F_regression_threshold,如果当前边框与真实边框的IOU大于这一阈值,则表示接近(此时边框回归的第一个值取1,否则取0) 。这一部分论文只是稍加提及,具体可见下图的划线部分:
2018-05-25_173813
这一部分的实现可以参考代码 process_data.py 的第 300~314 行。

  1. 针对第二个问题,为什么边框回归的训练数据是用的4096维的特征数据。

论文有提到边框回归是利用CNN网络提取的特征来进行,因此,边框回归的训练数据是AlexNet卷积层池化后(全连接层前)的图像特征,其维度是4096。而标签即为第一个问题所提到的。
image

以上为我对论文以及代码的一些理解,如果有疑问,非常希望能够进一步讨论。如有错误,迫切希望能够你能够指出。

@Ostnie
Copy link
Author

Ostnie commented May 27, 2018

@JackZiLong 不得不说你读的非常细,你的回答很好地解决了我的问题,感谢

我在一个阐述RCNN问题的博客看到这样一句话:20类即20个Bounding-box 回归器训练,每一类需要一个独立的回归器训练吗?我在作者的代码中看到的只是训练了一个回归器,这一块的矛盾问题出在哪里?

下一步我打算接着看fast rcnn,希望能继续和你一起讨论学习,同时我想问个题外话,就是你是否有看到过比较好的RCNN的keras实现,我现在希望变看代码边看论文学习,多版本的代码更有助于我自己在实现时候的学习

@zceng
Copy link

zceng commented May 27, 2018

@Ostnie 非常感谢你的认同

你提到的针对每一个类别分别需要独立的训练一个Bounding-box 回归器,论文我没有找到详细的说明。不过我从论文作者的 R-CNN 代码中找到具体的实现过程,可以发现你的说法是对的,即20个类需要20个Bounding-box 回归器训练。

如果对你对这些实现细节感兴趣,可以尝试阅读具体代码(RCNN),不过原作者是用matlab实现,且代码中存在很多其他方面的处理,阅读起来可能不是特别好理解。但是,我们只需要注意“Bounding-box 回归器训练是否针对每个类别单独训练”,这样我们只需要理解代码 bbox_regression/rcnn_train_bbox_regressor.m 中的第 76~111 行。我在这里列出了我对这部分的理解:

models = cell(num_clss, 1);
for i = 1:num_clss
  fprintf('Training regressors for class %s (%d/%d)\n', ...
      rcnn_model.classes{i}, i, num_clss);
  % ...
  % 省略的这一部分是利用 SVD 来求解bbox_regressor线性模型 
  % 其中, X为CNN网络pool5 层输出的特征,Y为bbox_regressor线性模型回归目标(4维)

  models{i}.mu = mu;
  models{i}.T = T;
  models{i}.T_inv = T_inv;

  models{i}.Beta = [ ...
    solve_robust(Xi, Yi(:,1), opts.lambda, method, opts.robust) ...
    solve_robust(Xi, Yi(:,2), opts.lambda, method, opts.robust) ...
    solve_robust(Xi, Yi(:,3), opts.lambda, method, opts.robust) ...
    solve_robust(Xi, Yi(:,4), opts.lambda, method, opts.robust)];
end

可以发现,对于每一个类别i,论文作者单独训练了一个model。同时你会发现,这里的Bounding-box 回归器得到的是4个值,与这里的代码也不一样。

另外,再多说一点我的个人理解,Github上有很多关于 RCNN、Fast RCNN 等的实现,每个人都会根据自己的理解以及实际应用情况添加或删减一些实现细节,不过我们可以结合多份 代码实现过程 来保证某些重要细节不会被我们忽略,但具体求证还是以 原论文作者的 代码实现为准。不过,回过头来考虑,我们阅读论文只是理解其论文思想就行,代码只是帮助我们理解。因为这些细节很可能在后来的技术取代掉,比如这一部分在 Faster-RCNN 就被取缔。

这里列出我参考的github:

@Ostnie
Copy link
Author

Ostnie commented May 28, 2018

@JackZiLong 感谢,你严谨且热心的态度是我的榜样,向你学习!

@oftenliu
Copy link

想请教下,分析可以得到log(p_w/g_w)和t_w在一定条件下是线性分布,但实际我们需要处理的是(pool5的特征,t)这个数据,(log(p_w/g_w),t_w)符合线性分布,(pool5的特征,t)就符合线性分布吗

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants