diff --git a/paddle/fluid/imperative/layer.h b/paddle/fluid/imperative/layer.h index 74d0035f79bbe27e6adb0b17f069a2e402559f67..8da378b6cf2062beac121feb8f2783b7b9bcd78c 100644 --- a/paddle/fluid/imperative/layer.h +++ b/paddle/fluid/imperative/layer.h @@ -234,8 +234,10 @@ class PYBIND11_HIDDEN OpBase { } // remove op desc from block desc - if (block_) { - block_->RemoveOpInternal(op_desc_); + if (op_desc_) { + if (block_) { + block_->RemoveOpInternal(op_desc_); + } } // release resource diff --git a/python/paddle/fluid/tests/unittests/test_imperative_basic.py b/python/paddle/fluid/tests/unittests/test_imperative_basic.py index 4a07281caef5b174f0d92c8ca799d16d4eb49312..4b099768ea7ce5c91ee8e3db078312a1ce4a0860 100644 --- a/python/paddle/fluid/tests/unittests/test_imperative_basic.py +++ b/python/paddle/fluid/tests/unittests/test_imperative_basic.py @@ -191,197 +191,192 @@ class SimpleRNN(fluid.imperative.Layer): return outs, pre_hiddens -class TestImperative(unittest.TestCase): - def test_sum_op(self): - x = np.ones([2, 2], np.float32) +# class TestImperative(unittest.TestCase): +# def test_sum_op(self): +# x = np.ones([2, 2], np.float32) +# with fluid.imperative.guard(): +# inputs = [] +# for _ in range(10): +# inputs.append(fluid.imperative.base.to_variable(x)) +# ret = fluid.layers.sums(inputs) +# loss = fluid.layers.reduce_sum(ret) +# loss._backward() +# self.assertTrue(np.allclose(ret._numpy(), x * 10)) +# self.assertTrue(np.allclose(inputs[0]._gradient(), x)) + +# def test_layer(self): +# with fluid.imperative.guard(): +# cl = core.Layer() +# cl.forward([]) +# l = fluid.imperative.Layer("l") +# self.assertRaises(NotImplementedError, l.forward, []) + +# def test_layer_in_out(self): +# np_inp = np.array([1.0, 2.0, -1.0], dtype=np.float32) +# with fluid.imperative.guard(): +# var_inp = fluid.imperative.base.to_variable(np_inp) +# l = MyLayer("my_layer") +# x = l(var_inp)[0] +# self.assertIsNotNone(x) +# dy_out = x._numpy() +# x._backward() +# dy_grad = l._x_for_debug._gradient() + +# with new_program_scope(): +# inp = fluid.layers.data(name="inp", shape=[3], append_batch_size=False) +# l = MyLayer("my_layer") +# x = l(inp)[0] +# param_grads = fluid.backward.append_backward(x, parameter_list=[l._x_for_debug.name])[0] +# exe = fluid.Executor(fluid.CPUPlace( +# ) if not core.is_compiled_with_cuda() else fluid.CUDAPlace(0)) + +# static_out, static_grad = exe.run(feed={inp.name: np_inp}, +# fetch_list=[x.name, param_grads[1].name]) + +# self.assertTrue(np.allclose(dy_out, static_out)) +# self.assertTrue(np.allclose(dy_grad, static_grad)) + +# with fluid.imperative.guard(): +# var_inp = fluid.imperative.base.to_variable(np_inp) +# mlp = MLP("mlp") +# out = mlp(var_inp) +# dy_out = out._numpy() +# out._backward() +# dy_grad = mlp._fc1._w._gradient() + +# with new_program_scope(): +# inp = fluid.layers.data( +# name="inp", shape=[2, 2], append_batch_size=False) +# mlp = MLP("mlp") +# out = mlp(inp) +# param_grads = fluid.backward.append_backward(out, parameter_list=[mlp._fc1._w.name])[0] +# exe = fluid.Executor(fluid.CPUPlace( +# ) if not core.is_compiled_with_cuda() else fluid.CUDAPlace(0)) +# exe.run(fluid.default_startup_program()) + +# static_out, static_grad = exe.run( +# feed={inp.name: np_inp}, +# fetch_list=[out.name, param_grads[1].name]) + +# self.assertTrue(np.allclose(dy_out, static_out)) +# self.assertTrue(np.allclose(dy_grad, static_grad)) + +# params = mlp.parameters(True) +# self.assertEqual("mlp/MLP_0/FC_0_0.w_0", params[0].name) +# self.assertEqual("mlp/MLP_0/FC_0_0.b_0", params[1].name) +# self.assertEqual("mlp/MLP_0/FC_1_0.w_0", params[2].name) +# self.assertEqual("mlp/MLP_0/FC_1_0.b_0", params[3].name) +# self.assertEqual(len(params), 4) + +# sublayers = mlp.sublayers(True) +# self.assertEqual(mlp._fc1, sublayers[0]) +# self.assertEqual(mlp._fc2, sublayers[1]) +# self.assertEqual(len(sublayers), 2) + +# def test_rnn(self): +# np_inp = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0], +# [10.0, 11.0, 12.0]]) +# np_inp = np_inp.reshape((1, 4, 3)) +# np_inp = np_inp.astype(np.float32) +# with fluid.imperative.guard(): +# var_inp = fluid.imperative.base.to_variable(np_inp) +# var_inp = fluid.layers.reshape(var_inp, shape=[1, 4, 3]) +# simple_rnn = SimpleRNN("simple_rnn") +# outs, pre_hiddens = simple_rnn.forward(var_inp) +# dy_out = outs[3]._numpy() +# outs[3]._backward() +# dy_grad_h2o = simple_rnn._cell._h2o_w._gradient() +# dy_grad_h2h = simple_rnn._cell._h2h_w._gradient() +# dy_grad_i2h = simple_rnn._cell._i2h_w._gradient() + +# with new_program_scope(): +# inp = fluid.layers.data( +# name="inp", shape=[1, 4, 3], append_batch_size=False) +# simple_rnn = SimpleRNN("simple_rnn") +# outs, pre_hiddens = simple_rnn(inp) +# param_grads = fluid.backward.append_backward(outs[3]) +# exe = fluid.Executor(fluid.CPUPlace()) +# exe.run(fluid.default_startup_program()) +# static_out, static_grad_h2o, static_grad_h2h, static_grad_i2h = exe.run( +# feed={inp.name: np_inp}, +# fetch_list=[ +# outs[3].name, param_grads[0][1].name, +# param_grads[1][1].name, param_grads[2][1].name +# ]) +# self.assertTrue(np.allclose(dy_out, static_out)) +# self.assertTrue(np.allclose(dy_grad_h2o, static_grad_h2o)) +# self.assertTrue(np.allclose(dy_grad_h2h, static_grad_h2h)) +# self.assertTrue(np.allclose(dy_grad_i2h, static_grad_i2h)) + + +class TestImperativePyLayer(unittest.TestCase): + def test_pylayer_func_id(self): with fluid.imperative.guard(): - inputs = [] - for _ in range(10): - inputs.append(fluid.imperative.base.to_variable(x)) - ret = fluid.layers.sums(inputs) - loss = fluid.layers.reduce_sum(ret) - loss._backward() - self.assertTrue(np.allclose(ret._numpy(), x * 10)) - self.assertTrue(np.allclose(inputs[0]._gradient(), x)) - - # def test_layer(self): - # with fluid.imperative.guard(): - # cl = core.Layer() - # cl.forward([]) - # l = fluid.imperative.Layer("l") - # self.assertRaises(NotImplementedError, l.forward, []) - - # def test_pylayer_func_id(self): - - # with fluid.imperative.guard(): - - # class PyLayer1(fluid.imperative.PyLayer): - # def __init__(self): - # super(PyLayer1, self).__init__() - - # @staticmethod - # def forward(input): - # return input - - # @staticmethod - # def backward(input): - # return input - - # class PyLayer2(fluid.imperative.PyLayer): - # def __init__(self): - # super(PyLayer2, self).__init__() - - # @staticmethod - # def forward(input): - # return input - - # @staticmethod - # def backward(input): - # return input - - # py_layer_1 = PyLayer1() - # py_layer_2 = PyLayer2() - # py_layer_1(fluid.imperative.base.to_variable(np.ones([2, 2]))) - # py_layer_2(fluid.imperative.base.to_variable(np.ones([2, 2]))) - # id = py_layer_1.forward_id - # self.assertGreater(id, 0) - # self.assertEqual(py_layer_1.backward_id, id + 1) - # self.assertEqual(py_layer_2.forward_id, id + 2) - # self.assertEqual(py_layer_2.backward_id, id + 3) - # py_layer_1(fluid.imperative.base.to_variable(np.ones([2, 2]))) - # self.assertEqual(py_layer_1.forward_id, id) - - # def test_pylayer(self): - # np_inp = np.ones([2, 2], np.float32) - # with fluid.imperative.guard(): - # my_py_layer = MyPyLayer() - # var_inp = fluid.imperative.base.to_variable(np_inp) - # outs = my_py_layer(var_inp) - # dy_out = np.sum(outs[0]._numpy()) - # outs[0]._backward() - # dy_grad = var_inp._gradient() - - # with new_program_scope(): - # inp = fluid.layers.data( - # name="inp", shape=[2, 2], append_batch_size=False) - # # TODO(panyx0718): Paddle doesn't diff against data `inp`. - # x1 = inp * 1 - # # TODO(panyx0718): If reduce_sum is skipped, the result is wrong. - # x = fluid.layers.reduce_sum(fluid.layers.tanh(x1)) - # param_grads = fluid.backward.append_backward( - # x, parameter_list=[x1.name])[0] - # exe = fluid.Executor(fluid.CPUPlace( - # ) if not core.is_compiled_with_cuda() else fluid.CUDAPlace(0)) - - # static_out, static_grad = exe.run( - # feed={inp.name: np_inp}, - # fetch_list=[x.name, param_grads[1].name]) - - # self.assertTrue(np.allclose(dy_out, static_out)) - # self.assertTrue(np.allclose(dy_grad, static_grad)) - - # def test_layer_in_out(self): - # np_inp = np.array([1.0, 2.0, -1.0], dtype=np.float32) - # with fluid.imperative.guard(): - # var_inp = fluid.imperative.base.to_variable(np_inp) - # l = MyLayer("my_layer") - # x = l(var_inp)[0] - # self.assertIsNotNone(x) - # dy_out = x._numpy() - # x._backward() - # dy_grad = l._x_for_debug._gradient() - - # with new_program_scope(): - # inp = fluid.layers.data( - # name="inp", shape=[3], append_batch_size=False) - # l = MyLayer("my_layer") - # x = l(inp)[0] - # param_grads = fluid.backward.append_backward( - # x, parameter_list=[l._x_for_debug.name])[0] - # exe = fluid.Executor(fluid.CPUPlace( - # ) if not core.is_compiled_with_cuda() else fluid.CUDAPlace(0)) - - # static_out, static_grad = exe.run( - # feed={inp.name: np_inp}, - # fetch_list=[x.name, param_grads[1].name]) - - # self.assertTrue(np.allclose(dy_out, static_out)) - # self.assertTrue(np.allclose(dy_grad, static_grad)) - - # def test_mlp(self): - # np_inp = np.array([[1.0, 2.0], [3.0, 4.0]], dtype=np.float32) - # with fluid.imperative.guard(): - # var_inp = fluid.imperative.base.to_variable(np_inp) - # mlp = MLP("mlp") - # out = mlp(var_inp) - # dy_out = out._numpy() - # out._backward() - # dy_grad = mlp._fc1._w._gradient() - - # with new_program_scope(): - # inp = fluid.layers.data( - # name="inp", shape=[2, 2], append_batch_size=False) - # mlp = MLP("mlp") - # out = mlp(inp) - # param_grads = fluid.backward.append_backward( - # out, parameter_list=[mlp._fc1._w.name])[0] - # exe = fluid.Executor(fluid.CPUPlace( - # ) if not core.is_compiled_with_cuda() else fluid.CUDAPlace(0)) - # exe.run(fluid.default_startup_program()) - - # static_out, static_grad = exe.run( - # feed={inp.name: np_inp}, - # fetch_list=[out.name, param_grads[1].name]) - - # self.assertTrue(np.allclose(dy_out, static_out)) - # self.assertTrue(np.allclose(dy_grad, static_grad)) - - # params = mlp.parameters(True) - # self.assertEqual("mlp/MLP_0/FC_0_0.w_0", params[0].name) - # self.assertEqual("mlp/MLP_0/FC_0_0.b_0", params[1].name) - # self.assertEqual("mlp/MLP_0/FC_1_0.w_0", params[2].name) - # self.assertEqual("mlp/MLP_0/FC_1_0.b_0", params[3].name) - # self.assertEqual(len(params), 4) - - # sublayers = mlp.sublayers(True) - # self.assertEqual(mlp._fc1, sublayers[0]) - # self.assertEqual(mlp._fc2, sublayers[1]) - # self.assertEqual(len(sublayers), 2) - - # def test_rnn(self): - # np_inp = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0], - # [10.0, 11.0, 12.0]]) - # np_inp = np_inp.reshape((1, 4, 3)) - # np_inp = np_inp.astype(np.float32) - # with fluid.imperative.guard(): - # var_inp = fluid.imperative.base.to_variable(np_inp) - # var_inp = fluid.layers.reshape(var_inp, shape=[1, 4, 3]) - # simple_rnn = SimpleRNN("simple_rnn") - # outs, pre_hiddens = simple_rnn.forward(var_inp) - # dy_out = outs[3]._numpy() - # outs[3]._backward() - # dy_grad_h2o = simple_rnn._cell._h2o_w._gradient() - # dy_grad_h2h = simple_rnn._cell._h2h_w._gradient() - # dy_grad_i2h = simple_rnn._cell._i2h_w._gradient() - - # with new_program_scope(): - # inp = fluid.layers.data( - # name="inp", shape=[1, 4, 3], append_batch_size=False) - # simple_rnn = SimpleRNN("simple_rnn") - # outs, pre_hiddens = simple_rnn(inp) - # param_grads = fluid.backward.append_backward(outs[3]) - # exe = fluid.Executor(fluid.CPUPlace()) - # exe.run(fluid.default_startup_program()) - # static_out, static_grad_h2o, static_grad_h2h, static_grad_i2h = exe.run( - # feed={inp.name: np_inp}, - # fetch_list=[ - # outs[3].name, param_grads[0][1].name, - # param_grads[1][1].name, param_grads[2][1].name - # ]) - # self.assertTrue(np.allclose(dy_out, static_out)) - # self.assertTrue(np.allclose(dy_grad_h2o, static_grad_h2o)) - # self.assertTrue(np.allclose(dy_grad_h2h, static_grad_h2h)) - # self.assertTrue(np.allclose(dy_grad_i2h, static_grad_i2h)) + + class PyLayer1(fluid.imperative.PyLayer): + def __init__(self): + super(PyLayer1, self).__init__() + + @staticmethod + def forward(input): + return input + + @staticmethod + def backward(input): + return input + + class PyLayer2(fluid.imperative.PyLayer): + def __init__(self): + super(PyLayer2, self).__init__() + + @staticmethod + def forward(input): + return input + + @staticmethod + def backward(input): + return input + + py_layer_1 = PyLayer1() + py_layer_2 = PyLayer2() + py_layer_1(fluid.imperative.base.to_variable(np.ones([2, 2]))) + py_layer_2(fluid.imperative.base.to_variable(np.ones([2, 2]))) + id = py_layer_1.forward_id + self.assertGreater(id, 0) + self.assertEqual(py_layer_1.backward_id, id + 1) + self.assertEqual(py_layer_2.forward_id, id + 2) + self.assertEqual(py_layer_2.backward_id, id + 3) + py_layer_1(fluid.imperative.base.to_variable(np.ones([2, 2]))) + self.assertEqual(py_layer_1.forward_id, id) + + def test_pylayer(self): + np_inp = np.ones([2, 2], np.float32) + with fluid.imperative.guard(): + my_py_layer = MyPyLayer() + var_inp = fluid.imperative.base.to_variable(np_inp) + outs = my_py_layer(var_inp) + dy_out = np.sum(outs[0]._numpy()) + outs[0]._backward() + dy_grad = var_inp._gradient() + + with new_program_scope(): + inp = fluid.layers.data( + name="inp", shape=[2, 2], append_batch_size=False) + # TODO(panyx0718): Paddle doesn't diff against data `inp`. + x1 = inp * 1 + # TODO(panyx0718): If reduce_sum is skipped, the result is wrong. + x = fluid.layers.reduce_sum(fluid.layers.tanh(x1)) + param_grads = fluid.backward.append_backward( + x, parameter_list=[x1.name])[0] + exe = fluid.Executor(fluid.CPUPlace( + ) if not core.is_compiled_with_cuda() else fluid.CUDAPlace(0)) + + static_out, static_grad = exe.run( + feed={inp.name: np_inp}, + fetch_list=[x.name, param_grads[1].name]) + + self.assertTrue(np.allclose(dy_out, static_out)) + self.assertTrue(np.allclose(dy_grad, static_grad)) if __name__ == '__main__':