def visit(self, op, *args): self.computation.set_op_rank(op) # op.args[0] : delta # op.args[1] : filters # op.fprop.args[0] : fprop data batch shape # op.fprop.conv_params : forward params delta = args[0] filters = args[1] data = op.fprop.args[0] conv_params = op.fprop.conv_params """ print(delta.axes) print(filters.axes) print(data.axes) print(conv_params) """ ngraph_bprop_conv = PyngConvolutionBackpropData( Shape(list(data.axes.lengths)), self.computation.lookup_cpp_op(filters), self.computation.lookup_cpp_op(delta), Strides([conv_params['str_h'], conv_params['str_w']]), Strides([conv_params['dil_h'], conv_params['dil_w']]), CoordinateDiff([conv_params['pad_h'], conv_params['pad_w']]), CoordinateDiff([conv_params['pad_h'], conv_params['pad_w']]), Strides([1, 1])) ngraph_bprop_conv.name = op.name.replace( '/', '_') + "_ConvolutionBackpropData" self.computation.register_cpp_op(op, ngraph_bprop_conv, set_name=False)
def test_convolutionBackpropData(): element_type = Type.f32 image_shape = Shape([1, 1, 10, 10]) filter_shape = Shape([1, 1, 3, 3]) output_shape = Shape([1, 1, 17, 17]) image_arr = np.arange(100, dtype=np.float32).reshape(1, 1, 10, 10) filter_arr = np.ones(9, dtype=np.float32).reshape(1, 1, 3, 3) window_strides = [1, 1] window_dilation = [1, 1] padding_below = [0, 0] padding_above = [0, 0] data_dilation = [2, 2] output_arr = convolution2d(image_arr[0][0], filter_arr[0][0], window_strides, window_dilation, padding_below, padding_above, data_dilation).reshape(1, 1, 17, 17) A = Parameter(element_type, filter_shape) B = Parameter(element_type, output_shape) parameter_list = [A, B] function = Function( NodeVector([ ConvolutionBackpropData(image_shape, A, B, Strides(window_strides), Strides(window_dilation), CoordinateDiff(padding_below), CoordinateDiff(padding_above), Strides(data_dilation)) ]), parameter_list, 'test') backend, cf = make_backend_call_frame(function) a = backend.make_primary_tensor_view(element_type, filter_shape) b = backend.make_primary_tensor_view(element_type, output_shape) a.write(util.numpy_to_c(filter_arr), 0, 3 * 3 * 4) b.write(util.numpy_to_c(output_arr), 0, 17 * 17 * 4) result_arr = np.zeros(10 * 10, dtype=np.float32).reshape(1, 1, 10, 10) result = backend.make_primary_tensor_view(element_type, Shape([1, 1, 10, 10])) result.write(util.numpy_to_c(result_arr), 0, 10 * 10 * 4) cf.call([result], [a, b]) result.read(util.numpy_to_c(result_arr), 0, 10 * 10 * 4) result_arr_ref = np.array( [[[[22, 60, 70, 80, 90, 100, 110, 120, 130, 54.], [105, 275, 300, 325, 350, 375, 400, 425, 450, 185.], [205, 525, 550, 575, 600, 625, 650, 675, 700, 285.], [305, 775, 800, 825, 850, 875, 900, 925, 950, 385.], [405, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 485.], [505, 1275, 1300, 1325, 1350, 1375, 1400, 1425, 1450, 585.], [605, 1525, 1550, 1575, 1600, 1625, 1650, 1675, 1700, 685.], [705, 1775, 1800, 1825, 1850, 1875, 1900, 1925, 1950, 785.], [805, 2025, 2050, 2075, 2100, 2125, 2150, 2175, 2200, 885.], [342, 860, 870, 880, 890, 900, 910, 920, 930, 374.]]]]) assert np.allclose(result_arr, result_arr_ref)
def convolution_backprop_data( data_batch_shape, # type: TensorShape filters, # type: Node output_delta, # type: Node window_movement_strides_forward=None, # type: List[int] window_dilation_strides_forward=None, # type: List[int] padding_below_forward=None, # type: List[int] padding_above_forward=None, # type: List[int] data_dilation_strides_forward=None, # type: List[int] name=None, # type: str ): # type: (...) -> Node """Return node performing a batched-convolution data batch-backprop operation. :param data_batch_shape: The shape of the data batch from forward-prop. :param filters: The node producing the filters from forward-prop. :param output_delta: The node producing output delta. :param window_movement_strides_forward: The window movement strides from forward-prop. :param window_dilation_strides_forward: The window dilation strides from forward-prop. :param padding_below_forward: The padding-below sizes from forward-prop. :param padding_above_forward: The padding-above sizes from forward-prop. :param data_dilation_strides_forward: The data dilation strides from forward-prop. """ spatial_dim_count = len(data_batch_shape) - 2 if window_movement_strides_forward is None: window_movement_strides_forward = [1] * spatial_dim_count if window_dilation_strides_forward is None: window_dilation_strides_forward = [1] * spatial_dim_count if padding_below_forward is None: padding_below_forward = [0] * spatial_dim_count if padding_above_forward is None: padding_above_forward = [0] * spatial_dim_count if data_dilation_strides_forward is None: data_dilation_strides_forward = [1] * spatial_dim_count return ConvolutionBackpropData(Shape(data_batch_shape), filters, output_delta, Strides(window_movement_strides_forward), Strides(window_dilation_strides_forward), CoordinateDiff(padding_below_forward), CoordinateDiff(padding_above_forward), Strides(data_dilation_strides_forward))