Ich lese ein Meisterwerk, ** "Deep Learning from Zero 2" **. Diesmal ist ein Memo von Kapitel 3. Um den Code auszuführen, laden Sie den gesamten Code von Github herunter und verwenden Sie das Jupiter-Notizbuch in Kapitel 03.
Lassen Sie uns ein einfaches word2vec CBOW-Modell ausführen. Führen Sie ch03 / train.py aus.
import sys
sys.path.append('..') #Einstellungen zum Importieren von Dateien in das übergeordnete Verzeichnis
from common.trainer import Trainer
from common.optimizer import Adam
from simple_cbow import SimpleCBOW
from common.util import preprocess, create_contexts_target, convert_one_hot
window_size = 1
hidden_size = 5
batch_size = 3
max_epoch = 1000
#Holen Sie sich Korpus und Wörterbuch
text = 'You say goodbye and I say hello.'
corpus, word_to_id, id_to_word = preprocess(text)
#Holen Sie sich Kontext, Ziel
contexts, target = create_contexts_target(corpus, window_size)
#Ein heißer Ausdruck
vocab_size = len(word_to_id)
contexts = convert_one_hot(contexts, vocab_size)
target = convert_one_hot(target, vocab_size)
#Netzwerkaufbau
model = SimpleCBOW(vocab_size, hidden_size)
#Anzeige von Lern- und Verlustübergängen
optimizer = Adam()
trainer = Trainer(model, optimizer)
trainer.fit(contexts, target, max_epoch, batch_size)
trainer.plot()
#Vektoranzeige von Wörtern
word_vecs = model.word_vecs
for word_id, word in id_to_word.items():
print(word, word_vecs[word_id])
Es sind nur 7 Wörter word2vec, aber ich würde mich freuen, wenn der Verlust reibungslos abnimmt und ein 5-dimensionaler Vektor jedes Wortes erhalten werden kann. Schauen wir uns den Code der Reihe nach an.
#Holen Sie sich Korpus und Wörterbuch
text = 'You say goodbye and I say hello.'
corpus, word_to_id, id_to_word = preprocess(text)
preprocess ()
befindet sich in common / util.py, beziehen Sie sich also darauf.
# -------------- from common/util.py ---------------
def preprocess(text):
text = text.lower() #Von Groß- zu Kleinbuchstaben
text = text.replace('.', ' .') #Ein Leerzeichen vor dem Zeitraum
words = text.split(' ') #Listen Sie Wörter auf, die durch Leerzeichen getrennt sind
word_to_id = {}
id_to_word = {}
for word in words: #Von der Liste zum Wort Wort für Wort
if word not in word_to_id: #Das Wort ist Wort_to_Wenn nicht in id
new_id = len(word_to_id) # word_to_Setzen Sie die Anzahl der registrierten IDs auf id
word_to_id[word] = new_id # word_to_Registrierung der ID
id_to_word[new_id] = word # id_to_Wortregistrierung
corpus = np.array([word_to_id[w] for w in words]) #Korpus in ID konvertieren
return corpus, word_to_id, id_to_word
Teilen Sie den Text in Wörter auf, um einen Korpus zu erhalten. Erstellen Sie ein Wörterbuch (Wörter → Zahlen, Zahlen → Wörter) und verwenden Sie dieses Wörterbuch, um den Korpus durch die ID zu ersetzen. corpus = [0 1 2 3 4 1 5 6] word_to_id = {'you': 0, 'say': 1, 'goodbye': 2, 'and':3 , 'i': 4, 'hello': 5, '.': 6} id_to_word = {0 :'you', 1 :'say', 2 :'goodbye', 3 :'and', 4 :'i', 5 :'hello', 6 : '.'}
#Holen Sie sich Kontext und Ziel
contexts, target = create_contexts_target(corpus, window_size)
create_contexts_target ()
befindet sich in common / util.py, verweisen Sie also darauf.
# -------------- from common/util.py ---------------
def create_contexts_target(corpus, window_size=1):
#Ziel ist das Fenster vor und nach dem Korpus_Minusgröße
target = corpus[window_size:-window_size]
contexts = []
#Lassen Sie die Kontexte t Minuten vor und nach dem Ziel sein
for idx in range(window_size, len(corpus)-window_size): # idx = 1 〜 6
cs = []
for t in range(-window_size, window_size + 1): # t = -1, 0, 1
if t == 0:
continue # t =Wenn es 0 ist, nichts tun
cs.append(corpus[idx + t]) # cs = courpus[idx-1, idx+1]
contexts.append(cs)
return np.array(contexts), np.array(target)
Ziel ist die Vorder- und Rückseite des Korpus minus window_size. Dann wird durch Setzen der Position des Ziels im Korpus in idx und Spezifizieren davor und danach mit t Kontexte erhalten. contexts = [[[0 2][1 3][2 4][3 1][4 5][1 6]]] target = [1 2 3 4 1 5]
#Ein heißer Ausdruck
vocab_size = len(word_to_id)
contexts = convert_one_hot(contexts, vocab_size)
target = convert_one_hot(target, vocab_size)
convert_one_hot ()
befindet sich in common / util.py, beziehen Sie sich also darauf.
# -------------- from common/util.py ---------------
def convert_one_hot(corpus, vocab_size):
N = corpus.shape[0]
if corpus.ndim == 1: #Für eine Dimension(Für das Ziel)
one_hot = np.zeros((N, vocab_size), dtype=np.int32) #Nullmatrixerstellung
for idx, word_id in enumerate(corpus): #Ziel zu Wort_Sequentielle Zuordnung zu id
one_hot[idx, word_id] = 1
elif corpus.ndim == 2: #Bei 2 Dimensionen(Für Kontexte)
C = corpus.shape[1]
one_hot = np.zeros((N, C, vocab_size), dtype=np.int32) #Nullmatrixerstellung
for idx_0, word_ids in enumerate(corpus): #Wörter aus Kontexten_Sequentielle Zuordnung zu IDs
for idx_1, word_id in enumerate(word_ids): # word_Wörter von IDs_Sequentielle Zuordnung zu id
one_hot[idx_0, idx_1, word_id] = 1
return one_hot
Im Fall von ** target ** wird (N, vocab_size) verwendet, um eine Nullmatrix zu erstellen, und one_hot [idx, word_id] wird verwendet, um die angegebene Position auf 1 zu setzen.
Bei ** Kontexten ** wird, da es zweidimensional ist, eine Nullmatrix mit (N, C, vocab_size) erstellt und der angegebene Teil mit one_hot [idx_0, idx_1, word_id] auf 1 gesetzt.
#Netzwerkaufbau
model = SimpleCBOW(vocab_size, hidden_size)
Dies ist der Teil des Netzwerkaufbaus. Gehen wir durch simple_cbow.py, das die Klasse SimpleCBOW ()
hat.
# -------------- from simple_cbow.py ---------------
class SimpleCBOW:
def __init__(self, vocab_size, hidden_size):
V, H = vocab_size, hidden_size
#Gewichtsinitialisierung
W_in = 0.01 * np.random.randn(V, H).astype('f')
W_out = 0.01 * np.random.randn(H, V).astype('f')
#Schichterzeugung
self.in_layer0 = MatMul(W_in)
self.in_layer1 = MatMul(W_in)
self.out_layer = MatMul(W_out)
self.loss_layer = SoftmaxWithLoss()
#Listen Sie alle Gewichte und Verläufe auf
layers = [self.in_layer0, self.in_layer1, self.out_layer]
self.params, self.grads = [], []
for layer in layers:
self.params += layer.params
self.grads += layer.grads
#Legen Sie die verteilte Darstellung von Wörtern in Mitgliedsvariablen fest
self.word_vecs = W_in
Da window_size = 1 ist, gibt es zwei Eingaben. Die Eingabe besteht aus 7 One-Hot-Vektoren, was der Anzahl der Vokabeln entspricht, die verborgene Ebene ist 5 und die Ausgabe ist 7, was der Anzahl der Vokabeln entspricht.
** Verteilungshypothese ** Basierend auf "Die Bedeutung eines Wortes wird durch umgebende Wörter gebildet", wenn Sie lernen, die leere Frage zu lösen, was ein Wort zwischen zwei Wörtern ist, $ W_ {in} Das $ ist eine verteilte Darstellung des Wortes.
Schließlich wird das Gewicht W_in word_vecs zugewiesen. Dies wird zur Vektoranzeige von Wörtern nach dem Lernen verwendet.
# -------------- from simple_cbow.py ---------------
def forward(self, contexts, target):
h0 = self.in_layer0.forward(contexts[:, 0])
h1 = self.in_layer1.forward(contexts[:, 1])
h = (h0 + h1) * 0.5
score = self.out_layer.forward(h)
loss = self.loss_layer.forward(score, target)
return loss
Die Gewichte $ W_ {in} $ für Layer0 und Layer1 werden gemeinsam genutzt. Teilen Sie nach dem Hinzufügen der Signale von Layer0 und Layer1 durch 2.
# -------------- from simple_cbow.py ---------------
def backward(self, dout=1):
ds = self.loss_layer.backward(dout)
da = self.out_layer.backward(ds)
da *= 0.5
self.in_layer1.backward(da)
self.in_layer0.backward(da)
return None
Es ist eine Fehlerrückübertragung. Dies sollte kein Problem sein.
#Diagrammanzeige für Lern- und Verlustübergang
optimizer = Adam()
trainer = Trainer(model, optimizer)
trainer.fit(contexts, target, max_epoch, batch_size)
trainer.plot()
Instanziieren Sie "class Trainer ()" in common / Trainer.py mit Adam, dem Modell und Optimierer, mit dem Sie das Netzwerk zuvor erstellt haben. Lernen Sie danach mit fit und zeigen Sie das Verlustübergangsdiagramm mit Diagramm an.
#Vektoranzeige von Wörtern
word_vecs = model.word_vecs #Gewicht W._in(Wortvektor)Erhalten
for word_id, word in id_to_word.items(): # id_to_Holen Sie sich Index und Wort für Wort
print(word, word_vecs[word_id]) #Zeigen Sie Wörter und Vektoren
Rufen Sie abschließend den gelernten Wortvektor "model.word_vecs" auf, um die Wörter und Vektoren anzuzeigen.
Recommended Posts