def forward_cpu(self, inputs): self.retain_inputs((1, 2)) self._bottom_data_shape = inputs[0].shape bottom_data, bottom_rois, bottom_roi_indices = inputs channels, height, width = bottom_data.shape[1:] n_rois = bottom_rois.shape[0] top_data = numpy.empty((n_rois, channels, self.outh, self.outw), dtype=bottom_data.dtype) self.argmax_data = numpy.empty(top_data.shape, numpy.int32) pooled_width, pooled_height = self.outw, self.outh spatial_scale = self.spatial_scale for i in six.moves.range(top_data.size): pw = i % pooled_width ph = int(i / pooled_width) % pooled_height c = int(i / pooled_width / pooled_height) % channels n = int(i / pooled_width / pooled_height / channels) roi_batch_ind = bottom_roi_indices[n] roi_start_h = bottom_rois[n, 0] * spatial_scale roi_start_w = bottom_rois[n, 1] * spatial_scale roi_end_h = bottom_rois[n, 2] * spatial_scale roi_end_w = bottom_rois[n, 3] * spatial_scale roi_width = max(roi_end_w - roi_start_w, 1.) roi_height = max(roi_end_h - roi_start_h, 1.) bin_size_h = roi_height / pooled_height bin_size_w = roi_width / pooled_width if self.sampling_ratio[0] is None: roi_bin_grid_h = int(numpy.ceil(roi_height / pooled_height)) else: roi_bin_grid_h = self.sampling_ratio[0] if self.sampling_ratio[1] is None: roi_bin_grid_w = int(numpy.ceil(roi_width / pooled_width)) else: roi_bin_grid_w = self.sampling_ratio[1] max_val = -numpy.inf max_index = -1 for iy in six.moves.range(roi_bin_grid_h): y = roi_start_h + ph * bin_size_h + \ (iy + .5) * bin_size_h / roi_bin_grid_h y, y_low, y_high = _get_bounds(y, height) if y is None or y_low is None or y_high is None: continue for ix in six.moves.range(roi_bin_grid_w): x = roi_start_w + pw * bin_size_w + \ (ix + .5) * bin_size_w / roi_bin_grid_w x, x_low, x_high = _get_bounds(x, width) if x is None or x_low is None or x_high is None: continue # bilinear interpolation {{ w1, w2, w3, w4 = _get_bilinear_interp_params( y, x, y_low, x_low, y_high, x_high) tmp_val = 0. if w1 > 0 and y_low >= 0 and x_low >= 0: v1 = bottom_data[roi_batch_ind, c, y_low, x_low] tmp_val += w1 * v1 if w2 > 0 and y_low >= 0 and x_high <= width - 1: v2 = bottom_data[roi_batch_ind, c, y_low, x_high] tmp_val += w2 * v2 if w3 > 0 and y_high <= height - 1 and x_low >= 0: v3 = bottom_data[roi_batch_ind, c, y_high, x_low] tmp_val += w3 * v3 if w4 > 0 and y_high <= height - 1 and x_high <= width - 1: v4 = bottom_data[roi_batch_ind, c, y_high, x_high] tmp_val += w4 * v4 tmp_index = iy * roi_bin_grid_w + ix if tmp_val > max_val: max_val = tmp_val max_index = tmp_index # }} top_data[n, c, ph, pw] = max_val self.argmax_data[n, c, ph, pw] = max_index return top_data,
def backward_cpu(self, inputs, gy): bottom_rois, bottom_roi_indices = inputs[1:] channels, height, width = self._bottom_data_shape[1:] bottom_diff = numpy.zeros(self._bottom_data_shape, gy[0].dtype) spatial_scale = self.spatial_scale pooled_height = self.outh pooled_width = self.outw top_diff = gy[0] for i in six.moves.range(top_diff.size): pw = i % pooled_width ph = int(i / pooled_width) % pooled_height c = int(i / pooled_width / pooled_height) % channels n = int(i / pooled_width / pooled_height / channels) roi_batch_ind = bottom_roi_indices[n] roi_start_h = bottom_rois[n, 0] * spatial_scale roi_start_w = bottom_rois[n, 1] * spatial_scale roi_end_h = bottom_rois[n, 2] * spatial_scale roi_end_w = bottom_rois[n, 3] * spatial_scale roi_width = max(roi_end_w - roi_start_w, 1.) roi_height = max(roi_end_h - roi_start_h, 1.) bin_size_h = roi_height / pooled_height bin_size_w = roi_width / pooled_width top_diff_this_bin = top_diff[n, c, ph, pw] max_index = self.argmax_data[n, c, ph, pw] if max_index != -1: if self.sampling_ratio[0] is None: roi_bin_grid_h = numpy.ceil(roi_height / pooled_height) else: roi_bin_grid_h = self.sampling_ratio[0] if self.sampling_ratio[1] is None: roi_bin_grid_w = numpy.ceil(roi_width / pooled_width) else: roi_bin_grid_w = self.sampling_ratio[1] iy = int(max_index / roi_bin_grid_w) ix = max_index % roi_bin_grid_w y = roi_start_h + ph * bin_size_h + \ (iy + .5) * bin_size_h / roi_bin_grid_h x = roi_start_w + pw * bin_size_w + \ (ix + .5) * bin_size_w / roi_bin_grid_w # bilinear_interpolation_gradient {{ y, y_low, y_high = _get_bounds(y, height) if y is None or y_low is None or y_high is None: continue x, x_low, x_high = _get_bounds(x, width) if x is None or x_low is None or x_high is None: continue w1, w2, w3, w4 = _get_bilinear_interp_params( y, x, y_low, x_low, y_high, x_high) if w1 > 0 and y_low >= 0 and x_low >= 0: g1 = top_diff_this_bin * w1 bottom_diff[roi_batch_ind, c, y_low, x_low] += g1 if w2 > 0 and y_low >= 0 and x_high <= width - 1: g2 = top_diff_this_bin * w2 bottom_diff[roi_batch_ind, c, y_low, x_high] += g2 if w3 > 0 and y_high <= height - 1 and x_low >= 0: g3 = top_diff_this_bin * w3 bottom_diff[roi_batch_ind, c, y_high, x_low] += g3 if w4 > 0 and y_high <= height - 1 and x_high <= width - 1: g4 = top_diff_this_bin * w4 bottom_diff[roi_batch_ind, c, y_high, x_high] += g4 # }} return bottom_diff, None, None
def backward_cpu(self, inputs, gy): bottom_rois, bottom_roi_indices = inputs[1:] channels, height, width = self._bottom_data_shape[1:] bottom_diff = numpy.zeros(self._bottom_data_shape, gy[0].dtype) spatial_scale = self.spatial_scale pooled_height = self.outh pooled_width = self.outw top_diff = gy[0] for i in six.moves.range(top_diff.size): pw = i % pooled_width ph = int(i / pooled_width) % pooled_height c = int(i / pooled_width / pooled_height) % channels n = int(i / pooled_width / pooled_height / channels) roi_batch_ind = bottom_roi_indices[n] roi_start_h = bottom_rois[n, 0] * spatial_scale roi_start_w = bottom_rois[n, 1] * spatial_scale roi_end_h = bottom_rois[n, 2] * spatial_scale roi_end_w = bottom_rois[n, 3] * spatial_scale roi_width = max(roi_end_w - roi_start_w, 1.) roi_height = max(roi_end_h - roi_start_h, 1.) bin_size_h = roi_height / pooled_height bin_size_w = roi_width / pooled_width top_diff_this_bin = top_diff[n, c, ph, pw] if self.sampling_ratio[0] is None: roi_bin_grid_h = numpy.ceil(roi_height / pooled_height) else: roi_bin_grid_h = self.sampling_ratio[0] if self.sampling_ratio[1] is None: roi_bin_grid_w = numpy.ceil(roi_width / pooled_width) else: roi_bin_grid_w = self.sampling_ratio[1] max_index = self.argmax_data[n, c, ph, pw] iy = int(max_index / roi_bin_grid_w) ix = max_index % roi_bin_grid_w y = roi_start_h + ph * bin_size_h + \ (iy + .5) * bin_size_h / roi_bin_grid_h x = roi_start_w + pw * bin_size_w + \ (ix + .5) * bin_size_w / roi_bin_grid_w # bilinear_interpolation_gradient {{ y_low, x_low, y_high, x_high, w1, w2, w3, w4 = \ _get_bilinear_interp_params(y, x, height, width) if y_low is None: continue g1 = top_diff_this_bin * w1 g2 = top_diff_this_bin * w2 g3 = top_diff_this_bin * w3 g4 = top_diff_this_bin * w4 if (x_low >= 0 and x_high >= 0 and y_low >= 0 and y_high >= 0): bottom_diff[roi_batch_ind, c, y_low, x_low] += g1 bottom_diff[roi_batch_ind, c, y_low, x_high] += g2 bottom_diff[roi_batch_ind, c, y_high, x_low] += g3 bottom_diff[roi_batch_ind, c, y_high, x_high] += g4 # }} return bottom_diff, None, None
def forward_cpu(self, inputs): self.retain_inputs((1, 2)) self._bottom_data_shape = inputs[0].shape bottom_data, bottom_rois, bottom_roi_indices = inputs channels, height, width = bottom_data.shape[1:] n_rois = bottom_rois.shape[0] top_data = numpy.empty((n_rois, channels, self.outh, self.outw), dtype=bottom_data.dtype) self.argmax_data = numpy.zeros(top_data.shape, numpy.int32) pooled_width, pooled_height = self.outw, self.outh spatial_scale = self.spatial_scale for i in six.moves.range(top_data.size): pw = i % pooled_width ph = int(i / pooled_width) % pooled_height c = int(i / pooled_width / pooled_height) % channels n = int(i / pooled_width / pooled_height / channels) roi_batch_ind = bottom_roi_indices[n] roi_start_h = bottom_rois[n, 0] * spatial_scale roi_start_w = bottom_rois[n, 1] * spatial_scale roi_end_h = bottom_rois[n, 2] * spatial_scale roi_end_w = bottom_rois[n, 3] * spatial_scale roi_width = max(roi_end_w - roi_start_w, 1.) roi_height = max(roi_end_h - roi_start_h, 1.) bin_size_h = roi_height / pooled_height bin_size_w = roi_width / pooled_width if self.sampling_ratio[0] is None: roi_bin_grid_h = numpy.ceil(roi_height / pooled_height) else: roi_bin_grid_h = self.sampling_ratio[0] if self.sampling_ratio[1] is None: roi_bin_grid_w = numpy.ceil(roi_width / pooled_width) else: roi_bin_grid_w = self.sampling_ratio[1] max_val = None max_index = None iy = 0 while iy < roi_bin_grid_h: y = roi_start_h + ph * bin_size_h + \ (iy + .5) * bin_size_h / roi_bin_grid_h ix = 0 while ix < roi_bin_grid_w: x = roi_start_w + pw * bin_size_w + \ (ix + .5) * bin_size_w / roi_bin_grid_w # bilinear interpolation {{ y_low, x_low, y_high, x_high, w1, w2, w3, w4 = \ _get_bilinear_interp_params(y, x, height, width) if y_low is None: continue v1 = bottom_data[roi_batch_ind, c, y_low, x_low] v2 = bottom_data[roi_batch_ind, c, y_low, x_high] v3 = bottom_data[roi_batch_ind, c, y_high, x_low] v4 = bottom_data[roi_batch_ind, c, y_high, x_high] tmp_val = w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4 tmp_index = iy * roi_bin_grid_w + ix if max_val is None or max_index is None \ or (tmp_val > max_val): max_val = tmp_val max_index = tmp_index # }} ix += 1 iy += 1 top_data[n, c, ph, pw] = max_val self.argmax_data[n, c, ph, pw] = max_index return top_data,
def forward_cpu(self, inputs): self.retain_inputs((1, 2)) self._bottom_data_shape = inputs[0].shape bottom_data, bottom_rois, bottom_roi_indices = inputs channels, height, width = bottom_data.shape[1:] n_rois = bottom_rois.shape[0] top_data = numpy.empty((n_rois, channels, self.outh, self.outw), dtype=bottom_data.dtype) self.argmax_data = numpy.zeros(top_data.shape, numpy.int32) pooled_width, pooled_height = self.outw, self.outh spatial_scale = self.spatial_scale for i in six.moves.range(top_data.size): pw = i % pooled_width ph = int(i / pooled_width) % pooled_height c = int(i / pooled_width / pooled_height) % channels n = int(i / pooled_width / pooled_height / channels) roi_batch_ind = bottom_roi_indices[n] roi_start_h = bottom_rois[n, 0] * spatial_scale roi_start_w = bottom_rois[n, 1] * spatial_scale roi_end_h = bottom_rois[n, 2] * spatial_scale roi_end_w = bottom_rois[n, 3] * spatial_scale roi_width = max(roi_end_w - roi_start_w, 1.) roi_height = max(roi_end_h - roi_start_h, 1.) bin_size_h = roi_height / pooled_height bin_size_w = roi_width / pooled_width if self.sampling_ratio[0] is None: roi_bin_grid_h = numpy.ceil(roi_height / pooled_height) else: roi_bin_grid_h = self.sampling_ratio[0] if self.sampling_ratio[1] is None: roi_bin_grid_w = numpy.ceil(roi_width / pooled_width) else: roi_bin_grid_w = self.sampling_ratio[1] max_val = None max_index = None iy = 0 while iy < roi_bin_grid_h: y = roi_start_h + ph * bin_size_h + \ (iy + .5) * bin_size_h / roi_bin_grid_h ix = 0 y, y_low, y_high = _get_bounds(y, height) if y is None or y_low is None or y_high is None: continue while ix < roi_bin_grid_w: x = roi_start_w + pw * bin_size_w + \ (ix + .5) * bin_size_w / roi_bin_grid_w x, x_low, x_high = _get_bounds(x, width) if x is None or x_low is None or x_high is None: continue # bilinear interpolation {{ w1, w2, w3, w4 = _get_bilinear_interp_params( y, x, y_low, x_low, y_high, x_high) v1 = bottom_data[roi_batch_ind, c, y_low, x_low] v2 = bottom_data[roi_batch_ind, c, y_low, x_high] v3 = bottom_data[roi_batch_ind, c, y_high, x_low] v4 = bottom_data[roi_batch_ind, c, y_high, x_high] tmp_val = w1 * v1 + w2 * v2 + w3 * v3 + w4 * v4 tmp_index = iy * roi_bin_grid_w + ix if max_val is None or max_index is None \ or (tmp_val > max_val): max_val = tmp_val max_index = tmp_index # }} ix += 1 iy += 1 top_data[n, c, ph, pw] = max_val self.argmax_data[n, c, ph, pw] = max_index return top_data,