[PYTHON] Deep Learning / Deep Learning von Grund auf neu 2 Kapitel 4 Memo

1. Zuallererst

Ich lese ein Meisterwerk, ** "Deep Learning from Zero 2" **. Diesmal ist ein Memo von Kapitel 4. Um den Code auszuführen, laden Sie den gesamten Code von Github herunter und verwenden Sie jupyter notebook in ch04.

2. Hochgeschwindigkeitsversion CBOW-Modell

In Kapitel 4 geht es darum, das in Kapitel 3 implementierte Word2vec CBOW-Modell zu beschleunigen und zu einem praktischen Modell zu machen. Führen Sie ch04 / train.py aus und sehen Sie sich den Inhalt der Reihe nach an.

Der Datensatz verwendet Penn Tree Bank, die Anzahl der Vokabeln beträgt 10.000 und die Korpusgröße des Zuges. Ist etwa 900.000 Wörter.

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.np import *
import pickle
from common.trainer import Trainer
from common.optimizer import Adam
from cbow import CBOW
from skip_gram import SkipGram
from common.util import create_contexts_target, to_cpu, to_gpu
from dataset import ptb

#Hyper-Parametereinstellungen
window_size = 5
hidden_size = 100
batch_size = 100
max_epoch = 10

#Daten lesen
corpus, word_to_id, id_to_word = ptb.load_data('train')
vocab_size = len(word_to_id)

#Holen Sie sich Kontext und Ziel
contexts, target = create_contexts_target(corpus, window_size)
if config.GPU:
    contexts, target = to_gpu(contexts), to_gpu(target)

#Netzwerkaufbau
model = CBOW(vocab_size, hidden_size, window_size, corpus)

#Lernen, Verlustübergangsdiagrammanzeige
optimizer = Adam()
trainer = Trainer(model, optimizer)
trainer.fit(contexts, target, max_epoch, batch_size)
trainer.plot()

#Speichern Sie die Daten, die Sie zur späteren Verwendung benötigen
word_vecs = model.word_vecs
if config.GPU:
    word_vecs = to_cpu(word_vecs)
params = {}
params['word_vecs'] = word_vecs.astype(np.float16)
params['word_to_id'] = word_to_id
params['id_to_word'] = id_to_word
pkl_file = 'cbow_params.pkl'  # or 'skipgram_params.pkl'
with open(pkl_file, 'wb') as f:
    pickle.dump(params, f, -1)

スクリーンショット 2020-05-13 16.27.53.png

Der Verlust scheint stetig gesunken zu sein. Dann wird es ein Punkt. Werfen wir einen Blick auf class CBOW in cbow.py im Netzwerkaufbauteil.

# --------------- from cbow.py ---------------
class CBOW:
    def __init__(self, vocab_size, hidden_size, window_size, corpus):
        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(V, H).astype('f')

        #Schichterzeugung
        self.in_layers = []
        for i in range(2 * window_size):
            layer = Embedding(W_in)  #Verwenden Sie die Einbettungsebene
            self.in_layers.append(layer)
        self.ns_loss = NegativeSamplingLoss(W_out, corpus, power=0.75, sample_size=5)

        #Listen Sie alle Gewichte und Verläufe auf
        layers = self.in_layers + [self.ns_loss]
        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

Einer der Punkte der Beschleunigung ist die Einführung der ** Einbettungsschicht **. Schauen Sie sich common / layer.py an.

3. Ebene einbetten

# --------------- from common/layers.py --------------
class Embedding:
    def __init__(self, W):
        self.params = [W]
        self.grads = [np.zeros_like(W)]
        self.idx = None

    def forward(self, idx):
        W, = self.params
        self.idx = idx
        out = W[idx]  #Geben Sie die durch idx angegebene Zeile aus
        return out

    def backward(self, dout):
        dW, = self.grads
        dW[...] = 0
        if GPU:
            np.scatter_add(dW, self.idx, dout)
        else:
            np.add.at(dW, self.idx, dout)  #Fügen Sie der von idx angegebenen Zeile Daten hinzu
        return None

スクリーンショット 2020-05-14 15.56.08.png

In Kapitel 3 wurde die ** MatMul-Ebene ** verwendet, um das innere Produkt des Vektors und der Gewichtsmatrix zu finden. Wenn Sie jedoch darüber nachdenken, ist es das innere Produkt des One-Hot-Vektors und der Gewichtsmatrix, also ** die Gewichtsmatrix $ W_ {in} Sie müssen lediglich die $ line ** angeben. Dies ist die ** Ebene einbetten **.

Auf diese Weise muss die Backpropagation nur die entsprechende Zeile mit den zuvor übertragenen Daten aktualisieren. Beim Mini-Batch-Lernen ist es jedoch möglich, dass mehrere Daten in dieselbe Zeile zurückkehren und sich überlappen. Statt zu ersetzen, werden ** Daten hinzugefügt **.

4.Negative Sampling Der zweite Punkt der Beschleunigung ist ** Negative Sampling **. Wie in Kapitel 3 ist es unrealistisch, nach Softmax anhand der Ausgabe der Anzahl der Vokabeln zu klassifizieren. Was sollen wir dann tun? Die Antwort lautet **, um das mehrwertige Klassifizierungsproblem zu lösen, indem es an das binäre Klassifizierungsproblem angenähert wird **.

Schauen Sie sich class NegativeSamplingLoss in negative_sampling_layer.py an.

# ------------- form negative_sampling_layer.py --------------
class NegativeSamplingLoss:
    def __init__(self, W, corpus, power=0.75, sample_size=5):
        self.sample_size = sample_size
        self.sampler = UnigramSampler(corpus, power, sample_size)
        self.loss_layers = [SigmoidWithLoss() for _ in range(sample_size + 1)]
        self.embed_dot_layers = [EmbeddingDot(W) for _ in range(sample_size + 1)]

        self.params, self.grads = [], []
        for layer in self.embed_dot_layers:
            self.params += layer.params
            self.grads += layer.grads

    def forward(self, h, target):
        batch_size = target.shape[0]
        negative_sample = self.sampler.get_negative_sample(target)

        #Positives Beispiel vorwärts
        score = self.embed_dot_layers[0].forward(h, target)
        correct_label = np.ones(batch_size, dtype=np.int32)
        loss = self.loss_layers[0].forward(score, correct_label)

        #Negativ vorwärts
        negative_label = np.zeros(batch_size, dtype=np.int32)
        for i in range(self.sample_size):
            negative_target = negative_sample[:, i]
            score = self.embed_dot_layers[1 + i].forward(h, negative_target)
            loss += self.loss_layers[1 + i].forward(score, negative_label)

        return loss

    def backward(self, dout=1):
        dh = 0
        for l0, l1 in zip(self.loss_layers, self.embed_dot_layers):
            dscore = l0.backward(dout)
            dh += l1.backward(dscore)

        return dh

スクリーンショット 2020-05-13 17.36.16.png Um die mehrwertige Klassifizierung an die binäre Klassifizierung anzunähern, stellen Sie zunächst die Wahrscheinlichkeit ein, dass say (1) für die Antwort des Wortes zwischen Ihnen (0) und auf Wiedersehen (2) so weit wie möglich korrekt ist (korrekt). Beispiel). Das reicht aber nicht.

Daher füge ich hinzu, dass die Wahrscheinlichkeit, dass ein richtig ausgewähltes Hallo (5) oder I (4) falsch ist, so groß wie möglich ist (negatives Beispiel).

Diese Technik wird als ** Negative Sampling ** bezeichnet. Die Anzahl der negativen Beispiele zur Auswahl ist sample_size = 5 im Code.

An dieser Stelle wird "Embedding_dot_layers" angezeigt. Sehen Sie sich dies ebenfalls an. Ebenso ist es in negative_sampling_layer.py.

# ------------- form negative_sampling_layer.py --------------
class EmbeddingDot:
    def __init__(self, W):
        self.embed = Embedding(W)
        self.params = self.embed.params
        self.grads = self.embed.grads
        self.cache = None

    def forward(self, h, idx):
        target_W = self.embed.forward(idx)
        out = np.sum(target_W * h, axis=1)

        self.cache = (h, target_W)
        return out

    def backward(self, dout):
        h, target_W = self.cache
        dout = dout.reshape(dout.shape[0], 1)

        dtarget_W = dout * h
        self.embed.backward(dtarget_W)
        dh = dout * target_W
        return dh

スクリーンショット 2020-05-14 10.56.04.png Um Mini-Batch zu unterstützen, wird am Ende die Summe von target_w * h genommen, damit sie auch dann berechnet werden kann, wenn mehrere idx und h vorhanden sind.

5. Modellbewertung

Zuerst haben wir ch04 / train.py verschoben, damit die gelernten Parameter in cbow_params.pkl gespeichert werden. Verwenden Sie diese Option, um mit eval.py zu überprüfen, ob die verteilte Darstellung von Wörtern gut ist.

import sys
sys.path.append('..')
from common.util import most_similar, analogy
import pickle

pkl_file = 'cbow_params.pkl'  #Angabe des Dateinamens

#Lesen Sie jeden Parameter
with open(pkl_file, 'rb') as f:  
    params = pickle.load(f)  
    word_vecs = params['word_vecs']
    word_to_id = params['word_to_id']
    id_to_word = params['id_to_word']

# most similar task
querys = ['you']
for query in querys:
    most_similar(query, word_to_id, id_to_word, word_vecs, top=5)

スクリーンショット 2020-05-14 15.41.11.png

Überprüfen Sie zunächst die Wortähnlichkeit mit der Methode "most_similar" (common / util.py). Das, was Ihnen am nächsten kommt, sind wir und ich, sie, Ihre, gefolgt von persönlichen Synonymen. Dies ist das Ergebnis der Berechnung der Ähnlichkeit jedes Wortes mit der folgenden Kosinusähnlichkeit. スクリーンショット 2020-05-14 15.25.40.png

# analogy task
analogy('king', 'man', 'queen',  word_to_id, id_to_word, word_vecs)

スクリーンショット 2020-05-14 15.40.21.png

Lassen Sie uns nun das berühmte Problem ** König - Mann + Frau = Königin ** mit der Alalogie-Methode (common / util.py) überprüfen. Das stimmt, nicht wahr?

Dies löst die Aufgabe, das ** Wort x ** so zu finden, dass der ** "König → x" -Vektor ** dem ** "Mann → Frau" -Vektor ** so nahe wie möglich kommt.

Recommended Posts

Deep Learning / Deep Learning von Grund auf neu 2 Kapitel 4 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 3 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 5 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 7 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 8 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 5 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 4 Memo
Deep Learning / Deep Learning von Grund auf neu 2 Kapitel 3 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 6 Memo
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 7]
Deep Learning / Deep Learning von Grund auf neu Kapitel 6 Memo
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 5]
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 6]
Deep Learning / Deep Learning von Grund auf neu Kapitel 7 Memo
[Lernnotiz] Deep Learning von Grund auf neu gemacht [~ Kapitel 4]
Deep Learning von Grund auf neu Kapitel 2 Perceptron (Memo lesen)
Verbessertes Lernen, um von null bis tief zu lernen
"Deep Learning from Grund" Memo zum Selbststudium (Teil 12) Deep Learning
Deep Learning von Grund auf neu
Selbststudien-Memo "Deep Learning from Grund" (unlesbares Glossar)
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 9) MultiLayerNet-Klasse
Deep Learning von Grund auf neu ① Kapitel 6 "Lerntechniken"
[Lernnotiz] Deep Learning von Grund auf ~ Implementierung von Dropout ~
"Deep Learning from Grund" Memo zum Selbststudium (10) MultiLayerNet-Klasse
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 11) CNN
Deep Learning von Grund auf 1-3 Kapitel
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 19) Datenerweiterung
Python-Lernnotiz für maschinelles Lernen von Chainer aus Kapitel 2
Deep Learning 2 von Grund auf 1.3 Verarbeitung natürlicher Sprache 1.3 Zusammenfassung
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 1
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 5
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 2
Tiefes Lernen von Grund auf neu (Kostenberechnung)
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 3
Ein Amateur stolperte in Deep Learning von Grund auf neu. Hinweis: Kapitel 7
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 5
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 1
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 4
Selbststudien-Memo "Deep Learning from Grund" (Nr. 18) Eins! Miau! Grad-CAM!
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 4
Deep Learning Memo von Grund auf neu gemacht
Tiefes Lernen
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 2
Selbststudien-Memo "Deep Learning from Grund" (Nr. 15) TensorFlow-Anfänger-Tutorial
Deep Learning Tutorial aus dem Umgebungsbau
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 14) Führen Sie das Programm in Kapitel 4 in Google Colaboratory aus
"Deep Learning from Grund" Memo zum Selbststudium (Teil 8) Ich habe die Grafik in Kapitel 6 mit matplotlib gezeichnet
Selbststudien-Memo "Deep Learning from Grund" (Nr. 13) Verwenden Sie Google Colaboratory
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 10-2) Anfangswert des Gewichts
Tiefes Lernen von Grund auf neu (Vorwärtsausbreitung)
Tiefes Lernen / Tiefes Lernen von Grund auf 2-Versuchen Sie, GRU zu bewegen
Bildausrichtung: von SIFT bis Deep Learning
"Deep Learning von Grund auf neu" mit Haskell (unvollendet)
[Windows 10] Aufbau einer "Deep Learning from Scratch" -Umgebung
Lernbericht über das Lesen von "Deep Learning von Grund auf neu"
[Deep Learning von Grund auf neu] Über die Optimierung von Hyperparametern
Deep Learning aus den mathematischen Grundlagen (während der Teilnahme)