We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Correct the error rate's computation for multiple sentences


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tools/tune.py`
Content:
```
1 """Beam search parameters tuning for DeepSpeech2 model."""
2 from __future__ import absolute_import
3 from __future__ import division
4 from __future__ import print_function
5 
6 import sys
7 import os
8 import numpy as np
9 import argparse
10 import functools
11 import gzip
12 import logging
13 import paddle.v2 as paddle
14 import _init_paths
15 from data_utils.data import DataGenerator
16 from decoders.swig_wrapper import Scorer
17 from decoders.swig_wrapper import ctc_beam_search_decoder_batch
18 from model_utils.model import deep_speech_v2_network
19 from utils.error_rate import wer, cer
20 from utils.utility import add_arguments, print_arguments
21 
22 parser = argparse.ArgumentParser(description=__doc__)
23 add_arg = functools.partial(add_arguments, argparser=parser)
24 # yapf: disable
25 add_arg('num_batches',      int,    -1,     "# of batches tuning on. "
26                                             "Default -1, on whole dev set.")
27 add_arg('batch_size',       int,    256,    "# of samples per batch.")
28 add_arg('trainer_count',    int,    8,      "# of Trainers (CPUs or GPUs).")
29 add_arg('beam_size',        int,    500,    "Beam search width.")
30 add_arg('num_proc_bsearch', int,    8,     "# of CPUs for beam search.")
31 add_arg('num_proc_data',    int,    8,      "# of CPUs for data preprocessing.")
32 add_arg('num_conv_layers',  int,    2,      "# of convolution layers.")
33 add_arg('num_rnn_layers',   int,    3,      "# of recurrent layers.")
34 add_arg('rnn_layer_size',   int,    2048,   "# of recurrent cells per layer.")
35 add_arg('num_alphas',       int,    45,     "# of alpha candidates for tuning.")
36 add_arg('num_betas',        int,    8,      "# of beta candidates for tuning.")
37 add_arg('alpha_from',       float,  1.0,    "Where alpha starts tuning from.")
38 add_arg('alpha_to',         float,  3.2,    "Where alpha ends tuning with.")
39 add_arg('beta_from',        float,  0.1,    "Where beta starts tuning from.")
40 add_arg('beta_to',          float,  0.45,   "Where beta ends tuning with.")
41 add_arg('cutoff_prob',      float,  1.0,    "Cutoff probability for pruning.")
42 add_arg('cutoff_top_n',     int,    40,     "Cutoff number for pruning.")
43 add_arg('use_gru',          bool,   False,  "Use GRUs instead of simple RNNs.")
44 add_arg('use_gpu',          bool,   True,   "Use GPU or not.")
45 add_arg('share_rnn_weights',bool,   True,   "Share input-hidden weights across "
46                                             "bi-directional RNNs. Not for GRU.")
47 add_arg('tune_manifest',    str,
48         'data/librispeech/manifest.dev-clean',
49         "Filepath of manifest to tune.")
50 add_arg('mean_std_path',    str,
51         'data/librispeech/mean_std.npz',
52         "Filepath of normalizer's mean & std.")
53 add_arg('vocab_path',       str,
54         'data/librispeech/vocab.txt',
55         "Filepath of vocabulary.")
56 add_arg('lang_model_path',  str,
57         'models/lm/common_crawl_00.prune01111.trie.klm',
58         "Filepath for language model.")
59 add_arg('model_path',       str,
60         './checkpoints/libri/params.latest.tar.gz',
61         "If None, the training starts from scratch, "
62         "otherwise, it resumes from the pre-trained model.")
63 add_arg('error_rate_type',  str,
64         'wer',
65         "Error rate type for evaluation.",
66         choices=['wer', 'cer'])
67 add_arg('specgram_type',    str,
68         'linear',
69         "Audio feature type. Options: linear, mfcc.",
70         choices=['linear', 'mfcc'])
71 # yapf: disable
72 args = parser.parse_args()
73 
74 
75 logging.basicConfig(
76     format='[%(levelname)s %(asctime)s %(filename)s:%(lineno)d] %(message)s')
77 
78 def tune():
79     """Tune parameters alpha and beta incrementally."""
80     if not args.num_alphas >= 0:
81         raise ValueError("num_alphas must be non-negative!")
82     if not args.num_betas >= 0:
83         raise ValueError("num_betas must be non-negative!")
84 
85     data_generator = DataGenerator(
86         vocab_filepath=args.vocab_path,
87         mean_std_filepath=args.mean_std_path,
88         augmentation_config='{}',
89         specgram_type=args.specgram_type,
90         num_threads=args.num_proc_data,
91         keep_transcription_text=True,
92         num_conv_layers=args.num_conv_layers)
93 
94     audio_data = paddle.layer.data(
95         name="audio_spectrogram",
96         type=paddle.data_type.dense_array(161 * 161))
97     text_data = paddle.layer.data(
98         name="transcript_text",
99         type=paddle.data_type.integer_value_sequence(data_generator.vocab_size))
100     seq_offset_data = paddle.layer.data(
101         name='sequence_offset',
102         type=paddle.data_type.integer_value_sequence(1))
103     seq_len_data = paddle.layer.data(
104         name='sequence_length',
105         type=paddle.data_type.integer_value_sequence(1))
106     index_range_datas = []
107     for i in xrange(args.num_rnn_layers):
108         index_range_datas.append(
109             paddle.layer.data(
110                 name='conv%d_index_range' % i,
111                 type=paddle.data_type.dense_vector(6)))
112 
113     output_probs, _ = deep_speech_v2_network(
114         audio_data=audio_data,
115         text_data=text_data,
116         seq_offset_data=seq_offset_data,
117         seq_len_data=seq_len_data,
118         index_range_datas=index_range_datas,
119         dict_size=data_generator.vocab_size,
120         num_conv_layers=args.num_conv_layers,
121         num_rnn_layers=args.num_rnn_layers,
122         rnn_size=args.rnn_layer_size,
123         use_gru=args.use_gru,
124         share_rnn_weights=args.share_rnn_weights)
125 
126     batch_reader = data_generator.batch_reader_creator(
127         manifest_path=args.tune_manifest,
128         batch_size=args.batch_size,
129         sortagrad=False,
130         shuffle_method=None)
131 
132     # load parameters
133     if not os.path.isfile(args.model_path):
134         raise IOError("Invaid model path: %s" % args.model_path)
135     parameters = paddle.parameters.Parameters.from_tar(
136         gzip.open(args.model_path))
137 
138     inferer = paddle.inference.Inference(
139         output_layer=output_probs, parameters=parameters)
140     # decoders only accept string encoded in utf-8
141     vocab_list = [chars.encode("utf-8") for chars in data_generator.vocab_list]
142 
143     # init logger
144     logger = logging.getLogger("")
145     logger.setLevel(level=logging.INFO)
146     # init external scorer
147     logger.info("begin to initialize the external scorer for tuning")
148     if not os.path.isfile(args.lang_model_path):
149         raise IOError("Invaid language model path: %s" % args.lang_model_path)
150     ext_scorer = Scorer(
151         alpha=args.alpha_from,
152         beta=args.beta_from,
153         model_path=args.lang_model_path,
154         vocabulary=vocab_list)
155     logger.info("language model: "
156                 "is_character_based = %d," % ext_scorer.is_character_based() +
157                 " max_order = %d," % ext_scorer.get_max_order() +
158                 " dict_size = %d" % ext_scorer.get_dict_size())
159     logger.info("end initializing scorer. Start tuning ...")
160 
161     error_rate_func = cer if args.error_rate_type == 'cer' else wer
162     # create grid for search
163     cand_alphas = np.linspace(args.alpha_from, args.alpha_to, args.num_alphas)
164     cand_betas = np.linspace(args.beta_from, args.beta_to, args.num_betas)
165     params_grid = [(alpha, beta) for alpha in cand_alphas
166                    for beta in cand_betas]
167 
168     err_sum = [0.0 for i in xrange(len(params_grid))]
169     err_ave = [0.0 for i in xrange(len(params_grid))]
170     num_ins, cur_batch = 0, 0
171     ## incremental tuning parameters over multiple batches
172     for infer_data in batch_reader():
173         if (args.num_batches >= 0) and (cur_batch >= args.num_batches):
174             break
175         infer_results = inferer.infer(input=infer_data,
176                                       feeding=data_generator.feeding)
177         start_pos = [0] * (len(infer_data) + 1)
178         for i in xrange(len(infer_data)):
179             start_pos[i + 1] = start_pos[i] + infer_data[i][3][0]
180         probs_split = [
181                 infer_results[start_pos[i]:start_pos[i + 1]]
182                 for i in xrange(0, len(infer_data))
183         ]
184 
185         target_transcripts = [ data[1] for data in infer_data ]
186 
187         num_ins += len(target_transcripts)
188         # grid search
189         for index, (alpha, beta) in enumerate(params_grid):
190             # reset alpha & beta
191             ext_scorer.reset_params(alpha, beta)
192             beam_search_results = ctc_beam_search_decoder_batch(
193                 probs_split=probs_split,
194                 vocabulary=vocab_list,
195                 beam_size=args.beam_size,
196                 num_processes=args.num_proc_bsearch,
197                 cutoff_prob=args.cutoff_prob,
198                 cutoff_top_n=args.cutoff_top_n,
199                 ext_scoring_func=ext_scorer, )
200 
201             result_transcripts = [res[0][1] for res in beam_search_results]
202             for target, result in zip(target_transcripts, result_transcripts):
203                 err_sum[index] += error_rate_func(target, result)
204             err_ave[index] = err_sum[index] / num_ins
205             if index % 2 == 0:
206                 sys.stdout.write('.')
207                 sys.stdout.flush()
208 
209         # output on-line tuning result at the end of current batch
210         err_ave_min = min(err_ave)
211         min_index = err_ave.index(err_ave_min)
212         print("\nBatch %d [%d/?], current opt (alpha, beta) = (%s, %s), "
213               " min [%s] = %f" %(cur_batch, num_ins,
214               "%.3f" % params_grid[min_index][0],
215               "%.3f" % params_grid[min_index][1],
216               args.error_rate_type, err_ave_min))
217         cur_batch += 1
218 
219     # output WER/CER at every (alpha, beta)
220     print("\nFinal %s:\n" % args.error_rate_type)
221     for index in xrange(len(params_grid)):
222         print("(alpha, beta) = (%s, %s), [%s] = %f"
223              % ("%.3f" % params_grid[index][0], "%.3f" % params_grid[index][1],
224              args.error_rate_type, err_ave[index]))
225 
226     err_ave_min = min(err_ave)
227     min_index = err_ave.index(err_ave_min)
228     print("\nFinish tuning on %d batches, final opt (alpha, beta) = (%s, %s)"
229             % (args.num_batches, "%.3f" % params_grid[min_index][0],
230               "%.3f" % params_grid[min_index][1]))
231 
232     logger.info("finish tuning")
233 
234 
235 def main():
236     print_arguments(args)
237     paddle.init(use_gpu=args.use_gpu,
238                 rnn_use_batch=True,
239                 trainer_count=args.trainer_count)
240     tune()
241 
242 
243 if __name__ == '__main__':
244     main()
245
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/tools/tune.py b/tools/tune.py
--- a/tools/tune.py
+++ b/tools/tune.py
@@ -16,7 +16,7 @@
 from decoders.swig_wrapper import Scorer
 from decoders.swig_wrapper import ctc_beam_search_decoder_batch
 from model_utils.model import deep_speech_v2_network
-from utils.error_rate import wer, cer
+from utils.error_rate import char_errors, word_errors
 from utils.utility import add_arguments, print_arguments
 
 parser = argparse.ArgumentParser(description=__doc__)
@@ -158,7 +158,7 @@
                 " dict_size = %d" % ext_scorer.get_dict_size())
     logger.info("end initializing scorer. Start tuning ...")
 
-    error_rate_func = cer if args.error_rate_type == 'cer' else wer
+    errors_func = char_errors if args.error_rate_type == 'cer' else word_errors
     # create grid for search
     cand_alphas = np.linspace(args.alpha_from, args.alpha_to, args.num_alphas)
     cand_betas = np.linspace(args.beta_from, args.beta_to, args.num_betas)
@@ -167,7 +167,7 @@
 
     err_sum = [0.0 for i in xrange(len(params_grid))]
     err_ave = [0.0 for i in xrange(len(params_grid))]
-    num_ins, cur_batch = 0, 0
+    num_ins, len_refs, cur_batch = 0, 0, 0
     ## incremental tuning parameters over multiple batches
     for infer_data in batch_reader():
         if (args.num_batches >= 0) and (cur_batch >= args.num_batches):
@@ -200,8 +200,14 @@
 
             result_transcripts = [res[0][1] for res in beam_search_results]
             for target, result in zip(target_transcripts, result_transcripts):
-                err_sum[index] += error_rate_func(target, result)
-            err_ave[index] = err_sum[index] / num_ins
+                errors, len_ref = errors_func(target, result)
+                err_sum[index] += errors
+                # accumulate the length of references of every batch
+                # in the first iteration
+                if args.alpha_from == alpha and args.beta_from == beta:
+                    len_refs += len_ref
+
+            err_ave[index] = err_sum[index] / len_refs
             if index % 2 == 0:
                 sys.stdout.write('.')
                 sys.stdout.flush()
@@ -226,7 +232,7 @@
     err_ave_min = min(err_ave)
     min_index = err_ave.index(err_ave_min)
     print("\nFinish tuning on %d batches, final opt (alpha, beta) = (%s, %s)"
-            % (args.num_batches, "%.3f" % params_grid[min_index][0],
+            % (cur_batch, "%.3f" % params_grid[min_index][0],
               "%.3f" % params_grid[min_index][1]))
 
     logger.info("finish tuning")

{"golden_diff": "diff --git a/tools/tune.py b/tools/tune.py\n--- a/tools/tune.py\n+++ b/tools/tune.py\n@@ -16,7 +16,7 @@\n from decoders.swig_wrapper import Scorer\n from decoders.swig_wrapper import ctc_beam_search_decoder_batch\n from model_utils.model import deep_speech_v2_network\n-from utils.error_rate import wer, cer\n+from utils.error_rate import char_errors, word_errors\n from utils.utility import add_arguments, print_arguments\n \n parser = argparse.ArgumentParser(description=__doc__)\n@@ -158,7 +158,7 @@\n                 \" dict_size = %d\" % ext_scorer.get_dict_size())\n     logger.info(\"end initializing scorer. Start tuning ...\")\n \n-    error_rate_func = cer if args.error_rate_type == 'cer' else wer\n+    errors_func = char_errors if args.error_rate_type == 'cer' else word_errors\n     # create grid for search\n     cand_alphas = np.linspace(args.alpha_from, args.alpha_to, args.num_alphas)\n     cand_betas = np.linspace(args.beta_from, args.beta_to, args.num_betas)\n@@ -167,7 +167,7 @@\n \n     err_sum = [0.0 for i in xrange(len(params_grid))]\n     err_ave = [0.0 for i in xrange(len(params_grid))]\n-    num_ins, cur_batch = 0, 0\n+    num_ins, len_refs, cur_batch = 0, 0, 0\n     ## incremental tuning parameters over multiple batches\n     for infer_data in batch_reader():\n         if (args.num_batches >= 0) and (cur_batch >= args.num_batches):\n@@ -200,8 +200,14 @@\n \n             result_transcripts = [res[0][1] for res in beam_search_results]\n             for target, result in zip(target_transcripts, result_transcripts):\n-                err_sum[index] += error_rate_func(target, result)\n-            err_ave[index] = err_sum[index] / num_ins\n+                errors, len_ref = errors_func(target, result)\n+                err_sum[index] += errors\n+                # accumulate the length of references of every batch\n+                # in the first iteration\n+                if args.alpha_from == alpha and args.beta_from == beta:\n+                    len_refs += len_ref\n+\n+            err_ave[index] = err_sum[index] / len_refs\n             if index % 2 == 0:\n                 sys.stdout.write('.')\n                 sys.stdout.flush()\n@@ -226,7 +232,7 @@\n     err_ave_min = min(err_ave)\n     min_index = err_ave.index(err_ave_min)\n     print(\"\\nFinish tuning on %d batches, final opt (alpha, beta) = (%s, %s)\"\n-            % (args.num_batches, \"%.3f\" % params_grid[min_index][0],\n+            % (cur_batch, \"%.3f\" % params_grid[min_index][0],\n               \"%.3f\" % params_grid[min_index][1]))\n \n     logger.info(\"finish tuning\")\n", "issue": "Correct the error rate's computation for multiple sentences\n\n", "before_files": [{"content": "\"\"\"Beam search parameters tuning for DeepSpeech2 model.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport sys\nimport os\nimport numpy as np\nimport argparse\nimport functools\nimport gzip\nimport logging\nimport paddle.v2 as paddle\nimport _init_paths\nfrom data_utils.data import DataGenerator\nfrom decoders.swig_wrapper import Scorer\nfrom decoders.swig_wrapper import ctc_beam_search_decoder_batch\nfrom model_utils.model import deep_speech_v2_network\nfrom utils.error_rate import wer, cer\nfrom utils.utility import add_arguments, print_arguments\n\nparser = argparse.ArgumentParser(description=__doc__)\nadd_arg = functools.partial(add_arguments, argparser=parser)\n# yapf: disable\nadd_arg('num_batches',      int,    -1,     \"# of batches tuning on. \"\n                                            \"Default -1, on whole dev set.\")\nadd_arg('batch_size',       int,    256,    \"# of samples per batch.\")\nadd_arg('trainer_count',    int,    8,      \"# of Trainers (CPUs or GPUs).\")\nadd_arg('beam_size',        int,    500,    \"Beam search width.\")\nadd_arg('num_proc_bsearch', int,    8,     \"# of CPUs for beam search.\")\nadd_arg('num_proc_data',    int,    8,      \"# of CPUs for data preprocessing.\")\nadd_arg('num_conv_layers',  int,    2,      \"# of convolution layers.\")\nadd_arg('num_rnn_layers',   int,    3,      \"# of recurrent layers.\")\nadd_arg('rnn_layer_size',   int,    2048,   \"# of recurrent cells per layer.\")\nadd_arg('num_alphas',       int,    45,     \"# of alpha candidates for tuning.\")\nadd_arg('num_betas',        int,    8,      \"# of beta candidates for tuning.\")\nadd_arg('alpha_from',       float,  1.0,    \"Where alpha starts tuning from.\")\nadd_arg('alpha_to',         float,  3.2,    \"Where alpha ends tuning with.\")\nadd_arg('beta_from',        float,  0.1,    \"Where beta starts tuning from.\")\nadd_arg('beta_to',          float,  0.45,   \"Where beta ends tuning with.\")\nadd_arg('cutoff_prob',      float,  1.0,    \"Cutoff probability for pruning.\")\nadd_arg('cutoff_top_n',     int,    40,     \"Cutoff number for pruning.\")\nadd_arg('use_gru',          bool,   False,  \"Use GRUs instead of simple RNNs.\")\nadd_arg('use_gpu',          bool,   True,   \"Use GPU or not.\")\nadd_arg('share_rnn_weights',bool,   True,   \"Share input-hidden weights across \"\n                                            \"bi-directional RNNs. Not for GRU.\")\nadd_arg('tune_manifest',    str,\n        'data/librispeech/manifest.dev-clean',\n        \"Filepath of manifest to tune.\")\nadd_arg('mean_std_path',    str,\n        'data/librispeech/mean_std.npz',\n        \"Filepath of normalizer's mean & std.\")\nadd_arg('vocab_path',       str,\n        'data/librispeech/vocab.txt',\n        \"Filepath of vocabulary.\")\nadd_arg('lang_model_path',  str,\n        'models/lm/common_crawl_00.prune01111.trie.klm',\n        \"Filepath for language model.\")\nadd_arg('model_path',       str,\n        './checkpoints/libri/params.latest.tar.gz',\n        \"If None, the training starts from scratch, \"\n        \"otherwise, it resumes from the pre-trained model.\")\nadd_arg('error_rate_type',  str,\n        'wer',\n        \"Error rate type for evaluation.\",\n        choices=['wer', 'cer'])\nadd_arg('specgram_type',    str,\n        'linear',\n        \"Audio feature type. Options: linear, mfcc.\",\n        choices=['linear', 'mfcc'])\n# yapf: disable\nargs = parser.parse_args()\n\n\nlogging.basicConfig(\n    format='[%(levelname)s %(asctime)s %(filename)s:%(lineno)d] %(message)s')\n\ndef tune():\n    \"\"\"Tune parameters alpha and beta incrementally.\"\"\"\n    if not args.num_alphas >= 0:\n        raise ValueError(\"num_alphas must be non-negative!\")\n    if not args.num_betas >= 0:\n        raise ValueError(\"num_betas must be non-negative!\")\n\n    data_generator = DataGenerator(\n        vocab_filepath=args.vocab_path,\n        mean_std_filepath=args.mean_std_path,\n        augmentation_config='{}',\n        specgram_type=args.specgram_type,\n        num_threads=args.num_proc_data,\n        keep_transcription_text=True,\n        num_conv_layers=args.num_conv_layers)\n\n    audio_data = paddle.layer.data(\n        name=\"audio_spectrogram\",\n        type=paddle.data_type.dense_array(161 * 161))\n    text_data = paddle.layer.data(\n        name=\"transcript_text\",\n        type=paddle.data_type.integer_value_sequence(data_generator.vocab_size))\n    seq_offset_data = paddle.layer.data(\n        name='sequence_offset',\n        type=paddle.data_type.integer_value_sequence(1))\n    seq_len_data = paddle.layer.data(\n        name='sequence_length',\n        type=paddle.data_type.integer_value_sequence(1))\n    index_range_datas = []\n    for i in xrange(args.num_rnn_layers):\n        index_range_datas.append(\n            paddle.layer.data(\n                name='conv%d_index_range' % i,\n                type=paddle.data_type.dense_vector(6)))\n\n    output_probs, _ = deep_speech_v2_network(\n        audio_data=audio_data,\n        text_data=text_data,\n        seq_offset_data=seq_offset_data,\n        seq_len_data=seq_len_data,\n        index_range_datas=index_range_datas,\n        dict_size=data_generator.vocab_size,\n        num_conv_layers=args.num_conv_layers,\n        num_rnn_layers=args.num_rnn_layers,\n        rnn_size=args.rnn_layer_size,\n        use_gru=args.use_gru,\n        share_rnn_weights=args.share_rnn_weights)\n\n    batch_reader = data_generator.batch_reader_creator(\n        manifest_path=args.tune_manifest,\n        batch_size=args.batch_size,\n        sortagrad=False,\n        shuffle_method=None)\n\n    # load parameters\n    if not os.path.isfile(args.model_path):\n        raise IOError(\"Invaid model path: %s\" % args.model_path)\n    parameters = paddle.parameters.Parameters.from_tar(\n        gzip.open(args.model_path))\n\n    inferer = paddle.inference.Inference(\n        output_layer=output_probs, parameters=parameters)\n    # decoders only accept string encoded in utf-8\n    vocab_list = [chars.encode(\"utf-8\") for chars in data_generator.vocab_list]\n\n    # init logger\n    logger = logging.getLogger(\"\")\n    logger.setLevel(level=logging.INFO)\n    # init external scorer\n    logger.info(\"begin to initialize the external scorer for tuning\")\n    if not os.path.isfile(args.lang_model_path):\n        raise IOError(\"Invaid language model path: %s\" % args.lang_model_path)\n    ext_scorer = Scorer(\n        alpha=args.alpha_from,\n        beta=args.beta_from,\n        model_path=args.lang_model_path,\n        vocabulary=vocab_list)\n    logger.info(\"language model: \"\n                \"is_character_based = %d,\" % ext_scorer.is_character_based() +\n                \" max_order = %d,\" % ext_scorer.get_max_order() +\n                \" dict_size = %d\" % ext_scorer.get_dict_size())\n    logger.info(\"end initializing scorer. Start tuning ...\")\n\n    error_rate_func = cer if args.error_rate_type == 'cer' else wer\n    # create grid for search\n    cand_alphas = np.linspace(args.alpha_from, args.alpha_to, args.num_alphas)\n    cand_betas = np.linspace(args.beta_from, args.beta_to, args.num_betas)\n    params_grid = [(alpha, beta) for alpha in cand_alphas\n                   for beta in cand_betas]\n\n    err_sum = [0.0 for i in xrange(len(params_grid))]\n    err_ave = [0.0 for i in xrange(len(params_grid))]\n    num_ins, cur_batch = 0, 0\n    ## incremental tuning parameters over multiple batches\n    for infer_data in batch_reader():\n        if (args.num_batches >= 0) and (cur_batch >= args.num_batches):\n            break\n        infer_results = inferer.infer(input=infer_data,\n                                      feeding=data_generator.feeding)\n        start_pos = [0] * (len(infer_data) + 1)\n        for i in xrange(len(infer_data)):\n            start_pos[i + 1] = start_pos[i] + infer_data[i][3][0]\n        probs_split = [\n                infer_results[start_pos[i]:start_pos[i + 1]]\n                for i in xrange(0, len(infer_data))\n        ]\n\n        target_transcripts = [ data[1] for data in infer_data ]\n\n        num_ins += len(target_transcripts)\n        # grid search\n        for index, (alpha, beta) in enumerate(params_grid):\n            # reset alpha & beta\n            ext_scorer.reset_params(alpha, beta)\n            beam_search_results = ctc_beam_search_decoder_batch(\n                probs_split=probs_split,\n                vocabulary=vocab_list,\n                beam_size=args.beam_size,\n                num_processes=args.num_proc_bsearch,\n                cutoff_prob=args.cutoff_prob,\n                cutoff_top_n=args.cutoff_top_n,\n                ext_scoring_func=ext_scorer, )\n\n            result_transcripts = [res[0][1] for res in beam_search_results]\n            for target, result in zip(target_transcripts, result_transcripts):\n                err_sum[index] += error_rate_func(target, result)\n            err_ave[index] = err_sum[index] / num_ins\n            if index % 2 == 0:\n                sys.stdout.write('.')\n                sys.stdout.flush()\n\n        # output on-line tuning result at the end of current batch\n        err_ave_min = min(err_ave)\n        min_index = err_ave.index(err_ave_min)\n        print(\"\\nBatch %d [%d/?], current opt (alpha, beta) = (%s, %s), \"\n              \" min [%s] = %f\" %(cur_batch, num_ins,\n              \"%.3f\" % params_grid[min_index][0],\n              \"%.3f\" % params_grid[min_index][1],\n              args.error_rate_type, err_ave_min))\n        cur_batch += 1\n\n    # output WER/CER at every (alpha, beta)\n    print(\"\\nFinal %s:\\n\" % args.error_rate_type)\n    for index in xrange(len(params_grid)):\n        print(\"(alpha, beta) = (%s, %s), [%s] = %f\"\n             % (\"%.3f\" % params_grid[index][0], \"%.3f\" % params_grid[index][1],\n             args.error_rate_type, err_ave[index]))\n\n    err_ave_min = min(err_ave)\n    min_index = err_ave.index(err_ave_min)\n    print(\"\\nFinish tuning on %d batches, final opt (alpha, beta) = (%s, %s)\"\n            % (args.num_batches, \"%.3f\" % params_grid[min_index][0],\n              \"%.3f\" % params_grid[min_index][1]))\n\n    logger.info(\"finish tuning\")\n\n\ndef main():\n    print_arguments(args)\n    paddle.init(use_gpu=args.use_gpu,\n                rnn_use_batch=True,\n                trainer_count=args.trainer_count)\n    tune()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "tools/tune.py"}], "after_files": [{"content": "\"\"\"Beam search parameters tuning for DeepSpeech2 model.\"\"\"\nfrom __future__ import absolute_import\nfrom __future__ import division\nfrom __future__ import print_function\n\nimport sys\nimport os\nimport numpy as np\nimport argparse\nimport functools\nimport gzip\nimport logging\nimport paddle.v2 as paddle\nimport _init_paths\nfrom data_utils.data import DataGenerator\nfrom decoders.swig_wrapper import Scorer\nfrom decoders.swig_wrapper import ctc_beam_search_decoder_batch\nfrom model_utils.model import deep_speech_v2_network\nfrom utils.error_rate import char_errors, word_errors\nfrom utils.utility import add_arguments, print_arguments\n\nparser = argparse.ArgumentParser(description=__doc__)\nadd_arg = functools.partial(add_arguments, argparser=parser)\n# yapf: disable\nadd_arg('num_batches',      int,    -1,     \"# of batches tuning on. \"\n                                            \"Default -1, on whole dev set.\")\nadd_arg('batch_size',       int,    256,    \"# of samples per batch.\")\nadd_arg('trainer_count',    int,    8,      \"# of Trainers (CPUs or GPUs).\")\nadd_arg('beam_size',        int,    500,    \"Beam search width.\")\nadd_arg('num_proc_bsearch', int,    8,     \"# of CPUs for beam search.\")\nadd_arg('num_proc_data',    int,    8,      \"# of CPUs for data preprocessing.\")\nadd_arg('num_conv_layers',  int,    2,      \"# of convolution layers.\")\nadd_arg('num_rnn_layers',   int,    3,      \"# of recurrent layers.\")\nadd_arg('rnn_layer_size',   int,    2048,   \"# of recurrent cells per layer.\")\nadd_arg('num_alphas',       int,    45,     \"# of alpha candidates for tuning.\")\nadd_arg('num_betas',        int,    8,      \"# of beta candidates for tuning.\")\nadd_arg('alpha_from',       float,  1.0,    \"Where alpha starts tuning from.\")\nadd_arg('alpha_to',         float,  3.2,    \"Where alpha ends tuning with.\")\nadd_arg('beta_from',        float,  0.1,    \"Where beta starts tuning from.\")\nadd_arg('beta_to',          float,  0.45,   \"Where beta ends tuning with.\")\nadd_arg('cutoff_prob',      float,  1.0,    \"Cutoff probability for pruning.\")\nadd_arg('cutoff_top_n',     int,    40,     \"Cutoff number for pruning.\")\nadd_arg('use_gru',          bool,   False,  \"Use GRUs instead of simple RNNs.\")\nadd_arg('use_gpu',          bool,   True,   \"Use GPU or not.\")\nadd_arg('share_rnn_weights',bool,   True,   \"Share input-hidden weights across \"\n                                            \"bi-directional RNNs. Not for GRU.\")\nadd_arg('tune_manifest',    str,\n        'data/librispeech/manifest.dev-clean',\n        \"Filepath of manifest to tune.\")\nadd_arg('mean_std_path',    str,\n        'data/librispeech/mean_std.npz',\n        \"Filepath of normalizer's mean & std.\")\nadd_arg('vocab_path',       str,\n        'data/librispeech/vocab.txt',\n        \"Filepath of vocabulary.\")\nadd_arg('lang_model_path',  str,\n        'models/lm/common_crawl_00.prune01111.trie.klm',\n        \"Filepath for language model.\")\nadd_arg('model_path',       str,\n        './checkpoints/libri/params.latest.tar.gz',\n        \"If None, the training starts from scratch, \"\n        \"otherwise, it resumes from the pre-trained model.\")\nadd_arg('error_rate_type',  str,\n        'wer',\n        \"Error rate type for evaluation.\",\n        choices=['wer', 'cer'])\nadd_arg('specgram_type',    str,\n        'linear',\n        \"Audio feature type. Options: linear, mfcc.\",\n        choices=['linear', 'mfcc'])\n# yapf: disable\nargs = parser.parse_args()\n\n\nlogging.basicConfig(\n    format='[%(levelname)s %(asctime)s %(filename)s:%(lineno)d] %(message)s')\n\ndef tune():\n    \"\"\"Tune parameters alpha and beta incrementally.\"\"\"\n    if not args.num_alphas >= 0:\n        raise ValueError(\"num_alphas must be non-negative!\")\n    if not args.num_betas >= 0:\n        raise ValueError(\"num_betas must be non-negative!\")\n\n    data_generator = DataGenerator(\n        vocab_filepath=args.vocab_path,\n        mean_std_filepath=args.mean_std_path,\n        augmentation_config='{}',\n        specgram_type=args.specgram_type,\n        num_threads=args.num_proc_data,\n        keep_transcription_text=True,\n        num_conv_layers=args.num_conv_layers)\n\n    audio_data = paddle.layer.data(\n        name=\"audio_spectrogram\",\n        type=paddle.data_type.dense_array(161 * 161))\n    text_data = paddle.layer.data(\n        name=\"transcript_text\",\n        type=paddle.data_type.integer_value_sequence(data_generator.vocab_size))\n    seq_offset_data = paddle.layer.data(\n        name='sequence_offset',\n        type=paddle.data_type.integer_value_sequence(1))\n    seq_len_data = paddle.layer.data(\n        name='sequence_length',\n        type=paddle.data_type.integer_value_sequence(1))\n    index_range_datas = []\n    for i in xrange(args.num_rnn_layers):\n        index_range_datas.append(\n            paddle.layer.data(\n                name='conv%d_index_range' % i,\n                type=paddle.data_type.dense_vector(6)))\n\n    output_probs, _ = deep_speech_v2_network(\n        audio_data=audio_data,\n        text_data=text_data,\n        seq_offset_data=seq_offset_data,\n        seq_len_data=seq_len_data,\n        index_range_datas=index_range_datas,\n        dict_size=data_generator.vocab_size,\n        num_conv_layers=args.num_conv_layers,\n        num_rnn_layers=args.num_rnn_layers,\n        rnn_size=args.rnn_layer_size,\n        use_gru=args.use_gru,\n        share_rnn_weights=args.share_rnn_weights)\n\n    batch_reader = data_generator.batch_reader_creator(\n        manifest_path=args.tune_manifest,\n        batch_size=args.batch_size,\n        sortagrad=False,\n        shuffle_method=None)\n\n    # load parameters\n    if not os.path.isfile(args.model_path):\n        raise IOError(\"Invaid model path: %s\" % args.model_path)\n    parameters = paddle.parameters.Parameters.from_tar(\n        gzip.open(args.model_path))\n\n    inferer = paddle.inference.Inference(\n        output_layer=output_probs, parameters=parameters)\n    # decoders only accept string encoded in utf-8\n    vocab_list = [chars.encode(\"utf-8\") for chars in data_generator.vocab_list]\n\n    # init logger\n    logger = logging.getLogger(\"\")\n    logger.setLevel(level=logging.INFO)\n    # init external scorer\n    logger.info(\"begin to initialize the external scorer for tuning\")\n    if not os.path.isfile(args.lang_model_path):\n        raise IOError(\"Invaid language model path: %s\" % args.lang_model_path)\n    ext_scorer = Scorer(\n        alpha=args.alpha_from,\n        beta=args.beta_from,\n        model_path=args.lang_model_path,\n        vocabulary=vocab_list)\n    logger.info(\"language model: \"\n                \"is_character_based = %d,\" % ext_scorer.is_character_based() +\n                \" max_order = %d,\" % ext_scorer.get_max_order() +\n                \" dict_size = %d\" % ext_scorer.get_dict_size())\n    logger.info(\"end initializing scorer. Start tuning ...\")\n\n    errors_func = char_errors if args.error_rate_type == 'cer' else word_errors\n    # create grid for search\n    cand_alphas = np.linspace(args.alpha_from, args.alpha_to, args.num_alphas)\n    cand_betas = np.linspace(args.beta_from, args.beta_to, args.num_betas)\n    params_grid = [(alpha, beta) for alpha in cand_alphas\n                   for beta in cand_betas]\n\n    err_sum = [0.0 for i in xrange(len(params_grid))]\n    err_ave = [0.0 for i in xrange(len(params_grid))]\n    num_ins, len_refs, cur_batch = 0, 0, 0\n    ## incremental tuning parameters over multiple batches\n    for infer_data in batch_reader():\n        if (args.num_batches >= 0) and (cur_batch >= args.num_batches):\n            break\n        infer_results = inferer.infer(input=infer_data,\n                                      feeding=data_generator.feeding)\n        start_pos = [0] * (len(infer_data) + 1)\n        for i in xrange(len(infer_data)):\n            start_pos[i + 1] = start_pos[i] + infer_data[i][3][0]\n        probs_split = [\n                infer_results[start_pos[i]:start_pos[i + 1]]\n                for i in xrange(0, len(infer_data))\n        ]\n\n        target_transcripts = [ data[1] for data in infer_data ]\n\n        num_ins += len(target_transcripts)\n        # grid search\n        for index, (alpha, beta) in enumerate(params_grid):\n            # reset alpha & beta\n            ext_scorer.reset_params(alpha, beta)\n            beam_search_results = ctc_beam_search_decoder_batch(\n                probs_split=probs_split,\n                vocabulary=vocab_list,\n                beam_size=args.beam_size,\n                num_processes=args.num_proc_bsearch,\n                cutoff_prob=args.cutoff_prob,\n                cutoff_top_n=args.cutoff_top_n,\n                ext_scoring_func=ext_scorer, )\n\n            result_transcripts = [res[0][1] for res in beam_search_results]\n            for target, result in zip(target_transcripts, result_transcripts):\n                errors, len_ref = errors_func(target, result)\n                err_sum[index] += errors\n                # accumulate the length of references of every batch\n                # in the first iteration\n                if args.alpha_from == alpha and args.beta_from == beta:\n                    len_refs += len_ref\n\n            err_ave[index] = err_sum[index] / len_refs\n            if index % 2 == 0:\n                sys.stdout.write('.')\n                sys.stdout.flush()\n\n        # output on-line tuning result at the end of current batch\n        err_ave_min = min(err_ave)\n        min_index = err_ave.index(err_ave_min)\n        print(\"\\nBatch %d [%d/?], current opt (alpha, beta) = (%s, %s), \"\n              \" min [%s] = %f\" %(cur_batch, num_ins,\n              \"%.3f\" % params_grid[min_index][0],\n              \"%.3f\" % params_grid[min_index][1],\n              args.error_rate_type, err_ave_min))\n        cur_batch += 1\n\n    # output WER/CER at every (alpha, beta)\n    print(\"\\nFinal %s:\\n\" % args.error_rate_type)\n    for index in xrange(len(params_grid)):\n        print(\"(alpha, beta) = (%s, %s), [%s] = %f\"\n             % (\"%.3f\" % params_grid[index][0], \"%.3f\" % params_grid[index][1],\n             args.error_rate_type, err_ave[index]))\n\n    err_ave_min = min(err_ave)\n    min_index = err_ave.index(err_ave_min)\n    print(\"\\nFinish tuning on %d batches, final opt (alpha, beta) = (%s, %s)\"\n            % (cur_batch, \"%.3f\" % params_grid[min_index][0],\n              \"%.3f\" % params_grid[min_index][1]))\n\n    logger.info(\"finish tuning\")\n\n\ndef main():\n    print_arguments(args)\n    paddle.init(use_gpu=args.use_gpu,\n                rnn_use_batch=True,\n                trainer_count=args.trainer_count)\n    tune()\n\n\nif __name__ == '__main__':\n    main()\n", "path": "tools/tune.py"}]}