Ejemplo n.º 1
0
def test_2layer_deconv(deconv_n4_hw4_c1_5x5):
    cf1 = ConvParams(**deconv_n4_hw4_c1_5x5)

    # 2nd layer filter
    fshape2 = (4, 3, 3)
    str_h = str_w = 2
    K, R, S = fshape2
    C, D, H, W, N = cf1.dimO  # 2nd layer input dimensions
    cf2 = ConvParams(C=C, D=D, H=H, W=W, N=N, K=K, R=R, S=S, str_h=str_h, str_w=str_w, deconv=True)

    # randomly initialize
    input_value = rng.uniform(-0.5, 0.5, cf1.ax_i)
    filter1_value = rng.uniform(-0.5, 0.5, cf1.ax_f)
    filter2_value = rng.uniform(-0.5, 0.5, cf2.ax_f)
    error_value = rng.uniform(-0.5, 0.5, cf2.ax_o)

    inputs = ng.placeholder(cf1.ax_i)
    filters1 = ng.placeholder(cf1.ax_f)
    filters2 = ng.placeholder(cf2.ax_f)
    errors = ng.placeholder(cf2.ax_o)

    out1 = ng.deconvolution(cf1.conv_params, inputs, filters1, axes=cf1.ax_o)
    out2 = ng.deconvolution(cf2.conv_params, out1, filters2, axes=cf2.ax_o)

    bprop_out = ng.deriv(out2, inputs, errors)
    updat_out2 = ng.deriv(out2, filters2, errors)
    updat_out1 = ng.deriv(out2, filters1, errors)

    with executor([out1, out2, bprop_out, updat_out1, updat_out2],
                  inputs, filters1, filters2, errors) as conv_executor:
        out1_ng, out2_ng, gradI_ng, gradF1_ng, gradF2_ng = \
            conv_executor(input_value, filter1_value, filter2_value, error_value)

    # Compute reference with NumPy
    # fprop
    out1_np = reference_deconv_fprop(cf1.conv_params, input_value, filter1_value)
    out2_np = reference_deconv_fprop(cf2.conv_params, out1_np, filter2_value)
    # bprop
    gradI2_np, gradF2_np = reference_deconv_bprop(cf2.conv_params,
                                                  error_value,
                                                  out1_np,
                                                  filter2_value)
    gradI1_np, gradF1_np = reference_deconv_bprop(cf1.conv_params,
                                                  gradI2_np,
                                                  input_value,
                                                  filter1_value)

    # Compare fprop
    assert np.allclose(out1_ng, out1_np, rtol=0.01, atol=0)
    assert np.allclose(out2_ng, out2_np, rtol=0.01, atol=0)

    # Compare bprop
    assert np.allclose(gradI_ng, gradI1_np, rtol=0.01, atol=0)

    # Compare update
    assert np.allclose(gradF1_ng, gradF1_np, rtol=0.01, atol=0)
    assert np.allclose(gradF2_ng, gradF2_np, rtol=0.01, atol=0)
Ejemplo n.º 2
0
def test_deconv(transformer_factory, deconv_n4_hw4_c1_5x5):
    cf = ConvParams(**deconv_n4_hw4_c1_5x5)

    # randomly initialize
    input_value = rng.uniform(-0.5, 0.5, cf.ax_i)
    filter_value = rng.uniform(-0.5, 0.5, cf.ax_f)
    error_value = rng.uniform(-0.5, 0.5, cf.ax_o)

    inputs = ng.placeholder(cf.ax_i)
    filters = ng.placeholder(cf.ax_f)
    errors = ng.placeholder(cf.ax_o)

    output = ng.deconvolution(cf.conv_params, inputs, filters, axes=cf.ax_o)
    bprop_out = ng.deriv(output, inputs, errors)
    updat_out = ng.deriv(output, filters, errors)

    with executor([output, bprop_out, updat_out], inputs, filters,
                  errors) as conv_executor:
        result_ng, gradI_ng, gradF_ng = conv_executor(input_value,
                                                      filter_value,
                                                      error_value)

    # Compute reference with NumPy
    result_np = reference_deconv_fprop(cf.conv_params, input_value,
                                       filter_value)
    gradI_np, gradF_np = reference_deconv_bprop(cf.conv_params, error_value,
                                                input_value, filter_value)

    # Compare fprop
    assert np.allclose(result_ng, result_np, rtol=0.1, atol=0)

    # Compare bprop
    assert np.allclose(gradI_ng, gradI_np, rtol=0.1, atol=0)

    # Compare update
    assert np.allclose(gradF_ng, gradF_np, rtol=0.1, atol=0)
Ejemplo n.º 3
0
def make_convolution_op(onnx_node, ng_inputs, transpose=False):
    # type: (NodeWrapper, List[TensorOp], bool) -> Op
    """
    Create an ngraph convolution or deconvolution Op based on an ONNX node.

    :param onnx_node: wrapped ONNX node for Conv of ConvTranspose op
    :param ng_inputs: ngraph TensorOp input tensors
    :param transpose: should this be a transposed convolution?
    :return: ngraph Op for convolution or deconvolution
    """
    if len(ng_inputs) == 3:
        x, weights, bias = ng_inputs
    elif len(ng_inputs) == 2:
        x, weights = ng_inputs
        bias = ng.constant(0)
    else:
        raise ValueError(
            'Conv node (%s): unexpected number of input values: %d.',
            onnx_node.name, len(ng_inputs))

    # Reorder x axes from ONNX convention (N, C, H, W, D) to ngraph (C, D, H, W, N)
    # Reorder weights axes from ONNX (K, J, R, S, T) to ngraph (J, T, R, S, K)
    # Axis names follow https://ngraph.nervanasys.com/index.html/axes.html
    if len(x.axes) == 4:  # 2D convolution
        x = reorder_axes(x, 'NCHW', 'CDHWN')
        weights = reorder_axes(weights, 'KJRS', 'JTRSK')
    elif len(x.axes) == 5:  # 3D convolution
        x = reorder_axes(x, 'NCHWD', 'CDHWN')
        weights = reorder_axes(weights, 'KJRST', 'JTRSK')
    else:
        raise NotImplementedError(
            'Conv node (%s): only 2D and 3D convolutions are supported.',
            onnx_node.name)

    groups = onnx_node.get_attribute_value('group', 1)
    if groups != 1:
        raise NotImplementedError(
            'Conv node (%s): `group` attribute value %d not supported.',
            onnx_node.name, groups)

    # Prepare ngraph convolution operation
    conv_params = get_conv_params(onnx_node)
    output_axes = make_conv_output_axes(x, weights, conv_params)

    if transpose:
        conv = ng.deconvolution(conv_params, x, weights, axes=output_axes)

    else:
        conv = ng.convolution(conv_params, x, weights, axes=output_axes)

    conv = cast_to_pos_axes(conv) + bias

    # ONNX output should have axes in the order N, C, H, W, D
    conv = reorder_axes(conv, 'CDHWN', 'NCHWD')

    if len(ng_inputs[0].axes
           ) == 4:  # 2D convolution, slice away the D axis from output
        conv = ng.tensor_slice(conv, [
            slice(None), slice(None),
            slice(None), slice(None), 0
        ])

    return conv