Diese Arbeit versucht, die Ergebnisse eines neuronalen Konversationsmodells (auch bekannt als Google Chatbot) zu reproduzieren. Es verwendet ein RNN (seq2seq-Modell) für Satzvorhersagen. Dies geschieht mit Python und TensorFlow.
Der Ladekorpus-Teil des Programms ist vom Torch Neuralconvo von Macournoyer inspiriert.
Derzeit unterstützt DeepQA das folgende Dialogkorpus:
--corpus opensubs
.--corpus scotus
. Beachten Sie die Anweisungen zur Installation.--corpus ubuntu
. Beachten Sie die Anweisungen zur Installation.Um das Training zu beschleunigen, ist es auch möglich, vorab trainierte Worteinbettungen zu verwenden (Danke an Eschnou). Weitere Infos hier.
Das Programm erfordert die folgenden Abhängigkeiten (einfache Installation mit pip: pip3 install -r requirements.txt
):
Möglicherweise müssen Sie auch zusätzliche Daten herunterladen, damit NLTK funktioniert.
python3 -m nltk.downloader punkt
Der Cornell-Datensatz ist bereits enthalten. Für die anderen Datensätze sehen Sie sich die Readme-Dateien in ihren jeweiligen Ordnern (innerhalb von data/
) an.
Für die Weboberfläche sind einige zusätzliche Pakete erforderlich:
Eine Docker-Installation ist ebenfalls verfügbar. Ausführlichere Anweisungen hier.
Um das Modell zu trainieren, führen Sie einfach main.py
aus. Nach dem Training können Sie die Ergebnisse mit main.py --test
(Ergebnisse werden in „save/model/samples_predictions.txt“ generiert) oder main.py --test interactive
(mehr Spaß) testen.
Hier sind einige Flags, die nützlich sein könnten. Für weitere Hilfe und Optionen verwenden Sie python main.py -h
:
--modelTag
: Ermöglicht die Vergabe eines Namens für das aktuelle Modell, um es beim Testen/Training zu unterscheiden.--keepAll
: Verwenden Sie dieses Flag beim Training, wenn Sie beim Testen die Vorhersagen in verschiedenen Schritten sehen möchten (es kann interessant sein zu sehen, wie das Programm seinen Namen und sein Alter ändert, wenn das Training fortschreitet). Warnung: Es kann schnell viel Speicherplatz beanspruchen, wenn Sie die Option --saveEvery
nicht erhöhen.--filterVocab 20
oder --vocabularySize 30000
: Beschränken Sie die Vokabulargröße auf und optimieren Sie die Leistung und Speichernutzung. Ersetzen Sie die Wörter, die weniger als 20 Mal verwendet werden, durch das Token
und legen Sie eine maximale Vokabulargröße fest.--verbose
: Gibt beim Testen die Sätze aus, während sie berechnet werden.--playDataset
: Zeigt einige Dialogbeispiele aus dem Datensatz (kann zusammen mit --createDataset
verwendet werden, wenn dies die einzige Aktion ist, die Sie ausführen möchten). Um das Rechendiagramm und die Kosten mit TensorBoard zu visualisieren, führen Sie einfach tensorboard --logdir save/
aus.
Standardmäßig ist die Netzwerkarchitektur ein Standard-Encoder/Decoder mit zwei LSTM-Schichten (versteckte Größe von 256) und einer Einbettungsgröße für das Vokabular von 32. Das Netzwerk wird mit ADAM trainiert. Die maximale Satzlänge ist auf 10 Wörter festgelegt, kann aber erhöht werden.
Nach der Schulung ist es über eine benutzerfreundlichere Oberfläche möglich, mit ihm zu chatten. Der Server prüft das nach save/model-server/model.ckpt
kopierte Modell. Wenn Sie es zum ersten Mal verwenden möchten, müssen Sie es wie folgt konfigurieren:
export CHATBOT_SECRET_KEY= " my-secret-key "
cd chatbot_website/
python manage.py makemigrations
python manage.py migrate
Um den Server dann lokal zu starten, verwenden Sie die folgenden Befehle:
cd chatbot_website/
redis-server & # Launch Redis in background
python manage.py runserver
Nach dem Start sollte die Schnittstelle unter http://localhost:8000/ verfügbar sein. Wenn Sie das Programm auf einem Server bereitstellen möchten, verwenden Sie stattdessen python manage.py runserver 0.0.0.0
. Weitere Infos hier.
Überraschenderweise ist es möglich, bereits nach 1 oder 2 Stunden Training (auf einer GeForce GT 740M) einige Ergebnisse zu erzielen, indem man die Eingabesequenz drastisch auf 5 Wörter und die Ausgabe auf 3 (plus die go
und eos
-Tokens) reduziert und ein kleines Wort verwendet Einbettungsgröße (etwa 25). Seitdem habe ich den Code geändert und jetzt muss die Ausgabelänge mit der Eingabelänge übereinstimmen, aber Sie können mit dieser Version immer noch die ursprünglichen Ergebnisse reproduzieren. Wirklich gesprächig wird es im Netzwerk natürlich nicht:
Q: Hi
A: Hi.
Q: What is your name ?
A: Laura.
Q: What does that mean ?
A: I dunno.
Q: How old are you ?
A: thirty-five.
Q: Will Google hire me ?
A: No.
Q: Tell me the alphabet
A: Fuck you.
Q: That's not nice
A: Yeah.
Hier ist ein Fall, in dem es fehlschlägt:
Q: Who is Laura ?
A: My brother.
Q: Say 'goodbye'
A: Alright.
Q: What is cooking ?
A: A channel.
Q: Can you say no ?
A: No.
Q: Two plus two
A: Manny...
Bei längeren Sätzen ist das Netzwerk viel langsamer zu trainieren. Nach 250.000 Iterationen mit maxLength=10 gibt das Netzwerk immer noch hauptsächlich ausweichende Antworten (indem es die meisten offenen Fragen mit „Ich weiß nicht“ beantwortet), aber es scheint einige grundlegende Semantik integriert zu haben:
Q: When are the fireworks ?
A: Tomorrow.
Q: What color ?
A: Gray.
Q: Which apple ?
A: That's the first one.
Q: What time is it ?
A: Eleven o'clock.
Q: Who is Skywalker ?
A: She's a freelance bio-exorcist.
Q: Who is John ?
A: The old man.
Q: Who is Jenny ?
A: The man who killed herself.
Q: When were you born ?
A: Soon.
Wie aus den letzten Fragen hervorgeht, führt das Netzwerk immer noch zu einer gewissen Verwirrung zwischen den Geschlechtern und der Gegenwart/Zukunft. Ich habe auch einige tiefergehende philosophische Fragen ausprobiert, mit mehr oder weniger Erfolg.
Q: What is the purpose of being intelligent ?
A: The man are obsolete.
Q: What is immoral ?
A: The truth.
Q: What is morality ?
A: The worst.
Q: What is the purpose of existence ?
A: It 's private.
Q: What happens if machines can think ?
A: I think I'll just lie with you.
Das von mir trainierte Modell ist durch die von mir eingegebene Einbettungsgröße, seine Größe und die Größe des Trainingskorpus ziemlich begrenzt. Sein „Gedankenvektor“ ist wahrscheinlich auch zu klein, um die folgenden Fragen zu beantworten:
Q: My name is David. What is my name ?
A: Debbie.
Q: My name is John. What is my name ?
A: Carl Smith.
Q: How many legs does a cat have ?
A: Four.
Q: How many legs does a spider have ?
A: Four.
Q: Do you prefer football or soccer ?
A: Whiskey.
Es scheint auch überzupassen, da es manchmal einfach Sätze aus seinem Trainingssatz herausspringt, die nichts mit der Frage zu tun haben. Das Hinzufügen einiger Dropouts sollte das Problem verringern.
Q: I play tennis. What do I play ?
A: I'm going to get laid.
Q: What color is the sky ?
A: One of the deputies is everywhere.
Hinweis: Links funktionieren nicht mehr.
Ein vorab trainiertes Modell finden Sie hier , trainiert mit dem Standardkorpus. Um es zu verwenden:
DeepQA/save/
save/model-pretrainedv2/dataset-cornell-old-lenght10-filter0-vocabSize0.pkl
nach data/samples/
../main.py --modelTag pretrainedv2 --test interactive
aus. Dank Nicholas C. finden Sie hier (im Original) einige zusätzliche vorab trainierte Modelle (kompatibel mit TF 1.2) für verschiedene Datensätze. Der Ordner enthält auch den vorverarbeiteten Datensatz für Cornell, OpenSubtitles, Ubuntu und Scotus (zum Verschieben in data/samples/
). Diese sind erforderlich, wenn Sie die Datensätze nicht selbst verarbeiten möchten.
Wenn Sie über eine High-End-GPU verfügen, zögern Sie nicht, mit den Hyperparametern/dem Korpus herumzuspielen, um ein besseres Modell zu trainieren. Aus meinen Experimenten geht hervor, dass die Lernrate und die Abbrecherquote den größten Einfluss auf die Ergebnisse haben. Auch wenn Sie Ihre Modelle teilen möchten, zögern Sie nicht, mich zu kontaktieren und ich werde sie hier hinzufügen.
Neben dem Versuch, ein größeres/tieferes Modell auszuprobieren, gibt es viele kleine Verbesserungen, die getestet werden könnten. Zögern Sie nicht, eine Pull-Anfrage zu senden, wenn Sie eine davon implementieren. Hier sind einige Ideen:
loop_function
von tf.nn.seq2seq.rnn_decoder
sollte das Hinzufügen nicht allzu schwierig sein. Danach sollte es möglich sein, mit der SoftMax-Temperatur zu spielen, um konservativere oder exotischere Vorhersagen zu erhalten.model.py
embedding_rnn_seq2seq
durch embedding_attention_seq2seq
ersetzen.Q:Sentence 1. Sentence 2. => A:Sentence X. Sentence Y.
wir könnten 3 generieren neue Beispiele: Q:Sentence 1. Sentence 2. => A:Sentence X.
, Q:Sentence 2. => A:Sentence X. Sentence Y.
und Q:Sentence 2. => A:Sentence X.
. Warnung: Andere 2 => X
wie Q:Sentence 1. => A:Sentence X.
Antwort)
und
hinzugefügt werden, damit der Encoder weiß, wann sich der Gesprächspartner ändert. Ich bin mir jedoch nicht sicher, ob das einfache seq2seq-Modell ausreichen würde, um langfristige Abhängigkeiten zwischen Sätzen zu erfassen. Das Hinzufügen eines Bucket-Systems zur Gruppierung ähnlicher Eingabelängen könnte die Trainingsgeschwindigkeit erheblich verbessern.