Ich lese ein Meisterwerk, ** "Deep Learning from Zero 2" **. Diesmal ist ein Memo von Kapitel 7. Um den Code auszuführen, laden Sie den gesamten Code von Github herunter und verwenden Sie das Jupiter-Notizbuch in Kapitel 07.
Lassen Sie uns zuerst den Code rnnlm_gen.py
ausführen, der die in train_rnnlm.py
in Kapitel 6 gelernte Gewichtsdatei ** Rnnlm.pkl ** liest und Sätze generiert.
import sys
sys.path.append('..')
from rnnlm_gen import RnnlmGen
from dataset import ptb
#PTB-Datensatz lesen
corpus, word_to_id, id_to_word = ptb.load_data('train')
vocab_size = len(word_to_id)
corpus_size = len(corpus)
model = RnnlmGen() #Modellgenerierung
model.load_params('../ch06/Rnnlm.pkl') #Gelernte Gewichte laden
#Start- und Sprungzeichen setzen
start_word = 'you'
start_id = word_to_id[start_word]
skip_words = ['N', '<unk>', '$']
skip_ids = [word_to_id[w] for w in skip_words]
#Satzerzeugung
word_ids = model.generate(start_id, skip_ids)
txt = ' '.join([id_to_word[i] for i in word_ids])
txt = txt.replace(' <eos>', '.\n')
print(txt)
Irgendwie wurde so ein englischer Satz erzeugt. Die Theorie ist einfach: Nachdem Sie das erste Wort festgelegt haben, sagen Sie das nächste Wort und dann das nächste Wort basierend auf dem Vorhersageergebnis voraus und so weiter. Der Punkt ist "RnnlmGen ()", der in der Modellgenerierung erscheint. Schauen wir uns das an.
3.class RnnlmGen
Sie können eine satzgenerierende Klasse von Grund auf neu erstellen, aber es ist einfacher, der Klasse Rnnlm
, die Sie beim Erlernen von Kapitel 6 verwendet haben, Funktionen hinzuzufügen.
Durch Deklarieren von "Klasse RnnlmGen (Rnnlm):" am Anfang des Codes, wie unten gezeigt, werden alle Methoden, die sich in "Klasse Rnnlm" befanden, in "Klasse RnnlmGen" integriert. Dies nennt man ** "Vererbung" **.
class RnnlmGen(Rnnlm):
def generate(self, start_id, skip_ids=None, sample_size=100):
word_ids = [start_id]
x = start_id #Geben Sie die Wort-ID für die Satzgenerierung an
# word_IDs ist Beispiel_Fahren Sie fort, bis die Größe erreicht ist
while len(word_ids) < sample_size:
x = np.array(x).reshape(1, 1) #In einem zweidimensionalen Array(Mini-Batch-Unterstützung)
score = self.predict(x) #Erhalten Sie Vorhersageergebnisse
p = softmax(score.flatten()) #Normalisieren Sie die Wahrscheinlichkeitsverteilung mit Softmax
#10000 in der Länge, 1 in der Größe, zufällige Auswahl gemäß der Wahrscheinlichkeitsverteilung von p
sampled = np.random.choice(len(p), size=1, p=p)
# skip_Fehlende IDs oder abgetastete Wörter werden übersprungen_Nicht in Ausweisen
if (skip_ids is None) or (sampled not in skip_ids):
x = sampled
word_ids.append(int(x)) # word_An IDs anhängen
return word_ids
def get_state(self):
return self.lstm_layer.h, self.lstm_layer.c
def set_state(self, state):
self.lstm_layer.set_state(*state)
Hier sind die Methoden zum Hinzufügen zu class Rnnlm
. Wenn Sie "vorhersagen (x)" verwenden, um das Auftreten des Wortes nach x vorherzusagen und es mit "softmax" zu normalisieren, erhalten Sie eine Wahrscheinlichkeitsverteilung p für die Anzahl der Vokabeln.
sampled = np.random.choice (len (p), size = 1, p = p)
ist eins von ** 0 bis zu einer ganzen Zahl ** mit der Anzahl der Vokabeln -1, was bedeutet, dass eine Zufallsstichprobe gemäß der Wahrscheinlichkeitsverteilung p durchgeführt wird. Wird sein.
Übrigens, wenn Sie sich class Rnnlm
ansehen,
class Rnnlm(BaseModel):
def __init__(self, vocab_size=10000, wordvec_size=100, hidden_size=100):
V, D, H = vocab_size, wordvec_size, hidden_size
rn = np.random.randn
#Gewichtsinitialisierung
embed_W = (rn(V, D) / 100).astype('f')
lstm_Wx = (rn(D, 4 * H) / np.sqrt(D)).astype('f')
lstm_Wh = (rn(H, 4 * H) / np.sqrt(H)).astype('f')
lstm_b = np.zeros(4 * H).astype('f')
affine_W = (rn(H, V) / np.sqrt(H)).astype('f')
affine_b = np.zeros(V).astype('f')
#Schichterzeugung
self.layers = [
TimeEmbedding(embed_W),
TimeLSTM(lstm_Wx, lstm_Wh, lstm_b, stateful=True),
TimeAffine(affine_W, affine_b)
]
self.loss_layer = TimeSoftmaxWithLoss()
self.lstm_layer = self.layers[1]
#Listen Sie alle Gewichte und Verläufe auf
self.params, self.grads = [], []
for layer in self.layers:
self.params += layer.params
self.grads += layer.grads
def predict(self, xs):
for layer in self.layers:
xs = layer.forward(xs)
return xs
def forward(self, xs, ts):
score = self.predict(xs)
loss = self.loss_layer.forward(score, ts)
return loss
def backward(self, dout=1):
dout = self.loss_layer.backward(dout)
for layer in reversed(self.layers):
dout = layer.backward(dout)
return dout
def reset_state(self):
self.lstm_layer.reset_state()
Das ist der Inhalt. Dieses Mal "erben" wir diese Klasse, daher werden diese Methoden automatisch in die Klasse RnnlmGen integriert. Das ist praktisch, nicht wahr?
Ich kann nicht wirklich spüren, dass die englische Satzgenerierung gut funktioniert, also werde ich es auch auf Japanisch versuchen. Die Vorhersagemethode ist jedoch ** Zeicheneinheit ** anstelle der Worteinheit.
Diesmal von Aozora Bunko, Soseki Natsumes "Ich bin eine Katze" ** Textdatei (mit Rubin) ** Herunterladen und verwenden. Entpacken Sie es nach dem Herunterladen und speichern Sie es auf ch07 unter dem Namen ** wagahaiwa_nekodearu.txt **.
import sys
import re
path = './wagahaiwa_nekodearu.txt'
bindata = open(path, "rb")
lines = bindata.readlines()
for line in lines:
text = line.decode('Shift_JIS') # Shift_Gelesen von JIS
text = re.split(r'\r',text)[0] #Zeilenumbrüche löschen
text = text.replace('|','') #Ruby gelöscht
text = re.sub(r'《.+?》','',text) #Ruby gelöscht
text = re.sub(r'[#.+?]','',text) #Eintragsnotiz gelöscht
print(text)
file = open('data_neko.txt','a',encoding='utf-8').write(text) # UTF-In 8 konvertieren
Code für die Vorverarbeitung. Bei der Ausführung wird es im Textdateiformat (Shift-JIS) gelesen, die Zeilenumbrüche, Rubine, Inputter-Notizen usw. werden gelöscht, dann in UTF-8 konvertiert und als ** data_neko.txt ** gespeichert. Verwenden Sie dann den Editor, um die zusätzlichen Teile vor und nach dem Satz manuell zu entfernen.
Definieren Sie als Nächstes eine Funktion load_data ()
, die den Korpus word_to_id, id_to_word aus data_neko.txt abruft.
import numpy as np
import io
def load_data():
# file_Name zu UTF-Lesen Sie in Text im 8-Format
file_name = './data_neko.txt'
with io.open(file_name, encoding='utf-8') as f:
text = f.read().lower()
# word_to_id, id_to_Wort erstellen
word_to_id, id_to_word = {}, {}
for word in text:
if word not in word_to_id:
new_id = len(word_to_id)
word_to_id[word] = new_id
id_to_word[new_id] = word
#Korpus erstellen
corpus = np.array([word_to_id[W] for W in text])
corpus_test = corpus[300000:] #Testdaten
corpus = corpus[:300000] #Trainingsdaten
return corpus_test, corpus, word_to_id, id_to_word
Da der gesamte ** Korpus **, der dieses Mal erstellt wurde, 318.800 Wörter beträgt, werden 18.800 Wörter nach 300.000 Wörtern als ** Korpustest ** und die vorherigen 300.000 Wörter als ** Korpus ** bezeichnet.
Lassen Sie uns nun den in ch06 verwendeten Lerncode mit der GPU ausführen.
import sys
sys.path.append('..')
from common import config
#Wenn Sie mit einer GPU arbeiten, löschen Sie den folgenden Kommentar (Cupy erforderlich).
# ==============================================
config.GPU = True
# ==============================================
from common.optimizer import SGD
from common.trainer import RnnlmTrainer
from common.util import eval_perplexity, to_gpu
from dataset import ptb
from ch06.better_rnnlm import BetterRnnlm
#Hyper-Parametereinstellungen
batch_size = 20
wordvec_size = 650
hidden_size = 650
time_size = 35
lr = 20.0
max_epoch = 40
max_grad = 0.25
dropout = 0.5
#Trainingsdaten lesen
corpus_test, corpus, word_to_id, id_to_word = load_data()
corpus_val = corpus_test #Der Einfachheit halber sind val und test gleich
if config.GPU:
corpus = to_gpu(corpus)
corpus_val = to_gpu(corpus_val)
corpus_test = to_gpu(corpus_test)
vocab_size = len(word_to_id)
xs = corpus[:-1]
ts = corpus[1:]
model = BetterRnnlm(vocab_size, wordvec_size, hidden_size, dropout)
optimizer = SGD(lr)
trainer = RnnlmTrainer(model, optimizer)
best_ppl = float('inf')
for epoch in range(max_epoch):
trainer.fit(xs, ts, max_epoch=1, batch_size=batch_size,
time_size=time_size, max_grad=max_grad)
model.reset_state()
ppl = eval_perplexity(model, corpus_val)
print('valid perplexity: ', ppl)
if best_ppl > ppl:
best_ppl = ppl
model.save_params()
else:
lr /= 4.0
optimizer.lr = lr
model.reset_state()
print('-' * 50)
#Auswertung mit Testdaten
model.reset_state()
ppl_test = eval_perplexity(model, corpus_test)
print('test perplexity: ', ppl_test)
Das Lernen wurde mit der Windows-Maschine (GTX1060) in ca. 40 Minuten abgeschlossen. Wenn Sie fertig sind, werden die trainierten Gewichtsparameter im Ordner ch07 als ** BetterRnnlm.pkl ** gespeichert.
6.class BetterRnnlmGen
Definieren Sie als Nächstes class BetterRnnlmGen
. Grundsätzlich erbt es die Klasse BetterRnnlm
von Kapitel 6, aber die ** Vokalgröße ** von " Ich bin eine Katze " unterscheidet sich von ** PTB **, so dass die verwandtedef __init___ Fügen Sie den Teil ()
hinzu und überschreiben Sie ihn (dies wird als ** Überschreiben ** bezeichnet).
import sys
sys.path.append('..')
import numpy as np
from common.functions import softmax
from ch06.rnnlm import Rnnlm
from ch06.better_rnnlm import BetterRnnlm
from common.time_layers import * # def __init__Importieren Sie die erforderlichen Dateien mit
class BetterRnnlmGen(BetterRnnlm):
def __init__(self, vocab_size=3038, wordvec_size=650,
hidden_size=650, dropout_ratio=0.5):
V, D, H = vocab_size, wordvec_size, hidden_size
rn = np.random.randn
embed_W = (rn(V, D) / 100).astype('f')
lstm_Wx1 = (rn(D, 4 * H) / np.sqrt(D)).astype('f')
lstm_Wh1 = (rn(H, 4 * H) / np.sqrt(H)).astype('f')
lstm_b1 = np.zeros(4 * H).astype('f')
lstm_Wx2 = (rn(H, 4 * H) / np.sqrt(H)).astype('f')
lstm_Wh2 = (rn(H, 4 * H) / np.sqrt(H)).astype('f')
lstm_b2 = np.zeros(4 * H).astype('f')
affine_b = np.zeros(V).astype('f')
self.layers = [
TimeEmbedding(embed_W),
TimeDropout(dropout_ratio),
TimeLSTM(lstm_Wx1, lstm_Wh1, lstm_b1, stateful=True),
TimeDropout(dropout_ratio),
TimeLSTM(lstm_Wx2, lstm_Wh2, lstm_b2, stateful=True),
TimeDropout(dropout_ratio),
TimeAffine(embed_W.T, affine_b) # weight tying!!
]
self.loss_layer = TimeSoftmaxWithLoss()
self.lstm_layers = [self.layers[2], self.layers[4]]
self.drop_layers = [self.layers[1], self.layers[3], self.layers[5]]
self.params, self.grads = [], []
for layer in self.layers:
self.params += layer.params
self.grads += layer.grads
def generate(self, start_id, skip_ids=None, sample_size=100):
word_ids = [start_id]
x = start_id
while len(word_ids) < sample_size:
x = np.array(x).reshape(1, 1)
score = self.predict(x).flatten()
p = softmax(score).flatten()
sampled = np.random.choice(len(p), size=1, p=p)
#sampled = np.argmax(p)
if (skip_ids is None) or (sampled not in skip_ids):
x = sampled
word_ids.append(int(x))
return word_ids
def get_state(self):
states = []
for layer in self.lstm_layers:
states.append((layer.h, layer.c))
return states
def set_state(self, states):
for layer, state in zip(self.lstm_layers, states):
layer.set_state(*state)
Führen Sie abschließend den folgenden Code aus, der Sätze generiert.
import sys
sys.path.append('..')
from common.np import *
corpus_test, corpus, word_to_id, id_to_word = load_data()
vocab_size = len(word_to_id)
corpus_size = len(corpus)
model = BetterRnnlmGen()
model.load_params('./BetterRnnlm.pkl')
#Start- und Sprungzeichen setzen
start_word = 'ich'
start_id = word_to_id[start_word]
skip_words = ['〇']
skip_ids = [word_to_id[w] for w in skip_words]
#Satzerzeugung(Vom ersten Wort an)
word_ids = model.generate(start_id, skip_ids)
txt = ''.join([id_to_word[i] for i in word_ids])
print(txt)
#Satzerzeugung(Aus dem Satz)
model.reset_state() #Modell zurücksetzen
start_words = 'Ich bin eine Katze.'
start_ids = [word_to_id[w] for w in start_words.split(' ')] #In Wort-ID konvertieren
#Vorhersage vor der letzten Wort-ID der Phrase(Verwenden Sie keine Vorhersageergebnisse)
for x in start_ids[:-1]:
x = np.array(x).reshape(1, 1)
model.predict(x)
word_ids = model.generate(start_ids[-1], skip_ids) #Vorhersage aus der letzten Wort-ID der Phrase
word_ids = start_ids[:-1] + word_ids #Verketten Sie Phrasen und Vorhersageergebnisse
txt = ''.join([id_to_word[i] for i in word_ids]) #In Satz umwandeln
print('-' * 50)
print(txt)
Es gibt zwei Muster der Satzerzeugung. Eine ist nach einem Wort vorherzusagen, und die andere ist nach einer Phrase vorherzusagen.
Ich verstehe die Bedeutung als Ganzes überhaupt nicht, aber wenn ich mir den Satz anschaue, denke ich, dass ich ihn nicht verstehe.
import sys
sys.path.append('..')
import numpy as np
import matplotlib.pyplot as plt
from dataset import sequence
from common.optimizer import Adam
from common.trainer import Trainer
from common.util import eval_seq2seq
from seq2seq import Seq2seq
from peeky_seq2seq import PeekySeq2seq
#Datensatz laden
(x_train, t_train), (x_test, t_test) = sequence.load_data('addition.txt')
char_to_id, id_to_char = sequence.get_vocab()
# Reverse input? =================================================
is_reverse = False # True
if is_reverse:
# [::-1]In umgekehrter Reihenfolge sortiert, weil es zweidimensional ist[:, ::-1]
x_train, x_test = x_train[:, ::-1], x_test[:, ::-1]
# ================================================================
#Hyper-Parametereinstellungen
vocab_size = len(char_to_id)
wordvec_size = 16
hidden_size = 128
batch_size = 128
max_epoch = 25
max_grad = 5.0
# Normal or Peeky? ==============================================
model = Seq2seq(vocab_size, wordvec_size, hidden_size)
# model = PeekySeq2seq(vocab_size, wordvec_size, hidden_size)
# ================================================================
optimizer = Adam()
trainer = Trainer(model, optimizer)
acc_list = []
for epoch in range(max_epoch):
trainer.fit(x_train, t_train, max_epoch=1,
batch_size=batch_size, max_grad=max_grad)
correct_num = 0
for i in range(len(x_test)):
question, correct = x_test[[i]], t_test[[i]]
verbose = i < 10
correct_num += eval_seq2seq(model, question, correct,
id_to_char, verbose, is_reverse)
acc = float(correct_num) / len(x_test)
acc_list.append(acc)
print('val acc %.3f%%' % (acc * 100))
#Zeichnen eines Diagramms
x = np.arange(len(acc_list))
plt.plot(x, acc_list, marker='o')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.ylim(0, 1.0)
plt.show()
Es ist ein nüchterner Code, der Sie an den Zusatz erinnert. Schauen wir uns zunächst die Klasse Seq2seq an.
9.class Seq2seq
class Seq2seq(BaseModel):
def __init__(self, vocab_size, wordvec_size, hidden_size):
V, D, H = vocab_size, wordvec_size, hidden_size
self.encoder = Encoder(V, D, H)
self.decoder = Decoder(V, D, H)
self.softmax = TimeSoftmaxWithLoss()
self.params = self.encoder.params + self.decoder.params
self.grads = self.encoder.grads + self.decoder.grads
def forward(self, xs, ts):
decoder_xs, decoder_ts = ts[:, :-1], ts[:, 1:]
h = self.encoder.forward(xs)
score = self.decoder.forward(decoder_xs, h)
loss = self.softmax.forward(score, decoder_ts)
return loss
def backward(self, dout=1):
dout = self.softmax.backward(dout)
dh = self.decoder.backward(dout)
dout = self.encoder.backward(dh)
return dout
def generate(self, xs, start_id, sample_size):
h = self.encoder.forward(xs)
sampled = self.decoder.generate(h, start_id, sample_size)
return sampled
Da wir nur die Klassen der Klasse Encoder und der Klasse Decoder kombinieren, schauen wir uns zunächst die Klasse Encoder an.
class Encoder:
def __init__(self, vocab_size, wordvec_size, hidden_size):
V, D, H = vocab_size, wordvec_size, hidden_size
rn = np.random.randn
embed_W = (rn(V, D) / 100).astype('f')
lstm_Wx = (rn(D, 4 * H) / np.sqrt(D)).astype('f')
lstm_Wh = (rn(H, 4 * H) / np.sqrt(H)).astype('f')
lstm_b = np.zeros(4 * H).astype('f')
self.embed = TimeEmbedding(embed_W)
self.lstm = TimeLSTM(lstm_Wx, lstm_Wh, lstm_b, stateful=False)
self.params = self.embed.params + self.lstm.params
self.grads = self.embed.grads + self.lstm.grads
self.hs = None
def forward(self, xs):
xs = self.embed.forward(xs)
hs = self.lstm.forward(xs)
self.hs = hs
return hs[:, -1, :]
def backward(self, dh):
dhs = np.zeros_like(self.hs)
dhs[:, -1, :] = dh
dout = self.lstm.backward(dhs)
dout = self.embed.backward(dout)
return dout
Es ist ein schematisches Diagramm von ** Encoder **. Die Trainingsdaten werden nacheinander eingegeben und die Ausgabe ** h ** des LSTM der Endstufe wird an den Decoder übergeben.
class Decoder:
def __init__(self, vocab_size, wordvec_size, hidden_size):
V, D, H = vocab_size, wordvec_size, hidden_size
rn = np.random.randn
embed_W = (rn(V, D) / 100).astype('f')
lstm_Wx = (rn(D, 4 * H) / np.sqrt(D)).astype('f')
lstm_Wh = (rn(H, 4 * H) / np.sqrt(H)).astype('f')
lstm_b = np.zeros(4 * H).astype('f')
affine_W = (rn(H, V) / np.sqrt(H)).astype('f')
affine_b = np.zeros(V).astype('f')
self.embed = TimeEmbedding(embed_W)
self.lstm = TimeLSTM(lstm_Wx, lstm_Wh, lstm_b, stateful=True)
self.affine = TimeAffine(affine_W, affine_b)
self.params, self.grads = [], []
for layer in (self.embed, self.lstm, self.affine):
self.params += layer.params
self.grads += layer.grads
def forward(self, xs, h):
self.lstm.set_state(h)
out = self.embed.forward(xs)
out = self.lstm.forward(out)
score = self.affine.forward(out)
return score
def backward(self, dscore):
dout = self.affine.backward(dscore)
dout = self.lstm.backward(dout)
dout = self.embed.backward(dout)
dh = self.lstm.dh
return dh
def generate(self, h, start_id, sample_size):
sampled = []
sample_id = start_id
self.lstm.set_state(h)
for _ in range(sample_size):
x = np.array(sample_id).reshape((1, 1))
out = self.embed.forward(x)
out = self.lstm.forward(out)
score = self.affine.forward(out)
sample_id = np.argmax(score.flatten())
sampled.append(int(sample_id))
return sampled
Es ist ein schematisches Diagramm von ** Decoder **. Der Decoder behandelt die Softmax with Loss-Ebene danach zwischen Lernen und Generieren unterschiedlich, sodass die Softmax with Loss-Ebene von der Seq2seq-Klasse unterstützt wird.
Das Invertieren der Eingabedaten beschleunigt den Lernprozess und verbessert die endgültige Genauigkeit. Führen Sie den Code des obigen Additionsmodells mit "is_reverse = True" aus. Nur durch Umkehren stieg die korrekte Antwortrate von 10% auf 50%. Je näher die Zeitverzögerung zwischen jedem Eingabeelement und seinem Ausgabeelement ist, desto besser ist die Genauigkeit. Das war's.
10.PeekyDecoder
Der vom Encoder ausgegebene Vektor h ist eine sehr wichtige Information, wird jedoch nur beim ersten Mal des Decoders eingegeben. Daher entsteht die Idee, die Informationen des Vektors h jederzeit in die LSTM-Schicht und die affine Schicht einzugeben. Diese Methode heißt ** Peeky **. Werfen wir einen Blick auf class PeekyDecoder
.
class PeekyDecoder:
def __init__(self, vocab_size, wordvec_size, hidden_size):
V, D, H = vocab_size, wordvec_size, hidden_size
rn = np.random.randn
embed_W = (rn(V, D) / 100).astype('f')
lstm_Wx = (rn(H + D, 4 * H) / np.sqrt(H + D)).astype('f')
lstm_Wh = (rn(H, 4 * H) / np.sqrt(H)).astype('f')
lstm_b = np.zeros(4 * H).astype('f')
affine_W = (rn(H + H, V) / np.sqrt(H + H)).astype('f')
affine_b = np.zeros(V).astype('f')
self.embed = TimeEmbedding(embed_W)
self.lstm = TimeLSTM(lstm_Wx, lstm_Wh, lstm_b, stateful=True)
self.affine = TimeAffine(affine_W, affine_b)
self.params, self.grads = [], []
for layer in (self.embed, self.lstm, self.affine):
self.params += layer.params
self.grads += layer.grads
self.cache = None
def forward(self, xs, h):
N, T = xs.shape
N, H = h.shape
self.lstm.set_state(h)
out = self.embed.forward(xs)
hs = np.repeat(h, T, axis=0).reshape(N, T, H)
out = np.concatenate((hs, out), axis=2)
out = self.lstm.forward(out)
out = np.concatenate((hs, out), axis=2)
score = self.affine.forward(out)
self.cache = H
return score
def backward(self, dscore):
H = self.cache
dout = self.affine.backward(dscore)
dout, dhs0 = dout[:, :, H:], dout[:, :, :H]
dout = self.lstm.backward(dout)
dembed, dhs1 = dout[:, :, H:], dout[:, :, :H]
self.embed.backward(dembed)
dhs = dhs0 + dhs1
dh = self.lstm.dh + np.sum(dhs, axis=1)
return dh
def generate(self, h, start_id, sample_size):
sampled = []
char_id = start_id
self.lstm.set_state(h)
H = h.shape[1]
peeky_h = h.reshape(1, 1, H)
for _ in range(sample_size):
x = np.array([char_id]).reshape((1, 1))
out = self.embed.forward(x)
out = np.concatenate((peeky_h, out), axis=2)
out = self.lstm.forward(out)
out = np.concatenate((peeky_h, out), axis=2)
score = self.affine.forward(out)
char_id = np.argmax(score.flatten())
sampled.append(char_id)
return sampled
Aktivieren Sie nun in der früheren Modellgenerierung des Additionsmodells "model = PeekySeq2seq (vocab_size, wordvec_size, hidden_size)" und führen Sie es aus.
Es ist ein dramatischer Effekt! Die korrekte Rücklaufquote betrug 99,1%.
Recommended Posts