未验证 提交 a646e75f 编写于 作者: J JYChen 提交者: GitHub

[Fluid Clean] remove module fluid.layers.control_flow (#55661)

* remove api staticrnn

* move select_input/output to static/controw flow

* delete some func, only remain Switch

* clean fluid.layers.controw_flow

* remove fluid.layers.controlflow

* fix conditional_block ut
上级 40cf6e64
...@@ -18,8 +18,6 @@ from . import io ...@@ -18,8 +18,6 @@ from . import io
from .io import * from .io import *
from . import tensor from . import tensor
from .tensor import * from .tensor import *
from . import control_flow
from .control_flow import *
from . import math_op_patch from . import math_op_patch
from .math_op_patch import * from .math_op_patch import *
from .learning_rate_scheduler import * from .learning_rate_scheduler import *
...@@ -30,5 +28,4 @@ __all__ = [] ...@@ -30,5 +28,4 @@ __all__ = []
__all__ += nn.__all__ __all__ += nn.__all__
__all__ += io.__all__ __all__ += io.__all__
__all__ += tensor.__all__ __all__ += tensor.__all__
__all__ += control_flow.__all__
__all__ += learning_rate_scheduler.__all__ __all__ += learning_rate_scheduler.__all__
此差异已折叠。
...@@ -24,7 +24,6 @@ import math ...@@ -24,7 +24,6 @@ import math
import numbers import numbers
import paddle import paddle
from . import control_flow
from . import nn from . import nn
from . import tensor from . import tensor
from ..framework import ( from ..framework import (
...@@ -434,8 +433,7 @@ def piecewise_decay(boundaries, values): ...@@ -434,8 +433,7 @@ def piecewise_decay(boundaries, values):
persistable=True, persistable=True,
name="learning_rate", name="learning_rate",
) )
# TODO: fluid.layers.control_flow.Switch should be replaced by paddle.static.nn.case(or cond) if possible with paddle.static.nn.control_flow.Switch() as switch:
with control_flow.Switch() as switch:
for i in range(len(boundaries)): for i in range(len(boundaries)):
boundary_val = paddle.tensor.fill_constant( boundary_val = paddle.tensor.fill_constant(
shape=[1], shape=[1],
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import paddle
from ....fluid.framework import Variable from ....fluid.framework import Variable
from ....fluid.layers.control_flow import BlockGuard
from ....framework import LayerHelper, core from ....framework import LayerHelper, core
class BlockGuardServ(BlockGuard): class BlockGuardServ(paddle.static.nn.control_flow.BlockGuard):
""" """
BlockGuardServ class. BlockGuardServ class.
......
...@@ -21,8 +21,6 @@ from paddle.fluid.dygraph.base import ( ...@@ -21,8 +21,6 @@ from paddle.fluid.dygraph.base import (
in_declarative_mode, in_declarative_mode,
) )
from paddle.fluid.framework import Variable, core, default_main_program from paddle.fluid.framework import Variable, core, default_main_program
from paddle.fluid.layers import control_flow
from paddle.fluid.layers.control_flow import while_loop
from .utils import ( from .utils import (
RETURN_NO_VALUE_VAR_NAME, RETURN_NO_VALUE_VAR_NAME,
...@@ -181,7 +179,9 @@ def _run_paddle_while( ...@@ -181,7 +179,9 @@ def _run_paddle_while(
return_name_ids, loop_vars return_name_ids, loop_vars
) # change the non-local var to variable ) # change the non-local var to variable
# variable maybe modified to inner var. change it into # variable maybe modified to inner var. change it into
loop_vars = control_flow.while_loop(new_cond_fn, new_body_fn, loop_vars) from paddle.static.nn import while_loop
loop_vars = while_loop(new_cond_fn, new_body_fn, loop_vars)
helper.set(return_name_ids, loop_vars) helper.set(return_name_ids, loop_vars)
return loop_vars return loop_vars
...@@ -820,6 +820,8 @@ def _run_paddle_pop(array, *args): ...@@ -820,6 +820,8 @@ def _run_paddle_pop(array, *args):
new_array = _slice_tensor_array(array, 0, idx) new_array = _slice_tensor_array(array, 0, idx)
i = idx + 1 i = idx + 1
from paddle.static.nn import while_loop
_, new_array = while_loop(cond, body, [i, new_array]) _, new_array = while_loop(cond, body, [i, new_array])
paddle.assign(new_array, output=array) paddle.assign(new_array, output=array)
......
...@@ -28,7 +28,6 @@ from paddle.fluid.framework import ( ...@@ -28,7 +28,6 @@ from paddle.fluid.framework import (
in_dygraph_mode, in_dygraph_mode,
program_guard, program_guard,
) )
from paddle.fluid.layers import control_flow
from paddle.framework import core from paddle.framework import core
from paddle.nn import functional as F from paddle.nn import functional as F
from paddle.nn import initializer as I from paddle.nn import initializer as I
...@@ -275,7 +274,7 @@ def _rnn_static_graph( ...@@ -275,7 +274,7 @@ def _rnn_static_graph(
end = paddle.cast(end, "int64") end = paddle.cast(end, "int64")
cond = start_i < end cond = start_i < end
while_op = control_flow.While(cond) while_op = paddle.static.nn.control_flow.While(cond)
out_array = paddle.tensor.create_array( out_array = paddle.tensor.create_array(
dtype=paddle.utils.flatten(inputs)[0].dtype dtype=paddle.utils.flatten(inputs)[0].dtype
......
...@@ -40,7 +40,6 @@ from .common import layer_norm # noqa: F401 ...@@ -40,7 +40,6 @@ from .common import layer_norm # noqa: F401
from .common import embedding # noqa: F401 from .common import embedding # noqa: F401
from .common import sparse_embedding # noqa: F401 from .common import sparse_embedding # noqa: F401
from ...fluid.layers import StaticRNN # noqa: F401
from .sequence_lod import sequence_conv # noqa: F401 from .sequence_lod import sequence_conv # noqa: F401
from .sequence_lod import sequence_softmax # noqa: F401 from .sequence_lod import sequence_softmax # noqa: F401
...@@ -99,6 +98,5 @@ __all__ = [ # noqa ...@@ -99,6 +98,5 @@ __all__ = [ # noqa
'sequence_scatter', 'sequence_scatter',
'sequence_enumerate', 'sequence_enumerate',
'sequence_reverse', 'sequence_reverse',
'StaticRNN',
'prelu', 'prelu',
] ]
...@@ -24,10 +24,8 @@ from paddle.common_ops_import import ( ...@@ -24,10 +24,8 @@ from paddle.common_ops_import import (
in_dygraph_mode, in_dygraph_mode,
) )
from paddle.fluid import core from paddle.fluid import core
from paddle.fluid.backward import _infer_var_data_type_shape_
from paddle.fluid.framework import Operator, Program, Variable, static_only from paddle.fluid.framework import Operator, Program, Variable, static_only
# Temporary solution, it will be deleted later
from paddle.fluid.layers.control_flow import ConditionalBlock, select_input
from paddle.utils import ( from paddle.utils import (
assert_same_structure, assert_same_structure,
copy_mutable_vars, copy_mutable_vars,
...@@ -152,6 +150,198 @@ class WhileGuard(BlockGuard): ...@@ -152,6 +150,198 @@ class WhileGuard(BlockGuard):
return super().__exit__(exc_type, exc_val, exc_tb) return super().__exit__(exc_type, exc_val, exc_tb)
class ConditionalBlock:
'''
**ConditionalBlock**
ConditionalBlock is an operator that bind a block to a specific condition,
if the condition matches, the corresponding block will be executed.
Args:
inputs (Variable): bool conditions.
is_scalar_condition (bool): whether the branch is controlled by a scalar.
name(str): name of this ConditionalBlock.
Examples:
.. code-block:: python
import paddle
import paddle.fluid as fluid
cond = paddle.less_than(x=label, y=limit)
true_image, false_image = layers.split_lod_tensor(
input=image, mask=cond)
true_cond = layers.ConditionalBlock([true_image])
with true_cond.block():
...
with false_cond.block():
...
'''
def __init__(self, inputs, is_scalar_condition=False, name=None):
for each_input in inputs:
check_type(each_input, "input", Variable, "ConditionalBlock")
self.inputs = inputs
self.is_scalar_condition = is_scalar_condition
self.helper = LayerHelper('conditional_block', name=name)
def block(self):
return ConditionalBlockGuard(self)
def complete(self):
inside_block = self.helper.main_program.current_block()
parent_block = self.helper.main_program.block(inside_block.parent_idx)
intermediate = set()
params = set()
params, intermediate = get_inputs_outputs_in_block(
inside_block, params, intermediate, helper=self.helper
)
# Todo(liym27) Here assume that all params are in recursive parent block
# but when minimize() called in control flow, some params may be in
# conditional grad block
param_list = [
parent_block._var_recursive(each_name) for each_name in params
]
out_list = []
for inner_out_name in intermediate:
inner_var = parent_block._find_var_recursive(inner_out_name)
if inner_var:
out_list.append(inner_var)
step_scope = parent_block.create_var(
type=core.VarDesc.VarType.STEP_SCOPES
)
conditional_block_op = parent_block.append_op(
type='conditional_block',
inputs={
'Cond': self.inputs,
'Input': param_list,
},
outputs={'Out': out_list, 'Scope': [step_scope]},
attrs={
'sub_block': inside_block,
'is_scalar_condition': self.is_scalar_condition,
},
)
if self.need_append_conditional_block_grad(inside_block):
self.append_conditional_block_grad(
parent_block, inside_block, conditional_block_op
)
def need_append_conditional_block_grad(self, inside_block):
grad_sub_block_idx = inside_block.backward_block_idx
inside_block_idx = inside_block.idx
# if inside_block have grad_block and grad_block is not itself,
# we will append conditional block grad.
return (
grad_sub_block_idx != -1 and grad_sub_block_idx != inside_block_idx
)
def append_conditional_block_grad(
self, parent_block, inside_block, conditional_block_op
):
'''
Append op `conditional_block_grad` manually.
When `optimizer.minimize/append_backward` is called in Paddle control flow,
grad ops will be appended before appending op `conditional_block` so that
op `conditional_block_grad` can't be appended when calling
`optimizer.minimize/append_backward`. After appending op `conditional_block`,
`conditional_block_grad` is appended manually.
Args:
parent_block (Block): The block that `conditional_block_op` blongs to.
inside_block (Block): The sub block of `conditional_block_op`.
conditional_block_op (Operator): The forward op conditional_block.
'''
grad_sub_block_idx = inside_block.backward_block_idx
grad_sub_block = self.helper.main_program.block(grad_sub_block_idx)
intermediate = set()
params = set()
for each_op in grad_sub_block.ops:
assert isinstance(each_op, Operator)
for iname in each_op.input_names:
for in_var_name in each_op.input(iname):
if in_var_name not in intermediate:
params.add(in_var_name)
for oname in each_op.output_names:
for out_var_name in each_op.output(oname):
intermediate.add(out_var_name)
param_list = []
for inner_input_name in params:
inner_var = parent_block._find_var_recursive(inner_input_name)
if inner_var:
param_list.append(inner_var.name)
grad_op_desc, op_grad_to_var = core.get_grad_op_desc(
conditional_block_op.desc, set(), [grad_sub_block.desc]
)
# append op_desc in grad_op_descs to target_block
op_role_attr_name = core.op_proto_and_checker_maker.kOpRoleAttrName()
backward = core.op_proto_and_checker_maker.OpRole.Backward
new_op_desc = parent_block.desc.append_op()
new_op_desc.copy_from(grad_op_desc[0])
new_op_desc._set_attr(op_role_attr_name, backward)
# set input and output manually
new_op_desc.set_input('Input', param_list)
new_op_desc.set_output(
'Input@GRAD', [param + "@GRAD" for param in param_list]
)
new_vars = set()
for grad_var_name in new_op_desc.output_arg_names():
if (
grad_sub_block.desc.has_var_recursive(grad_var_name.encode())
or grad_var_name == core.empty_var_name()
):
continue
grad_sub_block.desc.var(grad_var_name.encode())
new_vars.add(grad_var_name)
if grad_var_name not in op_grad_to_var:
continue
# infer_shape and infer_type
new_op_desc.infer_var_type(grad_sub_block.desc)
new_op_desc.infer_shape(grad_sub_block.desc)
for arg in new_op_desc.output_arg_names():
if arg in new_vars:
_infer_var_data_type_shape_(arg, grad_sub_block)
self.helper.main_program._sync_with_cpp()
class ConditionalBlockGuard(BlockGuard):
"""
ConditionalBlockGuard is derived from BlockGuard. It is dedicated for
holding a ConditionalBlock, and helping users entering and exiting the
ConditionalBlock via Python's 'with' keyword. However, ConditionalBlockGuard
is generally an internal component of IfElse, users should not use it directly.
"""
def __init__(self, block):
check_type(block, "block", ConditionalBlock, "ConditionalBlockGuard")
super().__init__(block.helper.main_program)
self.block = block
def __enter__(self):
return super().__enter__()
def __exit__(self, exc_type, exc_val, exc_tb):
self.block.complete()
return super().__exit__(exc_type, exc_val, exc_tb)
def get_inputs_outputs_in_block( def get_inputs_outputs_in_block(
current_block, inner_inputs, inner_outputs, helper current_block, inner_inputs, inner_outputs, helper
): ):
...@@ -1167,6 +1357,92 @@ def copy_var_to_parent_block(var, layer_helper): ...@@ -1167,6 +1357,92 @@ def copy_var_to_parent_block(var, layer_helper):
return parent_block_var return parent_block_var
def select_output(input, outputs, mask):
"""
**select_output**
This API takes in one input and multiple outputs and an integer mask. It
selects the output specified by the mask and copy the input to selected
output. It is useful in control flow.
Args:
input(Variable): The input variable
outputs(tuple|list): The output variables
mask(Variable): A tensor containing 1 integer number selecting which
output to be copied with input
Returns:
Variable: The outputs variables
"""
helper = LayerHelper('select_output', **locals())
check_type(input, 'input', (Variable), 'select_output')
check_variable_and_dtype(mask, 'mask', ['int32'], 'select_output')
check_type(outputs, 'outputs', (list, tuple), 'select_output')
helper.append_op(
type='select_output',
inputs={'X': input, 'Mask': mask},
outputs={'Out': outputs},
)
return outputs
def _select_input_infer_shape(first_shape, second_shape):
"""
This function infer the output shape by following algorithm:
1. if the dims is different, raise a error.
2. compare axis one by one:
if a == b: we set axis to a
if a != b: we set axis to -1
for compatibility, non declarative mode, we just return second_shape.
"""
if len(first_shape) != len(second_shape):
warnings.warn(
f"the input shapes of select_input should have the same rank, but get {first_shape}, {second_shape}"
)
return second_shape
out_shape = list(
map(lambda a, b: a if a == b else -1, first_shape, second_shape)
)
return out_shape
def select_input(inputs, mask):
"""
**select_input**
This API takes in multiple inputs and uses an integer mask to select one
input to output. It is useful in control flow.
Args:
inputs(tuple|list): The input variables
mask(Tensor): A tensor containing 1 integer number selecting which
input to output
Returns:
Variable: The selected input variable
"""
helper = LayerHelper('select_input', **locals())
check_type(inputs, 'inputs', (list, tuple), 'select_input')
check_variable_and_dtype(mask, 'mask', ['int32'], 'select_input')
# Select input should expand the shape. If it is - 1 and valid number, use - 1 first. If the dim is different, an error will be reported directly
# assert inputs[0].dtype == inputs[1].dtype, f"Expect the inputs should have the same dtype, but get {inputs[0].dtype} and {inputs[1].dtype}"
output_shape = _select_input_infer_shape(inputs[0].shape, inputs[1].shape)
output_dtype = inputs[1].dtype
output_type = inputs[1].type
out = helper.create_variable(
dtype=output_dtype, shape=output_shape, type=output_type
)
helper.append_op(
type='select_input',
inputs={'X': inputs, 'Mask': mask},
outputs={'Out': out},
)
return out
def select_input_with_buildin_type(inputs, mask, name): def select_input_with_buildin_type(inputs, mask, name):
from paddle.jit.dy2static.utils import UndefinedVar from paddle.jit.dy2static.utils import UndefinedVar
from paddle.jit.dy2static.variable_trans_func import to_static_variable from paddle.jit.dy2static.variable_trans_func import to_static_variable
...@@ -1433,3 +1709,64 @@ def Print( ...@@ -1433,3 +1709,64 @@ def Print(
}, },
) )
return output return output
class Switch:
def __init__(self, name=None):
self.helper = LayerHelper('switch', name=name)
self.inside_scope = False
self.pre_not_conditions = []
def case(self, condition):
if not self.inside_scope:
raise ValueError("case should be called inside with")
check_variable_and_dtype(
condition,
'condition',
['bool'],
'the member function case of fluid.layers.Switch',
)
if len(self.pre_not_conditions) == 0:
cond_block = ConditionalBlock([condition], is_scalar_condition=True)
not_cond = paddle.logical_not(x=condition)
self.pre_not_conditions.append(not_cond)
else:
pre_cond_num = len(self.pre_not_conditions)
pre_not_cond = self.pre_not_conditions[pre_cond_num - 1]
new_not_cond = paddle.logical_and(
x=pre_not_cond, y=paddle.logical_not(x=condition)
)
self.pre_not_conditions.append(new_not_cond)
cond_block = ConditionalBlock(
[paddle.logical_and(x=pre_not_cond, y=condition)],
is_scalar_condition=True,
)
return ConditionalBlockGuard(cond_block)
def default(self):
pre_cond_num = len(self.pre_not_conditions)
if pre_cond_num == 0:
raise ValueError("there should be at least one condition")
cond_block = ConditionalBlock(
[self.pre_not_conditions[pre_cond_num - 1]],
is_scalar_condition=True,
)
return ConditionalBlockGuard(cond_block)
def __enter__(self):
"""
set flag that now is inside switch.block {}
:return:
"""
self.inside_scope = True
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.inside_scope = False
if exc_type is not None:
return False # re-raise exception
return True
...@@ -16,6 +16,7 @@ import unittest ...@@ -16,6 +16,7 @@ import unittest
from test_eager_deletion_padding_rnn import PaddingRNNTestBase, RNNConfig from test_eager_deletion_padding_rnn import PaddingRNNTestBase, RNNConfig
import paddle
from paddle import fluid from paddle import fluid
from paddle.fluid import core from paddle.fluid import core
...@@ -36,4 +37,5 @@ class FusionGroupPaddingRNNTest(PaddingRNNTestBase): ...@@ -36,4 +37,5 @@ class FusionGroupPaddingRNNTest(PaddingRNNTestBase):
if __name__ == '__main__': if __name__ == '__main__':
paddle.enable_static()
unittest.main() unittest.main()
...@@ -19,9 +19,8 @@ import numpy as np ...@@ -19,9 +19,8 @@ import numpy as np
import paddle import paddle
from paddle import fluid from paddle import fluid
from paddle.fluid import core from paddle.fluid import core
from paddle.fluid.backward import append_backward from paddle.static import Executor, append_backward
from paddle.fluid.executor import Executor from paddle.static.nn.control_flow import ConditionalBlock
from paddle.fluid.layers.control_flow import ConditionalBlock
class ConditionalBlockTest(unittest.TestCase): class ConditionalBlockTest(unittest.TestCase):
...@@ -83,4 +82,5 @@ class TestConditionalBlockOpInferShape(unittest.TestCase): ...@@ -83,4 +82,5 @@ class TestConditionalBlockOpInferShape(unittest.TestCase):
if __name__ == '__main__': if __name__ == '__main__':
paddle.enable_static()
unittest.main() unittest.main()
...@@ -21,7 +21,6 @@ import paddle ...@@ -21,7 +21,6 @@ import paddle
from paddle import fluid from paddle import fluid
from paddle.fluid import layers from paddle.fluid import layers
from paddle.fluid.executor import Executor from paddle.fluid.executor import Executor
from paddle.fluid.layers.control_flow import StaticRNN as PaddingRNN
os.environ["CPU_NUM"] = "1" os.environ["CPU_NUM"] = "1"
...@@ -83,7 +82,7 @@ class RNNConfig: ...@@ -83,7 +82,7 @@ class RNNConfig:
else: else:
raise ValueError('Unsupported model_type.') raise ValueError('Unsupported model_type.')
if rnn_model not in ('static', 'padding', 'cudnn'): if rnn_model not in ('static', 'cudnn'):
raise ValueError('Unsupported rnn_model.') raise ValueError('Unsupported rnn_model.')
self.batch_size = 12 self.batch_size = 12
...@@ -117,124 +116,6 @@ def lm_model( ...@@ -117,124 +116,6 @@ def lm_model(
dropout=None, dropout=None,
rnn_model='static', rnn_model='static',
): ):
def padding_rnn(input_embedding, len=3, init_hidden=None, init_cell=None):
weight_1_arr = []
weight_2_arr = []
bias_arr = []
hidden_array = []
cell_array = []
mask_array = []
for i in range(num_layers):
weight_1 = paddle.create_parameter(
[hidden_size * 2, hidden_size * 4],
dtype="float32",
name="fc_weight1_" + str(i),
default_initializer=paddle.nn.initializer.Uniform(
low=-init_scale, high=init_scale
),
)
weight_1_arr.append(weight_1)
bias_1 = paddle.create_parameter(
[hidden_size * 4],
dtype="float32",
name="fc_bias1_" + str(i),
default_initializer=paddle.nn.initializer.Constant(0.0),
)
bias_arr.append(bias_1)
pre_hidden = paddle.slice(
init_hidden, axes=[0], starts=[i], ends=[i + 1]
)
pre_cell = paddle.slice(
init_cell, axes=[0], starts=[i], ends=[i + 1]
)
pre_hidden = paddle.reshape(pre_hidden, shape=[-1, hidden_size])
pre_cell = paddle.reshape(pre_cell, shape=[-1, hidden_size])
hidden_array.append(pre_hidden)
cell_array.append(pre_cell)
input_embedding = paddle.transpose(input_embedding, perm=[1, 0, 2])
rnn = PaddingRNN()
with rnn.step():
input = rnn.step_input(input_embedding)
for k in range(num_layers):
pre_hidden = rnn.memory(init=hidden_array[k])
pre_cell = rnn.memory(init=cell_array[k])
weight_1 = weight_1_arr[k]
bias = bias_arr[k]
nn = paddle.concat([input, pre_hidden], 1)
gate_input = paddle.matmul(x=nn, y=weight_1)
gate_input = paddle.add(gate_input, bias)
i = paddle.slice(
gate_input, axes=[1], starts=[0], ends=[hidden_size]
)
j = paddle.slice(
gate_input,
axes=[1],
starts=[hidden_size],
ends=[hidden_size * 2],
)
f = paddle.slice(
gate_input,
axes=[1],
starts=[hidden_size * 2],
ends=[hidden_size * 3],
)
o = paddle.slice(
gate_input,
axes=[1],
starts=[hidden_size * 3],
ends=[hidden_size * 4],
)
c = pre_cell * paddle.nn.functional.sigmoid(
f
) + paddle.nn.functional.sigmoid(i) * paddle.tanh(j)
m = paddle.tanh(c) * paddle.nn.functional.sigmoid(o)
rnn.update_memory(pre_hidden, m)
rnn.update_memory(pre_cell, c)
rnn.step_output(m)
rnn.step_output(c)
input = m
if dropout is not None and dropout > 0.0:
input = paddle.nn.functional.dropout(
input,
p=dropout,
mode='upscale_in_train',
)
rnn.step_output(input)
rnnout = rnn()
last_hidden_array = []
last_cell_array = []
real_res = rnnout[-1]
for i in range(num_layers):
m = rnnout[i * 2]
c = rnnout[i * 2 + 1]
m.stop_gradient = True
c.stop_gradient = True
last_h = paddle.slice(
m, axes=[0], starts=[num_steps - 1], ends=[num_steps]
)
last_hidden_array.append(last_h)
last_c = paddle.slice(
c, axes=[0], starts=[num_steps - 1], ends=[num_steps]
)
last_cell_array.append(last_c)
real_res = paddle.transpose(x=real_res, perm=[1, 0, 2])
last_hidden = paddle.concat(last_hidden_array, 0)
last_cell = paddle.concat(last_cell_array, 0)
return real_res, last_hidden, last_cell
def encoder_static( def encoder_static(
input_embedding, len=3, init_hidden=None, init_cell=None input_embedding, len=3, init_hidden=None, init_cell=None
): ):
...@@ -381,14 +262,7 @@ def lm_model( ...@@ -381,14 +262,7 @@ def lm_model(
mode='upscale_in_train', mode='upscale_in_train',
) )
if rnn_model == "padding": if rnn_model == "static":
rnn_out, last_hidden, last_cell = padding_rnn(
x_emb,
len=num_steps,
init_hidden=init_hidden_reshape,
init_cell=init_cell_reshape,
)
elif rnn_model == "static":
rnn_out, last_hidden, last_cell = encoder_static( rnn_out, last_hidden, last_cell = encoder_static(
x_emb, x_emb,
len=num_steps, len=num_steps,
...@@ -622,36 +496,6 @@ class PaddingRNNTestBase(unittest.TestCase): ...@@ -622,36 +496,6 @@ class PaddingRNNTestBase(unittest.TestCase):
ppl = np.append(ppl, train_ppl) ppl = np.append(ppl, train_ppl)
return ppl return ppl
def compare_padding_static_mode(self, use_program_cache=True):
'''
Test that train ppl of padding mode is same to that of static graph mode
'''
config = RNNConfig('test', 'padding')
with fluid.scope_guard(fluid.Scope()):
padding_rnn_ppl = self.train(config, use_program_cache)
config = RNNConfig('test', 'static')
with fluid.scope_guard(fluid.Scope()):
static_rnn_ppl = self.train(config, use_program_cache)
np.testing.assert_allclose(padding_rnn_ppl, static_rnn_ppl, rtol=0.001)
class EagerDeletionPaddingRNNTest(PaddingRNNTestBase):
def test_padding_mode_no_eager_deletion(self):
'''
Test that train ppl of padding mode is same to that of static graph mode without eager deletion
'''
fluid.core._set_eager_deletion_mode(-1.0, 1.0, True)
# When parallel is True, use_program_cache does not make a difference.
self.compare_padding_static_mode(use_program_cache=True)
def test_padding_mode_eager_deletion(self):
'''
Test that train ppl of padding mode is same to that of static graph mode under eager deletion
'''
fluid.core._set_eager_deletion_mode(0.0, 1.0, True)
# When parallel is True, use_program_cache does not make a difference.
self.compare_padding_static_mode(use_program_cache=True)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -98,7 +98,7 @@ class ExecutorPaddingRNNTest(PaddingRNNTestBase): ...@@ -98,7 +98,7 @@ class ExecutorPaddingRNNTest(PaddingRNNTestBase):
) )
def test_inference_output(self): def test_inference_output(self):
for rnn_model in ["static", "padding"]: for rnn_model in ["static"]:
# Set parallel to False to use the default executor. # Set parallel to False to use the default executor.
self.train_and_save_inference_program( self.train_and_save_inference_program(
rnn_model=rnn_model, use_program_cache=True rnn_model=rnn_model, use_program_cache=True
...@@ -166,4 +166,5 @@ class ExecutorPaddingRNNTest(PaddingRNNTestBase): ...@@ -166,4 +166,5 @@ class ExecutorPaddingRNNTest(PaddingRNNTestBase):
if __name__ == '__main__': if __name__ == '__main__':
paddle.enable_static()
unittest.main() unittest.main()
此差异已折叠。
...@@ -22,7 +22,7 @@ from paddle.fluid import core ...@@ -22,7 +22,7 @@ from paddle.fluid import core
from paddle.fluid.backward import append_backward from paddle.fluid.backward import append_backward
from paddle.fluid.executor import Executor from paddle.fluid.executor import Executor
from paddle.fluid.framework import Program, program_guard from paddle.fluid.framework import Program, program_guard
from paddle.fluid.layers.control_flow import select_input, select_output from paddle.static.nn.control_flow import select_input, select_output
paddle.enable_static() paddle.enable_static()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册