From 5846aab31730cb595f6210bed0758954529fc0f0 Mon Sep 17 00:00:00 2001 From: wanghaoshuang Date: Fri, 19 Jan 2018 14:53:46 +0800 Subject: [PATCH] 1. Rename 'edit_distance_error' to 'edit_distance' 2. Add edit distance evaluator to evaluator.py --- doc/api/v2/fluid/layers.rst | 2 +- python/paddle/v2/fluid/evaluator.py | 32 +++++++++++++++++++++++++++++ python/paddle/v2/fluid/layers/nn.py | 9 ++++---- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/doc/api/v2/fluid/layers.rst b/doc/api/v2/fluid/layers.rst index f1e4e753c52..2ae68d01d34 100644 --- a/doc/api/v2/fluid/layers.rst +++ b/doc/api/v2/fluid/layers.rst @@ -500,7 +500,7 @@ swish .. autofunction:: paddle.v2.fluid.layers.swish :noindex: -edit_distance_error +edit_distance --------------- .. autofunction:: paddle.v2.fluid.layers.edit_distance_error :noindex: diff --git a/python/paddle/v2/fluid/evaluator.py b/python/paddle/v2/fluid/evaluator.py index adf174a07da..336d25929ec 100644 --- a/python/paddle/v2/fluid/evaluator.py +++ b/python/paddle/v2/fluid/evaluator.py @@ -204,3 +204,35 @@ class ChunkEvaluator(Evaluator): [precision], dtype='float32'), np.array( [recall], dtype='float32'), np.array( [f1_score], dtype='float32') + + +class EditDistance(Evaluator): + """ + Average edit distance error for multiple mini-batches. + """ + + def __init__(self, input, label, k=1, **kwargs): + super(EditDistance, self).__init__("edit_distance", **kwargs) + main_program = self.helper.main_program + if main_program.current_block().idx != 0: + raise ValueError("You can only invoke Evaluator in root block") + + self.total_error = self.create_state( + dtype='int64', shape=[1], suffix='total') + self.batch_num = 0 + error = layers.edit_distance(input=input, label=label) + mean_error = layers.mean(input=error) + layers.sums(input=[self.total_error, mean_error], out=self.total_error) + self.metrics.append(mean_error) + + def eval(self, executor, eval_program=None): + self.batch_num += 1 + if eval_program is None: + eval_program = Program() + block = eval_program.current_block() + with program_guard(main_program=eval_program): + total_error = _clone_var_(block, self.total_error) + batch_num = layers.fill_constant( + shape=[1], value=self.batch_num, dtype="float32") + out = layers.elementwise_div(x=total_error, y=batch_num) + return np.array(executor.run(eval_program, fetch_list=[out])[0]) diff --git a/python/paddle/v2/fluid/layers/nn.py b/python/paddle/v2/fluid/layers/nn.py index 0c77b890656..8383e43dea0 100644 --- a/python/paddle/v2/fluid/layers/nn.py +++ b/python/paddle/v2/fluid/layers/nn.py @@ -28,8 +28,7 @@ __all__ = [ 'batch_norm', 'beam_search_decode', 'conv2d_transpose', 'sequence_expand', 'lstm_unit', 'reduce_sum', 'reduce_mean', 'reduce_max', 'reduce_min', 'sequence_first_step', 'sequence_last_step', 'dropout', 'split', - 'ctc_greedy_decoder', 'edit_distance_error', 'l2_normalize', 'matmul', - 'warpctc' + 'ctc_greedy_decoder', 'edit_distance', 'l2_normalize', 'matmul', 'warpctc' ] @@ -1768,7 +1767,7 @@ def matmul(x, y, transpose_x=False, transpose_y=False, name=None): return out -def edit_distance_error(input, label, normalized=False, name=None): +def edit_distance(input, label, normalized=False, name=None): """ EditDistance operator computes the edit distances between a batch of hypothesis strings and their references.Edit distance, also called Levenshtein distance, measures how dissimilar two strings are by counting the minimum number of operations to transform one string into anthor. Here the operations include insertion, deletion, and substitution. For example, given hypothesis string A = "kitten" and reference B = "sitting", the edit distance is 3 for A will be transformed into B at least after two substitutions and one insertion: @@ -1795,9 +1794,9 @@ def edit_distance_error(input, label, normalized=False, name=None): x = fluid.layers.data(name='x', shape=[8], dtype='float32') y = fluid.layers.data(name='y', shape=[7], dtype='float32') - cost = fluid.layers.edit_distance_error(input=x,label=y) + cost = fluid.layers.edit_distance(input=x,label=y) """ - helper = LayerHelper("edit_distance_error", **locals()) + helper = LayerHelper("edit_distance", **locals()) # edit distance op edit_distance_out = helper.create_tmp_variable(dtype="int64") -- GitLab