Dies ist eine Geschichte, auf die ich gestoßen bin, als ich zum ersten Mal maschinelles Lernen für die Verarbeitung natürlicher Sprache ausprobiert habe. Schreiben Sie den Prozess bis zur Produktion auf. Zum Zeitpunkt der Veröffentlichung des Artikels funktionierte es nicht gut, daher war es nur ein Lehrer. Wenn Sie wissen möchten, wie es gut geht, lesen Sie bitte hier.
Es wird ein Artikel eines solchen Auszubildenden zum Papieringenieur sein. Wenn Sie der Meinung sind, dass dies nicht sehr hilfreich ist, empfehlen wir den Browser zurück.
Ursprünglich berührte ich das maschinelle Lernen selbst. Da ich jedoch keine Erfahrung in der Verarbeitung natürlicher Sprache habe, habe ich mich entschlossen, vorerst Informationen und Wissen zu sammeln.
Das erste, worauf ich mich einließ, war, dass Googles BERT unglaublich war. Also habe ich die Struktur und den Lernmechanismus untersucht, aber es war in einem vollständig "??????" - Zustand.
Wie auch immer, BERT scheint erstaunlich zu sein. Dann habe ich beschlossen, etwas daraus zu machen und einen Chatbot zu machen.
Ich habe auch überlegt, das spätere XLNet und ALBERT zu verwenden. Es gab jedoch nichts, einschließlich BERT, das für mich leicht modifiziert werden konnte.
Insbesondere das von Google inoffiziell bereitgestellte BERT-Repository von Github und die Satzklassifizierung schienen einfach zu sein, aber es schien eine große Hürde zu sein, andere Aufgaben zu erledigen, die unerwartet zu sein schienen. Deshalb habe ich nach einer anderen Maßnahme gesucht.
Nachdem Sie verschiedene Dinge überprüft haben, Personen, die Japanisch-Englisch mit Transformator übersetzen und [Personen, die Chatbots mit Transformator erstellen] ](Https://sekailab.com/wp/2019/03/27/transformer-general-responce-bot/).
Warum dann nicht versuchen, einen Chatbot mit einem Transformator zu erstellen? Ich kam auf die Idee und beschloss, sie in die Praxis umzusetzen.
Klicken Sie hier für die diesmal verwendeten Materialien
Fahren wir fort mit der Vorgehensweise. Dieses Mal wird es in Google Colab ausgeführt, daher wird davon ausgegangen, dass es im Notebook-Format vorliegt. Klicken Sie hier für den vollständigen Code (https://github.com/NJIMAMTO/transformer-chat-bot/blob/master/transformer.ipynb)
Zuerst von der Installation des Installationsprogramms
!pip install keras-transformer
Installieren Sie als Nächstes das Satzstück, das als Sprecher verwendet werden soll
!pip install sentencepiece
Mounten Sie Google Drive hier (wie es geht)
Laden Sie als Nächstes den Korpus herunter und formen Sie ihn.
!git clone https://github.com/knok/make-meidai-dialogue.git
Wechseln Sie in das Verzeichnis, in dem sich das Repository befindet.
cd "/content/drive/My Drive/Colab Notebooks/make-meidai-dialogue"
Führen Sie das Makefile aus
!make all
Sie kehren zum ursprünglichen Verzeichnis zurück.
cd "/content/drive/My Drive/Colab Notebooks"
Wenn Sie den Korpus herunterladen und das Makefile ausführen, wird die Datei sequence.txt generiert. In diesem input:~~~~ output:~~~~ Da der Konversationssatz im Format von geschrieben ist, werden wir ihn so formatieren, dass er in Zukunft einfacher zu verwenden ist.
input_corpus = []
output_corpus = []
for_spm_corpus = []
with open('/content/drive/My Drive/Colab Notebooks/make-meidai-dialogue/sequence.txt') as f:
for s_line in f:
if s_line.startswith('input: '):
input_corpus.append(s_line[6:])
for_spm_corpus.append(s_line[6:])
elif s_line.startswith('output: '):
output_corpus.append(s_line[7:])
for_spm_corpus.append(s_line[7:])
with open('/content/drive/My Drive/Colab Notebooks/input_corpus.txt', 'w') as f:
f.writelines(input_corpus)
with open('/content/drive/My Drive/Colab Notebooks/output_corpus.txt', 'w') as f:
f.writelines(output_corpus)
with open('/content/drive/My Drive/Colab Notebooks/spm_corpus.txt', 'w') as f:
f.writelines(for_spm_corpus)
Es ist unterteilt in einen Text für die Eingabe in den Transformator und einen Text für die Ausgabe sowie einen Text für das Lernen mit der Eingabe: und Ausgabe: Teile, die für das Training im Satzstück entfernt wurden.
Verwenden Sie als Nächstes das Satzstück, um die Konversation zu teilen. Lassen Sie uns mit spm_corpus.txt trainieren.
import sentencepiece as spm
# train sentence piece
spm.SentencePieceTrainer.Train("--input=spm_corpus.txt --model_prefix=trained_model --vocab_size=8000 --bos_id=1 --eos_id=2 --pad_id=0 --unk_id=5")
Details werden weggelassen, da die Methode im offiziellen Repository des Satzstücks beschrieben ist.
Schreiben wir den Satz einmal mit dem Satzstück.
sp = spm.SentencePieceProcessor()
sp.Load("trained_model.model")
#test
print(sp.EncodeAsPieces("Oh, das stimmt"))
print(sp.EncodeAsPieces("Aha"))
print(sp.EncodeAsPieces("Was meinst du damit?"))
print(sp.DecodeIds([0,1,2,3,4,5]))
Dies ist das Ausführungsergebnis.
['Oh oh', 'Derartiges', 'Hallo']
['Aha', 'gut']
['▁', 'Mit anderen Worten', '、', 'Das', 'Sie', 'von', 'sagen', 'Wollen', 'Das ist', 'Derartiges', 'Ist es', '?']
、。 ⁇
Es stellt sich heraus, dass es wie oben unterteilt ist.
Der Inhalt von hier ist eine teilweise Änderung des Inhalts, der in README.md von Keras Transformer geschrieben wurde.
Lassen Sie uns nun den Korpus in ein Format formen, das für Polsterung und Transformatoren geeignet ist.
import numpy as np
# Generate toy data
encoder_inputs_no_padding = []
encoder_inputs, decoder_inputs, decoder_outputs = [], [], []
max_token_size = 168
with open('/content/drive/My Drive/Colab Notebooks/input_corpus.txt') as input_tokens, open('/content/drive/My Drive/Colab Notebooks/output_corpus.txt') as output_tokens:
#Lesen Sie Zeile für Zeile aus dem Korpus
input_tokens = input_tokens.readlines()
output_tokens = output_tokens.readlines()
for input_token, output_token in zip(input_tokens, output_tokens):
if input_token or output_token:
encode_tokens, decode_tokens = sp.EncodeAsPieces(input_token), sp.EncodeAsPieces(output_token)
#Polsterung
encode_tokens = ['<s>'] + encode_tokens + ['</s>'] + ['<pad>'] * (max_token_size - len(encode_tokens))
output_tokens = decode_tokens + ['</s>', '<pad>'] + ['<pad>'] * (max_token_size - len(decode_tokens))
decode_tokens = ['<s>'] + decode_tokens + ['</s>'] + ['<pad>'] * (max_token_size - len(decode_tokens))
encode_tokens = list(map(lambda x: sp.piece_to_id(x), encode_tokens))
decode_tokens = list(map(lambda x: sp.piece_to_id(x), decode_tokens))
output_tokens = list(map(lambda x: [sp.piece_to_id(x)], output_tokens))
encoder_inputs_no_padding.append(input_token)
encoder_inputs.append(encode_tokens)
decoder_inputs.append(decode_tokens)
decoder_outputs.append(output_tokens)
else:
break
#Zur Eingabe in das Trainingsmodell konvertieren
X = [np.asarray(encoder_inputs), np.asarray(decoder_inputs)]
Y = np.asarray(decoder_outputs)
Jetzt trainieren wir den Transformator.
from keras_transformer import get_model
# Build the model
model = get_model(
token_num=sp.GetPieceSize(),
embed_dim=32,
encoder_num=2,
decoder_num=2,
head_num=4,
hidden_dim=128,
dropout_rate=0.05,
use_same_embed=True, # Use different embeddings for different languages
)
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
)
model.summary()
# Train the model
model.fit(
x=X,
y=Y,
epochs=10,
batch_size=32,
)
Dies ist das Ausführungsergebnis.
Epoch 1/10
33361/33361 [==============================] - 68s 2ms/step - loss: 0.2818
Epoch 2/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2410
Epoch 3/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2331
Epoch 4/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2274
Epoch 5/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2230
Epoch 6/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2193
Epoch 7/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2163
Epoch 8/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2137
Epoch 9/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2114
Epoch 10/10
33361/33361 [==============================] - 66s 2ms/step - loss: 0.2094
Der Verlust sieht nicht schlecht aus.
Lassen Sie uns einen Rückschluss auf das trainierte Modell ziehen.
from keras_transformer import decode
input = "Das Wetter ist heute gut, nicht wahr?"
encode = sp.EncodeAsIds(input)
decoded = decode(
model,
encode,
start_token=sp.bos_id(),
end_token=sp.eos_id(),
pad_token=sp.pad_id(),
max_len=170
)
decoded = np.array(decoded,dtype=int)
decoded = decoded.tolist()
print(sp.decode(decoded))
Dies ist das Ausführungsergebnis.
Hey, aber das, das, das, das, das, das, das, das, das, das, das
Das ... das Ergebnis ist überhaupt nicht gut. Dies ist ein kommunikatives Hindernis.
Was war die Ursache des Fehlers?
Kann zuerst gegeben werden?
Also habe ich versucht, mich mit Optuna abzustimmen, aber es hat aus folgenden Gründen nicht funktioniert:
Also habe ich beschlossen, eine andere Methode auszuprobieren. Die Methode, die funktioniert hat, ist hier
Recommended Posts