
"""simple docstring"""


import re
from typing import Callable, List, Optional, Union

import tensorflow as tf


try:
						from tensorflow.keras.optimizers.legacy import Adam
except ImportError:
						from tensorflow.keras.optimizers import Adam




class  __lowerCamelCase  ( tf.keras.optimizers.schedules.LearningRateSchedule			):




				def __init__(				self							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase = 1.0							,						UpperCAmelCase = None							,						):
							super().__init__()
							lowerCamelCase_					=  initial_learning_rate
							lowerCamelCase_					=  warmup_steps
							lowerCamelCase_					=  power
							lowerCamelCase_					=  decay_schedule_fn
							lowerCamelCase_					=  name




				def __call__(				self							,						UpperCAmelCase   ):
							with tf.name_scope(self.name or '''WarmUp'''   ) as name:
										# Implements polynomial warmup. i.e., if global_step < warmup_steps, the
										# learning rate will be `global_step/num_warmup_steps * init_lr`.
										lowerCamelCase_					=  tf.cast(UpperCAmelCase							,						tf.floataa   )
										lowerCamelCase_					=  tf.cast(self.warmup_steps							,						tf.floataa   )
										lowerCamelCase_					=  global_step_float / warmup_steps_float
										lowerCamelCase_					=  self.initial_learning_rate * tf.math.pow(UpperCAmelCase							,						self.power   )
										return tf.cond(
										    global_step_float < warmup_steps_float							,						lambda: warmup_learning_rate							,						lambda: self.decay_schedule_fn(step - self.warmup_steps   )							,						name=UpperCAmelCase							,						)





				def        UpperCAmelCase__						(				self   ):
							return {
							    "initial_learning_rate": self.initial_learning_rate,
							    "decay_schedule_fn": self.decay_schedule_fn,
							    "warmup_steps": self.warmup_steps,
							    "power": self.power,
							    "name": self.name,
							}






def  lowercase						(	lowerCAmelCase__	,lowerCAmelCase__	,lowerCAmelCase__	,lowerCAmelCase__ = 0.0	,lowerCAmelCase__ = 0.9	,lowerCAmelCase__ = 0.999	,lowerCAmelCase__ = 1E-8	,lowerCAmelCase__ = None	,lowerCAmelCase__ = None	,lowerCAmelCase__ = 0.0	,lowerCAmelCase__ = 1.0	,lowerCAmelCase__ = None	,):
			lowerCamelCase_					=  tf.keras.optimizers.schedules.PolynomialDecay(
			    initial_learning_rate=lowerCAmelCase__	,decay_steps=num_train_steps - num_warmup_steps	,end_learning_rate=init_lr * min_lr_ratio	,power=lowerCAmelCase__	,)
			if num_warmup_steps:
						lowerCamelCase_					=  WarmUp(
						    initial_learning_rate=lowerCAmelCase__	,decay_schedule_fn=lowerCAmelCase__	,warmup_steps=lowerCAmelCase__	,)
			if weight_decay_rate > 0.0:
						lowerCamelCase_					=  AdamWeightDecay(
						    learning_rate=lowerCAmelCase__	,weight_decay_rate=lowerCAmelCase__	,beta_a=lowerCAmelCase__	,beta_a=lowerCAmelCase__	,epsilon=lowerCAmelCase__	,clipnorm=lowerCAmelCase__	,global_clipnorm=lowerCAmelCase__	,exclude_from_weight_decay=['''LayerNorm''', '''layer_norm''', '''bias''']	,include_in_weight_decay=lowerCAmelCase__	,)
			else:
						lowerCamelCase_					=  tf.keras.optimizers.Adam(
						    learning_rate=lowerCAmelCase__	,beta_a=lowerCAmelCase__	,beta_a=lowerCAmelCase__	,epsilon=lowerCAmelCase__	,clipnorm=lowerCAmelCase__	,global_clipnorm=lowerCAmelCase__	,)
			# We return the optimizer and the LR scheduler in order to better track the
			# evolution of the LR independently of the optimizer.
			return optimizer, lr_schedule




class  __lowerCamelCase  ( lowerCAmelCase			):




				def __init__(				self							,						UpperCAmelCase = 0.0_0_1							,						UpperCAmelCase = 0.9							,						UpperCAmelCase = 0.9_9_9							,						UpperCAmelCase = 1e-7							,						UpperCAmelCase = False							,						UpperCAmelCase = 0.0							,						UpperCAmelCase = None							,						UpperCAmelCase = None							,						UpperCAmelCase = "AdamWeightDecay"							,						**UpperCAmelCase							,						):
							super().__init__(UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase							,						**UpperCAmelCase   )
							lowerCamelCase_					=  weight_decay_rate
							lowerCamelCase_					=  include_in_weight_decay
							lowerCamelCase_					=  exclude_from_weight_decay




				@classmethod
				def        UpperCAmelCase__						(				cls							,						UpperCAmelCase   ):
							lowerCamelCase_					=  {'''WarmUp''': WarmUp}
							return super(UpperCAmelCase							,						cls   ).from_config(UpperCAmelCase							,						custom_objects=UpperCAmelCase   )




				def        UpperCAmelCase__						(				self							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase   ):
							super(UpperCAmelCase							,						self   )._prepare_local(UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase   )
							lowerCamelCase_					=  tf.constant(
							    self.weight_decay_rate							,						name='''adam_weight_decay_rate'''   )




				def        UpperCAmelCase__						(				self							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase   ):
							lowerCamelCase_					=  self._do_use_weight_decay(var.name   )
							if do_decay:
										return var.assign_sub(
										    learning_rate * var * apply_state[(var.device, var.dtype.base_dtype)]['''weight_decay_rate''']							,						use_locking=self._use_locking							,						)
							return tf.no_op()




				def        UpperCAmelCase__						(				self							,						UpperCAmelCase							,						UpperCAmelCase=None							,						**UpperCAmelCase   ):
							lowerCamelCase_		, lowerCamelCase_					=  list(zip(*UpperCAmelCase   )   )
							return super(UpperCAmelCase							,						self   ).apply_gradients(zip(UpperCAmelCase							,						UpperCAmelCase   )							,						name=UpperCAmelCase							,						**UpperCAmelCase   )




				def        UpperCAmelCase__						(				self							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase   ):
							if apply_state is None:
										return self._decayed_lr_t[var_dtype], {}

							lowerCamelCase_					=  apply_state or {}
							lowerCamelCase_					=  apply_state.get((var_device, var_dtype)   )
							if coefficients is None:
										lowerCamelCase_					=  self._fallback_apply_state(UpperCAmelCase							,						UpperCAmelCase   )
										lowerCamelCase_					=  coefficients

							return coefficients["lr_t"], {"apply_state": apply_state}




				def        UpperCAmelCase__						(				self							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase=None   ):
							lowerCamelCase_		, lowerCamelCase_					=  self._get_lr(var.device							,						var.dtype.base_dtype							,						UpperCAmelCase   )
							lowerCamelCase_					=  self._decay_weights_op(UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase   )
							with tf.control_dependencies([decay]   ):
										return super(UpperCAmelCase							,						self   )._resource_apply_dense(UpperCAmelCase							,						UpperCAmelCase							,						**UpperCAmelCase   )




				def        UpperCAmelCase__						(				self							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase=None   ):
							lowerCamelCase_		, lowerCamelCase_					=  self._get_lr(var.device							,						var.dtype.base_dtype							,						UpperCAmelCase   )
							lowerCamelCase_					=  self._decay_weights_op(UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase   )
							with tf.control_dependencies([decay]   ):
										return super(UpperCAmelCase							,						self   )._resource_apply_sparse(UpperCAmelCase							,						UpperCAmelCase							,						UpperCAmelCase							,						**UpperCAmelCase   )




				def        UpperCAmelCase__						(				self   ):
							lowerCamelCase_					=  super().get_config()
							config.update({'''weight_decay_rate''': self.weight_decay_rate}   )
							return config





				def        UpperCAmelCase__						(				self							,						UpperCAmelCase   ):
							if self.weight_decay_rate == 0:
										return False

							if self._include_in_weight_decay:
										for r in self._include_in_weight_decay:
													if re.search(UpperCAmelCase							,						UpperCAmelCase   ) is not None:
																return True

							if self._exclude_from_weight_decay:
										for r in self._exclude_from_weight_decay:
													if re.search(UpperCAmelCase							,						UpperCAmelCase   ) is not None:
																return False
							return True




class  __lowerCamelCase  ( lowerCAmelCase			):




				def __init__(				self   ):
							lowerCamelCase_					=  []
							lowerCamelCase_					=  None




				@property
				def        UpperCAmelCase__						(				self   ):
							if self._accum_steps is None:
										lowerCamelCase_					=  tf.Variable(
										    tf.constant(0							,						dtype=tf.intaa   )							,						trainable=UpperCAmelCase							,						synchronization=tf.VariableSynchronization.ON_READ							,						aggregation=tf.VariableAggregation.ONLY_FIRST_REPLICA							,						)

							return self._accum_steps.value()




				@property
				def        UpperCAmelCase__						(				self   ):
							if not self._gradients:
										raise ValueError('''The accumulator should be called first to initialize the gradients'''   )
							return [gradient.value() if gradient is not None else gradient for gradient in self._gradients]




				def __call__(				self							,						UpperCAmelCase   ):
							if not self._gradients:
										lowerCamelCase_					=  self.step  # Create the step variable.
										self._gradients.extend(
										    [
										        tf.Variable(
										            tf.zeros_like(UpperCAmelCase   )							,						trainable=UpperCAmelCase							,						synchronization=tf.VariableSynchronization.ON_READ							,						aggregation=tf.VariableAggregation.ONLY_FIRST_REPLICA							,						)
										        if gradient is not None
										        else gradient
										        for gradient in gradients
										    ]   )
							if len(UpperCAmelCase   ) != len(self._gradients   ):
										raise ValueError(f"Expected {len(self._gradients   )} gradients, but got {len(UpperCAmelCase   )}"   )

							for accum_gradient, gradient in zip(self._gradients							,						UpperCAmelCase   ):
										if accum_gradient is not None and gradient is not None:
													accum_gradient.assign_add(UpperCAmelCase   )

							self._accum_steps.assign_add(1   )





				def        UpperCAmelCase__						(				self   ):
							if not self._gradients:
										return
							self._accum_steps.assign(0   )
							for gradient in self._gradients:
										if gradient is not None:
													gradient.assign(tf.zeros_like(UpperCAmelCase   )   )





"""simple docstring"""


from jiwer import compute_measures

import datasets


A_    							=					"""\
@inproceedings{inproceedings,
    author = {Morris, Andrew and Maier, Viktoria and Green, Phil},
    year = {2004},
    month = {01},
    pages = {},
    title = {From WER and RIL to MER and WIL: improved evaluation measures for connected speech recognition.}
}
"""

A_    							=					"""\
Word error rate (WER) is a common metric of the performance of an automatic speech recognition system.

The general difficulty of measuring performance lies in the fact that the recognized word sequence can have a different length from the reference word sequence (supposedly the correct one). The WER is derived from the Levenshtein distance, working at the word level instead of the phoneme level. The WER is a valuable tool for comparing different systems as well as for evaluating improvements within one system. This kind of measurement, however, provides no details on the nature of translation errors and further work is therefore required to identify the main source(s) of error and to focus any research effort.

This problem is solved by first aligning the recognized word sequence with the reference (spoken) word sequence using dynamic string alignment. Examination of this issue is seen through a theory called the power law that states the correlation between perplexity and word error rate.

Word error rate can then be computed as:

WER = (S + D + I) / N = (S + D + I) / (S + D + C)

where

S is the number of substitutions,
D is the number of deletions,
I is the number of insertions,
C is the number of correct words,
N is the number of words in the reference (N=S+D+C).

This value indicates the average number of errors per reference word. The lower the value, the better the
performance of the ASR system with a WER of 0 being a perfect score.
"""

A_    							=					"""
Compute WER score of transcribed segments against references.

Args:
    references: List of references for each speech input.
    predictions: List of transcriptions to score.
    concatenate_texts (bool, default=False): Whether to concatenate all input texts or compute WER iteratively.

Returns:
    (float): the word error rate

Examples:

    >>> predictions = [\"this is the prediction\", \"there is an other sample\"]
    >>> references = [\"this is the reference\", \"there is another one\"]
    >>> wer = datasets.load_metric(\"wer\")
    >>> wer_score = wer.compute(predictions=predictions, references=references)
    >>> print(wer_score)
    0.5
"""




@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION						,	_KWARGS_DESCRIPTION			)
class  __lowerCamelCase  ( datasets.Metric			):




				def        UpperCAmelCase__						(				self   ):
							return datasets.MetricInfo(
							    description=_DESCRIPTION							,						citation=_CITATION							,						inputs_description=_KWARGS_DESCRIPTION							,						features=datasets.Features(
							        {
							            '''predictions''': datasets.Value('''string'''							,						id='''sequence'''   ),
							            '''references''': datasets.Value('''string'''							,						id='''sequence'''   ),
							        }   )							,						codebase_urls=['''https://github.com/jitsi/jiwer/''']							,						reference_urls=[
							        '''https://en.wikipedia.org/wiki/Word_error_rate''',
							    ]							,						)





				def        UpperCAmelCase__						(				self							,						UpperCAmelCase=None							,						UpperCAmelCase=None							,						UpperCAmelCase=False   ):
							if concatenate_texts:
										return compute_measures(UpperCAmelCase							,						UpperCAmelCase   )["wer"]
							else:
										lowerCamelCase_					=  0
										lowerCamelCase_					=  0
										for prediction, reference in zip(UpperCAmelCase							,						UpperCAmelCase   ):
													lowerCamelCase_					=  compute_measures(UpperCAmelCase							,						UpperCAmelCase   )
													incorrect += measures["substitutions"] + measures["deletions"] + measures["insertions"]
													total += measures["substitutions"] + measures["deletions"] + measures["hits"]
										return incorrect / total



