提交 1543eeb4 编写于 作者: S superjom

init

上级 9eaef753
...@@ -275,6 +275,13 @@ All parameter, weight, gradient are variables in Paddle. ...@@ -275,6 +275,13 @@ All parameter, weight, gradient are variables in Paddle.
const std::shared_ptr<operators::NetOp> &net) -> void { const std::shared_ptr<operators::NetOp> &net) -> void {
self.set_stepnet(net); self.set_stepnet(net);
}); });
rnn.def("backward", [](const operators::RecurrentOp &forwardOp,
const std::unordered_set<std::string> &no_grad_vars) {
const auto &op = *static_cast<const OperatorBase *>(&forwardOp);
return Backward(op, no_grad_vars);
});
ExposeOperator(rnn); ExposeOperator(rnn);
m.def("unique_integer", UniqueIntegerGenerator); m.def("unique_integer", UniqueIntegerGenerator);
......
...@@ -77,7 +77,6 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const { ...@@ -77,7 +77,6 @@ void RecurrentAlgorithm::CreateScopes(const Scope& scope) const {
// Now all variables in scope must be created outside of op. // Now all variables in scope must be created outside of op.
PADDLE_ENFORCE_NOT_NULL(stepnet_); PADDLE_ENFORCE_NOT_NULL(stepnet_);
PADDLE_ENFORCE(!(*stepnet_)->Outputs().empty(), "stepnet_ op has no outputs"); PADDLE_ENFORCE(!(*stepnet_)->Outputs().empty(), "stepnet_ op has no outputs");
PADDLE_ENFORCE(!(*stepnet_)->Outputs().empty(), "net_op has no outputs");
if (seq_len_ > step_scopes->size()) { if (seq_len_ > step_scopes->size()) {
for (size_t i = step_scopes->size(); i < seq_len_; ++i) { for (size_t i = step_scopes->size(); i < seq_len_; ++i) {
......
...@@ -29,13 +29,13 @@ def get_numeric_gradient(op, ...@@ -29,13 +29,13 @@ def get_numeric_gradient(op,
local_scope=None): local_scope=None):
""" """
Get Numeric Gradient for an operator's input. Get Numeric Gradient for an operator's input.
:param op: C++ operator instance, could be an network :param op: C++ operator instance, could be an network
:param input_values: The input variables. Should be an dictionary, key is :param input_values: The input variables. Should be an dictionary, key is
variable name. Value is numpy array. variable name. Value is numpy array
:param output_name: The final output variable name. :param output_name: The final output variable name.
:param input_to_check: The input variable need to get gradient. :param input_to_check: The input variable need to get gradient.
:param delta: The perturbation value for numeric gradient method. The :param delta: The perturbation value for numeric gradient method. The
smaller delta is, the more accurate result will get. But if that delta is smaller delta is, the more accurate result will get. But if that delta is
too small, it could occur numerical stability problem. too small, it could occur numerical stability problem.
:param local_scope: The local scope used for get_numeric_gradient. :param local_scope: The local scope used for get_numeric_gradient.
......
...@@ -3,6 +3,7 @@ import paddle.v2.framework.core as core ...@@ -3,6 +3,7 @@ import paddle.v2.framework.core as core
import unittest import unittest
import numpy as np import numpy as np
from paddle.v2.framework.op import Operator, RecurrentOp from paddle.v2.framework.op import Operator, RecurrentOp
from gradient_checker import GradientChecker
def py_sigmoid(x): def py_sigmoid(x):
...@@ -69,7 +70,7 @@ def create_tensor(scope, name, shape, np_data): ...@@ -69,7 +70,7 @@ def create_tensor(scope, name, shape, np_data):
return tensor return tensor
class TestRecurrentOp(unittest.TestCase): class RecurrentOpTest(unittest.TestCase):
''' '''
Test RNNOp Test RNNOp
...@@ -164,5 +165,42 @@ class TestRecurrentOp(unittest.TestCase): ...@@ -164,5 +165,42 @@ class TestRecurrentOp(unittest.TestCase):
self.assertEqual(pd_output.shape, py_output.shape) self.assertEqual(pd_output.shape, py_output.shape)
class RecurrentGradientOpTest(unittest.TestCase):
def create_forward_op(self):
self.forward_op = RecurrentOp(
# inputs
inlinks=["x"],
boot_memories=["h_boot"],
step_net="stepnet",
# outputs
outlinks=["h"],
step_scopes="step_scopes",
# attributes
inlink_alias=["x@alias"],
outlink_alias=["h@alias"],
pre_memories=["h@pre"],
memories=["h@alias"])
# create a stepnet for RNN
stepnet = core.Net.create()
x_fc_op = Operator("mul", X="x@alias", Y="W", Out="Wx")
h_fc_op = Operator("mul", X="h@pre", Y="U", Out="Uh")
sum_op = Operator("add_two", X="Wx", Y="Uh", Out="sum")
sig_op = Operator("sigmoid", X="sum", Y="h@alias")
for op in [x_fc_op, h_fc_op, sum_op, sig_op]:
stepnet.add_op(op)
stepnet.complete_add_op(True)
self.forward_op.set_stepnet(stepnet)
def create_gradient_op(self):
a = set()
backward_op = core.RecurrentOp.backward(self.forward_op, a)
def test_grad(self):
self.create_forward_op()
self.create_gradient_op()
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册