
Dieses Repository enthält die letzte Version des Pytorch-Kaldi-Toolkits (Pytorch-Kaldi-V1.0). Klicken Sie hier, um einen Blick in die vorherige Version (Pytorch-Kaldi-V0.1) zu werfen.
Wenn Sie diesen Code oder einen Teil davon verwenden, zitieren Sie bitte das folgende Papier:
M. Ravanelli, T. Parcollet, Y. Bengio, "The Pytorch-Kaldi Spracherkennungs-Toolkit", Arxiv
@inproceedings{pytorch-kaldi,
title = {The PyTorch-Kaldi Speech Recognition Toolkit},
author = {M. Ravanelli and T. Parcollet and Y. Bengio},
booktitle = {In Proc. of ICASSP},
year = {2019}
}
Das Toolkit wird unter einer internationalen Lizenz für Creative Commons zuzuschreiben. Sie können den Code für Forschung, kommerzielle und nichtkommerzielle Zwecke kopieren, verteilen, verteilt, ändern. Wir bitten nur darum, unser oben genannter Papier zu zitieren.
Um die Transparenz und Replikabilität von Spracherkennungsergebnissen zu verbessern, geben wir den Benutzern die Möglichkeit, ihr Pytorch-Kaldi-Modell in diesem Repository freizugeben. Wenden Sie sich dazu, sich dafür zu kontaktieren (oder eine Pull -Anfrage). Wenn Ihr Papier Pytorch-Kaldi verwendet, ist es außerdem möglich, in diesem Repository zu werben.
Siehe ein kurzes Einführungsvideo auf dem Pytorch-Kaldi-Toolkit
Wir freuen uns, Ihnen mitteilen zu können, dass das Sprachprojekt (https://speechbrain.github.io/) jetzt öffentlich ist! Wir ermutigen die Benutzer nachdrücklich, in die Sprache zu migrieren. Es ist ein viel besseres Projekt, das bereits mehrere Sprachverarbeitungsaufgaben wie Spracherkennung, Sprechererkennung, SLU, Sprachverbesserung, Sprachtrennung, Multi-Mikrophon-Signalverarbeitung und viele andere unterstützt.
Ziel ist es, ein einzelnes , flexibles und benutzerfreundliches Toolkit zu entwickeln, das verwendet werden kann, um auf einfache Weise hochmoderne Sprachsysteme für die Spracherkennung (sowohl End-to-End- als auch HMM-DNN), Sprechererkennung, Sprachtrennung, Multi-Mikrophon-Signalverarbeitung (z.
Das Projekt wird von Mila geleitet und wird von Samsung, Nvidia, Dolby, gesponsert. Sprache wird auch von der Zusammenarbeit und dem Fachwissen anderer Unternehmen wie Facebook/Pytorch, Ibmresearch, Fluentai profitieren.
Wir suchen aktiv nach Mitarbeitern. Wenden Sie sich bitte an [email protected], wenn Sie daran interessiert sind, zusammenzuarbeiten.
Dank unserer Sponsoren können wir auch Praktikanten einstellen, die bei MILA am Sprachprojekt arbeiten. Der ideale Kandidat ist ein Doktorand mit Erfahrung in Pytorch- und Sprachtechnologien (senden Sie Ihren Lebenslauf an [email protected])
Die Entwicklung von Speechbrain erfordert einige Monate, bevor ein funktionierendes Repository besteht. In der Zwischenzeit werden wir weiterhin das Pytorch-Kaldi-Projekt unterstützen.
Bleiben Sie dran!
Das Pytorch-Kaldi-Projekt zielt darauf ab, die Lücke zwischen Kaldi und Pytorch-Toolkits zu schließen und die Effizienz von Kaldi und die Flexibilität von Pytorch zu erben. Pytorch-Kaldi ist nicht nur eine einfache Schnittstelle zwischen diesen Toolkits, sondern bettet mehrere nützliche Merkmale für die Entwicklung moderner Spracherkenner ein. Zum Beispiel ist der Code speziell so konzipiert, dass sie benutzerdefinierte akustische Modelle auf natürliche Weise platzieren. Alternative können Benutzer mehrere präplementierte neuronale Netzwerke ausnutzen, die mithilfe intuitiver Konfigurationsdateien angepasst werden können. Pytorch-Kaldi unterstützt mehrere Merkmal- und Etikettenströme sowie Kombinationen von neuronalen Netzwerken und ermöglicht die Verwendung komplexer neuronaler Architekturen. Das Toolkit ist zusammen mit einer reichhaltigen Dokumentation öffentlich veröffentlicht und ist so konzipiert, dass sie lokal oder auf HPC-Clustern ordnungsgemäß arbeiten.
Einige Funktionen der neuen Version des Pytorch-Kaldi-Toolkits:
export KALDI_ROOT=/home/mirco/kaldi-trunk
PATH=$PATH:$KALDI_ROOT/tools/openfst
PATH=$PATH:$KALDI_ROOT/src/featbin
PATH=$PATH:$KALDI_ROOT/src/gmmbin
PATH=$PATH:$KALDI_ROOT/src/bin
PATH=$PATH:$KALDI_ROOT//src/nnetbin
export PATH
Denken Sie daran, die Variable kaldi_root mit Ihrem Pfad zu ändern. Als erster Test zur Überprüfung der Installation öffnen Sie eine Bash-Shell, geben Sie "Kopierfeats" oder "HMM-Info" ein und stellen Sie sicher, dass keine Fehler angezeigt werden.
Wenn nicht bereits fertig, installieren Sie PyTorch (http://pytorch.org/). Wir haben unsere Codes auf Pytorch 1.0 und Pytorch 0.4 getestet. Eine ältere Version von Pytorch erhöht wahrscheinlich Fehler. Geben Sie „Python“ ein, um Ihre Installation zu überprüfen. Geben Sie, wenn Sie in die Konsole eingegeben wurden, „Taschenlampe“ ein und stellen Sie sicher, dass keine Fehler angezeigt werden.
Wir empfehlen, den Code auf einem GPU -Computer auszuführen. Stellen Sie sicher, dass die CUDA-Bibliotheken (https://developer.nvidia.com/cuda-downloads) installiert sind und korrekt funktionieren. Wir haben unser System auf CUDA 9.0, 9.1 und 8.0 getestet. Stellen Sie sicher, dass Python installiert ist (der Code wird mit Python 2.7 und Python 3.7 getestet). Obwohl nicht obligatorisch, empfehlen wir die Verwendung von Anaconda (https://anaconda.org/anaconda/python).
19. Februar 2019: Updates:
batch_size_train = 128*12 | 64*10 | 32*2
Die obige Linie bedeutet: 12 Epochen mit 128 Chargen, 10 Epochen mit 64 Chargen und 2 Epochen mit 32 Chargen durchführen. Ein ähnlicher Formalismus kann für die Lernrate und die Abbrecherplanung verwendet werden. Weitere Informationen finden Sie in diesem Abschnitt.
5. Februar 2019: Updates:
Hinweise zur nächsten Version: In der nächsten Version planen wir, die Funktionen unseres Toolkits weiter zu erweitern und weitere Modelle und Funktionen zu unterstützen. Ziel ist es, unser Toolkit für andere sprachbezogene Aufgaben wie End-to-End-Spracherkennung, Sprecheridentifikation, Schlüsselwort-Spoting, Sprachtrennung, Sprachaktivitätserkennung, Sprachverbesserung usw. geeignet zu machen.
Führen Sie die folgenden Schritte aus: Um Pytorch-Kaldi zu installieren, führen Sie die folgenden Schritte aus:
git clone https://github.com/mravanelli/pytorch-kaldi
pip install -r requirements.txt
Im Folgenden bieten wir ein kurzes Tutorial des Pytorch-Kaldi-Toolkits basierend auf dem beliebten Zeitpunkt.
Stellen Sie sicher, dass Sie den Zeitpunkt des Zeitpunkts haben. Wenn nicht, kann es von der LDC -Website heruntergeladen werden (https://catalog.ldc.upenn.edu/ldc93s1).
Stellen Sie sicher, dass die Installationen von Kaldi und Pytorch in Ordnung sind. Stellen Sie auch sicher, dass Ihre Kaldi -Pfade derzeit funktionieren (Sie sollten die Kaldi -Pfade in das .bashrc hinzufügen, wie im Abschnitt "Voraussetzungen" gemeldet). Geben Sie beispielsweise "Kopierfeats" und "HMM-Info" ein und stellen Sie sicher, dass keine Fehler angezeigt werden.
Führen Sie die Kaldi S5 -Grundlinie des Zeitverkehrs durch. Dieser Schritt ist erforderlich, um Funktionen und Beschriftungen zu berechnen, die später zum Training des neuronalen Netzes Pytorch verwendet werden. Wir empfehlen, das vollständige Timit S5 -Rezept auszuführen (einschließlich des DNN -Trainings):
cd kaldi/egs/timit/s5
./run.sh
./local/nnet/run_dnn.sh
Auf diese Weise werden alle erforderlichen Dateien erstellt und der Benutzer kann die von Kaldi erzielten Ergebnisse direkt mit dem mit unserem Toolkit erzielten Ergebnis vergleichen.
steps/align_fmllr.sh --nj 4 data/dev data/lang exp/tri3 exp/tri3_ali_dev
steps/align_fmllr.sh --nj 4 data/test data/lang exp/tri3 exp/tri3_ali_test
Wenn Sie DNN -Alignments verwenden möchten (wie vorgeschlagen), geben Sie:
steps/nnet/align.sh --nj 4 data-fmllr-tri3/train data/lang exp/dnn4_pretrain-dbn_dnn exp/dnn4_pretrain-dbn_dnn_ali
steps/nnet/align.sh --nj 4 data-fmllr-tri3/dev data/lang exp/dnn4_pretrain-dbn_dnn exp/dnn4_pretrain-dbn_dnn_ali_dev
steps/nnet/align.sh --nj 4 data-fmllr-tri3/test data/lang exp/dnn4_pretrain-dbn_dnn exp/dnn4_pretrain-dbn_dnn_ali_test
Wir beginnen dieses Tutorial mit einem sehr einfachen MLP -Netzwerk, das auf MFCC -Funktionen geschult ist. Schauen Sie sich vor dem Start des Experiments die Konfigurationsdatei CFG/Timit_Baselines/timit_mlp_mfcc_basic.cfg an . In der Beschreibung der Konfigurationsdateien finden Sie eine detaillierte Beschreibung aller Felder.
Ändern Sie die Konfigurationsdatei gemäß Ihren Pfaden. Insbesondere:
Um Fehler zu vermeiden, stellen Sie sicher, dass alle Pfade in der CFG -Datei vorhanden sind. Bitte vermeiden Sie die Verwendung von Pfaden, die Bash-Variablen enthalten, da Pfade wörtlich gelesen und nicht automatisch erweitert werden (z.
python run_exp.py cfg/TIMIT_baselines/TIMIT_MLP_mfcc_basic.cfg
Dieses Skript startet ein volles ASR -Experiment und führt Trainings-, Validierungs-, Vorwärts- und Dekodierungsschritte durch. Ein Fortschrittsbalken zeigt die Entwicklung aller oben genannten Phasen. Das Skript run_exp.py erstellt schrittweise die folgenden Dateien im Ausgabeverzeichnis:
Beachten Sie, dass Sie das Experiment jederzeit stoppen können. Wenn Sie das Skript erneut ausführen, startet es automatisch vom letzten richtig verarbeitet. Das Training könnte je nach verfügbarer GPU einige Stunden dauern. Beachten Sie auch, dass Sie einen anderen Ausgangsordner angeben müssen, wenn Sie einige Parameter der Konfigurationsdatei (z. B. n_chunks =, fea_lst =, batch_size_train =, ..) ändern möchten.
DEBUG: Wenn Sie auf einige Fehler stoßen, empfehlen wir, die folgenden Überprüfungen durchzuführen:
Schauen Sie sich die Standardausgabe an.
Wenn es nicht hilfreich ist, schauen Sie sich die Datei log.log -Datei an.
Schauen Sie sich die Funktion run_nn in die core.py -Bibliothek an. Fügen Sie einige Drucke in den verschiedenen Teil der Funktion hinzu, um das Problem zu isolieren und das Problem herauszufinden.
Am Ende des Trainings wird die Telefonfehlerrate (pro%) in die RES.RES -Datei beigefügt. Um weitere Details zu den Dekodierungsergebnissen anzuzeigen, können Sie im Ausgaberordner in "decoding_test" eingehen und sich auf die verschiedenen erstellten Dateien wenden. Für dieses spezifische Beispiel haben wir die folgende res.res -Datei erhalten:
ep=000 tr=['TIMIT_tr'] loss=3.398 err=0.721 valid=TIMIT_dev loss=2.268 err=0.591 lr_architecture1=0.080000 time(s)=86
ep=001 tr=['TIMIT_tr'] loss=2.137 err=0.570 valid=TIMIT_dev loss=1.990 err=0.541 lr_architecture1=0.080000 time(s)=87
ep=002 tr=['TIMIT_tr'] loss=1.896 err=0.524 valid=TIMIT_dev loss=1.874 err=0.516 lr_architecture1=0.080000 time(s)=87
ep=003 tr=['TIMIT_tr'] loss=1.751 err=0.494 valid=TIMIT_dev loss=1.819 err=0.504 lr_architecture1=0.080000 time(s)=88
ep=004 tr=['TIMIT_tr'] loss=1.645 err=0.472 valid=TIMIT_dev loss=1.775 err=0.494 lr_architecture1=0.080000 time(s)=89
ep=005 tr=['TIMIT_tr'] loss=1.560 err=0.453 valid=TIMIT_dev loss=1.773 err=0.493 lr_architecture1=0.080000 time(s)=88
.........
ep=020 tr=['TIMIT_tr'] loss=0.968 err=0.304 valid=TIMIT_dev loss=1.648 err=0.446 lr_architecture1=0.002500 time(s)=89
ep=021 tr=['TIMIT_tr'] loss=0.965 err=0.304 valid=TIMIT_dev loss=1.649 err=0.446 lr_architecture1=0.002500 time(s)=90
ep=022 tr=['TIMIT_tr'] loss=0.960 err=0.302 valid=TIMIT_dev loss=1.652 err=0.447 lr_architecture1=0.001250 time(s)=88
ep=023 tr=['TIMIT_tr'] loss=0.959 err=0.301 valid=TIMIT_dev loss=1.651 err=0.446 lr_architecture1=0.000625 time(s)=88
%WER 18.1 | 192 7215 | 84.0 11.9 4.2 2.1 18.1 99.5 | -0.583 | /home/mirco/pytorch-kaldi-new/exp/TIMIT_MLP_basic5/decode_TIMIT_test_out_dnn1/score_6/ctm_39phn.filt.sys
Der erreichte Per (%) beträgt 18,1%. Beachten Sie, dass die Ergebnisse aufgrund unterschiedlicher Initialisierungen auf verschiedenen Maschinen eine gewisse Variabilität geben können. Wir sind der Ansicht, dass die Mittelung der mit unterschiedlichen Initialisierungssamen erhaltenen Leistung (dh die Feldsamen in der Konfigurationsdatei) für den Zeitpunkt von entscheidender Bedeutung ist, da die natürliche Leistungsvariabilität die experimentellen Nachweise vollständig verbergen könnte. Wir haben eine Standardabweichung von etwa 0,2% für die Timit -Experimente festgestellt.
Wenn Sie die Funktionen ändern möchten, müssen Sie sie zuerst mit dem Kaldi -Toolkit berechnen. Um FBANK -Funktionen zu berechnen, müssen Sie $ kaldi_root/EGS/Timit/s5/run.sh eröffnen und mit den folgenden Zeilen berechnen:
feadir=fbank
for x in train dev test; do
steps/make_fbank.sh --cmd "$train_cmd" --nj $feats_nj data/$x exp/make_fbank/$x $feadir
steps/compute_cmvn_stats.sh data/$x exp/make_fbank/$x $feadir
done
Ändern Sie dann die oben genannte Konfigurationsdatei mit der neuen Funktionsliste. Wenn Sie das vollständige Timit-Kaldi-Rezept bereits ausgeführt haben, können Sie die FMLLR-Funktionen in $ kaldi_root/eGS/Timit/S5/data-fmllr-Tri3 direkt finden. Wenn Sie das neuronale Netzwerk mit solchen Funktionen ernähren, sollten Sie aufgrund der Einführung der Sprecheranpassung eine erhebliche Leistungsverbesserung erwarten.
Im Ordner Timit_Baseline schlagen wir mehrere andere Beispiele für mögliche Timit -Basislinien vor. Ähnlich wie beim vorherigen Beispiel können Sie sie durch einfaches Tippen ausführen:
python run_exp.py $cfg_file
Es gibt einige Beispiele mit wiederkehrenden (Timit_Rnn*, Timit_LSTM*, Timit_Gru*, Timit_ligru*) und CNN -Architekturen (Timit_cnn*). Wir schlagen auch ein fortschrittlicheres Modell vor (TIMIT_DNN_LIGRU_DNN_MFCC+FBANK+FMLLR.CFG), in dem wir eine Kombination aus Feed-Forward- und wiederkehrenden neuronalen Netzwerken verwendeten, die von einer Verkettung von MFCC-, FBANK- und FMLLR-Merkmalen gefüttert wurden. Beachten Sie, dass die letzteren Konfigurationsdateien der besten im Referenzpapier beschriebenen Architektur entsprechen. Wie Sie möglicherweise aus den oben genannten Konfigurationsdateien erkennen, verbessern wir die ASR-Leistung, indem wir einige Tricks wie die Monophon-Regularisierung einbeziehen (dh gemeinsam schätzen wir gemeinsam sowohl kontextabhängige als auch kontextunabhängige Ziele). In der folgenden Tabelle werden die Ergebnisse berichtet, die durch Ausführen der letzteren Systeme (durchschnittlich pro%) erhalten wurden:
| Modell | MFCC | FBANK | fmllr |
|---|---|---|---|
| Kaldi DNN -Grundlinie | ----- | ------- | 18.5 |
| MLP | 18.2 | 18.7 | 16.7 |
| Rnn | 17.7 | 17.2 | 15.9 |
| SRU | ----- | 16.6 | ----- |
| Lstm | 15.1 | 14.3 | 14.5 |
| Gru | 16.0 | 15.2 | 14.9 |
| li-gro | 15.5 | 14.9 | 14.2 |
Die Ergebnisse zeigen, dass FMLLR dank des Lautsprecheranpassungsprozesses wie erwartet MFCCs und FBANKS -Koeffizienten übertreffen. Wiederkehrende Modelle übertreffen den Standard-MLP-Standard erheblich, insbesondere bei der Verwendung von LSTM-, GRU- und Li-Gru-Architektur, die das Verschwinden von Gradienten, die durch multiplikative Tore verschwinden, effektiv angehen. Das beste Ergebnis per = 14,2 $% wird mit dem Li-Gru-Modell [2,3] erhalten, das auf einem einzigen Gate basiert und somit 33% der Berechnungen über einen Standard-Gru spart.
Die besten Ergebnisse werden tatsächlich mit einer komplexeren Architektur erzielt, die MFCC-, FBANK- und FMLLR -Funktionen kombiniert (siehe CFG/Timi_Baselines/timit_mfcc_fbank_fmllr_ligru_best.cfg ). Nach unserem Kenntnisstand liefert das durch das letztere System erreichte Per = 13,8% die am besten veröffentlichte Leistung für die Timit-Testeinstellung.
Die einfachen rezidivierenden Einheiten (SRU) sind ein effizientes und hoch parallelisierbares rezidivierendes Modell. Die Leistung bei ASR ist schlechter als Standard-LSTM-, Gru- und Li-Gru-Modelle, aber es ist erheblich schneller. SRU wird hier implementiert und im folgenden Papier beschrieben:
T. Lei, Y. Zhang, Si Wang, H. Dai, Y. Artzi, "einfache wiederkehrende Einheiten für hoch parallelisierbare Wiederholungen, Proc. Von EMNLP 2018. Arxiv
Um Experimente mit diesem Modell durchzuführen, verwenden Sie die Konfigurationsdatei CFG/Timit_Baselines/timit_sru_fbank.cfg . Bevor Sie das Modell mit pip install sru installieren und "SRU" in neural_networks.py importieren sollten.
Sie können Ihre Ergebnisse direkt mit unseren vergleichen, indem Sie hierher gehen. In diesem externen Repository finden Sie alle Ordner, die die generierten Dateien enthalten.
Die Schritte zum Ausführen von Pytorch-Kaldi im Librispeech-Datensatz ähneln der oben angegebenen Zeit für das Timit. Das folgende Tutorial basiert auf der 100-Stunden-Untereinstellung , kann jedoch leicht auf den vollständigen Datensatz (960H) erweitert werden.
mkdir exp/tri4b/decode_tgsmall_train_clean_100 && cp exp/tri4b/trans.* exp/tri4b/decode_tgsmall_train_clean_100/
. ./cmd.sh ## You'll want to change cmd.sh to something that will work on your system.
. ./path.sh ## Source the tools/utils (import the queue.pl)
gmmdir=exp/tri4b
for chunk in train_clean_100 dev_clean test_clean; do
dir=fmllr/$chunk
steps/nnet/make_fmllr_feats.sh --nj 10 --cmd "$train_cmd"
--transform-dir $gmmdir/decode_tgsmall_$chunk
$dir data/$chunk $gmmdir $dir/log $dir/data || exit 1
compute-cmvn-stats --spk2utt=ark:data/$chunk/spk2utt scp:fmllr/$chunk/feats.scp ark:$dir/data/cmvn_speaker.ark
done
# aligments on dev_clean and test_clean
steps/align_fmllr.sh --nj 30 data/train_clean_100 data/lang exp/tri4b exp/tri4b_ali_clean_100
steps/align_fmllr.sh --nj 10 data/dev_clean data/lang exp/tri4b exp/tri4b_ali_dev_clean_100
steps/align_fmllr.sh --nj 10 data/test_clean data/lang exp/tri4b exp/tri4b_ali_test_clean_100
python run_exp.py cfg/Librispeech_baselines/libri_MLP_fmllr.cfg
Wenn Sie ein rezidivierendes Modell verwenden möchten, können Sie libri_rnn_fmllr.cfg , libri_lstm_fmllr.cfg , libri_gru_fmllr.cfg oder libri_ligru_fmllr.cfg verwenden. Die Ausbildung wiederkehrender Modelle kann einige Tage dauern (abhängig von der angenommenen GPU). Die mit dem TGSmall -Diagramm erhaltene Leistung ist in der folgenden Tabelle angegeben:
| Modell | Wer% |
|---|---|
| MLP | 9.6 |
| Lstm | 8.6 |
| Gru | 8.6 |
| li-gro | 8.6 |
Diese Ergebnisse werden erhalten, ohne eine Gitterresatzierung hinzuzufügen (dh nur unter Verwendung des TGSmall -Diagramms). Sie können die Leistung verbessern, indem Sie auf diese Weise eine Neuauflage des Gitters hinzufügen (führen Sie sie aus dem Ordner kaldi_decoding_script von pytorch-kaldi aus):
data_dir=/data/milatmp1/ravanelm/librispeech/s5/data/
dec_dir=/u/ravanelm/pytorch-Kaldi-new/exp/libri_fmllr/decode_test_clean_out_dnn1/
out_dir=/u/ravanelm/pytorch-kaldi-new/exp/libri_fmllr/
steps/lmrescore_const_arpa.sh $data_dir/lang_test_{tgsmall,fglarge}
$data_dir/test_clean $dec_dir $out_dir/decode_test_clean_fglarge || exit 1;
Die endgültigen Ergebnisse werden in der folgenden Tabelle angegeben:
| Modell | Wer% |
|---|---|
| MLP | 6.5 |
| Lstm | 6.4 |
| Gru | 6.3 |
| li-gro | 6.2 |
Sie können sich die hier erhaltenen Ergebnisse ansehen.
Das Hauptskript zum Ausführen eines ASR -Experiments ist run_exp.py . Dieses Python -Skript führt Trainings-, Validierungs-, Vorwärts- und Dekodierungsschritte durch. Das Training wird über mehrere Epochen durchgeführt, die das gesamte Trainingsmaterial mit dem betrachteten neuronalen Netzwerk schrittweise verarbeiten. Nach jeder Trainings-Epoche wird ein Validierungsschritt durchgeführt, um die Systemleistung auf Helddaten zu überwachen. Am Ende des Trainings wird die Vorwärtsphase durch Berechnung der hinteren Wahrscheinlichkeiten des angegebenen Testdatensatzes durchgeführt. Die hinteren Wahrscheinlichkeiten werden durch ihre Priors (unter Verwendung einer Zähldatei) normalisiert und in einer ARK -Datei gespeichert. Anschließend wird ein Dekodierungsschritt durchgeführt, um die endgültige Abfolge von Wörtern abzurufen, die der Sprecher in den Testsätzen ausgesprochen hat.
Das Skript run_exp.py nimmt eine globale Konfigurationsdatei (z. B. CFG/Timit_MLP_MFCC.cfg ) ein, in der alle erforderlichen Optionen für die Ausführung eines vollständigen Experiments angegeben sind. Der Code run_exp.py ruft eine andere Funktion run_nn auf (siehe Core.py -Bibliothek), in der Schulungen, Validierung und Weiterleitungsvorgänge für jeden Datenbetrag durchgeführt werden. Die Funktion run_nn nimmt eine klobspezifische Konfigurationsdatei (z. B. exp/timit_mlp_mfcc/exp_files/train_timit_tr+timit_dev_ep000_ck00.cfg*) ein, die alle erforderlichen Parameter angeben. Die Funktion run_nn gibt einige Informationen aus (z. B. exp/timit_mlp_mfcc/exp_files/train_timit_tr+timit_dev_ep000_ck00.info ), die Verluste und Fehler des verarbeiteten Chunk zusammenfassen.
Die Ergebnisse werden in die RES.RES -Dateien zusammengefasst, während Fehler und Warnungen in die Datei log.log.log umgeleitet werden.
Es gibt zwei Arten von Konfigurationsdateien (globale und klobende CFG-Dateien). Sie sind beide im INI -Format und werden mit der ConfigParser -Bibliothek von Python gelesen, verarbeitet und geändert. Die globale Datei enthält mehrere Abschnitte, die alle Hauptschritte eines Spracherkennungsexperimente (Training, Validierung, Vorwärts- und Decodierung) angeben. Die Struktur der Konfigurationsdatei wird in einer Prototyp -Datei beschrieben (siehe zum Beispiel Proto/global.Proto ), in dem nicht nur alle erforderlichen Abschnitte und Felder aufgeführt sind, sondern auch den Typ jedes möglichen Feldes angeben. Zum Beispiel bedeutet n_ep = int (1, inf) , dass die Felder n_ep (dh Anzahl der Trainings -Epochen) eine Ganzzahl von 1 bis Inf sein müssen. In ähnlicher Weise bedeutet LR = Float (0, Inf) , dass das LR -Feld (dh die Lernrate) ein Float von 0 bis Inf sein muss. Jeder Versuch, eine Konfigurationsdatei zu schreiben, die nicht diesen Spezifikationen entspricht, erhöht einen Fehler.
Versuchen wir nun, eine Konfigurationsdatei zu öffnen (z. B. CFG/Timit_Baselines/timit_mlp_mfcc_basic.cfg ) und beschreiben wir die Hauptabschnitte:
[cfg_proto]
cfg_proto = proto/global.proto
cfg_proto_chunk = proto/global_chunk.proto
Die aktuelle Version der Konfigurationsdatei gibt zunächst die Pfade der globalen und klobenden Prototypendateien im Abschnitt [cfg_proto] an.
[exp]
cmd =
run_nn_script = run_nn
out_folder = exp/TIMIT_MLP_basic5
seed = 1234
use_cuda = True
multi_gpu = False
save_gpumem = False
n_epochs_tr = 24
Der Abschnitt [Exp] enthält einige wichtige Felder, wie den Ausgaberordner ( Out_Folder ) und den Pfad des Chunk-spezifischen Verarbeitungsskripts run_nn (standardmäßig sollte diese Funktion in der Core.Py-Bibliothek implementiert werden). Das Feld n_epochs_tr gibt die ausgewählte Anzahl der Trainings -Epochen an. Weitere Optionen zu verwenden_cuda, multi_gpu und Save_Gpumem können vom Benutzer aktiviert werden. Mit dem Feld CMD kann ein Befehl angehängt werden, um das Skript auf einem HPC -Cluster auszuführen.
[dataset1]
data_name = TIMIT_tr
fea = fea_name=mfcc
fea_lst=quick_test/data/train/feats_mfcc.scp
fea_opts=apply-cmvn --utt2spk=ark:quick_test/data/train/utt2spk ark:quick_test/mfcc/train_cmvn_speaker.ark ark:- ark:- | add-deltas --delta-order=2 ark:- ark:- |
cw_left=5
cw_right=5
lab = lab_name=lab_cd
lab_folder=quick_test/dnn4_pretrain-dbn_dnn_ali
lab_opts=ali-to-pdf
lab_count_file=auto
lab_data_folder=quick_test/data/train/
lab_graph=quick_test/graph
n_chunks = 5
[dataset2]
data_name = TIMIT_dev
fea = fea_name=mfcc
fea_lst=quick_test/data/dev/feats_mfcc.scp
fea_opts=apply-cmvn --utt2spk=ark:quick_test/data/dev/utt2spk ark:quick_test/mfcc/dev_cmvn_speaker.ark ark:- ark:- | add-deltas --delta-order=2 ark:- ark:- |
cw_left=5
cw_right=5
lab = lab_name=lab_cd
lab_folder=quick_test/dnn4_pretrain-dbn_dnn_ali_dev
lab_opts=ali-to-pdf
lab_count_file=auto
lab_data_folder=quick_test/data/dev/
lab_graph=quick_test/graph
n_chunks = 1
[dataset3]
data_name = TIMIT_test
fea = fea_name=mfcc
fea_lst=quick_test/data/test/feats_mfcc.scp
fea_opts=apply-cmvn --utt2spk=ark:quick_test/data/test/utt2spk ark:quick_test/mfcc/test_cmvn_speaker.ark ark:- ark:- | add-deltas --delta-order=2 ark:- ark:- |
cw_left=5
cw_right=5
lab = lab_name=lab_cd
lab_folder=quick_test/dnn4_pretrain-dbn_dnn_ali_test
lab_opts=ali-to-pdf
lab_count_file=auto
lab_data_folder=quick_test/data/test/
lab_graph=quick_test/graph
n_chunks = 1
Die Konfigurationsdatei enthält eine Anzahl von Abschnitten ( [dataset1] , [dataset2] , [dataset3] , ...), die alle für das ASR -Experiment verwendeten Korpora beschreiben. Die Felder im Abschnitt [Dataset*] beschreiben alle im Experiment berücksichtigten Merkmale und Beschriftungen. The features, for instance, are specified in the field fea: , where fea_name contains the name given to the feature, fea_lst is the list of features (in the scp Kaldi format), fea_opts allows users to specify how to process the features (eg, doing CMVN or adding the derivatives), while cw_left and cw_right set the characteristics of the context window (ie, number of left and right frames anhängen). Beachten Sie, dass die aktuelle Version des Pytorch-Kaldi-Toolkits die Definition mehrerer Merkmals Streams unterstützt. Wie in CFG/Timit_Baselines/timit_mfcc_fbank_fmllr_ligru_best.cfg mehrere Feature -Streams (z. B. MFCC, FBANK, FMLLR) gezeigt.
In ähnlicher Weise enthält der Laborabschnitt einige Unterfelder. Zum Beispiel bezieht sich Lab_Name auf den dem Etikett angegebenen Namen, während Lab_Folder den Ordner enthält, in dem die vom Kaldi -Rezept generierten Alignments gespeichert werden. Mit Lab_Opts können der Benutzer einige Optionen für die betrachteten Ausrichtungen angeben. Zum Beispiel extrahiert Lab_opts = "Ali-to-PDF" Standard-Kontext-abhängige Telefonzustandsbezeichnungen, während Lab_opts = Ali-to-Phones --per-Frame = True verwendet werden kann, um Monophonziele zu extrahieren. Lab_Count_file wird verwendet, um die Datei anzugeben, die die Zählungen der betrachteten Telefonzustände enthält. Diese Zählungen sind in der Vorwärtsphase wichtig, wo die vom neuronalen Netzwerk berechneten hinteren Wahrscheinlichkeiten durch ihre Priors geteilt werden. Mit Pytorch-Kaldi können Benutzer sowohl eine externe Zähldatei angeben als auch automatisch abrufen (mit Lab_Count_File = auto ). Benutzer können auch Lab_Count_File = Keine angeben, wenn die Zähldatei nicht ausschließlich benötigt wird, z. B. wenn die Beschriftungen einer Ausgabe entsprechen, die nicht zur Generierung der in der Vorwärtsphase verwendeten posterioren Wahrscheinlichkeiten verwendet wird (siehe zum Beispiel die Monophonziele in CFG/Timit_Baselines/timit_mlp_mfcc.cfg ). Lab_data_Folder entspricht stattdessen dem Datenordner, der während der Kaldi -Datenvorbereitung erstellt wurde. Es enthält mehrere Dateien, darunter die Textdatei, die schließlich für die Berechnung der endgültigen WER verwendet wird. Der letzte Sub-Field Lab_Graph ist der Pfad des Kaldi-Diagramms, mit dem die Etiketten generiert werden.
Der vollständige Datensatz ist normalerweise groß und kann nicht in den GPU/RAM -Speicher passen. Es sollte daher in mehrere Stücke aufgeteilt werden. Pytorch-Kaldi teilt den Datensatz automatisch in die Anzahl der in N_Chwers angegebenen Stücke auf. Die Anzahl der Stücke kann vom spezifischen Datensatz abhängen. Im Allgemeinen schlagen wir vor, Sprachbrocken von etwa 1 oder 2 Stunden (abhängig vom verfügbaren Speicher) zu verarbeiten.
[data_use]
train_with = TIMIT_tr
valid_with = TIMIT_dev
forward_with = TIMIT_test
In diesem Abschnitt wird angegeben, wie die in den Abschnitten [Datensätzen*] aufgeführten Daten im Skript run_exp.py verwendet werden. Die erste Zeile bedeutet, dass wir ein Training mit den als Timit_TR bezeichneten Daten durchführen. Beachten Sie, dass dieser Datensatzname in einem der Datensatzabschnitte angezeigt werden muss, andernfalls wird der Konfigurationsparser einen Fehler erhöht. In ähnlicher Weise geben die zweiten und dritten Zeilen die Daten an, die zur Validierung bzw. die Vorwärtsphasen verwendet werden.
[batches]
batch_size_train = 128
max_seq_length_train = 1000
increase_seq_length_train = False
start_seq_len_train = 100
multply_factor_seq_len_train = 2
batch_size_valid = 128
max_seq_length_valid = 1000
Batch_Size_Train wird verwendet, um die Anzahl der Trainingsbeispiele im Mini-Batch zu definieren. Die Felder max_seq_length_train reduzieren die Sätze länger als der angegebene Wert. Bei der Schulung wiederkehrender Modelle zu sehr langen Sätzen können außerdem Probleme auftreten. Mit dieser Option können Benutzer solche Speicherprobleme durch Abschneiden langer Sätze abschwächen. Darüber hinaus ist es möglich, die maximale Satzlänge während des Trainings nach und nach durch Einstellen von erhöhtem_seq_length_train = true aufzubauen. Wenn aktiviert, beginnt das Training mit einer in start_seq_len_train (z. B., start_seq_len_train = 100 ) angegebenen maximalen Satzlänge. Nach jeder Epoche wird die maximale Satzlänge mit multply_factor_seq_len_train multipliziert (z. B. multply_factor_seq_len_train = 2 ). Wir haben festgestellt, dass diese einfache Strategie die Systemleistung im Allgemeinen verbessert, da sie das Modell dazu ermutigt, sich zunächst auf kurzfristige Abhängigkeiten zu konzentrieren und längerfristige zu lernen, nur zu einem späteren Zeitpunkt.
In ähnlicher Weise geben batch_size_valid und max_seq_length_valid die Anzahl der Beispiele in den Mini-Batches und die maximale Länge für den Dev-Datensatz an.
[architecture1]
arch_name = MLP_layers1
arch_proto = proto/MLP.proto
arch_library = neural_networks
arch_class = MLP
arch_pretrain_file = none
arch_freeze = False
arch_seq_model = False
dnn_lay = 1024,1024,1024,1024,N_out_lab_cd
dnn_drop = 0.15,0.15,0.15,0.15,0.0
dnn_use_laynorm_inp = False
dnn_use_batchnorm_inp = False
dnn_use_batchnorm = True,True,True,True,False
dnn_use_laynorm = False,False,False,False,False
dnn_act = relu,relu,relu,relu,softmax
arch_lr = 0.08
arch_halving_factor = 0.5
arch_improvement_threshold = 0.001
arch_opt = sgd
opt_momentum = 0.0
opt_weight_decay = 0.0
opt_dampening = 0.0
opt_nesterov = False
Die Abschnitte [Architektur*] werden verwendet, um die Architekturen der in den ASR -Experimenten beteiligten neuronalen Netzwerke anzugeben. Der Feld arch_name gibt den Namen der Architektur an. Da verschiedene neuronale Netze von einem anderen Satz von Hyperparametern abhängen können, muss der Benutzer den Pfad einer Proto -Datei hinzufügen, die die Liste der Hyperparameter in das Feldproto enthält. Beispielsweise enthält die Prototyp -Datei für ein Standard -MLP -Modell die folgenden Felder:
[proto]
library=path
class=MLP
dnn_lay=str_list
dnn_drop=float_list(0.0,1.0)
dnn_use_laynorm_inp=bool
dnn_use_batchnorm_inp=bool
dnn_use_batchnorm=bool_list
dnn_use_laynorm=bool_list
dnn_act=str_list
Ähnlich wie bei den anderen Prototypendateien definiert jede Zeile einen Hyperparameter mit dem zugehörigen Werttyp. Alle in der Proto -Datei definierten Hyperparameter müssen in der globalen Konfigurationsdatei unter dem entsprechenden Abschnitt [Architektur*] angezeigt werden. Das Feld arch_library gibt an, wo das Modell codiert ist (z. B. neural_nets.py ), während arch_class den Namen der Klasse angibt, in dem die Architektur implementiert ist (z. B. wenn wir class = mlp festlegen, werden wir von neural_nets.py importieren mlp ).
Mit dem Feld arch_praining_file kann das neuronale Netzwerk mit einer zuvor ausgebildeten Architektur vorverträgt werden, während arch_freeze auf false eingestellt werden kann, wenn Sie die Parameter der Architektur während des Trainings trainieren möchten und auf true do die Parameter (dh eingefroren) während des Trainings eingestellt werden sollten. Der Abschnitt arch_seq_model gibt an, ob die Architektur sequentiell (z. B. RNNs) oder nicht-sequentiell (z. B. ein Feed-Forward-MLP oder CNN) ist. Die Art und Weise, wie Pytorch-Kaldi die Eingangsstapel verarbeitet, ist in beiden Fällen unterschiedlich. Für wiederkehrende neuronale Netzwerke ( arch_seq_model = true ) ist die Abfolge der Merkmale nicht randomisiert (um die Elemente der Sequenzen zu erhalten), während für Feedforward -Modelle ( arch_seq_model = false ) die Merkmale randomisieren (dies hilft normalerweise zur Verbesserung der Leistung). Bei mehreren Architekturen wird eine sequentielle Verarbeitung verwendet, wenn mindestens eine der verwendeten Architekturen als sequentiell gekennzeichnet ist ( arch_seq_model = true ).
Beachten Sie, dass die Hyperparameter, die mit "arch_" und "opt_" beginnen, obligatorisch sind und in allen in der Konfigurationsdatei angegebenen Architektur vorhanden sein müssen. Die anderen Hyperparameter (z. B. DNN_*,) sind spezifisch für die betrachtete Architektur (sie hängen davon ab, wie die Klasse MLP vom Benutzer tatsächlich implementiert wird) und können die Anzahl und Typologie versteckter Ebenen, Stapel- und Schichtnormalisierungen sowie andere Parameter definieren. Andere wichtige Parameter beziehen sich auf die Optimierung der betrachteten Architektur. Beispielsweise ist Arch_lr die Lernrate, während arch_halving_factor zur Implementierung der Lernrate verwendet wird. Insbesondere, wenn die relative Leistungsverbesserung auf dem Dev-Set zwischen zwei aufeinanderfolgenden Epochen kleiner ist als die im Arch_improvement_threshold (z. B. arch_improvement_threshold), multiplizieren wir die Lernrate mit Arch_Halving_Factor (z. B. Arch_Aling_Factor = 0,5 ). Das Feld arch_opt gibt den Typ des Optimierungsalgorithmus an. Derzeit unterstützen wir SGD, Adam und RMSProp. Die anderen Parameter sind spezifisch für den betrachteten Optimierungsalgorithmus (siehe Pytorch-Dokumentation für die genaue Bedeutung aller optimierungsspezifischen Hyperparameter). Beachten Sie, dass die verschiedenen Architekturen, die in [Erziktatur*] definiert sind, unterschiedliche Optimierungshyperparameter haben können und sogar einen anderen Optimierungsalgorithmus verwenden können.
[model]
model_proto = proto/model.proto
model = out_dnn1=compute(MLP_layers1,mfcc)
loss_final=cost_nll(out_dnn1,lab_cd)
err_final=cost_err(out_dnn1,lab_cd)
Die Art und Weise, wie alle verschiedenen Merkmale und Architekturen kombiniert werden, wird in diesem Abschnitt mit einer sehr einfachen und intuitiven Metasprachung angegeben. Das Feldmodell : Beschreibt, wie Merkmale und Architekturen mit einer Reihe von hinteren Wahrscheinlichkeiten verbunden sind. Die Zeile out_dnn1 = compute (mlp_layers, mfcc) bedeutet " Füttere die Architektur, die als MLP_Layers1 bezeichnet wird, mit den als MFCC bezeichneten Funktionen und speichern die Ausgabe in die Variable out_dnn1 ." Aus dem neuronalen Netzwerkausgang out_dnn1 werden der Fehler und die Verlustfunktionen mit den Bezeichnungen LAB_CD berechnet, die zuvor in den Abschnitten [Datensätze*] definiert werden müssen. Die Felder ERR_FINAL und LUST_FINAL sind obligatorische Teilfelder, die die endgültige Ausgabe des Modells definieren.
Ein viel komplexeres Beispiel (hier diskutiert, nur um die Möglichkeit des Toolkits hervorzuheben) wird in CFG/Timit_Baselines/Timit_Mfcc_fbank_fmllr_ligru_best.cfg angegeben:
[model]
model_proto=proto/model.proto
model:conc1=concatenate(mfcc,fbank)
conc2=concatenate(conc1,fmllr)
out_dnn1=compute(MLP_layers_first,conc2)
out_dnn2=compute(liGRU_layers,out_dnn1)
out_dnn3=compute(MLP_layers_second,out_dnn2)
out_dnn4=compute(MLP_layers_last,out_dnn3)
out_dnn5=compute(MLP_layers_last2,out_dnn3)
loss_mono=cost_nll(out_dnn5,lab_mono)
loss_mono_w=mult_constant(loss_mono,1.0)
loss_cd=cost_nll(out_dnn4,lab_cd)
loss_final=sum(loss_cd,loss_mono_w)
err_final=cost_err(out_dnn4,lab_cd)
In diesem Fall verkettet wir zuerst MFCC-, FBANK- und FMLLR -Funktionen und füttern dann einen MLP. Die Ausgabe des MLP wird in ein wiederkehrendes neuronales Netzwerk (insbesondere ein Li-Gru-Modell) eingespeist. Wir haben dann eine weitere MLP -Schicht ( mlp_layers_second ), gefolgt von zwei Softmax -Klassifikatoren (dh, mlp_layers_last , mlp_layers_last2 ). Der erste schätzt die Standard-Kontext-abhängigen Zustände, während die zweiten Monophonziele schätzt. Die endgültige Kostenfunktion ist eine gewichtete Summe zwischen diesen beiden Vorhersagen. Auf diese Weise implementieren wir die Monophon -Regularisierung, die sich als nützlich herausstellte, um die ASR -Leistung zu verbessern.
Das vollständige Modell kann als einzelnes großes Rechendiagramm betrachtet werden, bei dem alle im Abschnitt [Modell] verwendeten grundlegenden Architekturen gemeinsam trainiert werden. Für jeden Mini-Batch werden die Eingangsfunktionen über das vollständige Modell ausgebildet und das cost_final wird unter Verwendung der angegebenen Etiketten berechnet. Anschließend wird der Gradient der Kostenfunktion in Bezug auf alle lernbaren Parameter der Architektur berechnet. Alle Parameter der verwendeten Architekturen werden dann zusammen mit dem in den Abschnitten [Architektur*] angegebenen Algorithmus aktualisiert.
[forward]
forward_out = out_dnn1
normalize_posteriors = True
normalize_with_counts_from = lab_cd
save_out_file = True
require_decoding = True
Der Abschnitt wird zunächst definiert, welche Ausgabe weiterleitet (er muss in den Modellabschnitt definiert werden). Wenn Normalize_Posteriors = true ist , werden diese hinteren durch ihre Priors (unter Verwendung einer Zähldatei) normalisiert. Wenn save_out_file = true , wird die posteriore Datei (normalerweise eine sehr große Ark -Datei) gespeichert, während bei SAVE_OUT_FILE = false diese Datei gelöscht wird, wenn sie nicht mehr benötigt werden. Das Request_Decoding ist ein Boolescher, der angibt, ob wir die angegebene Ausgabe dekodieren müssen. Das Feld Normalize_with_Counts_from set, das zur Normalisierung der hinteren Wahrscheinlichkeiten zählt.
[decoding]
decoding_script_folder = kaldi_decoding_scripts/
decoding_script = decode_dnn.sh
decoding_proto = proto/decoding.proto
min_active = 200
max_active = 7000
max_mem = 50000000
beam = 13.0
latbeam = 8.0
acwt = 0.2
max_arcs = -1
skip_scoring = false
scoring_script = local/score.sh
scoring_opts = "--min-lmwt 1 --max-lmwt 10"
norm_vars = False
Der Dekodierungsabschnitt meldet Parameter über die Dekodierung, dh die Schritte, die es ermöglicht, aus einer Abfolge der kontextabhängigen Wahrscheinlichkeiten zu übergeben, die der DNN in eine Abfolge von Wörtern bereitstellt. Das Feld decoding_script_Folder gibt den Ordner an, in dem das Dekodierungsskript gespeichert wird. The decoding script field is the script used for decoding (eg, decode_dnn.sh ) that should be in the decoding_script_folder specified before. The field decoding_proto reports all the parameters needed for the considered decoding script.
To make the code more flexible, the config parameters can also be specified within the command line. For example, you can run:
python run_exp.py quick_test/example_newcode.cfg --optimization,lr=0.01 --batches,batch_size=4
The script will replace the learning rate in the specified cfg file with the specified lr value. The modified config file is then stored into out_folder/config.cfg .
The script run_exp.py automatically creates chunk-specific config files, that are used by the run_nn function to perform a single chunk training. The structure of chunk-specific cfg files is very similar to that of the global one. The main difference is a field to_do={train, valid, forward} that specifies the type of processing to on the features chunk specified in the field fea .
Why proto files? Different neural networks, optimization algorithms, and HMM decoders might depend on a different set of hyperparameters. To address this issue, our current solution is based on the definition of some prototype files (for global, chunk, architecture config files). In general, this approach allows a more transparent check of the fields specified into the global config file. Moreover, it allows users to easily add new parameters without changing any line of the python code. For instance, to add a user-defined model, a new proto file (eg, user-model.prot o) that specifies the hyperparameter must be written. Then, the user should only write a class (eg, user-model in neural_networks.py ) that implements the architecture).
The toolkit is designed to allow users to easily plug-in their own acoustic models. To add a customized neural model do the following steps:
[proto]
dnn_lay=str_list
dnn_drop=float_list(0.0,1.0)
dnn_use_laynorm_inp=bool
dnn_use_batchnorm_inp=bool
dnn_use_batchnorm=bool_list
dnn_use_laynorm=bool_list
dnn_act=str_list
The parameter dnn_lay must be a list of string, dnn_drop (ie, the dropout factors for each layer) is a list of float ranging from 0.0 and 1.0, dnn_use_laynorm_inp and dnn_use_batchnorm_inp are booleans that enable or disable batch or layer normalization of the input. dnn_use_batchnorm and dnn_use_laynorm are a list of boolean that decide layer by layer if batch/layer normalization has to be used. The parameter dnn_act is again a list of string that sets the activation function of each layer. Since every model is based on its own set of hyperparameters, different models have a different prototype file. For instance, you can take a look into GRU.proto and see that the hyperparameter list is different from that of a standard MLP. Similarly to the previous examples, you should add here your list of hyperparameters and save the file.
Write a PyTorch class implementing your model. Open the library neural_networks.py and look at some of the models already implemented. For simplicity, you can start taking a look into the class MLP. The classes have two mandatory methods: init and forward . The first one is used to initialize the architecture, the second specifies the list of computations to do. The method init takes in input two variables that are automatically computed within the run_nn function. inp_dim is simply the dimensionality of the neural network input, while options is a dictionary containing all the parameters specified into the section architecture of the configuration file.
For instance, you can access to the DNN activations of the various layers in this way: options['dnn_lay'].split(',') . As you might see from the MLP class, the initialization method defines and initializes all the parameters of the neural network. The forward method takes in input a tensor x (ie, the input data) and outputs another vector containing x. If your model is a sequence model (ie, if there is at least one architecture with arch_seq_model=true in the cfg file), x is a tensor with (time_steps, batches, N_in), otherwise is a (batches, N_in) matrix. The class forward defines the list of computations to transform the input tensor into a corresponding output tensor. The output must have the sequential format (time_steps, batches, N_out) for recurrent models and the non-sequential format (batches, N_out) for feed-forward models. Similarly to the already-implemented models the user should write a new class (eg, myDNN) that implements the customized model:
class myDNN(nn.Module):
def __init__(self, options,inp_dim):
super(myDNN, self).__init__()
// initialize the parameters
def forward(self, x):
// do some computations out=f(x)
return out
[architecture1]
arch_name= mynetwork (this is a name you would like to use to refer to this architecture within the following model section)
arch_proto=proto/myDNN.proto (here is the name of the proto file defined before)
arch_library=neural_networks (this is the name of the library where myDNN is implemented)
arch_class=myDNN (This must be the name of the class you have implemented)
arch_pretrain_file=none (With this you can specify if you want to pre-train your model)
arch_freeze=False (set False if you want to update the parameters of your model)
arch_seq_model=False (set False for feed-forward models, True for recurrent models)
Then, you have to specify proper values for all the hyperparameters specified in proto/myDNN.proto . For the MLP.proto , we have:
dnn_lay=1024,1024,1024,1024,1024,N_out_lab_cd
dnn_drop=0.15,0.15,0.15,0.15,0.15,0.0
dnn_use_laynorm_inp=False
dnn_use_batchnorm_inp=False
dnn_use_batchnorm=True,True,True,True,True,False
dnn_use_laynorm=False,False,False,False,False,False
dnn_act=relu,relu,relu,relu,relu,softmax
Then, add the following parameters related to the optimization of your own architecture. You can use here standard sdg, adam, or rmsprop (see cfg/TIMIT_baselines/TIMIT_LSTM_mfcc.cfg for an example with rmsprop):
arch_lr=0.08
arch_halving_factor=0.5
arch_improvement_threshold=0.001
arch_opt=sgd
opt_momentum=0.0
opt_weight_decay=0.0
opt_dampening=0.0
opt_nesterov=False
Save the configuration file into the cfg folder (eg, cfg/myDNN_exp.cfg ).
Run the experiment with:
python run_exp.py cfg/myDNN_exp.cfg
When implementing a new model, an important debug test consists of doing an overfitting experiment (to make sure that the model is able to overfit a tiny dataset). If the model is not able to overfit, it means that there is a major bug to solve.
A hyperparameter tuning is often needed in deep learning to search for proper neural architectures. To help tuning the hyperparameters within PyTorch-Kaldi, we have implemented a simple utility that implements a random search. In particular, the script tune_hyperparameters.py generates a set of random configuration files and can be run in this way:
python tune_hyperparameters.py cfg/TIMIT_MLP_mfcc.cfg exp/TIMIT_MLP_mfcc_tuning 10 arch_lr=randfloat(0.001,0.01) batch_size_train=randint(32,256) dnn_act=choose_str{relu,relu,relu,relu,softmax|tanh,tanh,tanh,tanh,softmax}
The first parameter is the reference cfg file that we would like to modify, while the second one is the folder where the random configuration files are saved. The third parameter is the number of the random config file that we would like to generate. There is then the list of all the hyperparameters that we want to change. For instance, arch_lr=randfloat(0.001,0.01) will replace the field arch_lr with a random float ranging from 0.001 to 0.01. batch_size_train=randint(32,256) will replace batch_size_train with a random integer between 32 and 256 and so on. Once the config files are created, they can be run sequentially or in parallel with:
python run_exp.py $cfg_file
PyTorch-Kaldi can be used with any speech dataset. To use your own dataset, the steps to take are similar to those discussed in the TIMIT/Librispeech tutorials. In general, what you have to do is the following:
python run_exp.py $cfg_file . The current version of PyTorch-Kaldi supports input features stored with the Kaldi ark format. If the user wants to perform experiments with customized features, the latter must be converted into the ark format. Take a look into the Kaldi-io-for-python git repository (https://github.com/vesis84/kaldi-io-for-python) for a detailed description about converting numpy arrays into ark files. Moreover, you can take a look into our utility called save_raw_fea.py. This script generates Kaldi ark files containing raw features, that are later used to train neural networks fed by the raw waveform directly (see the section about processing audio with SincNet).
The current version of Pytorch-Kaldi supports the standard production process of using a Pytorch-Kaldi pre-trained acoustic model to transcript one or multiples .wav files. It is important to understand that you must have a trained Pytorch-Kaldi model. While you don't need labels or alignments anymore, Pytorch-Kaldi still needs many files to transcript a new audio file:
Once you have all these files, you can start adding your dataset section to the global configuration file. The easiest way is to copy the cfg file used to train your acoustic model and just modify by adding a new [dataset] :
[dataset4]
data_name = myWavFile
fea = fea_name=fbank
fea_lst=myWavFilePath/data/feats.scp
fea_opts=apply-cmvn --utt2spk=ark:myWavFilePath/data//utt2spk ark:myWavFilePath/cmvn_test.ark ark:- ark:- | add-deltas --delta-order=0 ark:- ark:- |
cw_left=5
cw_right=5
lab = lab_name=none
lab_data_folder=myWavFilePath/data/
lab_graph=myWavFilePath/exp/tri3/graph
n_chunks=1
[data_use]
train_with = TIMIT_tr
valid_with = TIMIT_dev
forward_with = myWavFile
The key string for your audio file transcription is lab_name=none . The none tag asks Pytorch-Kaldi to enter a production mode that only does the forward propagation and decoding without any labels. You don't need TIMIT_tr and TIMIT_dev to be on your production server since Pytorch-Kaldi will skip this information to directly go to the forward phase of the dataset given in the forward_with field. As you can see, the global fea field requires the exact same parameters than standard training or testing dataset, while the lab field only requires two parameters. Please, note that lab_data_folder is nothing more than the same path as fea_lst . Finally, you still need to specify the number of chunks you want to create to process this file (1 hour = 1 chunk).
WARNINGS
In your standard .cfg, you might have used keywords such as N_out_lab_cd that can not be used anymore. Indeed, in a production scenario, you don't want to have the training data on your machine. Therefore, all the variables that were on your .cfg file must be replaced by their true values. To replace all the N_out_{mono,lab_cd} you can take a look at the output of:
hmm-info /path/to/the/final.mdl/used/to/generate/the/training/ali
Then, if you normalize posteriors as (check in your .cfg Section forward):
normalize_posteriors = True
normalize_with_counts_from = lab_cd
You must replace lab_cd by:
normalize_posteriors = True
normalize_with_counts_from = /path/to/ali_train_pdf.counts
This normalization step is crucial for HMM-DNN speech recognition. DNNs, in fact, provide posterior probabilities, while HMMs are generative models that work with likelihoods. To derive the required likelihoods, one can simply divide the posteriors by the prior probabilities. To create this ali_train_pdf.counts file you can follow:
alidir=/path/to/the/exp/tri_ali (change it with your path to the exp with the ali)
num_pdf=$(hmm-info $alidir/final.mdl | awk '/pdfs/{print $4}')
labels_tr_pdf="ark:ali-to-pdf $alidir/final.mdl "ark:gunzip -c $alidir/ali.*.gz |" ark:- |"
analyze-counts --verbose=1 --binary=false --counts-dim=$num_pdf "$labels_tr_pdf" ali_train_pdf.counts
et voilà ! In a production scenario, you might need to transcript a huge number of audio files, and you don't want to create as much as needed .cfg file. In this extent, and after creating this initial production .cfg file (you can leave the path blank), you can call the run_exp.py script with specific arguments referring to your different.wav features:
python run_exp.py cfg/TIMIT_baselines/TIMIT_MLP_fbank_prod.cfg --dataset4,fea,0,fea_lst="myWavFilePath/data/feats.scp" --dataset4,lab,0,lab_data_folder="myWavFilePath/data/" --dataset4,lab,0,lab_graph="myWavFilePath/exp/tri3/graph/"
This command will internally alter the configuration file with your specified paths, and run and your defined features! Note that passing long arguments to the run_exp.py script requires a specific notation. --dataset4 specifies the name of the created section, fea is the name of the higher level field, fea_lst or lab_graph are the name of the lowest level field you want to change. The 0 is here to indicate which lowest level field you want to alter, indeed some configuration files may contain multiple lab_graph per dataset! Therefore, 0 indicates the first occurrence, 1 the second ... Paths MUST be encapsulated by " " to be interpreted as full strings! Note that you need to alter the data_name and forward_with fields if you don't want different .wav files transcriptions to erase each other (decoding files are stored accordingly to the field data_name ). --dataset4,data_name=MyNewName --data_use,forward_with=MyNewName .
In order to give users more flexibility, the latest version of PyTorch-Kaldi supports scheduling of the batch size, max_seq_length_train, learning rate, and dropout factor. This means that it is now possible to change these values during training. To support this feature, we implemented the following formalisms within the config files:
batch_size_train = 128*12 | 64*10 | 32*2
In this case, our batch size will be 128 for the first 12 epochs, 64 for the following 10 epochs, and 32 for the last two epochs. By default "*" means "for N times", while "|" is used to indicate a change of the batch size. Note that if the user simply sets batch_size_train = 128 , the batch size is kept fixed during all the training epochs by default.
A similar formalism can be used to perform learning rate scheduling:
arch_lr = 0.08*10|0.04*5|0.02*3|0.01*2|0.005*2|0.0025*2
In this case, if the user simply sets arch_lr = 0.08 the learning rate is annealed with the new-bob procedure used in the previous version of the toolkit. In practice, we start from the specified learning rate and we multiply it by a halving factor every time that the improvement on the validation dataset is smaller than the threshold specified in the field arch_improvement_threshold .
Also the dropout factor can now be changed during training with the following formalism:
dnn_drop = 0.15*12|0.20*12,0.15,0.15*10|0.20*14,0.15,0.0
With the line before we can set a different dropout rate for different layers and for different epochs. For instance, the first hidden layer will have a dropout rate of 0.15 for the first 12 epochs, and 0.20 for the other 12. The dropout factor of the second layer, instead, will remain constant to 0.15 over all the training. The same formalism is used for all the layers. Note that "|" indicates a change in the dropout factor within the same layer, while "," indicates a different layer.
You can take a look here into a config file where batch sizes, learning rates, and dropout factors are changed here:
cfg/TIMIT_baselines/TIMIT_mfcc_basic_flex.cfg
or here:
cfg/TIMIT_baselines/TIMIT_liGRU_fmllr_lr_schedule.cfg
The project is still in its initial phase and we invite all potential contributors to participate. We hope to build a community of developers larger enough to progressively maintain, improve, and expand the functionalities of our current toolkit. For instance, it could be helpful to report any bug or any suggestion to improve the current version of the code. People can also contribute by adding additional neural models, that can eventually make richer the set of currently-implemented architectures.
Schauen Sie sich unsere Video -Einführung in Sincnet an
SincNet is a convolutional neural network recently proposed to process raw audio waveforms. In particular, SincNet encourages the first layer to discover more meaningful filters by exploiting parametrized sinc functions. In contrast to standard CNNs, which learn all the elements of each filter, only low and high cutoff frequencies of band-pass filters are directly learned from data. This inductive bias offers a very compact way to derive a customized filter-bank front-end, that only depends on some parameters with a clear physical meaning.
For a more detailed description of the SincNet model, please refer to the following papers:
M. Ravanelli, Y. Bengio, "Speaker Recognition from raw waveform with SincNet", in Proc. of SLT 2018 ArXiv
M. Ravanelli, Y.Bengio, "Interpretable Convolutional Filters with SincNet", in Proc. of NIPS@IRASL 2018 ArXiv
To use this model for speech recognition on TIMIT, to the following steps:
python ./run_exp.py cfg/TIMIT_baselines/TIMIT_SincNet_raw.cfg
In the following table, we compare the result of SincNet with other feed-forward neural network:
| Modell | WER(%) |
|---|---|
| MLP -fbank | 18.7 |
| MLP -mfcc | 18.2 |
| CNN -raw | 18.1 |
| SincNet -raw | 17.2 |
In this section, we show how to use PyTorch-Kaldi to jointly train a cascade between a speech enhancement and a speech recognition neural networks. The speech enhancement has the goal of improving the quality of the speech signal by minimizing the MSE between clean and noisy features. The enhanced features then feed another neural network that predicts context-dependent phone states.
In the following, we report a toy-task example based on a reverberated version of TIMIT, that is only intended to show how users should set the config file to train such a combination of neural networks. Even though some implementation details (and the adopted datasets) are different, this tutorial is inspired by this paper:
To run the system do the following steps:
1- Make sure you have the standard clean version of TIMIT available.
2- Run the Kaldi s5 baseline of TIMIT. This step is necessary to compute the clean features (that will be the labels of the speech enhancement system) and the alignments (that will be the labels of the speech recognition system). We recommend running the full timit s5 recipe (including the DNN training).
3- The standard TIMIT recipe uses MFCCs features. In this tutorial, instead, we use FBANK features. To compute FBANK features run the following script in $KALDI_ROOT/egs/TIMIT/s5 :
feadir=fbank
for x in train dev test; do
steps/make_fbank.sh --cmd "$train_cmd" --nj $feats_nj data/$x exp/make_fbank/$x $feadir
steps/compute_cmvn_stats.sh data/$x exp/make_fbank/$x $feadir
done
Note that we use 40 FBANKS here, while Kaldi uses by default 23 FBANKs. To compute 40-dimensional features go into "$KALDI_ROOT/egs/TIMIT/conf/fbank.conf" and change the number of considered output filters.
4- Go to this external repository and follow the steps to generate a reverberated version of TIMIT starting from the clean one. Note that this is just a toy task that is only helpful to show how setting up a joint-training system.
5- Compute the FBANK features for the TIMIT_rev dataset. To do it, you can copy the scripts in $KALDI_ROOT/egs/TIMIT/ into $KALDI_ROOT/egs/TIMIT_rev/ . Please, copy also the data folder. Note that the audio files in the TIMIT_rev folders are saved with the standard WAV format, while TIMIT is released with the SPHERE format. To bypass this issue, open the files data/train/wav.scp , data/dev/wav.scp , data/test/wav.scp and delete the part about SPHERE reading (eg, /home/mirco/kaldi-trunk/tools/sph2pipe_v2.5/sph2pipe -f wav ). You also have to change the paths from the standard TIMIT to the reverberated one (eg replace /TIMIT/ with /TIMIT_rev/). Remind to remove the final pipeline symbol“ |”. Save the changes and run the computation of the fbank features in this way:
feadir=fbank
for x in train dev test; do
steps/make_fbank.sh --cmd "$train_cmd" --nj $feats_nj data/$x exp/make_fbank/$x $feadir
steps/compute_cmvn_stats.sh data/$x exp/make_fbank/$x $feadir
done
Remember to change the $KALDI_ROOT/egs/TIMIT_rev/conf/fbank.conf file in order to compute 40 features rather than the 23 FBANKS of the default configuration.
6- Once features are computed, open the following config file:
cfg/TIMIT_baselines/TIMIT_rev/TIMIT_joint_training_liGRU_fbank.cfg
Remember to change the paths according to where data are stored in your machine. As you can see, we consider two types of features. The fbank_rev features are computed from the TIMIT_rev dataset, while the fbank_clean features are derived from the standard TIMIT dataset and are used as targets for the speech enhancement neural network. As you can see in the [model] section of the config file, we have the cascade between networks doing speech enhancement and speech recognition. The speech recognition architecture jointly estimates both context-dependent and monophone targets (thus using the so-called monophone regularization). To run an experiment type the following command:
python run_exp.py cfg/TIMIT_baselines/TIMIT_rev/TIMIT_joint_training_liGRU_fbank.cfg
7- Results With this configuration file, you should obtain a Phone Error Rate (PER)=28.1% . Note that some oscillations around this performance are more than natural and are due to different initialization of the neural parameters.
You can take a closer look into our results here
In this tutorial, we use the DIRHA-English dataset to perform a distant speech recognition experiment. The DIRHA English Dataset is a multi-microphone speech corpus being developed under the EC project DIRHA. The corpus is composed of both real and simulated sequences recorded with 32 sample-synchronized microphones in a domestic environment. The database contains signals of different characteristics in terms of noise and reverberation making it suitable for various multi-microphone signal processing and distant speech recognition tasks. The part of the dataset currently released is composed of 6 native US speakers (3 Males, 3 Females) uttering 409 wall-street journal sentences. The training data have been created using a realistic data contamination approach, that is based on contaminating the clean speech wsj-5k sentences with high-quality multi-microphone impulse responses measured in the targeted environment. For more details on this dataset, please refer to the following papers:
M. Ravanelli, L. Cristoforetti, R. Gretter, M. Pellin, A. Sosi, M. Omologo, "The DIRHA-English corpus and related tasks for distant-speech recognition in domestic environments", in Proceedings of ASRU 2015. ArXiv
M. Ravanelli, P. Svaizer, M. Omologo, "Realistic Multi-Microphone Data Simulation for Distant Speech Recognition", in Proceedings of Interspeech 2016. ArXiv
In this tutorial, we use the aforementioned simulated data for training (using LA6 microphone), while test is performed using the real recordings (LA6). This task is very realistic, but also very challenging. The speech signals are characterized by a reverberation time of about 0.7 seconds. Non-stationary domestic noises (such as vacuum cleaner, steps, phone rings, etc.) are also present in the real recordings.
Let's start now with the practical tutorial.
1- If not available, download the DIRHA dataset from the LDC website. LDC releases the full dataset for a small fee.
2- Go this external reposotory. As reported in this repository, you have to generate the contaminated WSJ dataset with the provided MATLAB script. Then, you can run the proposed KALDI baseline to have features and labels ready for our pytorch-kaldi toolkit.
3- Open the following configuration file:
cfg/DIRHA_baselines/DIRHA_liGRU_fmllr.cfg
The latter configuration file implements a simple RNN model based on a Light Gated Recurrent Unit (Li-GRU). We used fMLLR as input features. Change the paths and run the following command:
python run_exp.py cfg/DIRHA_baselines/DIRHA_liGRU_fmllr.cfg
4- Results: The aforementioned system should provide Word Error Rate (WER%)=23.2% . You can find the results obtained by us here.
Using the other configuration files in the cfg/DIRHA_baselines folder you can perform experiments with different setups. With the provided configuration files you can obtain the following results:
| Modell | WER(%) |
|---|---|
| MLP | 26.1 |
| Gru | 25.3 |
| Li-GRU | 23.8 |
The current version of the repository is mainly designed for speech recognition experiments. We are actively working a new version, which is much more flexible and can manage input/output different from Kaldi features/labels. Even with the current version, however, it is possible to implement other systems, such as an autoencoder.
An autoencoder is a neural network whose inputs and outputs are the same. The middle layer normally contains a bottleneck that forces our representations to compress the information of the input. In this tutorial, we provide a toy example based on the TIMIT dataset. For instance, see the following configuration file:
cfg/TIMIT_baselines/TIMIT_MLP_fbank_autoencoder.cfg
Our inputs are the standard 40-dimensional fbank coefficients that are gathered using a context windows of 11 frames (ie, the total dimensionality of our input is 440). A feed-forward neural network (called MLP_encoder) encodes our features into a 100-dimensional representation. The decoder (called MLP_decoder) is fed by the learned representations and tries to reconstruct the output. The system is trained with Mean Squared Error (MSE) metric. Note that in the [Model] section we added this line “err_final=cost_err(dec_out,lab_cd)” at the end. The current version of the model, in fact, by default needs that at least one label is specified (we will remove this limit in the next version).
You can train the system running the following command:
python run_exp.py cfg/TIMIT_baselines/TIMIT_MLP_fbank_autoencoder.cfg
The results should look like this:
ep=000 tr=['TIMIT_tr'] loss=0.139 err=0.999 valid=TIMIT_dev loss=0.076 err=1.000 lr_architecture1=0.080000 lr_architecture2=0.080000 time(s)=41
ep=001 tr=['TIMIT_tr'] loss=0.098 err=0.999 valid=TIMIT_dev loss=0.062 err=1.000 lr_architecture1=0.080000 lr_architecture2=0.080000 time(s)=39
ep=002 tr=['TIMIT_tr'] loss=0.091 err=0.999 valid=TIMIT_dev loss=0.058 err=1.000 lr_architecture1=0.040000 lr_architecture2=0.040000 time(s)=39
ep=003 tr=['TIMIT_tr'] loss=0.088 err=0.999 valid=TIMIT_dev loss=0.056 err=1.000 lr_architecture1=0.020000 lr_architecture2=0.020000 time(s)=38
ep=004 tr=['TIMIT_tr'] loss=0.087 err=0.999 valid=TIMIT_dev loss=0.055 err=0.999 lr_architecture1=0.010000 lr_architecture2=0.010000 time(s)=39
ep=005 tr=['TIMIT_tr'] loss=0.086 err=0.999 valid=TIMIT_dev loss=0.054 err=1.000 lr_architecture1=0.005000 lr_architecture2=0.005000 time(s)=39
ep=006 tr=['TIMIT_tr'] loss=0.086 err=0.999 valid=TIMIT_dev loss=0.054 err=1.000 lr_architecture1=0.002500 lr_architecture2=0.002500 time(s)=39
ep=007 tr=['TIMIT_tr'] loss=0.086 err=0.999 valid=TIMIT_dev loss=0.054 err=1.000 lr_architecture1=0.001250 lr_architecture2=0.001250 time(s)=39
ep=008 tr=['TIMIT_tr'] loss=0.086 err=0.999 valid=TIMIT_dev loss=0.054 err=0.999 lr_architecture1=0.000625 lr_architecture2=0.000625 time(s)=41
ep=009 tr=['TIMIT_tr'] loss=0.086 err=0.999 valid=TIMIT_dev loss=0.054 err=0.999 lr_architecture1=0.000313 lr_architecture2=0.000313 time(s)=38
You should only consider the field "loss=". The filed "err=" only contains not useuful information in this case (for the aforementioned reason). You can take a look into the generated features typing the following command:
copy-feats ark:exp/TIMIT_MLP_fbank_autoencoder/exp_files/forward_TIMIT_test_ep009_ck00_enc_out.ark ark,t:- | more
[1] M. Ravanelli, T. Parcollet, Y. Bengio, "The PyTorch-Kaldi Speech Recognition Toolkit", ArxIv
[2] M. Ravanelli, P. Brakel, M. Omologo, Y. Bengio, "Improving speech recognition by revising gated recurrent units", in Proceedings of Interspeech 2017. ArXiv
[3] M. Ravanelli, P. Brakel, M. Omologo, Y. Bengio, "Light Gated Recurrent Units for Speech Recognition", in IEEE Transactions on Emerging Topics in Computational Intelligence. ArXiv
[4] M. Ravanelli, "Deep Learning for Distant Speech Recognition", PhD Thesis, Unitn 2017. ArXiv
[5] T. Parcollet, M. Ravanelli, M. Morchid, G. Linarès, C. Trabelsi, R. De Mori, Y. Bengio, "Quaternion Recurrent Neural Networks", in Proceedings of ICLR 2019 ArXiv
[6] T. Parcollet, M. Morchid, G. Linarès, R. De Mori, "Bidirectional Quaternion Long-Short Term Memory Recurrent Neural Networks for Speech Recognition", in Proceedings of ICASSP 2019 ArXiv