Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

scatter求导有问题 #17457

Closed
Yelrose opened this issue May 17, 2019 · 2 comments · Fixed by #18640
Closed

scatter求导有问题 #17457

Yelrose opened this issue May 17, 2019 · 2 comments · Fixed by #18640
Assignees

Comments

@Yelrose
Copy link
Contributor

Yelrose commented May 17, 2019

PaddlePaddle 1.4.1 CPU版本 MacOs
如下代码报错,估计是scatter对于update无法求导

import paddle.fluid as fluid
import numpy as np

zeros = fluid.layers.fill_constant(shape=[5, 3], dtype="float32", value=0.0)
ind = fluid.layers.data("index", shape=[2], dtype="int32", append_batch_size=False)
ori_data = fluid.layers.data("ori_data", shape=[2, 5], dtype="float32", append_batch_size=False)
update = fluid.layers.fc(ori_data, 3, act="relu")
output = fluid.layers.scatter(zeros, ind, update)
pred = fluid.layers.fc(output, 5, act="softmax")

label = fluid.layers.data("label", shape=[5, 1], dtype="int64", append_batch_size=False)
loss = fluid.layers.cross_entropy(input=pred, label=label)
loss = fluid.layers.reduce_mean(loss)

place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(program=fluid.default_startup_program())
o = np.random.randn(2, 5)
o = np.array(o, dtype="float32")

adam = fluid.optimizer.Adam(learning_rate=0.01)
adam.minimize(loss)
feed_dict = {"index": np.array([1, 3], dtype="int32"),
            "label": np.array([[1], [1], [1], [1], [1]], dtype="int64"),
            "ori_data": o
        }


ret = exe.run(fluid.default_main_program(),
            feed=feed_dict,
            fetch_list=[loss], return_numpy=True)

错误为

Traceback (most recent call last):
  File "paddle_debug.py", line 22, in <module>
    adam.minimize(loss)
  File "/anaconda2/envs/snorkel/lib/python3.6/site-packages/paddle/fluid/optimizer.py", line 498, in minimize
    no_grad_set=no_grad_set)
  File "/anaconda2/envs/snorkel/lib/python3.6/site-packages/paddle/fluid/optimizer.py", line 403, in backward
    no_grad_set, callbacks)
  File "/anaconda2/envs/snorkel/lib/python3.6/site-packages/paddle/fluid/backward.py", line 518, in append_backward
    _append_backward_vars_(root_block, fwd_op_num, grad_to_var, grad_info_map)
  File "/anaconda2/envs/snorkel/lib/python3.6/site-packages/paddle/fluid/backward.py", line 354, in _append_backward_vars_
    op_desc.infer_shape(block.desc)
paddle.fluid.core.EnforceNotMet: Enforce failed. Expected arg_names.size() == 1UL, but received arg_names.size():0 != 1UL:1.
Output(X@GRAD) should hold one element, but now it holds 0 at [/home/teamcity/work/ef54dc8a5b211854/paddle/fluid/framework/op_desc.cc:167]
PaddlePaddle Call Stacks:
0          0x11acfe454p void paddle::platform::EnforceNotMet::Init<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, char const*, int) + 628
1          0x11acfe180p paddle::platform::EnforceNotMet::EnforceNotMet(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, char const*, int) + 80
2          0x11ae4bdbfp paddle::framework::CompileTimeInferShapeContext::SetOutputDim(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, paddle::framework::DDim const&) + 319
3          0x11b073d05p paddle::operators::ScatterGradOp::InferShape(paddle::framework::InferShapeContext*) const + 485
4          0x11ae4a888p paddle::framework::OpDesc::InferShape(paddle::framework::BlockDesc const&) const + 1464
5          0x11adbba16p void pybind11::cpp_function::initialize<pybind11::cpp_function::cpp_function<void, paddle::framework::OpDesc, paddle::framework::BlockDesc const&, pybind11::name, pybind11::is_method, pybind11::sibling>(void (paddle::framework::OpDesc::*)(paddle::framework::BlockDesc const&) const, pybind11::name const&, pybind11::is_method const&, pybind11::sibling const&)::'lambda'(paddle::framework::OpDesc const*, paddle::framework::BlockDesc const&), void, paddle::framework::OpDesc const*, paddle::framework::BlockDesc const&, pybind11::name, pybind11::is_method, pybind11::sibling>(void&&, paddle::framework::OpDesc (*)(paddle::framework::BlockDesc const&), pybind11::name const&, pybind11::is_method const&, pybind11::sibling const&)::'lambda'(pybind11::detail::function_call&)::operator()(pybind11::detail::function_call&) const + 198
6          0x11acdf308p pybind11::cpp_function::dispatcher(_object*, _object*, _object*) + 3400
7          0x10678f5dap _PyCFunction_FastCallDict + 362
8          0x106715e81p _PyObject_FastCallKeywords + 385
9          0x106866688p call_function + 392
10         0x106864111p _PyEval_EvalFrameDefault + 46817
11         0x10686694cp fast_function + 188
12         0x1068665ecp call_function + 236
13         0x106864111p _PyEval_EvalFrameDefault + 46817
14         0x106857869p _PyEval_EvalCodeWithName + 425
15         0x1068669fap fast_function + 362
16         0x1068665ecp call_function + 236
17         0x106864111p _PyEval_EvalFrameDefault + 46817
18         0x106857869p _PyEval_EvalCodeWithName + 425
19         0x1068669fap fast_function + 362
20         0x1068665ecp call_function + 236
21         0x1068641c1p _PyEval_EvalFrameDefault + 46993
22         0x106857869p _PyEval_EvalCodeWithName + 425
23         0x1068669fap fast_function + 362
24         0x1068665ecp call_function + 236
25         0x106864111p _PyEval_EvalFrameDefault + 46817
26         0x106857869p _PyEval_EvalCodeWithName + 425
27         0x1068b00bcp PyRun_FileExFlags + 252
28         0x1068af594p PyRun_SimpleFileExFlags + 372
29         0x1068d61f6p Py_Main + 3766
30         0x106705d19p main + 313
31      0x7fff64399ed9p start + 1
32                 0x2p

@Yelrose
Copy link
Contributor Author

Yelrose commented May 19, 2019

目前在代码中将 zeros 设置为stop_gradient=False 能正常运行,不知道符不符合原来代码逻辑?

import paddle.fluid as fluid
import numpy as np

zeros = fluid.layers.fill_constant(shape=[5, 3], dtype="float32", value=0.0)
zeros.stop_gradient=False
ind = fluid.layers.data("index", shape=[2], dtype="int32", append_batch_size=False)
ori_data = fluid.layers.data("ori_data", shape=[2, 5], dtype="float32", append_batch_size=False)
update = fluid.layers.fc(ori_data, 3, act="relu")
output = fluid.layers.scatter(zeros, ind, update)
pred = fluid.layers.fc(output, 5, act="softmax")

label = fluid.layers.data("label", shape=[5, 1], dtype="int64", append_batch_size=False)
loss = fluid.layers.cross_entropy(input=pred, label=label)
loss = fluid.layers.reduce_mean(loss)

place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe.run(program=fluid.default_startup_program())
o = np.random.randn(2, 5)
o = np.array(o, dtype="float32")

adam = fluid.optimizer.Adam(learning_rate=0.01)
adam.minimize(loss)
feed_dict = {"index": np.array([1, 3], dtype="int32"),
            "label": np.array([[1], [1], [1], [1], [1]], dtype="int64"),
            "ori_data": o
        }


ret = exe.run(fluid.default_main_program(),
            feed=feed_dict,
            fetch_list=[loss], return_numpy=True)

@sneaxiy
Copy link
Collaborator

sneaxiy commented May 20, 2019

这个错误的原因是,scatter必须对输入input求导,但fill_constant的结果是不可求导的,即stop_gradient = True。您这种改法是对的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants