[PYTHON] Deep Learning / Deep Learning von Null 2 Kapitel 5 Memo

1. Zuallererst

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

2.RNNLM Versuchen Sie zunächst, den folgenden Code ch05 / train_custom_loop.py auszuführen, der die Wortreihenfolge des PTB-Datensatzes lernt.

import sys
sys.path.append('..')
import matplotlib.pyplot as plt
import numpy as np
from common.optimizer import SGD
from dataset import ptb
from simple_rnnlm import SimpleRnnlm

#Hyper-Parametereinstellungen
batch_size = 10
wordvec_size = 100
hidden_size = 100
time_size = 5  #Zeitgröße für die Bereitstellung von abgeschnittenem BPTT
lr = 0.1
max_epoch = 100

#Trainingsdaten lesen (Datensatz verkleinern)
corpus, word_to_id, id_to_word = ptb.load_data('train')
corpus_size = 1000
corpus = corpus[:corpus_size]
vocab_size = int(max(corpus) + 1)

xs = corpus[:-1]  #Eingang
ts = corpus[1:]  #Ausgabe (Lehreretikett)
data_size = len(xs)
print('corpus size: %d, vocabulary size: %d' % (corpus_size, vocab_size))

#Während des Lernens verwendete Variablen
max_iters = data_size // (batch_size * time_size)
time_idx = 0
total_loss = 0
loss_count = 0
ppl_list = []

#Modellgenerierung
model = SimpleRnnlm(vocab_size, wordvec_size, hidden_size)
optimizer = SGD(lr)

#Berechnen Sie die Startposition für das Laden jeder Probe in der Mini-Charge
jump = (corpus_size - 1) // batch_size
offsets = [i * jump for i in range(batch_size)]

for epoch in range(max_epoch):
    for iter in range(max_iters):
        #Holen Sie sich eine Mini-Charge
        batch_x = np.empty((batch_size, time_size), dtype='i')
        batch_t = np.empty((batch_size, time_size), dtype='i')
        for t in range(time_size):
            for i, offset in enumerate(offsets):
                batch_x[i, t] = xs[(offset + time_idx) % data_size]
                batch_t[i, t] = ts[(offset + time_idx) % data_size]
            time_idx += 1

        #Finden Sie den Farbverlauf und aktualisieren Sie die Parameter
        loss = model.forward(batch_x, batch_t)
        model.backward()
        optimizer.update(model.params, model.grads)
        total_loss += loss
        loss_count += 1

    #Bewertung der Ratlosigkeit für jede Epoche
    ppl = np.exp(total_loss / loss_count)
    print('| epoch %d | perplexity %.2f'
          % (epoch+1, ppl))
    ppl_list.append(float(ppl))
    total_loss, loss_count = 0, 0

#Zeichnen eines Diagramms
x = np.arange(len(ppl_list))
plt.plot(x, ppl_list, label='train')
plt.xlabel('epochs')
plt.ylabel('perplexity')
plt.show()

スクリーンショット 2020-05-18 18.32.37.png Die vertikale Achse des Graphen ist ein Index namens ** Ratlosigkeit **, der die Wahrscheinlichkeit des nächsten Wortes vorhersagt, und $ Ratlosigkeit = e ^ L \ (L = - \ frac {1} {N} \ sum_n \ sum_k t_ { Es wird durch die Formel nk} log y_ {nk}) $ ausgedrückt. Je näher der Ratlosigkeitswert an 1 liegt, desto höher ist die Vorhersagegenauigkeit. Einfach ausgedrückt ist Ratlosigkeit die Anzahl der Auswahlmöglichkeiten für das nächste Wort. Werfen wir einen kurzen Blick auf den Teil, der die Daten aufbereitet.

スクリーンショット 2020-05-19 10.45.53.png

** Korpus ** verwendet nur die ersten 1.000 Wörter des PTB-Datensatzes, und ** Trainingsdaten xs ** und ** Lehrerdaten ts ** erhalten jeweils 999 Wörter, jeweils ein Wort.

Verwenden Sie dann "Offsets", um die Lesepositionen (10 Positionen) für die Stapelgröße zu bestimmen, und erstellen Sie einen Mini-Stapel, indem Sie alle Daten für die Zeitgröße (5) teilen. Wenn "Offsets + time_idx" die Datengröße von 999 oder mehr erreicht, beginnt es wieder bei 0 und die Daten werden erfasst.

Werfen wir einen Blick auf die ** Klasse SimpleRnnlm **, die das Modell generiert.

3.SimpleRnnlm

class SimpleRnnlm:
    def __init__(self, vocab_size, wordvec_size, hidden_size):
        V, D, H = vocab_size, wordvec_size, hidden_size
        rn = np.random.randn

        #Gewichtsinitialisierung
        embed_W = (rn(V, D) / 100).astype('f')
        rnn_Wx = (rn(D, H) / np.sqrt(D)).astype('f')
        rnn_Wh = (rn(H, H) / np.sqrt(H)).astype('f')
        rnn_b = np.zeros(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),
            TimeRNN(rnn_Wx, rnn_Wh, rnn_b, stateful=True),
            TimeAffine(affine_W, affine_b)
        ]
        self.loss_layer = TimeSoftmaxWithLoss()
        self.rnn_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 forward(self, xs, ts):
        for layer in self.layers:
            xs = layer.forward(xs)
        loss = self.loss_layer.forward(xs, 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.rnn_layer.reset_state()

スクリーンショット 2020-05-17 13.58.22.png

** Klasse SimpleRnnlm ** ist ein Stapel von vier ** Zeitschichten **: ** TimeEmbedding, Time RNN, Time Affine, Time Softmax With Loss **. Schauen wir uns die Zeitebene der Reihe nach an.

4. Time Embedding-Ebene

class TimeEmbedding:
    def __init__(self, W):
        self.params = [W]
        self.grads = [np.zeros_like(W)]
        self.layers = None
        self.W = W

    def forward(self, xs):
        N, T = xs.shape
        V, D = self.W.shape

        out = np.empty((N, T, D), dtype='f')
        self.layers = []

        for t in range(T):
            layer = Embedding(self.W)
            out[:, t, :] = layer.forward(xs[:, t])
            self.layers.append(layer)

        return out

    def backward(self, dout):
        N, T, D = dout.shape

        grad = 0
        for t in range(T):
            layer = self.layers[t]
            layer.backward(dout[:, t, :])
            grad += layer.grads[0]

        self.grads[0][...] = grad
        return None

スクリーンショット 2020-05-21 09.21.15.png

Die ** Time Embedding-Ebene ** schneidet Daten spaltenweise aus xs aus, gibt sie in die ** Embedding-Ebene ** ein und speichert die Ausgabe in ** out (N, T, D) **. Es wiederholt T-mal in einer Schleife.

5. RNN-Schicht

Bevor wir uns die TimeRNN-Schicht ansehen, schauen wir uns die RNN-Schicht an, die für die TimeRNN-Schicht verwendet wird.

class RNN:
    def __init__(self, Wx, Wh, b):
        self.params = [Wx, Wh, b]
        self.grads = [np.zeros_like(Wx), np.zeros_like(Wh), np.zeros_like(b)]
        self.cache = None

    def forward(self, x, h_prev):
        Wx, Wh, b = self.params
        t = np.dot(h_prev, Wh) + np.dot(x, Wx) + b
        h_next = np.tanh(t)

        self.cache = (x, h_prev, h_next)
        return h_next

スクリーンショット 2020-05-21 10.53.11.png

Die RNN-Schicht hat zwei Gewichte. Sie sind das Gewicht ** W_x **, das die Eingabe x_t und das innere Produkt (MatMul) nimmt, und das Gewicht ** W_h **, das die Eingabe h_prev und das innere Produkt (MatMUl) nimmt.

    def backward(self, dh_next):
        Wx, Wh, b = self.params
        x, h_prev, h_next = self.cache

        dt = dh_next * (1 - h_next ** 2)
        db = np.sum(dt, axis=0)
        dWh = np.dot(h_prev.T, dt)
        dh_prev = np.dot(dt, Wh.T)
        dWx = np.dot(x.T, dt)
        dx = np.dot(dt, Wx.T)

        self.grads[0][...] = dWx
        self.grads[1][...] = dWh
        self.grads[2][...] = db

        return dx, dh_prev

スクリーンショット 2020-05-21 10.54.58.png

Backpropagation sieht so aus. Es ist eine modifizierte Version von Affine, daher ist nichts kompliziert.

6. TimeRNN-Schicht

class TimeRNN:
    def __init__(self, Wx, Wh, b, stateful=False):
        self.params = [Wx, Wh, b]
        self.grads = [np.zeros_like(Wx), np.zeros_like(Wh), np.zeros_like(b)]
        self.layers = None

        self.h, self.dh = None, None
        self.stateful = stateful

    def forward(self, xs):
        Wx, Wh, b = self.params
        N, T, D = xs.shape
        D, H = Wx.shape

        self.layers = []
        hs = np.empty((N, T, H), dtype='f')

        if not self.stateful or self.h is None:
            self.h = np.zeros((N, H), dtype='f')

        for t in range(T):
            layer = RNN(*self.params)
            self.h = layer.forward(xs[:, t, :], self.h)
            hs[:, t, :] = self.h
            self.layers.append(layer)

        return hs

スクリーンショット 2020-05-21 10.56.02.png

** TimeRNN-Schicht ** ist ein Netzwerk von T RNN-Schichten, die miteinander verbunden sind. Hier können Sie anpassen, ob der Status h zwischen Blöcken mit dem Argument "stateful" geerbt werden soll.

Bereiten Sie für die Vorwärtsausbreitung zuerst den Ausgabecontainer "hs (N, T, H)" vor. Während die for-Schleife gedreht wird, werden die t-ten Daten durch "xs [:, t ,:]" ausgeschnitten und in die normale RNN eingegeben, und die Ausgabe ist der von "hs [:, t ,:]" vorbereitete Container. Registrieren Sie die Ebene in Ebenen, während Sie sie an der angegebenen Position von speichern.

Mit anderen Worten ist die TimeRNN-Schicht die Eingabe / Ausgabe der RNN-Schicht mit den Funktionen der Datenextraktion und Datenzusammenfassung.

    def backward(self, dhs):
        Wx, Wh, b = self.params
        N, T, H = dhs.shape
        D, H = Wx.shape

        dxs = np.empty((N, T, D), dtype='f')
        dh = 0
        grads = [0, 0, 0]
        for t in reversed(range(T)):
            layer = self.layers[t]
            dx, dh = layer.backward(dhs[:, t, :] + dh)  #Summierter Gradient
            dxs[:, t, :] = dx

            for i, grad in enumerate(layer.grads):
                grads[i] += grad

        for i, grad in enumerate(grads):
            self.grads[i][...] = grad
        self.dh = dh

        return dxs

    def set_state(self, h):
        self.h = h

    def reset_state(self):
        self.h = None

スクリーンショット 2020-05-19 10.27.35.png

Die TimeRNN-Vorwärtsausbreitung hat zwei Ausgänge. Im Fall der Rückwärtsausbreitung wird also $ dh_t + dh_ {next} $, die Summe der beiden, eingegeben.

Erstellen Sie zunächst einen Container dxs, der stromabwärts fließt, ermitteln Sie den Gradienten dx jedes Mal mit backward () der RNN-Schicht in umgekehrter Reihenfolge der Vorwärtsausbreitung und weisen Sie ihn dem entsprechenden Index von dxs zu. Der Parameter weight fügt die Gewichtsverläufe für jede Ebene hinzu und überschreibt das Endergebnis in self.grads.

7. TimeAffine-Ebene

class TimeAffine:
    def __init__(self, W, b):
        self.params = [W, b]
        self.grads = [np.zeros_like(W), np.zeros_like(b)]
        self.x = None

    def forward(self, x):
        N, T, D = x.shape
        W, b = self.params

        rx = x.reshape(N*T, -1)
        out = np.dot(rx, W) + b
        self.x = x
        return out.reshape(N, T, -1)

    def backward(self, dout):
        x = self.x
        N, T, D = x.shape
        W, b = self.params

        dout = dout.reshape(N*T, -1)
        rx = x.reshape(N*T, -1)

        db = np.sum(dout, axis=0)
        dW = np.dot(rx.T, dout)
        dx = np.dot(dout, W.T)
        dx = dx.reshape(*x.shape)

        self.grads[0][...] = dW
        self.grads[1][...] = db

        return dx

スクリーンショット 2020-05-21 10.56.51.png

Die ** Zeitaffine Ebene ** ist die Eingabe und Ausgabe der ** Affinen Ebene ** mit hinzugefügter Umformung, so dass sie T in Richtung der Zeitachse entsprechen kann.

8.TimeSoftmaxWithLoss

class TimeSoftmaxWithLoss:
    def __init__(self):
        self.params, self.grads = [], []
        self.cache = None
        self.ignore_label = -1

    def forward(self, xs, ts):
        N, T, V = xs.shape

        if ts.ndim == 3:  #Das Lehrerlabel ist eins-Für heißen Vektor
            ts = ts.argmax(axis=2)

        mask = (ts != self.ignore_label)

        #Stapel- und Zeitreihen sammeln (umformen)
        xs = xs.reshape(N * T, V)
        ts = ts.reshape(N * T)
        mask = mask.reshape(N * T)

        ys = softmax(xs)
        ls = np.log(ys[np.arange(N * T), ts])
        ls *= mask  # ignore_Daten, die dem Etikett entsprechen, setzen den Verlust auf 0
        loss = -np.sum(ls)
        loss /= mask.sum()

        self.cache = (ts, ys, mask, (N, T, V))
        return loss

    def backward(self, dout=1):
        ts, ys, mask, (N, T, V) = self.cache

        dx = ys
        dx[np.arange(N * T), ts] -= 1
        dx *= dout
        dx /= mask.sum()
        dx *= mask[:, np.newaxis]  # ignore_Setzen Sie den Farbverlauf für die der Beschriftung entsprechenden Daten auf 0

        dx = dx.reshape((N, T, V))

        return dx

スクリーンショット 2020-05-20 19.00.44.png ** Time Softmax mit Verlustschicht ** ist eine Schicht, die T von Sotmax mit einem Verlust von $ x_t und t_t $ addiert und durch T dividiert.

9. Erstellen eines japanischen Versionsdatensatzes

Versuchen wir es mit einem japanischen Datensatz, um das Ganze besser zu verstehen. Wenn Sie jedoch versuchen, dies Wort für Wort zu tun, ist eine morphologische Analyse erforderlich, also ** Zeicheneinheit **. Dieses Mal habe ich "Alter Mann und das Meer" von Aozora Bunko heruntergeladen und verwendet.

import numpy as np
import io

def load_data():
    
    # file_UTF die ersten 1000 Zeichen des Namens-Lesen Sie in Text im 8-Format
    file_name = './data_rojinto_umi.txt'
    length = 1000
    with io.open(file_name, encoding='utf-8') as f:
        text = f.read().lower()
        text = text[:length]

    # 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])  
    
    return text, corpus, word_to_id, id_to_word

Liest 1000 Zeichen vom Anfang der durch Dateiname angegebenen Textdatei im UTF-8-Format. Eine Funktion, die Text, Korpus, word_to_id, id_to_word zurückgibt. Bewegen wir es ein wenig.

text, corpus, word_to_id, id_to_word = load_data()
print('text_length = ', len(text))
print(text)

スクリーンショット 2020-05-20 15.09.17.png Die Länge von "Text" beträgt 1000 wie angegeben. Wenn Sie es in Zeicheneinheiten vorbereiten, ist der Text sehr kompakt.

print('vocab_size = ', len(word_to_id))
print(word_to_id)

スクリーンショット 2020-05-20 15.17.08.png

Es ist word_to_id. vocab_size ist nicht so groß wie ich dachte es war 236. Dies wird verwendet, um jedes Zeichen von "Text" durch ID zu ersetzen, um "Korpus" zu erstellen.

print('corpus_length = ', len(corpus))
print(corpus[:500])

スクリーンショット 2020-05-20 15.22.04.png Es ist Korpus. Die Anzeige ist von Anfang an auf 500 Zeichen begrenzt.

text2 = ''.join([id_to_word[id] for id in corpus])
print(text2)

スクリーンショット 2020-05-20 15.26.55.png

Das Konvertieren der ID von "Korpus" in ein Zeichen mit "id_to_word" kehrt zum ersten Text wie diesem zurück.

Jetzt, da es eine große Sache ist, möchte ich Testdaten und Antworten vorbereiten und prüfen, wie viel Vorhersage für jede Epoche gemacht werden kann.

#Probe aus dem Korpus
x = corpus[:50]
t = corpus[1:51]
print('x = ', x)
print('t = ', t)

#Bestätigung per Text
text_x = ''.join([id_to_word[id] for id in x])
text_t = ''.join([id_to_word[id] for id in t])
print('text_x = ', text_x)
print('text_t = ', text_t)

#In Stapelformat konvertieren
test_x = x.reshape(10, 5)
test_t = t.reshape(10, 5)
print(test_x)
print(test_t)

スクリーンショット 2020-05-20 15.57.51.png Holen Sie sich x, t aus "Korpus", indem Sie 50 Zeichen um ein Zeichen verschieben. Zur Zeit konvertiere ich es in Zeichen und überprüfe den Inhalt. Anschließend wird es in die im Modell verwendete Form (10, 5) konvertiert und die Vorhersagedaten test_x und test_t zum Testen werden erstellt.

    def generate(self, xs):
        for layer in self.layers:
            xs = layer.forward(xs)
        return xs

Später werde ich diesen Code am Ende von simple_rnnlm.py hinzufügen, um Vorhersagen für jede Epoche zu treffen.

10. Modifiziertes RNNLM

Ändern und fügen Sie dann basierend auf dem zuerst ausgeführten Code ch05 / train_custom_loop.py die beiden Teile ** hinzu, lesen Sie die Trainingsdaten und führen Sie die Inferenz der Testdaten aus **. Die Anzahl der Epochen beträgt das 1000-fache.

import sys
sys.path.append('..')
import matplotlib.pyplot as plt
import numpy as np
from common.optimizer import SGD
from dataset import ptb
from simple_rnnlm import SimpleRnnlm    

#Hyper-Parametereinstellungen
batch_size = 10
wordvec_size = 100
hidden_size = 100
time_size = 5  #Zeitgröße für die Bereitstellung von abgeschnittenem BPTT
lr = 0.1
max_epoch = 1000  

# -----------Trainingsdaten lesen-------------
text, corpus, word_to_id, id_to_word = load_data()
corpus_size = 1000
vocab_size = int(max(corpus) + 1)
# ----------------------------------------------

xs = corpus[:-1]  #Eingang
ts = corpus[1:]  #Ausgabe (Lehreretikett)
data_size = len(xs)
print('corpus size: %d, vocabulary size: %d' % (corpus_size, vocab_size))

#Während des Lernens verwendete Variablen
max_iters = data_size // (batch_size * time_size)  
time_idx = 0
total_loss = 0
loss_count = 0
ppl_list = []

#Modellgenerierung
model = SimpleRnnlm(vocab_size, wordvec_size, hidden_size)
optimizer = SGD(lr)

#Berechnen Sie die Startposition für das Laden jeder Probe in der Mini-Charge
jump = (corpus_size - 1) // batch_size
offsets = [i * jump for i in range(batch_size)]

for epoch in range(max_epoch):
    for iter in range(max_iters):
        #Holen Sie sich eine Mini-Charge
        batch_x = np.empty((batch_size, time_size), dtype='i')
        batch_t = np.empty((batch_size, time_size), dtype='i')
        for t in range(time_size):
            for i, offset in enumerate(offsets):
                batch_x[i, t] = xs[(offset + time_idx) % data_size]
                batch_t[i, t] = ts[(offset + time_idx) % data_size]
            time_idx += 1

        #Finden Sie den Farbverlauf und aktualisieren Sie die Parameter
        loss = model.forward(batch_x, batch_t)
        model.backward()
        optimizer.update(model.params, model.grads)
        total_loss += loss
        loss_count += 1

    #Bewertung der Ratlosigkeit für jede Epoche
    ppl = np.exp(total_loss / loss_count)
    print('| epoch %d | perplexity %.2f'
          % (epoch+1, ppl))
    ppl_list.append(float(ppl))
    total_loss, loss_count = 0, 0
    
    # ----------Mit Testdaten vorhergesagt------------
    pred= model.generate(test_x) 
    predict = np.argmax(pred, axis = 2) 
    print(predict)
    # ------------------------------------------------
    
#Zeichnen eines Diagramms
x = np.arange(len(ppl_list))
plt.plot(x, ppl_list, label='train')
plt.xlabel('epochs')
plt.ylabel('perplexity')
plt.show()

スクリーンショット 2020-05-20 17.02.11.png Nach 1000 Epochen fiel die Ratlosigkeit auf 1,08. Da das auf den Testdaten basierende Vorhersageergebnis für jede Epoche angezeigt wird, sind alle 5 (Hiraganas "ta"), wenn Sie das Vorhersageergebnis nach 1 Epoche betrachten. Wenn Sie gerade gelernt haben, sieht es so aus. Dies ist das Vorhersageergebnis nach 1000 Epochen ziemlich ähnlich. Lassen Sie uns nun das endgültige Vorhersageergebnis überprüfen.

スクリーンショット 2020-05-20 18.42.27.png

Die richtige Antwort wird nach dem Abgleichen der Vorhersageergebnisse rot eingekreist. Da es 24/50 ist, beträgt die korrekte Antwortrate 48%, was nicht so hoch ist, wie ich erwartet hatte. Liegt es daran, dass die korrekte Antwortrate in der zweiten Hälfte der fünf Zeichen hoch ist, weil sie anhand der Zeichen in der ersten Hälfte vorhergesagt werden kann? Wenn Sie versuchen, das Vorhersageergebnis der ersten Zeile mit einem Modell auszudrücken,

スクリーンショット 2020-05-20 18.36.00.png

Das war's. Hast du so einen Fehler gemacht?

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)
"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 ü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)
LPIC201 Studiennotiz
Django Lernnotiz