Fix slow parsing a recursive depends topology

* Fix  #2797
* It because trainer_config_helpers' __dfs_travel__ did not record the
  node which travelled, and if the topology has a recursive dependency,
  there are some nodes will be travelled multiple times.
* Add a `travelled` set to record which node is travelled.
* Also add a unittest for this situation.
gangliao-patch-1
Yu Yang 8 years ago
parent 6398c15c7f
commit 313e9f551f

@ -1408,6 +1408,8 @@ def outputs(layers, *args):
:return:
"""
traveled = set()
def __dfs_travel__(layer,
predicate=lambda x: x.layer_type == LayerType.DATA):
"""
@ -1419,6 +1421,11 @@ def outputs(layers, *args):
:type layer: LayerOutput
:return:
"""
if layer in traveled:
return []
else:
traveled.add(layer)
assert isinstance(layer, LayerOutput), "layer is %s" % (layer)
retv = []
if layer.parents is not None:

@ -6,6 +6,7 @@ img_layers img_trans_layers util_layers simple_rnn_layers unused_layers test_cos
test_rnn_group shared_fc shared_lstm shared_gru test_cost_layers_with_weight
test_spp_layer test_bilinear_interp test_maxout test_bi_grumemory math_ops
test_seq_concat_reshape test_pad test_smooth_l1 test_multiplex_layer
test_prelu_layer test_row_conv test_detection_output_layer test_multibox_loss_layer)
test_prelu_layer test_row_conv test_detection_output_layer test_multibox_loss_layer
test_recursive_topology)
export whole_configs=(test_split_datasource)

@ -131,6 +131,7 @@ input_layer_names: "weight"
input_layer_names: "multi_class_label"
output_layer_names: "__cost_0__"
output_layer_names: "__mse_cost_0__"
output_layer_names: "__nce_layer_0__"
evaluators {
name: "classification_error_evaluator"
type: "classification_error"
@ -154,6 +155,7 @@ sub_models {
input_layer_names: "multi_class_label"
output_layer_names: "__cost_0__"
output_layer_names: "__mse_cost_0__"
output_layer_names: "__nce_layer_0__"
evaluator_names: "classification_error_evaluator"
is_recurrent_layer_group: false
}

@ -0,0 +1,16 @@
from paddle.trainer_config_helpers import *
settings(batch_size=1000, learning_rate=1e-5)
din = data_layer(name='data', size=100)
enc = din
for i in range(32):
enc = addto_layer([enc, enc])
pred = fc_layer(
input=fc_layer(
input=enc, size=32, act=ReluActivation()),
size=10,
act=SoftmaxActivation())
outputs(pred)
Loading…
Cancel
Save