parent
9ad688c6aa
commit
3e449d6500
@ -0,0 +1,169 @@
|
|||||||
|
# Copyright (c) 2021 PaddlePaddle Authors. All Rights Reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
"""Contains the volume perturb augmentation model."""
|
||||||
|
import logging
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
from deepspeech.frontend.augmentor.base import AugmentorBase
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class SpecAugmentor(AugmentorBase):
|
||||||
|
"""Augmentation model for Time warping, Frequency masking, Time masking.
|
||||||
|
|
||||||
|
SpecAugment: A Simple Data Augmentation Method for Automatic Speech Recognition
|
||||||
|
https://arxiv.org/abs/1904.08779
|
||||||
|
|
||||||
|
SpecAugment on Large Scale Datasets
|
||||||
|
https://arxiv.org/abs/1912.05533
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self,
|
||||||
|
rng,
|
||||||
|
F,
|
||||||
|
T,
|
||||||
|
n_freq_masks,
|
||||||
|
n_time_masks,
|
||||||
|
p=1.0,
|
||||||
|
W=40,
|
||||||
|
adaptive_number_ratio=0,
|
||||||
|
adaptive_size_ratio=0,
|
||||||
|
max_n_time_masks=20):
|
||||||
|
"""SpecAugment class.
|
||||||
|
Args:
|
||||||
|
rng (random.Random): random generator object.
|
||||||
|
F (int): parameter for frequency masking
|
||||||
|
T (int): parameter for time masking
|
||||||
|
n_freq_masks (int): number of frequency masks
|
||||||
|
n_time_masks (int): number of time masks
|
||||||
|
p (float): parameter for upperbound of the time mask
|
||||||
|
W (int): parameter for time warping
|
||||||
|
adaptive_number_ratio (float): adaptive multiplicity ratio for time masking
|
||||||
|
adaptive_size_ratio (float): adaptive size ratio for time masking
|
||||||
|
max_n_time_masks (int): maximum number of time masking
|
||||||
|
"""
|
||||||
|
super().__init__()
|
||||||
|
self._rng = rng
|
||||||
|
|
||||||
|
self.W = W
|
||||||
|
self.F = F
|
||||||
|
self.T = T
|
||||||
|
self.n_freq_masks = n_freq_masks
|
||||||
|
self.n_time_masks = n_time_masks
|
||||||
|
self.p = p
|
||||||
|
|
||||||
|
# adaptive SpecAugment
|
||||||
|
self.adaptive_number_ratio = adaptive_number_ratio
|
||||||
|
self.adaptive_size_ratio = adaptive_size_ratio
|
||||||
|
self.max_n_time_masks = max_n_time_masks
|
||||||
|
|
||||||
|
if adaptive_number_ratio > 0:
|
||||||
|
self.n_time_masks = 0
|
||||||
|
logger.info('n_time_masks is set ot zero for adaptive SpecAugment.')
|
||||||
|
if adaptive_size_ratio > 0:
|
||||||
|
self.T = 0
|
||||||
|
logger.info('T is set to zero for adaptive SpecAugment.')
|
||||||
|
|
||||||
|
self._freq_mask = None
|
||||||
|
self._time_mask = None
|
||||||
|
|
||||||
|
def librispeech_basic(self):
|
||||||
|
self.W = 80
|
||||||
|
self.F = 27
|
||||||
|
self.T = 100
|
||||||
|
self.n_freq_masks = 1
|
||||||
|
self.n_time_masks = 1
|
||||||
|
self.p = 1.0
|
||||||
|
|
||||||
|
def librispeech_double(self):
|
||||||
|
self.W = 80
|
||||||
|
self.F = 27
|
||||||
|
self.T = 100
|
||||||
|
self.n_freq_masks = 2
|
||||||
|
self.n_time_masks = 2
|
||||||
|
self.p = 1.0
|
||||||
|
|
||||||
|
def switchboard_mild(self):
|
||||||
|
self.W = 40
|
||||||
|
self.F = 15
|
||||||
|
self.T = 70
|
||||||
|
self.n_freq_masks = 2
|
||||||
|
self.n_time_masks = 2
|
||||||
|
self.p = 0.2
|
||||||
|
|
||||||
|
def switchboard_strong(self):
|
||||||
|
self.W = 40
|
||||||
|
self.F = 27
|
||||||
|
self.T = 70
|
||||||
|
self.n_freq_masks = 2
|
||||||
|
self.n_time_masks = 2
|
||||||
|
self.p = 0.2
|
||||||
|
|
||||||
|
@property
|
||||||
|
def freq_mask(self):
|
||||||
|
return self._freq_mask
|
||||||
|
|
||||||
|
@property
|
||||||
|
def time_mask(self):
|
||||||
|
return self._time_mask
|
||||||
|
|
||||||
|
def time_warp(xs, W=40):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def mask_freq(self, xs, replace_with_zero=False):
|
||||||
|
n_bins = xs.shape[0]
|
||||||
|
for i in range(0, self.n_freq_masks):
|
||||||
|
f = int(self._rng.uniform(low=0, high=self.F))
|
||||||
|
f_0 = int(self._rng.uniform(low=0, high=n_bins - f))
|
||||||
|
xs[f_0:f_0 + f, :] = 0
|
||||||
|
assert f_0 <= f_0 + f
|
||||||
|
self._freq_mask = (f_0, f_0 + f)
|
||||||
|
return xs
|
||||||
|
|
||||||
|
def mask_time(self, xs, replace_with_zero=False):
|
||||||
|
n_frames = xs.shape[1]
|
||||||
|
|
||||||
|
if self.adaptive_number_ratio > 0:
|
||||||
|
n_masks = int(n_frames * self.adaptive_number_ratio)
|
||||||
|
n_masks = min(n_masks, self.max_n_time_masks)
|
||||||
|
else:
|
||||||
|
n_masks = self.n_time_masks
|
||||||
|
|
||||||
|
if self.adaptive_size_ratio > 0:
|
||||||
|
T = self.adaptive_size_ratio * n_frames
|
||||||
|
else:
|
||||||
|
T = self.T
|
||||||
|
|
||||||
|
for i in range(n_masks):
|
||||||
|
t = int(self._rng.uniform(low=0, high=T))
|
||||||
|
t = min(t, int(n_frames * self.p))
|
||||||
|
t_0 = int(self._rng.uniform(low=0, high=n_frames - t))
|
||||||
|
xs[:, t_0:t_0 + t] = 0
|
||||||
|
assert t_0 <= t_0 + t
|
||||||
|
self._time_mask = (t_0, t_0 + t)
|
||||||
|
return xs
|
||||||
|
|
||||||
|
def transform_feature(self, xs: np.ndarray):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
xs (FloatTensor): `[F, T]`
|
||||||
|
Returns:
|
||||||
|
xs (FloatTensor): `[F, T]`
|
||||||
|
"""
|
||||||
|
# xs = self.time_warp(xs)
|
||||||
|
xs = self.mask_freq(xs)
|
||||||
|
xs = self.mask_time(xs)
|
||||||
|
return xs
|
@ -1,8 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "shift",
|
|
||||||
"params": {"min_shift_ms": -5,
|
|
||||||
"max_shift_ms": 5},
|
|
||||||
"prob": 1.0
|
|
||||||
}
|
|
||||||
]
|
|
@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "shift",
|
||||||
|
"params": {
|
||||||
|
"min_shift_ms": -5,
|
||||||
|
"max_shift_ms": 5
|
||||||
|
},
|
||||||
|
"prob": 1.0
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,34 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "speed",
|
||||||
|
"params": {
|
||||||
|
"min_speed_rate": 0.9,
|
||||||
|
"max_speed_rate": 1.1,
|
||||||
|
"num_rates": 3
|
||||||
|
},
|
||||||
|
"prob": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shift",
|
||||||
|
"params": {
|
||||||
|
"min_shift_ms": -5,
|
||||||
|
"max_shift_ms": 5
|
||||||
|
},
|
||||||
|
"prob": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "specaug",
|
||||||
|
"params": {
|
||||||
|
"F": 10,
|
||||||
|
"T": 50,
|
||||||
|
"n_freq_masks": 2,
|
||||||
|
"n_time_masks": 2,
|
||||||
|
"p": 1.0,
|
||||||
|
"W": 80,
|
||||||
|
"adaptive_number_ratio": 0,
|
||||||
|
"adaptive_size_ratio": 0,
|
||||||
|
"max_n_time_masks": 20
|
||||||
|
},
|
||||||
|
"prob": 0.0
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,110 @@
|
|||||||
|
# https://yaml.org/type/float.html
|
||||||
|
data:
|
||||||
|
train_manifest: data/manifest.train
|
||||||
|
dev_manifest: data/manifest.dev
|
||||||
|
test_manifest: data/manifest.test
|
||||||
|
vocab_filepath: data/vocab.txt
|
||||||
|
unit_type: 'char'
|
||||||
|
spm_model_prefix: ''
|
||||||
|
mean_std_filepath: ""
|
||||||
|
augmentation_config: conf/augmentation.json
|
||||||
|
batch_size: 16
|
||||||
|
min_input_len: 0.5
|
||||||
|
max_input_len: 20.0
|
||||||
|
min_output_len: 0.0
|
||||||
|
max_output_len: 400
|
||||||
|
min_output_input_ratio: 0.05
|
||||||
|
max_output_input_ratio: 10.0
|
||||||
|
raw_wav: True # use raw_wav or kaldi feature
|
||||||
|
specgram_type: fbank #linear, mfcc, fbank
|
||||||
|
feat_dim: 80
|
||||||
|
delta_delta: False
|
||||||
|
target_sample_rate: 16000
|
||||||
|
max_freq: None
|
||||||
|
n_fft: None
|
||||||
|
stride_ms: 10.0
|
||||||
|
window_ms: 25.0
|
||||||
|
use_dB_normalization: True
|
||||||
|
target_dB: -20
|
||||||
|
random_seed: 0
|
||||||
|
keep_transcription_text: False
|
||||||
|
sortagrad: True
|
||||||
|
shuffle_method: batch_shuffle
|
||||||
|
num_workers: 0
|
||||||
|
|
||||||
|
|
||||||
|
# network architecture
|
||||||
|
model:
|
||||||
|
cmvn_file: "data/mean_std.npz"
|
||||||
|
cmvn_file_type: "npz"
|
||||||
|
# encoder related
|
||||||
|
encoder: conformer
|
||||||
|
encoder_conf:
|
||||||
|
output_size: 256 # dimension of attention
|
||||||
|
attention_heads: 4
|
||||||
|
linear_units: 2048 # the number of units of position-wise feed forward
|
||||||
|
num_blocks: 12 # the number of encoder blocks
|
||||||
|
dropout_rate: 0.1
|
||||||
|
positional_dropout_rate: 0.1
|
||||||
|
attention_dropout_rate: 0.0
|
||||||
|
input_layer: conv2d # encoder input type, you can chose conv2d, conv2d6 and conv2d8
|
||||||
|
normalize_before: True
|
||||||
|
use_cnn_module: True
|
||||||
|
cnn_module_kernel: 15
|
||||||
|
activation_type: 'swish'
|
||||||
|
pos_enc_layer_type: 'rel_pos'
|
||||||
|
selfattention_layer_type: 'rel_selfattn'
|
||||||
|
|
||||||
|
# decoder related
|
||||||
|
decoder: transformer
|
||||||
|
decoder_conf:
|
||||||
|
attention_heads: 4
|
||||||
|
linear_units: 2048
|
||||||
|
num_blocks: 6
|
||||||
|
dropout_rate: 0.1
|
||||||
|
positional_dropout_rate: 0.1
|
||||||
|
self_attention_dropout_rate: 0.0
|
||||||
|
src_attention_dropout_rate: 0.0
|
||||||
|
|
||||||
|
# hybrid CTC/attention
|
||||||
|
model_conf:
|
||||||
|
ctc_weight: 0.3
|
||||||
|
lsm_weight: 0.1 # label smoothing option
|
||||||
|
length_normalized_loss: false
|
||||||
|
|
||||||
|
|
||||||
|
training:
|
||||||
|
n_epoch: 240
|
||||||
|
accum_grad: 4
|
||||||
|
global_grad_clip: 5.0
|
||||||
|
optim: adam
|
||||||
|
optim_conf:
|
||||||
|
lr: 0.002
|
||||||
|
weight_decay: 1e-06
|
||||||
|
scheduler: warmuplr # pytorch v1.1.0+ required
|
||||||
|
scheduler_conf:
|
||||||
|
warmup_steps: 25000
|
||||||
|
lr_decay: 1.0
|
||||||
|
log_interval: 100
|
||||||
|
|
||||||
|
|
||||||
|
decoding:
|
||||||
|
batch_size: 16
|
||||||
|
error_rate_type: wer
|
||||||
|
decoding_method: attention # 'attention', 'ctc_greedy_search', 'ctc_prefix_beam_search', 'attention_rescoring'
|
||||||
|
lang_model_path: data/lm/common_crawl_00.prune01111.trie.klm
|
||||||
|
alpha: 2.5
|
||||||
|
beta: 0.3
|
||||||
|
beam_size: 10
|
||||||
|
cutoff_prob: 1.0
|
||||||
|
cutoff_top_n: 0
|
||||||
|
num_proc_bsearch: 8
|
||||||
|
ctc_weight: 0.0 # ctc weight for attention rescoring decode mode.
|
||||||
|
decoding_chunk_size: -1 # decoding chunk size. Defaults to -1.
|
||||||
|
# <0: for decoding, use full chunk.
|
||||||
|
# >0: for decoding, use fixed chunk size as set.
|
||||||
|
# 0: used for training, it's prohibited here.
|
||||||
|
num_decoding_left_chunks: -1 # number of left chunks for decoding. Defaults to -1.
|
||||||
|
simulate_streaming: False # simulate streaming inference. Defaults to False.
|
||||||
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "shift",
|
|
||||||
"params": {"min_shift_ms": -5,
|
|
||||||
"max_shift_ms": 5},
|
|
||||||
"prob": 1.0
|
|
||||||
}
|
|
||||||
]
|
|
@ -1,40 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "noise",
|
|
||||||
"params": {"min_snr_dB": 40,
|
|
||||||
"max_snr_dB": 50,
|
|
||||||
"noise_manifest_path": "datasets/manifest.noise"},
|
|
||||||
"prob": 0.6
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "impulse",
|
|
||||||
"params": {"impulse_manifest_path": "datasets/manifest.impulse"},
|
|
||||||
"prob": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "speed",
|
|
||||||
"params": {"min_speed_rate": 0.95,
|
|
||||||
"max_speed_rate": 1.05,
|
|
||||||
"num_rates": 3},
|
|
||||||
"prob": 0.5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "shift",
|
|
||||||
"params": {"min_shift_ms": -5,
|
|
||||||
"max_shift_ms": 5},
|
|
||||||
"prob": 1.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "volume",
|
|
||||||
"params": {"min_gain_dBFS": -10,
|
|
||||||
"max_gain_dBFS": 10},
|
|
||||||
"prob": 0.0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "bayesian_normal",
|
|
||||||
"params": {"target_db": -20,
|
|
||||||
"prior_db": -20,
|
|
||||||
"prior_samples": 100},
|
|
||||||
"prob": 0.0
|
|
||||||
}
|
|
||||||
]
|
|
@ -0,0 +1,67 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "noise",
|
||||||
|
"params": {
|
||||||
|
"min_snr_dB": 40,
|
||||||
|
"max_snr_dB": 50,
|
||||||
|
"noise_manifest_path": "datasets/manifest.noise"
|
||||||
|
},
|
||||||
|
"prob": 0.6
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "impulse",
|
||||||
|
"params": {
|
||||||
|
"impulse_manifest_path": "datasets/manifest.impulse"
|
||||||
|
},
|
||||||
|
"prob": 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "speed",
|
||||||
|
"params": {
|
||||||
|
"min_speed_rate": 0.95,
|
||||||
|
"max_speed_rate": 1.05,
|
||||||
|
"num_rates": 3
|
||||||
|
},
|
||||||
|
"prob": 0.5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "shift",
|
||||||
|
"params": {
|
||||||
|
"min_shift_ms": -5,
|
||||||
|
"max_shift_ms": 5
|
||||||
|
},
|
||||||
|
"prob": 1.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "volume",
|
||||||
|
"params": {
|
||||||
|
"min_gain_dBFS": -10,
|
||||||
|
"max_gain_dBFS": 10
|
||||||
|
},
|
||||||
|
"prob": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "bayesian_normal",
|
||||||
|
"params": {
|
||||||
|
"target_db": -20,
|
||||||
|
"prior_db": -20,
|
||||||
|
"prior_samples": 100
|
||||||
|
},
|
||||||
|
"prob": 0.0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "specaug",
|
||||||
|
"params": {
|
||||||
|
"F": 10,
|
||||||
|
"T": 50,
|
||||||
|
"n_freq_masks": 2,
|
||||||
|
"n_time_masks": 2,
|
||||||
|
"p": 1.0,
|
||||||
|
"W": 80,
|
||||||
|
"adaptive_number_ratio": 0,
|
||||||
|
"adaptive_size_ratio": 0,
|
||||||
|
"max_n_time_masks": 20
|
||||||
|
},
|
||||||
|
"prob": 0.0
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "shift",
|
||||||
|
"params": {
|
||||||
|
"min_shift_ms": -5,
|
||||||
|
"max_shift_ms": 5
|
||||||
|
},
|
||||||
|
"prob": 1.0
|
||||||
|
}
|
||||||
|
]
|
@ -1,8 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "shift",
|
|
||||||
"params": {"min_shift_ms": -5,
|
|
||||||
"max_shift_ms": 5},
|
|
||||||
"prob": 1.0
|
|
||||||
}
|
|
||||||
]
|
|
@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "shift",
|
||||||
|
"params": {
|
||||||
|
"min_shift_ms": -5,
|
||||||
|
"max_shift_ms": 5
|
||||||
|
},
|
||||||
|
"prob": 1.0
|
||||||
|
}
|
||||||
|
]
|
@ -1,8 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "shift",
|
|
||||||
"params": {"min_shift_ms": -5,
|
|
||||||
"max_shift_ms": 5},
|
|
||||||
"prob": 1.0
|
|
||||||
}
|
|
||||||
]
|
|
@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "shift",
|
||||||
|
"params": {
|
||||||
|
"min_shift_ms": -5,
|
||||||
|
"max_shift_ms": 5
|
||||||
|
},
|
||||||
|
"prob": 1.0
|
||||||
|
}
|
||||||
|
]
|
@ -1,8 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "shift",
|
|
||||||
"params": {"min_shift_ms": -5,
|
|
||||||
"max_shift_ms": 5},
|
|
||||||
"prob": 1.0
|
|
||||||
}
|
|
||||||
]
|
|
@ -0,0 +1,10 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "shift",
|
||||||
|
"params": {
|
||||||
|
"min_shift_ms": -5,
|
||||||
|
"max_shift_ms": 5
|
||||||
|
},
|
||||||
|
"prob": 1.0
|
||||||
|
}
|
||||||
|
]
|
Loading…
Reference in new issue