This is an automated email from the ASF dual-hosted git repository.
marcoabreu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
The following commit(s) were added to refs/heads/master by this push:
new 2b4d512 fix flasky unittest for deformable psroi pooling (#12178)
2b4d512 is described below
commit 2b4d5120d0bd28c7b73acb286f61bcbc2f3505f3
Author: Haozhi Qi <[email protected]>
AuthorDate: Fri Aug 17 09:44:05 2018 -0700
fix flasky unittest for deformable psroi pooling (#12178)
* fix flasky unittest for deformable psroi pooling
* Fix incorrect gpu specification
---
tests/python/unittest/test_operator.py | 79 ++++++++++++++++++++++++++++------
1 file changed, 66 insertions(+), 13 deletions(-)
diff --git a/tests/python/unittest/test_operator.py
b/tests/python/unittest/test_operator.py
index 1c0f940..3f8846f 100644
--- a/tests/python/unittest/test_operator.py
+++ b/tests/python/unittest/test_operator.py
@@ -5015,23 +5015,80 @@ def test_deformable_convolution():
grad_nodes=grad_nodes,
ctx=mx.gpu(0))
-# Seed set because the test is not robust enough to operate on random data.
Repro issue with:
-# MXNET_TEST_SEED=1234 nosetests --verbose
tests/python/gpu/test_operator_gpu.py:test_deformable_psroipooling
-@with_seed(0)
+def _validate_sample_location(input_rois, input_offset, spatial_scale,
pooled_w, pooled_h, sample_per_part, part_size, output_dim, num_classes,
trans_std, feat_h, feat_w):
+ num_rois = input_rois.shape[0]
+ output_offset = input_offset.copy()
+ # simulate deformable psroipooling forward function
+ for roi_idx in range(num_rois):
+ sub_rois = input_rois[roi_idx, :].astype(np.float32)
+ img_idx, x0, y0, x1, y1 = int(sub_rois[0]), sub_rois[1], sub_rois[2],
sub_rois[3], sub_rois[4]
+ roi_start_w = round(x0) * spatial_scale - 0.5
+ roi_start_h = round(y0) * spatial_scale - 0.5
+ roi_end_w = round(x1 + 1) * spatial_scale - 0.5
+ roi_end_h = round(y1 + 1) * spatial_scale - 0.5
+ roi_w, roi_h = roi_end_w - roi_start_w, roi_end_h - roi_start_h
+ bin_size_w, bin_size_h = roi_w / pooled_w, roi_h / pooled_h
+ sub_bin_size_w, sub_bin_size_h = bin_size_w / sample_per_part,
bin_size_h / sample_per_part
+ for c_top in range(output_dim):
+ channel_each_cls = output_dim / num_classes
+ class_id = int(c_top / channel_each_cls)
+ for ph in range(pooled_h):
+ for pw in range(pooled_w):
+ part_h = int(math.floor(float(ph) / pooled_h * part_size))
+ part_w = int(math.floor(float(pw) / pooled_w * part_size))
+ trans_x = input_offset[roi_idx, class_id * 2, part_h,
part_w] * trans_std
+ trans_y = input_offset[roi_idx, class_id * 2 + 1, part_h,
part_w] * trans_std
+ bin_h_start, bin_w_start = ph * bin_size_h + roi_start_h,
pw * bin_size_w + roi_start_w
+
+ need_check = True
+ while need_check:
+ pass_check = True
+ for ih in range(sample_per_part):
+ for iw in range(sample_per_part):
+ h = bin_h_start + trans_y * roi_h + ih *
sub_bin_size_h
+ w = bin_w_start + trans_x * roi_w + iw *
sub_bin_size_w
+
+ if w < -0.5 or w > feat_w - 0.5 or h < -0.5 or
h > feat_h - 0.5:
+ continue
+
+ w = min(max(w, 0.1), feat_w - 1.1)
+ h = min(max(h, 0.1), feat_h - 1.1)
+ # if the following condiiton holds, the
sampling location is not differentiable
+ # therefore we need to re-do the sampling
process
+ if h - math.floor(h) < 1e-3 or math.ceil(h) -
h < 1e-3 or w - math.floor(w) < 1e-3 or math.ceil(w) - w < 1e-3:
+ trans_x, trans_y = random.random() *
trans_std, random.random() * trans_std
+ pass_check = False
+ break
+ if not pass_check:
+ break
+ if pass_check:
+ output_offset[roi_idx, class_id * 2 + 1, part_h,
part_w] = trans_y / trans_std
+ output_offset[roi_idx, class_id * 2, part_h,
part_w] = trans_x / trans_std
+ need_check = False
+
+ return output_offset
+
+@with_seed()
def test_deformable_psroipooling():
+ sample_per_part = 4
+ trans_std = 0.1
for num_rois in [1, 2]:
for num_classes, num_group in itertools.product([2, 3], [2, 3]):
- for image_height, image_width in itertools.product([168, 224],
[168, 224]):
+ for image_height, image_width in itertools.product([160, 224],
[160, 224]):
for grad_nodes in [['im_data'], ['offset_data']]:
spatial_scale = 0.0625
+ stride = int(1 / spatial_scale)
feat_height = np.int(image_height * spatial_scale)
feat_width = np.int(image_width * spatial_scale)
im_data = np.random.rand(1,
num_classes*num_group*num_group, feat_height, feat_width)
rois_data = np.zeros([num_rois, 5])
- rois_data[:, [1,3]] = np.sort(np.random.rand(num_rois,
2)*(image_width-1))
- rois_data[:, [2,4]] = np.sort(np.random.rand(num_rois,
2)*(image_height-1))
- offset_data = np.random.rand(num_rois, 2*num_classes,
num_group, num_group) * 0.1
-
+ rois_data[:, [1,3]] = np.sort(np.random.rand(num_rois,
2)*(image_width-1 - 2 * stride)) + stride
+ rois_data[:, [2,4]] = np.sort(np.random.rand(num_rois,
2)*(image_height-1 - 2 * stride)) + stride
+ offset_data = np.random.rand(num_rois, 2*num_classes,
num_group, num_group)
+ # at certain points, the bilinear interpolation function
may be non-differentiable
+ # to avoid this, we check whether the input locates on the
valid points
+ offset_data = _validate_sample_location(rois_data,
offset_data, spatial_scale, num_group, num_group,
+ sample_per_part,
num_group, num_classes, num_classes, trans_std, feat_height, feat_width)
im_data_var = mx.symbol.Variable(name="im_data")
rois_data_var = mx.symbol.Variable(name="rois_data")
offset_data_var = mx.symbol.Variable(name="offset_data")
@@ -5040,11 +5097,7 @@ def test_deformable_psroipooling():
sample_per_part=4, group_size=num_group,
pooled_size=num_group, output_dim=num_classes,
trans_std=0.1,
no_trans=False, name='test_op')
- if grad_nodes[0] == 'offset_data':
- # wider tolerance needed for coordinate differential
- rtol, atol = 1.0, 1e-2
- else:
- rtol, atol = 1e-2, 1e-3
+ rtol, atol = 1e-2, 1e-3
# By now we only have gpu implementation
if default_context().device_type == 'gpu':
check_numeric_gradient(op, [im_data, rois_data,
offset_data], rtol=rtol, atol=atol,