tune.py 6.5 KB
Newer Older
Y
Yibing Liu 已提交
1 2 3 4
"""Parameters tuning for DeepSpeech2 model."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
5

6
import numpy as np
7 8
import distutils.util
import argparse
9
import multiprocessing
Y
Yibing Liu 已提交
10
import paddle.v2 as paddle
Y
Yibing Liu 已提交
11
from data_utils.data import DataGenerator
12
from model import DeepSpeech2Model
13
from error_rate import wer
Y
Yibing Liu 已提交
14
import utils
15

Y
Yibing Liu 已提交
16
parser = argparse.ArgumentParser(description=__doc__)
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
parser.add_argument(
    "--num_samples",
    default=100,
    type=int,
    help="Number of samples for parameters tuning. (default: %(default)s)")
parser.add_argument(
    "--num_conv_layers",
    default=2,
    type=int,
    help="Convolution layer number. (default: %(default)s)")
parser.add_argument(
    "--num_rnn_layers",
    default=3,
    type=int,
    help="RNN layer number. (default: %(default)s)")
parser.add_argument(
    "--rnn_layer_size",
34
    default=2048,
35 36
    type=int,
    help="RNN layer cell number. (default: %(default)s)")
37 38 39 40 41 42 43
parser.add_argument(
    "--share_rnn_weights",
    default=True,
    type=distutils.util.strtobool,
    help="Whether to share input-hidden weights between forword and backward "
    "directional simple RNNs. Only available when use_gru=False. "
    "(default: %(default)s)")
X
Xinghai Sun 已提交
44 45
parser.add_argument(
    "--use_gru",
46 47
    default=False,
    type=distutils.util.strtobool,
X
Xinghai Sun 已提交
48
    help="Use GRU or simple RNN. (default: %(default)s)")
49 50 51 52 53
parser.add_argument(
    "--use_gpu",
    default=True,
    type=distutils.util.strtobool,
    help="Use gpu or not. (default: %(default)s)")
54 55 56 57 58
parser.add_argument(
    "--trainer_count",
    default=8,
    type=int,
    help="Trainer number. (default: %(default)s)")
Y
Yibing Liu 已提交
59 60
parser.add_argument(
    "--num_threads_data",
61
    default=1,
Y
Yibing Liu 已提交
62 63 64 65
    type=int,
    help="Number of cpu threads for preprocessing data. (default: %(default)s)")
parser.add_argument(
    "--num_processes_beam_search",
66
    default=multiprocessing.cpu_count() // 2,
Y
Yibing Liu 已提交
67 68
    type=int,
    help="Number of cpu processes for beam search. (default: %(default)s)")
69 70 71 72 73 74
parser.add_argument(
    "--specgram_type",
    default='linear',
    type=str,
    help="Feature type of audio data: 'linear' (power spectrum)"
    " or 'mfcc'. (default: %(default)s)")
Y
Yibing Liu 已提交
75 76 77 78 79
parser.add_argument(
    "--mean_std_filepath",
    default='mean_std.npz',
    type=str,
    help="Manifest path for normalizer. (default: %(default)s)")
80
parser.add_argument(
81
    "--tune_manifest_path",
82
    default='datasets/manifest.dev',
83
    type=str,
84
    help="Manifest path for tuning. (default: %(default)s)")
85 86
parser.add_argument(
    "--model_filepath",
Y
Yibing Liu 已提交
87
    default='checkpoints/params.latest.tar.gz',
88 89 90 91
    type=str,
    help="Model filepath. (default: %(default)s)")
parser.add_argument(
    "--vocab_filepath",
Y
Yibing Liu 已提交
92
    default='datasets/vocab/eng_vocab.txt',
93 94 95 96 97 98 99 100 101
    type=str,
    help="Vocabulary filepath. (default: %(default)s)")
parser.add_argument(
    "--beam_size",
    default=500,
    type=int,
    help="Width for beam search decoding. (default: %(default)d)")
parser.add_argument(
    "--language_model_path",
Y
Yibing Liu 已提交
102
    default="lm/data/common_crawl_00.prune01111.trie.klm",
103 104 105 106
    type=str,
    help="Path for language model. (default: %(default)s)")
parser.add_argument(
    "--alpha_from",
107
    default=0.1,
108
    type=float,
109
    help="Where alpha starts from. (default: %(default)f)")
110
parser.add_argument(
111 112 113 114
    "--num_alphas",
    default=14,
    type=int,
    help="Number of candidate alphas. (default: %(default)d)")
115 116
parser.add_argument(
    "--alpha_to",
117
    default=0.36,
118
    type=float,
119
    help="Where alpha ends with. (default: %(default)f)")
120 121
parser.add_argument(
    "--beta_from",
122
    default=0.05,
123
    type=float,
124
    help="Where beta starts from. (default: %(default)f)")
125
parser.add_argument(
126 127
    "--num_betas",
    default=20,
128
    type=float,
129
    help="Number of candidate betas. (default: %(default)d)")
130 131
parser.add_argument(
    "--beta_to",
132
    default=1.0,
133
    type=float,
134 135 136 137 138 139 140
    help="Where beta ends with. (default: %(default)f)")
parser.add_argument(
    "--cutoff_prob",
    default=0.99,
    type=float,
    help="The cutoff probability of pruning"
    "in beam search. (default: %(default)f)")
141 142 143 144
args = parser.parse_args()


def tune():
Y
Yibing Liu 已提交
145
    """Tune parameters alpha and beta on one minibatch."""
146 147 148 149
    if not args.num_alphas >= 0:
        raise ValueError("num_alphas must be non-negative!")
    if not args.num_betas >= 0:
        raise ValueError("num_betas must be non-negative!")
150 151 152

    data_generator = DataGenerator(
        vocab_filepath=args.vocab_filepath,
Y
Yibing Liu 已提交
153
        mean_std_filepath=args.mean_std_filepath,
Y
Yibing Liu 已提交
154
        augmentation_config='{}',
155
        specgram_type=args.specgram_type,
Y
Yibing Liu 已提交
156
        num_threads=args.num_threads_data)
Y
Yibing Liu 已提交
157
    batch_reader = data_generator.batch_reader_creator(
158
        manifest_path=args.tune_manifest_path,
159
        batch_size=args.num_samples,
Y
Yibing Liu 已提交
160 161
        sortagrad=False,
        shuffle_method=None)
162 163 164 165
    tune_data = batch_reader().next()
    target_transcripts = [
        ''.join([data_generator.vocab_list[token] for token in transcript])
        for _, transcript in tune_data
166 167
    ]

168 169 170 171 172
    ds2_model = DeepSpeech2Model(
        vocab_size=data_generator.vocab_size,
        num_conv_layers=args.num_conv_layers,
        num_rnn_layers=args.num_rnn_layers,
        rnn_layer_size=args.rnn_layer_size,
X
Xinghai Sun 已提交
173
        use_gru=args.use_gru,
174 175
        pretrained_model_path=args.model_filepath,
        share_rnn_weights=args.share_rnn_weights)
176

177 178 179 180 181 182
    # 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)
    params_grid = [(alpha, beta) for alpha in cand_alphas
                   for beta in cand_betas]

183
    ## tune parameters in loop
Y
Yibing Liu 已提交
184
    for alpha, beta in params_grid:
185 186 187 188 189
        result_transcripts = ds2_model.infer_batch(
            infer_data=tune_data,
            decode_method='beam_search',
            beam_alpha=alpha,
            beam_beta=beta,
Y
Yibing Liu 已提交
190 191
            beam_size=args.beam_size,
            cutoff_prob=args.cutoff_prob,
192 193 194 195 196 197 198
            vocab_list=data_generator.vocab_list,
            language_model_path=args.language_model_path,
            num_processes=args.num_processes_beam_search)
        wer_sum, num_ins = 0.0, 0
        for target, result in zip(target_transcripts, result_transcripts):
            wer_sum += wer(target, result)
            num_ins += 1
199
        print("alpha = %f\tbeta = %f\tWER = %f" %
200
              (alpha, beta, wer_sum / num_ins))
201 202 203


def main():
204 205
    utils.print_arguments(args)
    paddle.init(use_gpu=args.use_gpu, trainer_count=args.trainer_count)
206 207 208 209 210
    tune()


if __name__ == '__main__':
    main()