From 8143a42667d3dd158a464449e3492b7b0acf55c7 Mon Sep 17 00:00:00 2001 From: wanghaoshuang Date: Mon, 22 Jan 2018 17:34:45 +0800 Subject: [PATCH] 1. Add more comments --- python/paddle/v2/fluid/evaluator.py | 36 +++++++++++++++++++++++++---- python/paddle/v2/fluid/layers/nn.py | 16 ++++++++----- 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/python/paddle/v2/fluid/evaluator.py b/python/paddle/v2/fluid/evaluator.py index 67e99a70ad3..5dde8d623af 100644 --- a/python/paddle/v2/fluid/evaluator.py +++ b/python/paddle/v2/fluid/evaluator.py @@ -208,20 +208,46 @@ class ChunkEvaluator(Evaluator): class EditDistance(Evaluator): """ - Average edit distance error for multiple mini-batches. + Accumulate edit distance sum and sequence number from mini-batches and + compute the average edit_distance of all batches. + + Args: + input: the sequences predicted by network + label: the target sequences which must has same sequence count + with input. + ignored_tokens(list of int): Tokens that should be removed before + calculating edit distance. + + Example: + + exe = fluid.executor(place) + distance_evaluator = fluid.Evaluator.EditDistance(input, label) + for epoch in PASS_NUM: + distance_evaluator.reset(exe) + for data in batches: + loss, sum_distance = exe.run(fetch_list=[cost] + distance_evaluator.metrics) + avg_distance = distance_evaluator.eval(exe) + pass_distance = distance_evaluator.eval(exe) + + In the above example: + 'sum_distance' is the sum of the batch's edit distance. + 'avg_distance' is the average of edit distance from the firt batch to the current batch. + 'pass_distance' is the average of edit distance from all the pass. + """ - def __init__(self, input, label, k=1, **kwargs): + def __init__(self, input, label, ignored_tokens=None, **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='float32', shape=[1], suffix='total') + dtype='float32', shape=[1], suffix='total_error') self.seq_num = self.create_state( - dtype='int64', shape=[1], suffix='total') - error, seq_num = layers.edit_distance(input=input, label=label) + dtype='int64', shape=[1], suffix='seq_num') + error, seq_num = layers.edit_distance( + input=input, label=label, ignored_tokens=ignored_tokens) #error = layers.cast(x=error, dtype='float32') sum_error = layers.reduce_sum(error) layers.sums(input=[self.total_error, sum_error], out=self.total_error) diff --git a/python/paddle/v2/fluid/layers/nn.py b/python/paddle/v2/fluid/layers/nn.py index 9a1fc2f1202..7dd77aca959 100644 --- a/python/paddle/v2/fluid/layers/nn.py +++ b/python/paddle/v2/fluid/layers/nn.py @@ -1864,7 +1864,11 @@ def matmul(x, y, transpose_x=False, transpose_y=False, name=None): return out -def edit_distance(input, label, normalized=False, tokens=None, name=None): +def edit_distance(input, + label, + normalized=False, + ignored_tokens=None, + 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: @@ -1882,10 +1886,10 @@ def edit_distance(input, label, normalized=False, tokens=None, name=None): normalized(bool): Indicated whether to normalize the edit distance by the length of reference string. - tokens(list): Tokens that should be removed before calculating edit distance. + ignored_tokens(list of int): Tokens that should be removed before calculating edit distance. Returns: - Variable: sequence-to-sequence edit distance loss in shape [batch_size, 1]. + Variable: sequence-to-sequence edit distance in shape [batch_size, 1]. Examples: .. code-block:: python @@ -1898,7 +1902,7 @@ def edit_distance(input, label, normalized=False, tokens=None, name=None): helper = LayerHelper("edit_distance", **locals()) # remove some tokens from input and labels - if tokens is not None and len(tokens) > 0: + if ignored_tokens is not None and len(ignored_tokens) > 0: erased_input = helper.create_tmp_variable(dtype="int64") erased_label = helper.create_tmp_variable(dtype="int64") @@ -1906,14 +1910,14 @@ def edit_distance(input, label, normalized=False, tokens=None, name=None): type="sequence_erase", inputs={"X": [input]}, outputs={"Out": [erased_input]}, - attrs={"tokens": tokens}) + attrs={"tokens": ignored_tokens}) input = erased_input helper.append_op( type="sequence_erase", inputs={"X": [label]}, outputs={"Out": [erase_label]}, - attrs={"tokens": tokens}) + attrs={"tokens": ignored_tokens}) label = erased_label # edit distance op -- GitLab