CTCDECODE ist eine Implementierung von CTC (Connectionist Temporal Classification) Strahlsuch -Dekodierung für Pytorch. C ++ Code liberal aus Paddle Paddles 'Deep Speech. Es umfasst Swappable Scorer Support, die die Standard-Strahlsuche und die KenLM-basierte Decodierung aktivieren. Wenn Sie neu in den Konzepten der CTC- und Strahlsuche sind, besuchen Sie bitte den Ressourcenabschnitt, in dem wir einige Tutorials verknüpfen, in denen erklärt wird, warum sie benötigt werden.
Die Bibliothek ist weitgehend in sich geschlossen und benötigt nur Pytorch. Erstellen der C ++ - Bibliothek sind GCC oder Clang erforderlich. Die Unterstützung der KenLM -Sprachmodellierung ist ebenfalls optional enthalten und standardmäßig aktiviert.
Die folgende Installation funktioniert auch für 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 sind die Token, mit denen Sie Ihr Modell trainiert haben. Sie sollten in der gleichen Reihenfolge wie Ihre Ausgänge sein. Wenn Ihre Token die englischen Buchstaben sind und Sie 0 als leeres Token verwendet habenmodel_path ist der Pfad zu Ihrem externen KenLM -Sprachmodell (LM). Standard ist keine.alpha -Gewichtung im Zusammenhang mit den LMS -Wahrscheinlichkeiten. Ein Gewicht von 0 bedeutet, dass der LM keine Wirkung hat.beta -Gewicht, die mit der Anzahl der Wörter in unserem Strahl verbunden ist.cutoff_top_n Cutoff -Nummer beim Beschneiden. Nur die oberen Cutoff_top_n -Zeichen mit der höchsten Wahrscheinlichkeit im Vokab, werden bei der Strahlsuche verwendet.cutoff_prob Cutoff -Wahrscheinlichkeit beim Beschneiden. 1.0 bedeutet kein Schnitt.beam_width Dies steuert, wie breit die Strahlsuche ist. Höhere Werte finden mit größerer Wahrscheinlichkeit Top -Strahlen, machen aber auch Ihre Strahlsuche exponentiell langsamer. Je länger Ihre Ausgänge sind, desto mehr Zeit werden große Strahlen dauern. Dies ist ein wichtiger Parameter, der einen Kompromiss darstellt, den Sie basierend auf Ihrem Datensatz und Ihren Anforderungen einlassen müssen.num_processes parallel die Stapel mit num_processes -Arbeitern parallelizieren. Sie möchten wahrscheinlich die Anzahl der CPUs übergeben, die Ihr Computer hat. Sie finden dies in Python mit import multiprocessing dann n_cpus = multiprocessing.cpu_count() . Standard 4.blank_id Dies sollte der Index des CTC Blank -Tokens sein (wahrscheinlich 0).log_probs_input Wenn Ihre Ausgänge einen Softmax durchlaufen haben und Wahrscheinlichkeiten darstellen, sollte dies falsch sein. Wenn sie einen LogSoftMax durchlaufen haben und eine negative Log -Wahrscheinlichkeit darstellen, müssen Sie True bestehen. Wenn Sie dies nicht verstehen, führen Sie print(output[0][0].sum()) . Wenn es sich um eine negative Zahl handelt, die Sie wahrscheinlich NLL erhalten haben und true übergeben müssen. Wenn es auf ~ 1.0 fasst, sollten Sie false übergeben. Standard falsch.decodeoutput sollte die Ausgangsaktivierungen von Ihrem Modell sein. Wenn Ihre Ausgabe eine Softmax -Ebene durchlaufen hat, sollten Sie sie nicht ändern müssen (außer vielleicht um zu transponieren). Wenn Ihre output jedoch negative Protokoll -Wahrscheinlichkeiten (Rohprotokoll) darstellt, müssen Sie sie entweder durch eine zusätzliche torch.nn.functional.softmax übergeben oder Sie können log_probs_input=False an das Decoder übergeben. Ihre Ausgabe sollte batchsize x n_timesteps x n_labels sein, sodass Sie sie möglicherweise übertragen müssen, bevor Sie sie an den Decoder weitergeben. Beachten Sie, dass Sie, wenn Sie Dinge in der falschen Reihenfolge übergeben, die Strahlsuche wahrscheinlich immer noch ausgeführt wird, Sie einfach Nonsense -Ergebnisse zurückbringen.decode 4 Dinge werden von decode zurückgegeben
beam_results - Form: batchsize x n_beams x n_timesteps Eine Stapel, die die Zeichenreihe enthält (dies sind INTs, müssen sie noch zu Ihrem Text zurückziehen), das die Ergebnisse einer bestimmten Strahlsuche darstellt. Beachten Sie, dass die Strahlen fast immer kürzer sind als die Gesamtzahl der Zeitschritte und die zusätzlichen Daten nicht unterempfindlich. Um den oberen Strahl (als int beschriftete) aus dem ersten Element in der Stapel zu sehen, müssen Sie beam_results[0][0][:out_len[0][0]] ausführen.beam_scores - Form: batchsize x n_beams eine Stapel mit der ungefähren CTC -Punktzahl jedes Strahls (siehe Code hier für weitere Informationen). Wenn dies zutrifft, können Sie das Vertrauen des Modells, dass der Strahl mit p=1/np.exp(beam_score) korrekt ist.timesteps - Form: Batchsize x n_beams Der Zeitschritt, bei dem das nte Ausgangszeichen eine Spitzenwahrscheinlichkeit aufweist. Kann als Ausrichtung zwischen dem Audio und dem Transkript verwendet werden.out_lens - Form: batchsize x n_beams. out_lens[i][j] ist die Länge des JTH Beam_Result, von Gegenstand I Ihrer Charge. 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 ])Der Online -Decoder kopiert die CTCBeamDecoder -Schnittstelle, benötigt jedoch Zustände und IS_EOS_S -Sequenzen.
Zustände werden verwendet, um Sequenzen von Stücken zu sammeln, die jeweils einer Datenquelle entsprechen. IS_EOS_S teilt dem Decoder mit, ob die Stücke nicht mehr in den entsprechenden Zustand gedrückt werden.
Holen Sie sich den oberen Strahl für das erste Element in Ihrem Batch beam_results[0][0][:out_len[0][0]]
Holen Sie sich die Top 50 Strahlen für den ersten Artikel in Ihrer Stapel
for i in range ( 50 ):
print ( beam_results [ 0 ][ i ][: out_len [ 0 ][ i ]]) Beachten Sie, dass dies eine Liste von INTs sein wird, die dekodiert werden müssen. Sie haben wahrscheinlich bereits eine Funktion, die Sie von INT zu Text dekodieren können, aber wenn nicht, können Sie so etwas wie möglich tun. "".join[labels[n] for n in beam_results[0][0][:out_len[0][0]]] Verwenden der Beschriftungen, die Sie an CTCBeamDecoder übergeben haben