From 61222578b457b8efc32dd2899aa7653a880ed801 Mon Sep 17 00:00:00 2001 From: xuwei06 Date: Mon, 19 Jun 2017 23:45:25 -0700 Subject: [PATCH] Allow printer layer to print user provided message For example: layer.printer(input=[x, y], format="x=%s y=%s") --- paddle/gserver/layers/PrintLayer.cpp | 27 +++++++++++++++++-- python/paddle/trainer/config_parser.py | 8 +++++- .../paddle/trainer_config_helpers/layers.py | 3 ++- .../protostr/test_print_layer.protostr | 1 + 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/paddle/gserver/layers/PrintLayer.cpp b/paddle/gserver/layers/PrintLayer.cpp index de198af111b..a97fa6bf78f 100644 --- a/paddle/gserver/layers/PrintLayer.cpp +++ b/paddle/gserver/layers/PrintLayer.cpp @@ -22,10 +22,33 @@ public: void forward(PassType passType) override { Layer::forward(passType); + std::vector vals; for (size_t i = 0; i != inputLayers_.size(); ++i) { - getInput(i).printValueString(LOG(INFO), - "layer=" + inputLayers_[i]->getName() + " "); + std::ostringstream s; + getInput(i).printValueString(s, ""); + vals.push_back(s.str()); } + size_t pos = 0; + int i = 0; + std::ostringstream s; + const std::string& format = config_.user_arg(); + while (true) { + size_t pos1 = format.find("%s", pos); + if (pos1 == std::string::npos) break; + if (i >= vals.size()) { + break; + } + s << format.substr(pos, pos1 - pos) << vals[i]; + pos = pos1 + 2; + ++i; + } + if (i != inputLayers_.size()) { + LOG(ERROR) << "Number of value in the format (" << format + << ") is not same as the number of inputs (" + << inputLayers_.size() << ") at " << getName(); + } + s << format.substr(pos); + LOG(INFO) << s.str(); } void backward(const UpdateCallback& callback) override {} diff --git a/python/paddle/trainer/config_parser.py b/python/paddle/trainer/config_parser.py index 95419442571..c11dc09a8b9 100644 --- a/python/paddle/trainer/config_parser.py +++ b/python/paddle/trainer/config_parser.py @@ -1628,8 +1628,14 @@ class SelectiveFCLayer(LayerBase): @config_layer('print') class PrintLayer(LayerBase): - def __init__(self, name, inputs): + def __init__(self, name, inputs, format=None): super(PrintLayer, self).__init__(name, 'print', 0, inputs) + if format is None: + format = "\n".join([ + "layer=" + input.input_layer_name + " %s" + for input in self.inputs + ]) + self.config.user_arg = format @config_layer('priorbox') diff --git a/python/paddle/trainer_config_helpers/layers.py b/python/paddle/trainer_config_helpers/layers.py index a201c68a63b..b8ce0373c0e 100755 --- a/python/paddle/trainer_config_helpers/layers.py +++ b/python/paddle/trainer_config_helpers/layers.py @@ -964,7 +964,7 @@ def fc_layer(input, @wrap_name_default("print") -def printer_layer(input, name=None): +def printer_layer(input, format=None, name=None): """ Print the output value of input layers. This layer is useful for debugging. @@ -982,6 +982,7 @@ def printer_layer(input, name=None): Layer( name=name, + format=format, type=LayerType.PRINT_LAYER, inputs=[l.name for l in input], ) # this layer don't return anything, can not be input of other layer. diff --git a/python/paddle/trainer_config_helpers/tests/configs/protostr/test_print_layer.protostr b/python/paddle/trainer_config_helpers/tests/configs/protostr/test_print_layer.protostr index c402aff174a..f4cc492dfb9 100644 --- a/python/paddle/trainer_config_helpers/tests/configs/protostr/test_print_layer.protostr +++ b/python/paddle/trainer_config_helpers/tests/configs/protostr/test_print_layer.protostr @@ -12,6 +12,7 @@ layers { inputs { input_layer_name: "input" } + user_arg: "layer=input %s" } input_layer_names: "input" output_layer_names: "input" -- GitLab