CTCDECODE est une implémentation du décodage de recherche de faisceau CTC (Connectionning Temporal Classification) pour Pytorch. Le code C ++ a été emprunté généreusement à DeepSpeech de Paddle Paddles. Il comprend un support de marqueur swappable permettant une recherche de faisceau standard et un décodage basé sur Kenlm. Si vous êtes nouveau dans les concepts de CTC et de recherche de faisceau, veuillez visiter la section Ressources où nous lions quelques tutoriels expliquant pourquoi ils sont nécessaires.
La bibliothèque est largement autonome et ne nécessite que du pytorch. La construction de la bibliothèque C ++ nécessite du CCG ou du Cang. La prise en charge de la modélisation du langage Kenlm est également éventuellement incluse et activée par défaut.
L'installation ci-dessous fonctionne également pour Google Colab.
# get the code
git clone --recursive https://github.com/parlance/ctcdecode.git
cd ctcdecode && pip install . from ctcdecode import CTCBeamDecoder
decoder = CTCBeamDecoder (
labels ,
model_path = None ,
alpha = 0 ,
beta = 0 ,
cutoff_top_n = 40 ,
cutoff_prob = 1.0 ,
beam_width = 100 ,
num_processes = 4 ,
blank_id = 0 ,
log_probs_input = False
)
beam_results , beam_scores , timesteps , out_lens = decoder . decode ( output )CTCBeamDecoderlabels sont les jetons que vous avez utilisés pour former votre modèle. Ils devraient être dans le même ordre que vos sorties. Par exemple, si vos jetons sont les lettres anglaises et que vous avez utilisé 0 comme jeton vide, alors vous transmettez la liste ("_ ABCDEFGHIJKLMOPQRSTUVWXYZ") comme argument aux étiquettesmodel_path est le chemin de votre modèle de langue Kenlm externe (LM). La valeur par défaut n'est pas.alpha associée aux probabilités LMS. Un poids de 0 signifie que le LM n'a aucun effet.beta associé au nombre de mots dans notre poutre.cutoff_top_n Numéro de coupure en élagage. Seuls les caractères supérieurs Coupoff_top_n avec la plus grande probabilité du vocabulaire seront utilisés dans la recherche de faisceau.cutoff_prob CUTOFF PROBLABILITÉ DANS L'élagage. 1.0 signifie aucune élagage.beam_width Ceci contrôle à quel point la recherche de faisceau est large. Des valeurs plus élevées sont plus susceptibles de trouver des poutres supérieures, mais elles rendront également votre recherche de faisceau exponentiellement plus lente. De plus, plus vos sorties sont longues, plus les grandes poutres prendront du temps. Il s'agit d'un paramètre important qui représente un compromis que vous devez faire en fonction de votre ensemble de données et de vos besoins.num_processes PARALLALLISE LE LOTS À l'aide des travailleurs NUM_PROCESS. Vous voulez probablement passer le nombre de processeurs de votre ordinateur. Vous pouvez le trouver dans Python avec import multiprocessing puis n_cpus = multiprocessing.cpu_count() . Par défaut 4.blank_id cela devrait être l'index du jeton à blanc CTC (probablement 0).log_probs_input Si vos sorties ont traversé un softmax et représentent des probabilités, cela devrait être faux, s'ils passaient par LogsoftMax et représentent la vraisemblance du logarithme négatif, vous devez passer True. Si vous ne comprenez pas cela, exécutez print(output[0][0].sum()) , s'il s'agit d'un nombre négatif, vous avez probablement NLL et vous devez passer True, si cela résume à ~ 1,0, vous devez passer faux. Par défaut false.decodeoutput doit être les activations de sortie de votre modèle. Si votre sortie est passé par une couche Softmax, vous ne devriez pas avoir besoin de la modifier (sauf peut-être pour transposer), mais si votre output représente la vraisemblance des logaries négatives (logits bruts), vous devez soit le passer par une torch.nn.functional.softmax supplémentaire.nn.functional.softmax ou vous pouvez passer log_probs_input=False au décodeur. Votre sortie doit être BatchSize x N_timeSesteps x n_labels, vous devrez peut-être le transposer avant de le passer au décodeur. Notez que si vous passez des choses dans le mauvais ordre, la recherche de faisceau fonctionnera probablement toujours, vous obtiendrez simplement des résultats absurdes.decode 4 choses sont retournées de decode
beam_results - Forme: BatchSize X N_BEAMS X N_TIMESTEPS Un lot contenant la série de caractères (ce sont des INT, vous devez toujours les décoder à votre texte) représentant les résultats d'une recherche de faisceau donnée. Notez que les faisceaux sont presque toujours plus courts que le nombre total de temps de temps, et les données supplémentaires sont non sensibles, donc pour voir le faisceau supérieur (comme des étiquettes INT) du premier élément du lot, vous devez exécuter beam_results[0][0][:out_len[0][0]] .beam_scores - Forme: BatchSize X N_BEAMS Un lot avec le score CTC approximatif de chaque faisceau (regardez le code ici pour plus d'informations). Si cela est vrai, vous pouvez obtenir la confiance du modèle que le faisceau est correct avec p=1/np.exp(beam_score) .timesteps - Forme: BatchSize X N_BEAMS L'EXPOSITION DU COMPARTEUR DE LA NE NTH AUTRE PROPOBABILITÉ. Peut être utilisé comme alignement entre l'audio et la transcription.out_lens - Forme: BatchSize x n_beams. out_lens[i][j] est la longueur du Jth Beam_result, de l'article I de votre lot. from ctcdecode import OnlineCTCBeamDecoder
decoder = OnlineCTCBeamDecoder (
labels ,
model_path = None ,
alpha = 0 ,
beta = 0 ,
cutoff_top_n = 40 ,
cutoff_prob = 1.0 ,
beam_width = 100 ,
num_processes = 4 ,
blank_id = 0 ,
log_probs_input = False
)
state1 = ctcdecode . DecoderState ( decoder )
probs_seq = torch . FloatTensor ([ probs_seq ])
beam_results , beam_scores , timesteps , out_seq_len = decoder . decode ( probs_seq [:, : 2 ], [ state1 ], [ False ])
beam_results , beam_scores , timesteps , out_seq_len = decoder . decode ( probs_seq [:, 2 :], [ state1 ], [ True ])Le décodeur en ligne copie l'interface CTCBEAMDECODER, mais il nécessite des séquences d'états et d'Is_EOS_S.
Les états sont utilisés pour accumuler des séquences de morceaux, chacun correspondant à une seule source de données. IS_EOS_S dit au décodeur si les morceaux ont cessé d'être poussés à l'état correspondant.
Obtenez la poutre supérieure pour le premier élément de votre lot beam_results[0][0][:out_len[0][0]]
Obtenez les 50 poutres supérieures pour le premier élément de votre lot
for i in range ( 50 ):
print ( beam_results [ 0 ][ i ][: out_len [ 0 ][ i ]]) Remarque, ce sera une liste des INT qui nécessitent un décodage. Vous avez probablement déjà une fonction pour décoder de l'INT au texte, mais sinon vous pouvez faire quelque chose comme. "".join[labels[n] for n in beam_results[0][0][:out_len[0][0]]] en utilisant les étiquettes que vous avez transmises dans CTCBeamDecoder