Hey,
I was browsing through the code and noticed something weird. The anchors don't appear to be transformed well with regard to the ratio. As far as I know the area of the anchor shouldn't change when a different ratio is applied. However, due to a np.round in the computation, the areas of ratio-transformed anchors do change.
Here is a snippet to show what I mean:
import numpy as np
#### Code copied from https://github.com/facebookresearch/Detectron/blob/master/lib/modeling/generate_anchors.py
def _whctrs(anchor):
"""Return width, height, x center, and y center for an anchor (window)."""
w = anchor[2] - anchor[0] + 1
h = anchor[3] - anchor[1] + 1
x_ctr = anchor[0] + 0.5 * (w - 1)
y_ctr = anchor[1] + 0.5 * (h - 1)
return w, h, x_ctr, y_ctr
def _mkanchors(ws, hs, x_ctr, y_ctr):
"""Given a vector of widths (ws) and heights (hs) around a center
(x_ctr, y_ctr), output a set of anchors (windows).
"""
ws = ws[:, np.newaxis]
hs = hs[:, np.newaxis]
anchors = np.hstack(
(
x_ctr - 0.5 * (ws - 1),
y_ctr - 0.5 * (hs - 1),
x_ctr + 0.5 * (ws - 1),
y_ctr + 0.5 * (hs - 1)
)
)
return anchors
def _ratio_enum(anchor, ratios):
"""Enumerate a set of anchors for each aspect ratio wrt an anchor."""
w, h, x_ctr, y_ctr = _whctrs(anchor)
size = w * h
size_ratios = size / ratios
ws = np.round(np.sqrt(size_ratios)) # why this round?
hs = np.round(ws * ratios) # why this round?
anchors = _mkanchors(ws, hs, x_ctr, y_ctr)
return anchors
#### End code copy
anchor = np.array([0, 0, 15, 15])
print('anchor: \n', anchor)
print('anchor area: \n', (anchor[2] - anchor[0] + 1) * (anchor[3] - anchor[ 1] + 1))
transformed_anchors = _ratio_enum(anchor, np.array([0.5, 1, 2]))
transformed_areas = (transformed_anchors[:, 2] - transformed_anchors[:, 0] + 1) * (transformed_anchors[:, 3] - transformed_anchors[:, 1] + 1)
print('transformed anchors: \n', transformed_anchors)
print('transformed areas: \n', transformed_areas)
Where I get the following output:
anchor:
[ 0 0 15 15]
anchor area:
256
transformed anchors:
[[-3.5 2. 18.5 13. ]
[ 0. 0. 15. 15. ]
[ 2.5 -3. 12.5 18. ]]
transformed areas:
[276. 256. 242.]
I assume those area's should've all been 256. Is there a reason for this np.round?
ps. for comparison, if I remove those np.round's, I get the following output:
anchor:
[ 0 0 15 15]
anchor area:
256
transformed anchors:
[[-3.3137085 2.34314575 18.3137085 12.65685425]
[ 0. 0. 15. 15. ]
[ 2.34314575 -3.3137085 12.65685425 18.3137085 ]]
transformed areas:
[256. 256. 256.]
I agree that it's odd. The implementation is intended to be consistent with the original matlab Faster R-CNN implementation, which had this artifact (https://github.com/ShaoqingRen/faster_rcnn/blob/master/functions/rpn/proposal_generate_anchors.m#L54). I'd predict that in practice this particular implementation detail does not matter. If you're interested, you can test out variations to see.
Thanks for the reply @rbgirshick, that confirms my suspicion :)
Actually I've run the training once without the rounding here and didn't see any difference in performance.
Certainly, so why rounds here?
2018-03-06 1:20 GMT+08:00 Yuxin Wu notifications@github.com:
Actually I've run the training once without the rounding here and didn't
see any difference in performance.—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/facebookresearch/Detectron/issues/227#issuecomment-370494248,
or mute the thread
https://github.com/notifications/unsubscribe-auth/APROTNJIMfwKbK_l8j6aR_O2DUPOOv0mks5tbXPEgaJpZM4SbjBo
.
Wow! you are so careful.
Most helpful comment
Actually I've run the training once without the rounding here and didn't see any difference in performance.