Exemplo n.º 1
0
    def setUp(self):
        class Model(chainer.Chain):
            def __init__(self):
                super(Model, self).__init__()

            def __call__(self, x1, x2):
                return F.concat((x1, x2))

        self.model = Model()
        self.x1 = input_generator.increasing(2, 5)
        self.x2 = input_generator.increasing(2, 4)
Exemplo n.º 2
0
    def setUp(self):
        class Model(chainer.Chain):
            def __init__(self):
                super(Model, self).__init__()
                with self.init_scope():
                    self.prelu = L.PReLU()

            def __call__(self, x, y, z):
                return F.relu(x) + self.prelu(y) * z

        self.model = Model()
        self.ins = (input_generator.increasing(1, 5),
                    input_generator.increasing(1, 5),
                    input_generator.increasing(1, 5))
        self.fn = 'MultiInputs.onnx'
Exemplo n.º 3
0
    def test_output(self):
        class Model(chainer.Chain):
            def __init__(self, value):
                super().__init__()
                self.value = value

            @as_funcnode('NumpyFull')
            def full(self, xs, value=0):
                # not support `def full(self, xs_shape, value=0)`
                # wrapped function node cannot handle shape directly yet.
                return np.full(xs.array.shape, value, dtype=np.float32)

            def __call__(self, xs):
                return F.sigmoid(self.full(xs, value=self.value))

        model = Model(value=5)
        x = input_generator.increasing(2, 3, 4)

        def numpy_full_converter(params):
            gb = onnx_helper.GraphBuilder()
            output = gb.op('Shape', params.input_names)
            value = onnx.helper.make_tensor(
                'value', onnx.TensorProto.FLOAT, [1], [params.func.value])
            gb.op_output_named(
                'ConstantOfShape', [output], params.output_names, value=value)
            return gb.nodes()

        addon_converters = {'NumpyFull': numpy_full_converter}

        self.expect(
            model, x, skip_opset_version=[7, 8],
            external_converters=addon_converters)
Exemplo n.º 4
0
def test_get_item_error(slices):
    model = chainer.Sequential(
        lambda x: F.get_item(x, slices=slices))
    x = input_generator.increasing(2, 3, 4)

    with pytest.raises(ValueError):
        export(model, x)
Exemplo n.º 5
0
    def test_output(self, name, slices):
        name = 'get_item_' + name

        model = chainer.Sequential(lambda x: F.get_item(x, slices=slices))
        x = input_generator.increasing(2, 3, 4)

        self.expect(model, x, name=name, expected_num_initializers=0)
Exemplo n.º 6
0
 def test_output(self):
     model = chainer.Sequential(
         F.where
     )
     cond = np.array([[1, 0, 0], [0, 1, 0]], dtype=np.bool)
     x = input_generator.increasing(2, 3)
     y = np.zeros((2, 3), np.float32)
     self.expect(model, (cond, x, y), skip_opset_version=[7, 8])
Exemplo n.º 7
0
    def setUp(self):
        class Model(chainer.Chain):
            def __call__(self, x):
                gamma = np.ones(x.shape[1:], dtype=x.dtype)
                beta = np.zeros(x.shape[1:], dtype=x.dtype)
                return F.batch_normalization(x, gamma, beta)

        self.model = Model()
        self.x = input_generator.increasing(2, 5)
Exemplo n.º 8
0
    def test_output(self):
        attr = None
        is_deco = False
        if self.func_kind == 'list':
            def input_converter(xs):
                return ([xs[0], xs[1]],), {}

            def target_func(xs):
                return xs[0].array + xs[1].array

        elif self.func_kind == 'list_kwargs':
            def input_converter(xs):
                return (), {'xs': [xs[0], xs[1]]}

            def target_func(xs=None):
                assert xs is not None
                return xs[0].array + xs[1].array

        elif self.func_kind == 'var_with_deco':
            def input_converter(xs):
                return (xs,), {}

            @as_funcnode('AddConstant', rename_attributes=[('b', 'value')])
            def target_func(x, b=0.01):
                return x.array + b

            is_deco = True

        elif self.func_kind == 'var_kwargs':
            def input_converter(xs):
                return (), {'x': xs, 'value': 0.02}

            def target_func(x=None, value=0.01):
                assert x is not None
                return x.array + value

        else:
            assert self.func_kind == 'var'

            def input_converter(xs):
                return (xs, 0.01), {}

            def target_func(x, value):
                return x.array + value

            attr = [(1, 'value')]

        model = self.get_model(target_func, input_converter)
        x = input_generator.increasing(*self.in_shape)

        if not is_deco:
            model.fn = fake_as_funcnode(
                model.fn, self.op_type, rename_attributes=attr)

        name = 'replace_func_' + self.func_kind
        self.expect(model, x, name=name)
Exemplo n.º 9
0
    def test_grad_error(self):
        model = self.get_model()
        # this alternative function does not return chainer.Variable
        # backward propagation will fail
        model.half = fake_as_funcnode(
            lambda xs, value=0.5: xs.array * value, 'MulConstant')
        x = input_generator.increasing(2, 5)

        with pytest.raises(ValueError):
            self.expect(model, x, output_grad=True)
Exemplo n.º 10
0
    def setUp(self):
        class Model(chainer.Chain):
            def __init__(self, ops):
                super(Model, self).__init__()
                self.ops = ops

            def __call__(self, a, b, c):
                if not isinstance(a, chainer.Variable):
                    a = chainer.Variable(a)
                if not isinstance(b, chainer.Variable):
                    b = chainer.Variable(b)
                if not isinstance(c, chainer.Variable):
                    c = chainer.Variable(c)
                return eval(self.ops)

        self.model = Model(self.ops)
        a = chainer.Variable(input_generator.increasing(2, 3))
        b = chainer.Variable(input_generator.increasing(2, 3) * 0.3)
        c = chainer.Variable(input_generator.increasing(2, 3) * 0.7)
        self.x = (a, b, c)
Exemplo n.º 11
0
 def get_x(self, in_type=None):
     base_x = (input_generator.increasing(1, 5),
               input_generator.increasing(1, 5) * 1.1,
               input_generator.increasing(1, 5) * 1.2)
     names = ['x', 'y', 'z']
     if in_type is None:
         return base_x
     elif in_type == 'list':
         return list(base_x)
     elif in_type == 'variable':
         return tuple(chainer.Variable(v) for v in base_x)
     elif in_type == 'variable_list':
         return [chainer.Variable(v) for v in base_x]
     elif in_type == 'dict':
         return {names[i]: v for i, v in enumerate(base_x)}
     elif in_type == 'variable_dict':
         return {
             names[i]: chainer.Variable(v)
             for i, v in enumerate(base_x)
         }
Exemplo n.º 12
0
    def setUp(self):
        class Model(chainer.Chain):
            def __call__(self, x, gamma, beta, mean, var):
                return F.fixed_batch_normalization(x, gamma, beta, mean, var)

        self.model = Model()
        self.x = input_generator.increasing(2, 5)
        self.mean = self.x.mean(axis=0)
        self.var = self.x.var(axis=0)
        self.gamma = np.ones_like(self.mean, dtype=self.x.dtype)
        self.beta = np.zeros_like(self.mean, dtype=self.x.dtype)
Exemplo n.º 13
0
    def test_output(self):
        class Model(chainer.Chain):
            def forward(self, x, t):
                return F.select_item(x, t)

        model = Model()
        x = input_generator.increasing(3, 5)
        t = np.array([4, 1, 0], dtype=np.int32)

        self.expect(model, (x, t),
                    expected_num_initializers=0,
                    skip_opset_version=list(range(1, 9)))
Exemplo n.º 14
0
    def test_output(self):
        class Model(chainer.Chain):
            def __init__(self):
                super(Model, self).__init__()

            def __call__(self, *xs):
                return F.transpose_sequence(xs)

        model = Model()
        xs = [input_generator.increasing(*shape) for shape in self.in_shapes]

        self.expect(model, xs, name=self.name)
Exemplo n.º 15
0
    def test_get_item_slice_step(self, name, slices):
        skip_opsets = tuple(range(7, 11))
        name = 'get_item_' + name

        model = chainer.Sequential(lambda x: F.get_item(x, slices=slices))
        x = input_generator.increasing(2, 3, 4)

        self.expect(model,
                    x,
                    name=name,
                    expected_num_initializers=0,
                    skip_opset_version=skip_opsets)
Exemplo n.º 16
0
def test_export_external_converters_custom_op(tmpdir, domain, version):
    path = str(tmpdir)

    class Dummy(chainer.FunctionNode):
        def forward_cpu(self, inputs):
            self.x = inputs[0]
            return np.ones_like(inputs[0]),

        def backward(self, indexes, grad_outputs):
            return chainer.Variable(np.zeros_like(self.x)),

    def dummy_function(x):
        return Dummy().apply((x, ))[0]

    model = chainer.Sequential(dummy_function)
    x = input_generator.increasing(2, 5)

    def custom_converter(params):
        return onnx_helper.make_node('Dummy',
                                     params.input_names,
                                     params.output_names,
                                     domain=domain),

    addon_converters = {'Dummy': custom_converter}

    # warnings list
    # 1. `external_converter` is experimental feature
    # 2. `return_named_inout` which is used internally is experimental feature
    expected_warning_num = 2
    external_opset_imports = {}
    if domain is not None:
        external_opset_imports[domain] = version
        # 3. `external_opset_imports` is experimental feature
        expected_warning_num += 1
        if not onnx_helper.is_support_non_standard_domain():
            # 4. ValidationError is ignored
            expected_warning_num += 1
    else:
        # 3. ValidationError is ignored
        expected_warning_num += 1
    with warnings.catch_warnings(record=True) as w:
        export_testcase(model,
                        x,
                        path,
                        external_converters=addon_converters,
                        external_opset_imports=external_opset_imports)
        assert len(w) == expected_warning_num

    output_path = os.path.join(path, 'test_data_set_0', 'output_0.pb')
    assert os.path.isfile(output_path)
    output = onnx.numpy_helper.to_array(onnx.load_tensor(output_path))
    expected_output = np.ones_like(x)
    np.testing.assert_allclose(output, expected_output, rtol=1e-5, atol=1e-5)
Exemplo n.º 17
0
    def setUp(self):
        class Model(chainer.Chain):
            def __init__(self, **kwargs):
                super(Model, self).__init__()
                with self.init_scope():
                    self.bn = L.BatchNormalization(5, **kwargs)

            def __call__(self, x):
                return self.bn(x)

        self.model = Model(**self.kwargs)
        self.x = input_generator.increasing(2, 5)
Exemplo n.º 18
0
    def setUp(self):
        class Model(chainer.Chain):
            def __init__(self):
                super(Model, self).__init__()
                with self.init_scope():
                    self.prelu = L.PReLU()

            def __call__(self, x):
                return self.prelu(x)

        self.model = Model()
        self.x = input_generator.increasing(2, 5)
Exemplo n.º 19
0
    def test_output(self, tmpdir):
        # first, make expected gradients to temp directory
        expected_result_path = str(tmpdir)

        model = self.get_model()
        x = input_generator.increasing(2, 5)
        export_testcase(model, x, expected_result_path, output_grad=True)

        data_set_name = 'test_data_set_0'
        expected_gradients = [
            os.path.join(expected_result_path, data_set_name,
                         'gradient_{}.pb').format(i) for i in range(2)
        ]
        assert all([os.path.isfile(path) for path in expected_gradients])

        # model.half returns chainer.Variable and enabled backward
        # regardless using replacing
        model.half = fake_as_funcnode(model.half, 'MulConstant')
        x = input_generator.increasing(2, 5)

        def gradient_check(model, path):
            actual_gradients = [
                os.path.join(path, data_set_name, 'gradient_{}.pb').format(i)
                for i in range(2)
            ]
            assert all([os.path.isfile(path) for path in actual_gradients])

            def load_tensor(path):
                tensor = onnx.load_tensor(path)
                return onnx.numpy_helper.to_array(tensor)

            for e_path, a_path in zip(expected_gradients, actual_gradients):
                expected = load_tensor(e_path)
                actual = load_tensor(a_path)
                np.testing.assert_allclose(expected, actual)

        self.expect(model,
                    x,
                    output_grad=True,
                    custom_model_test_func=gradient_check)
Exemplo n.º 20
0
    def test_output(self):
        n_layers = self.n_layers
        dropout_ratio = 0.0
        batch_size = 3
        input_size = 4
        hidden_size = 5
        seq_length = 6

        class Model(chainer.Chain):
            def __init__(self):
                super().__init__()

            def __call__(self, hx, ws1, ws2, ws3, bs, xs):
                ws = [F.separate(ws1) + F.separate(ws2)]
                if n_layers > 1:
                    ws.extend([F.separate(w) for w in F.separate(ws3)])
                bs = [F.separate(b) for b in F.separate(bs)]
                xs = F.separate(xs)
                hy, ys = F.n_step_gru(n_layers, dropout_ratio, hx, ws, bs, xs)
                return hy, F.stack(ys, axis=0)

        model = Model()

        hx = input_generator.increasing(n_layers, batch_size, hidden_size)
        ws1 = input_generator.increasing(3, hidden_size, input_size)
        ws2 = input_generator.increasing(3, hidden_size, hidden_size)
        ws3 = input_generator.increasing(n_layers - 1, 6, hidden_size,
                                         hidden_size)
        bs = input_generator.increasing(n_layers, 6, hidden_size)
        xs = input_generator.increasing(seq_length, batch_size, input_size)

        self.expect(model, (hx, ws1, ws2, ws3, bs, xs))
Exemplo n.º 21
0
    def setUp(self):
        class Model(chainer.Chain):
            def __init__(self, ops, args, input_argname):
                super(Model, self).__init__()
                self.ops = getattr(F, ops)
                self.args = args
                self.input_argname = input_argname

            def __call__(self, x):
                self.args[self.input_argname] = x
                return self.ops(**self.args)

        self.model = Model(self.ops, self.args, self.input_argname)
        self.x = input_generator.increasing(*self.input_shape)
Exemplo n.º 22
0
def test_export_external_converters_custom_op(tmpdir, domain, version):
    path = str(tmpdir)

    class Dummy(chainer.FunctionNode):
        def forward_cpu(self, inputs):
            self.x = inputs[0]
            return np.ones_like(inputs[0]),

        def backward(self, indexes, grad_outputs):
            return chainer.Variable(np.zeros_like(self.x)),

    def dummy_function(x):
        return Dummy().apply((x, ))[0]

    model = chainer.Sequential(dummy_function)
    x = input_generator.increasing(2, 5)

    def custom_converter(params):
        return onnx_helper.make_node('Dummy',
                                     params.input_names,
                                     params.output_names,
                                     domain=domain),

    addon_converters = {'Dummy': custom_converter}

    external_opset_imports = {}
    is_set_domain = domain is not None
    if is_set_domain:
        external_opset_imports[domain] = version
    if is_set_domain and onnx_helper.is_support_non_standard_domain():
        export_testcase(model,
                        x,
                        path,
                        external_converters=addon_converters,
                        external_opset_imports=external_opset_imports)
    else:
        with testing.assert_warns(UserWarning):
            export_testcase(model,
                            x,
                            path,
                            external_converters=addon_converters,
                            external_opset_imports=external_opset_imports)

    output_path = os.path.join(path, 'test_data_set_0', 'output_0.pb')
    assert os.path.isfile(output_path)
    output = onnx.numpy_helper.to_array(onnx.load_tensor(output_path))
    expected_output = np.ones_like(x)
    np.testing.assert_allclose(output, expected_output, rtol=1e-5, atol=1e-5)
Exemplo n.º 23
0
    def setUp(self):
        class Model(chainer.Chain):
            def __init__(self, ops, args):
                super(Model, self).__init__()
                self.ops = ops
                self.args = args

            def __call__(self, x):
                return self.ops(x, **self.args)

        ops = getattr(F, self.name)
        args = {}
        if hasattr(self, 'args'):
            args = self.args
        self.model = Model(ops, args)
        self.x = input_generator.increasing(2, 5, 3)
Exemplo n.º 24
0
    def setUp(self):
        class Model(chainer.Chain):
            def __init__(self, link, args, kwargs):
                super(Model, self).__init__()
                with self.init_scope():
                    self.l1 = link(*args, **kwargs)

            def __call__(self, x):
                return self.l1(x)

        self.model = Model(self.link, self.args, self.kwargs)
        if self.link is L.EmbedID:
            self.x = np.random.randint(0, self.args[0], size=self.in_shape)
            self.x = self.x.astype(self.in_type)
        else:
            self.x = input_generator.increasing(*self.in_shape,
                                                dtype=self.in_type)
Exemplo n.º 25
0
def test_fake_as_funcnode_without_replace():

    class Model(chainer.Chain):
        def _init__(self):
            super().__init__()

        def add(self, xs, value=0.01):
            return xs.array + value

        def __call__(self, xs):
            return F.sigmoid(self.add(xs))

    model = Model()
    x = input_generator.increasing(3, 4)

    with pytest.raises(onnx.checker.ValidationError):
        export(model, x)
Exemplo n.º 26
0
def test_replace_func_collection_return(tmpdir, return_type):
    path = str(tmpdir)

    class Model(chainer.Chain):
        def __init__(self, return_type):
            super().__init__()
            self.return_type = return_type

        def tiled_array(self, xs, n=5):
            if self.return_type == 'list':
                return [xs.array * i for i in range(1, 1+n)]
            else:
                assert self.return_type == 'dict'
                return {str(i): xs.array * i for i in range(1, 1+n)}

        def __call__(self, xs):
            return self.tiled_array(xs)

    model = Model(return_type)
    x = input_generator.increasing(1, 5)

    with warnings.catch_warnings(record=True):
        model.tiled_array = fake_as_funcnode(model.tiled_array, 'xTiledArray')

    def tiled_array_converter(params):
        return onnx_helper.make_node(
            'xTiledArray', params.input_names, params.output_names),

    addon_converters = {'xTiledArray': tiled_array_converter}

    with testing.assert_warns(UserWarning):
        export_testcase(model, x, path, external_converters=addon_converters)

    model_filepath = os.path.join(path, 'model.onnx')
    assert os.path.isfile(model_filepath)

    onnx_model = onnx.load(model_filepath)
    node_names = [n.name for n in onnx_model.graph.node]
    assert len(node_names) == 1
    assert node_names[0] == 'xTiledArray_0'
    output_names = [n.name for n in onnx_model.graph.output]
    assert len(output_names) == 5
    for i, name in enumerate(output_names):
        assert name == 'xTiledArray_0_{:d}'.format(i)
Exemplo n.º 27
0
    def test_output(self):

        class Model(chainer.Chain):
            def __init__(self, ops, kwargs):
                super(Model, self).__init__()
                self.ops = getattr(F, ops)
                self.kwargs = kwargs

            def __call__(self, *xs):
                return self.ops(xs, **self.kwargs)

        model = Model(ops=self.ops, kwargs=self.kwargs)
        if hasattr(self, 'inputs'):
            xs = [np.array(value, dtype=np.float32) for value in self.inputs]
        else:
            xs = [input_generator.increasing(*shape) for
                  shape in self.in_shapes]

        self.expect(model, xs, name=self.name)
Exemplo n.º 28
0
    def test_output(self):
        from onnx_chainer.replace_func import as_funcnode

        class Model(chainer.Chain):
            def __init__(self):
                super().__init__()

            @as_funcnode('Shape')
            def shape(self, x):
                # ONNX Shape operator constrains to return int64 type
                return np.array(x.shape, dtype=np.int64)

            def forward(self, x):
                # use shape method instead of x.shape to connect graph.
                return self.shape(x)

        model = Model()
        x = input_generator.increasing(3, 4, 5)

        self.expect(model, (x,))
Exemplo n.º 29
0
def test_fake_as_funcnode_without_replace():

    class Model(chainer.Chain):
        def _init__(self):
            super().__init__()

        def add(self, xs, value=0.01):
            return xs.array + value

        def __call__(self, xs):
            return F.sigmoid(self.add(xs))

    model = Model()
    x = input_generator.increasing(3, 4)

    onnx_model = export(model, x)
    sigmoid_nodes = [
        node for node in onnx_model.graph.node if node.op_type == 'Sigmoid']
    assert len(sigmoid_nodes) == 1
    # sigmoid node should be expected to connect with input
    # but the connection is cut because `add` method takes array.
    assert not sigmoid_nodes[0].input[0] == 'Input_0'
Exemplo n.º 30
0
def test_fake_as_funcnode_keep_structure(tmpdir):
    path = str(tmpdir)

    class Model(chainer.Chain):
        def __init__(self):
            super().__init__()

        def f(self, x):
            return {'a': (x, x+1), 'b': [x+2, x+3, x+4]}

        def __call__(self, x):
            ret = self.f(x)
            return ret['a'][0] + ret['b'][1]

    model = Model()
    x = input_generator.increasing(2, 3)

    with warnings.catch_warnings(record=True):
        model.f = fake_as_funcnode(model.f, 'xF')

    def f_converter(params):
        return onnx_helper.make_node(
            'xF', params.input_names, params.output_names),

    addon_converters = {'xF': f_converter}

    with testing.assert_warns(UserWarning):
        export_testcase(model, x, path, external_converters=addon_converters)
        export_testcase(model, x, ".", external_converters=addon_converters)

    model_filepath = os.path.join(path, 'model.onnx')
    assert os.path.isfile(model_filepath)

    onnx_model = onnx.load(model_filepath)
    node_names = [n.name for n in onnx_model.graph.node]
    assert len(node_names) == 2
    assert node_names[0] == 'xF_0'
    assert len(onnx_model.graph.node[0].output) == 5
    assert len(onnx_model.graph.output) == 1