Genshi Yonezu verkauft jedes Mal, wenn er komponiert. Die Texte, die herausgesponnen werden, scheinen die Kraft zu haben, Menschen zu faszinieren. Dieses Mal beschloss ich, tiefes Lernen seinen Charme lernen zu lassen.
Dieser Artikel ist "** Implementierung **". Im vorherigen Artikel finden Sie den Code "Vorverarbeitung". Der allgemeine Ablauf der Implementierung ist wie folgt.
Rahmen: Pytorch Modell: seq2seq mit Aufmerksamkeit Morphologisches Analysemodul: Jonome Umgebung: Google Colaboratory
Informationen zum Mechanismus von seq2seq und Attention finden Sie unter Vorheriger Artikel.
Das schematische Diagramm dieses Modells ist wie folgt. Referenzartikel
Hier ist SOS "_".
Nach dem Hochladen des erforderlichen selbst erstellten Moduls in Google Colab Kopieren Sie die später beschriebene main.py und führen Sie sie aus.
** Erforderliches selbst erstelltes Modul **
Den Code dieser selbst erstellten Module finden Sie unter github.
Wie unten gezeigt, sagt Genji Yonezu die "nächste Passage" aus der "einen Passage" der bisher veröffentlichten Songs voraus.
|Eingabetext|Text ausgeben| |-------+-------| |Ich freue mich sehr, dich zu sehen| _Alle sind selbstverständlich traurig| |Alle sind selbstverständlich traurig| _Ich habe jetzt schmerzlich glückliche Erinnerungen| |Ich habe jetzt schmerzlich glückliche Erinnerungen| _Erhebe dich und gehe zum Abschied, der eines Tages kommen wird| |Erhebe dich und gehe zum Abschied, der eines Tages kommen wird| _Es reicht aus, jemanden einzunehmen und zu leben|
Dies wurde durch Scraping von Lyrics Net erstellt.
Hier ist eine Ergänzung zum vorherigen Inhalt. Letztes Mal war mein Ziel, "Eingabetext" und "Ausgabetext" zu erstellen, die auf Japanisch waren, aber in Wirklichkeit werden sie mit "yonedu_dataset.prepare ()" identifiziert (quantifiziert), damit DL gelesen werden kann. Ich werde.
Der Parameter ** hyper ** wird von oben wie folgt angegeben.
Das ** Modell ** ist seq2seq, daher teilt es seine Rolle in einen Codierer und einen Decodierer auf.
encoder: embedding layer + hidden layer with LSTM decoder with attention: embedding layer + hidden layer with LSTM + attention system + softmax layer
Die ** Verlustfunktion ** verwendet die Kreuzentropiefehlerfunktion, und die ** Optimierungsmethode ** verwendet Adam sowohl für den Codierer als auch für den Decodierer.
Wenn ein Modellparameter vorhanden ist, wird dieser geladen.
from datasets import LyricDataset
import torch
import torch.optim as optim
from modules import *
from device import device
from utils import *
from dataloaders import SeqDataLoader
import math
import os
from utils
==========================================
# Datenaufbereitung
==========================================
# Pfad Genshi Yonezu_lyrics.txt
file_path = "lyric / Genshi Yonezu_lyrics.txt"
editierter_Dateipfad = "lyric / Genshi Yonezu_lyrics_edit.txt"
yonedu_dataset = LyricDataset(file_path, edited_file_path)
yonedu_dataset.prepare()
check
print(yonedu_dataset[0])
# In Zug teilen und um 8: 2 testen
train_rate = 0.8
data_num = len(yonedu_dataset)
train_set = yonedu_dataset[:math.floor(data_num * train_rate)]
test_set = yonedu_dataset[math.floor(data_num * train_rate):]
# Soweit letztes Mal
================================================
# Hyperparametereinstellung / Modell / Verlustfunktion / Optimierungsmethode
================================================
# Hyperparameter
embedding_dim = 200
hidden_dim = 128
BATCH_NUM = 100
EPOCH_NUM = 100
vocab_size = len (yonedu_dataset.word2id) #Anzahl des Wortschatzes
padding_idx = yonedu_dataset.word2id [""] # Leere ID
# Modell-
encoder = Encoder(vocab_size, embedding_dim, hidden_dim, padding_idx).to(device)
attn_decoder = AttentionDecoder(vocab_size, embedding_dim, hidden_dim, BATCH_NUM, padding_idx).to(device)
# Verlustfunktion
criterion = nn.CrossEntropyLoss()
# Optimierungsmethode
encoder_optimizer = optim.Adam(encoder.parameters(), lr=0.001)
attn_decoder_optimizer = optim.Adam(attn_decoder.parameters(), lr=0.001)
# Laden Sie Parameter, wenn Sie ein trainiertes Modell haben
encoder_weights_path = "yonedsu_lyric_encoder.pth"
decoder_weights_path = "yonedsu_lyric_decoder.pth"
if os.path.exists(encoder_weights_path):
encoder.load_state_dict(torch.load(encoder_weights_path))
if os.path.exists(decoder_weights_path):
attn_decoder.load_state_dict(torch.load(decoder_weights_path))
Als nächstes kommt der Lerncode. Ich denke, dass seq2seq mit Aufmerksamkeit so aussehen wird, aber ich werde nur einen Punkt hinzufügen. Mit ** meinem eigenen Datenlader ** erhalte ich einen Mini-Batch für 100 Batch-Größen für jede Epoche, propagiere den Gesamtverlust in diesen Daten zurück, erhalte den Gradienten und aktualisiere die Parameter.
Informationen zum ** selbst erstellten Datenlader ** finden Sie in Yasuki Saitos Quellcode für Deep Learning 3 von Grund auf neu. Ich mache es.
================================================
# Lernen
================================================
all_losses = []
print("training ...")
for epoch in range(1, EPOCH_NUM+1):
epoch_loss = 0
# Teilen Sie die Daten in Mini-Batch
dataloader = SeqDataLoader(train_set, batch_size=BATCH_NUM, shuffle=False)
for train_x, train_y in dataloader:
#Initialisierung des Gradienten
encoder_optimizer.zero_grad()
attn_decoder_optimizer.zero_grad()
#Encoder Forward Propagation
hs, h = encoder(train_x)
# Achtung Decoder Eingang
source = train_y[:, :-1]
Richtige Antwortdaten von # Attention Decoder
target = train_y[:, 1:]
loss = 0
decoder_output, _, attention_weight = attn_decoder(source, hs, h)
for j in range(decoder_output.size()[1]):
loss += criterion(decoder_output[:, j, :], target[:, j])
epoch_loss += loss.item()
# Fehler bei der Weitergabe
loss.backward()
# Parameteraktualisierung
encoder_optimizer.step()
attn_decoder_optimizer.step()
# Verlust anzeigen
print("Epoch %d: %.2f" % (epoch, epoch_loss))
all_losses.append(epoch_loss)
if epoch_loss < 0.1: break
print("Done")
import matplotlib.pyplot as plt
plt.plot(all_losses)
plt.savefig("attn_loss.png ")
# Modell speichern
torch.save(encoder.state_dict(), encoder_weights_path)
torch.save(attn_decoder.state_dict(), decoder_weights_path)
Hier ist der Testcode. Ich erstelle die in ** [Ergebnisse] ** gezeigte Tabelle. Es gibt zwei Punkte zu beachten.
=======================================
# Prüfung
=======================================
# Word-> ID-Konvertierungswörterbuch
word2id = yonedu_dataset.word2id
# ID-> Wortkonvertierungswörterbuch
id2word = get_id2word(word2id)
# Anzahl der Elemente in einer richtigen Antwortdaten
output_len = len(yonedu_dataset[0][1])
# Bewertungsdaten
test_dataloader = SeqDataLoader(test_set, batch_size=BATCH_NUM, shuffle=False)
# Datenrahmen zur Anzeige des Ergebnisses
df = pd.DataFrame(None, columns=["input", "answer", "predict", "judge"])
# Drehen Sie den Datenlader, um den Datenrahmen zu füllen, in dem die Ergebnisse angezeigt werden
for test_x, test_y in test_dataloader:
with torch.no_grad():
hs, encoder_state = encoder(test_x)
Zunächst wird "_", das den Beginn der Zeichenfolgengenerierung angibt, in # Decoder eingegeben
# Erstellen Sie den Tensor "_" für die Stapelgröße
start_char_batch = [[word2id["_"]] for _ in range(BATCH_NUM)]
decoder_input_tensor = torch.tensor(start_char_batch, device=device)
decoder_hidden = encoder_state
batch_tmp = torch.zeros(100,1, dtype=torch.long, device=device)
for _ in range(output_len - 1):
decoder_output, decoder_hidden, _ = attn_decoder(decoder_input_tensor, hs, decoder_hidden)
# Während das vorhergesagte Zeichen abgerufen wird, wird es so wie es ist die Eingabe des nächsten Decoders
decoder_input_tensor = get_max_index(decoder_output.squeeze(), BATCH_NUM)
batch_tmp = torch.cat([batch_tmp, decoder_input_tensor], dim=1)
predicts = batch_tmp [:, 1:] # Empfangen Sie vorhergesagte Stapel
if test_dataloader.reverse:
test_x = [Liste (Zeile) [:: -1] für Zeile in test_x] # Die invertierte Zeile zurückgeben
df = predict2df(test_x, test_y, predicts, df)
df.to_csv("predict_yonedsu_lyric.csv", index=False)
Alle Fragen sind falsch. Dieses Mal war das Ziel jedoch "** Erfassung der Eigenschaften der Texte von Herrn Genji Yonezu **". Ein Teil der Tabelle ist ein Auszug.
** Eingabe **: Text eingeben ** Ausgabe **: Korrigieren Sie den Ausgabetext ** vorhersagen **: DL vorhergesagter Text ** Richter **: Stimmen Ausgabe und Vorhersage überein?
input | output | predict | judge ---------+----------------+----------------+------------ Es war mir egal, ob es ein Fehler oder eine richtige Antwort war|In dem blassen Dunst, der in einem Augenblick fiel|Ich bin traurig, weil ich geliebt werden möchte, also bist du vielleicht der einzige|X Ich hatte das Gefühl, dass sich seit diesem Tag alles geändert hatte|Lass dich nicht vom Wind umhauen, einer tiefen Frühlingsecke|Der warme Ort ist immer noch schön|X Lassen Sie uns eins nach dem anderen herausfinden|Wie ein Weckkind|Verwelktes Blau, sogar diese Farbe|X Egal was du heute machst|ich werde nach dir suchen|Ich suchte nach einer Stadt, die sich nicht ändern würde|X
Da diesmal kein Überlernen festgestellt wurde, wird angenommen, dass die Ursache für den Mangel an Lernen hauptsächlich in der geringen Anzahl von Daten liegt. Nein, wir sind die einzigen, die entschieden haben, dass sie "nicht ausreichend lernen", und sie denken möglicherweise auf ihre eigene Weise ...
Recommended Posts