[PYTHON] [Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 7]

Deep Learning von Grund auf neu Kapitel 7

Das Thema von Kapitel 7 ist Faltungsneurales Netzwerk: ** CNN **

Gesamtstruktur

CNN ist das gleiche wie das neuronale Netzwerk, das wir bisher gesehen haben, und es ist möglich, eine Kombination von Schichten wie einen Legoblock zu erstellen. Weiter ist neu ・ "Faltungsschicht" ・ "Pooling Layer"

Kobito.JxbIF2.png

Kobito.SXd9XQ.png

Allgemeine CNN-Funktionen ・ Fluss von "Convolution --ReLU- (Pooling)" ・ Die Pooling-Ebene kann weggelassen werden ・ Die Kombination "Affine --ReLU" wird in der Ebene nahe der Ausgabe verwendet. ・ Die letzte Ausgabeebene ist eine Kombination aus "Affine --Softmax"

Faltschicht

Die folgenden Begriffe wurden angezeigt ・ Putten ·schreiten

Zusätzlich sind dreidimensionale Daten erschienen

Probleme mit vollständig verbundenen Schichten

Das Problem bei vollständigen Verknüpfungen ist, dass ** die Struktur der Daten "ignoriert" wird **

Beispielsweise handelt es sich bei einem Bild normalerweise um eine dreidimensionale Form in vertikaler, horizontaler und Kanalrichtung. Diese Form enthält wichtige räumliche Informationen Zum Beispiel -Spatial Close Pixel können ähnliche Werte haben ・ Zwischen jedem RBG-Kanal besteht eine enge Beziehung ・ Pixel, die weit voneinander entfernt sind, sind nicht so verwandt Es gibt ein wesentliches Muster, das in der dreidimensionalen Form aufgenommen werden muss.

Die vollständig verbundene Schicht ignoriert die obige Form und behandelt sie alle als äquivalente Neuronen (Neuronen derselben Dimension). Andererseits behält die Faltungsschicht ihre Form bei

In CNN sind die Eingabe- / Ausgabedaten der Faltungsschicht ** Merkmalskarte ** (Merkmalskarte). Eingabedaten ** Feature-Map eingeben ** (Feature-Map) Ausgabedaten ** Feature-Map ausgeben ** (Feature-Map) Manchmal sage ich.

Klappvorgang

Kobito.uMcQj4.png

"Klappvorgang" Entspricht "Filterverarbeitung" in der Bildverarbeitung In einigen Literaturstellen wird der Begriff "Filter" manchmal als "Kernel" bezeichnet.

Die für diesen Filter verwendeten Parameter entsprechen den "Gewichten" im vollständig gekoppelten neuronalen Netzwerk.

Berechnungsbeispiel

Kobito.Wo1MG2.png

Voreingenommener Betrieb

Kobito.gNgZ98.png

Polsterung

Putting: Füllen fester Daten (zB 0) um die Eingabedaten

Die folgende Abbildung ist mit 1 Pixel 0 in der Breite gefüllt Kobito.joYXx3.png

schreiten

Schritt: Der Abstand zwischen den Positionen, an denen der Filter angewendet wird.

Kobito.WoeNb7.png

Berechnung der Ausgabegröße

Eingabegröße (H, B) Filtergröße (FH, FW) Ausgabegröße (OH, OW) Polsterung P. Schritt S. Die Ausgabegröße ist wie folgt

OH = \frac{H + 2P - FH}{S} + 1\\
OW = \frac{W + 2P - FW}{S} + 1

Denken Sie in Blöcken

In Anbetracht der dreidimensionalen Faltungsoperation in einem leicht verständlichen rechteckigen Block ist dies wie folgt.

Kobito.ITLGJH.png

Das Obige ist eine Feature-Map mit einer Ausgabe. Mit anderen Worten, es handelt sich um eine Feature-Map mit einem Kanal.

Das Folgende ist ein Diagramm bei Mehrkanalmethoden.

Kobito.l5nAG0.png

Das Hinzufügen des Bias-Terms ist wie folgt. image.png

Stapelverarbeitung

Bei der Stapelverarbeitung von N Datenelementen ist die Form der Daten dieselbe

image.png

Pooling-Schicht

Pooling: Berechnung zur Reduzierung der vertikalen und horizontalen Sicht auf den Himmel

In der folgenden Abbildung wird die Speicherplatzgröße reduziert, indem eine Verarbeitung durchgeführt wird, bei der der 2x2-Bereich zu einem Element zusammengefasst wird.

Kobito.HL2U8Q.png

In diesem Beispiel wird auf Pool 2 2x2 Max-Pooling ausgeführt.

Max Pooling: Berechnung, um den Maximalwert in der Fläche zu ermitteln Außerdem werden im Allgemeinen die Größe des Poolfensters und die Folie auf denselben Wert festgelegt.

Zusätzlich zum maximalen Pooling gibt es ein durchschnittliches Pooling, das den Durchschnittswert in der Region annimmt.

Merkmale der Pooling-Schicht

・ Es sind keine Parameter zu lernen

Pooling ist ein Prozess, bei dem nur der Maximalwert (oder Durchschnittswert) vom Ziel übernommen wird, sodass keine Parameter zu lernen sind.

・ Die Anzahl der Kanäle ändert sich nicht

Die Anzahl der Kanäle für Eingangsdaten und Ausgangsdaten ändert sich aufgrund der Pooling-Berechnung nicht. (OH und OW ändern sich, FN jedoch nicht)

・ Robust gegen winzige Positionsänderungen

Das Pooling liefert ähnliche Ergebnisse für kleine Abweichungen in den Eingabedaten. Daher ist es robust gegen geringfügige Abweichungen in den Eingabedaten.

Kobito.rOBXno.png

Implementierung der Faltungs- / Pooling-Schicht

4-dimensionales Array

#Generieren Sie zufällig Daten
x = np.random.rand(10,1,28,28)
x.shape
# (10, 1, 28, 28)

x[0].shape
# (1, 28, 28)
x[1].shape
# (1, 28, 28)

x[0, 0].shape # x[0][0]Aber ok
# (28, 28)

Bereitstellung durch im2col

Wenn Sie die Faltung wie in der vorherigen Abbildung gezeigt implementieren, müssen Sie mehrere for-Anweisungen kombinieren. Außerdem ist NumPy bei Verwendung der for-Anweisung langsam.

Implementieren Sie daher eine Funktion namens im2col anstelle einer for-Anweisung. im2col ist eine Funktion, die die Eingabedaten entsprechend dem Filter erweitert.

image.png

In dieser Abbildung haben wir die Verständlichkeit hervorgehoben und ein Beispiel angegeben, bei dem sich die Filterbereiche nicht überlappen.

・ Im2col Vorteile Nachteile Vorteil: Es ist möglich, die Bibliothek der linearen Algebra effektiv zu nutzen, da sie auf die Matrixberechnung reduziert werden kann. Nachteile: Verbrauchen Sie mehr Speicher als üblich

#----------------------------------------------------
# Parameters
#   input_data : (Die Anzahl der Daten,Kanal,Höhe,Breite)Eingabedaten bestehend aus einem 4-dimensionalen Array von
#   filter_h :Filterhöhe
#   filter_w :Filterbreite
#   stride :schreiten
#   pad :Polsterung
# Returns
#   col :Ein zweidimensionales Array
#----------------------------------------------------
def im2col(input_data, filter_h, filter_w, stride=1, pad=0):

    N, C, H, W = input_data.shape
    out_h = (H + 2*pad - filter_h)//stride + 1
    out_w = (W + 2*pad - filter_w)//stride + 1

    img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')
    col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))

    for y in range(filter_h):
        y_max = y + stride*out_h
        for x in range(filter_w):
            x_max = x + stride*out_w
            col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]

    col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)
    return col

Ansicht mit im2col

import sys, os
sys.path.append(os.pardir)
from common.util import im2col

x1 = np.random.rand(1, 3, 7, 7)
col1 = im2col(x1, 5, 5, stride=1, pad=0)
print(col1.shape)

x2 = np.random.rand(10, 3, 7, 7)
col2 = im2col(x2, 5, 5, stride=1, pad=0)
print(col2.shape)

Ergebnis (9, 75) (90, 75)

x1 sind 7x7-Daten mit Kanälen der Stapelgröße 1 und 3 x2 sind 7x7-Daten mit einer Stapelgröße von 10 und 3 Kanälen

In beiden Fällen beträgt die Anzahl der Elemente in der zweiten Dimension 75, was die Summe der Anzahl der Aspekte des Filters ist. (Kanal 3, Größe 5 x 5)

Implementierung der Faltungsschicht

Nachdem Sie die Daten mit im2col erweitert haben, müssen Sie lediglich den Filter (das Gewicht) der Faltungsschicht in eine Spalte erweitern und das innere Produkt der beiden Matrizen berechnen. Dies ist fast das gleiche wie in der affinen Schicht der vollständig verbundenen Schicht. image.png

class Convolution:
    def __init__(self, W, b, stride=1, pad=0):
        self.W = W
        self.b = b
        self.stride = stride
        self.pad = pad
        
        #Zwischendaten (werden rückwärts verwendet)
        self.x = None   
        self.col = None
        self.col_W = None
        
        #Gradient des Gewichts / Bias-Parameters
        self.dW = None
        self.db = None

    def forward(self, x):
        FN, C, FH, FW = self.W.shape
        N, C, H, W = x.shape
        out_h = 1 + int((H + 2*self.pad - FH) / self.stride)
        out_w = 1 + int((W + 2*self.pad - FW) / self.stride)

        col = im2col(x, FH, FW, self.stride, self.pad)
        #zur Umformfunktion-Wenn 1 angegeben ist, wird die Anzahl der Elemente zusammengefasst, sodass das Tsuji des mehrdimensionalen Arrays übereinstimmt.
        col_W = self.W.reshape(FN, -1).T

        out = np.dot(col, col_W) + self.b
        #Zum Schluss formen Sie die Ausgabegröße in die entsprechende Form
        #Durch Umformen wird die angegebene Ausgabegröße neu konfiguriert
        #transponieren ändert die Reihenfolge der Achsen
        out = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)

        self.x = x
        self.col = col
        self.col_W = col_W

        return out

    def backward(self, dout):
        FN, C, FH, FW = self.W.shape
        dout = dout.transpose(0,2,3,1).reshape(-1, FN)

        #Die Berechnung der inversen Matrix selbst erfolgt in den folgenden zwei Zeilen, die mit Affine identisch sind. Der einzige Unterschied besteht in der Anpassung der Abmessungen der Matrix.
        self.db = np.sum(dout, axis=0)
        self.dW = np.dot(self.col.T, dout)

        self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)

        dcol = np.dot(dout, self.col_W.T)
        #Umgekehrte Verarbeitung von im2col
        dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad)

        return dx

Implementierung der Pooling-Schicht

Verwenden Sie wie bei der Convolution-Ebene im2col, um die Eingabedaten zu erweitern und zu implementieren Beim Pooling besteht der Unterschied jedoch darin, dass sie in Kanalrichtung unabhängig sind.

class Pooling:
    def __init__(self, pool_h, pool_w, stride=1, pad=0):
        self.pool_h = pool_h
        self.pool_w = pool_w
        self.stride = stride
        self.pad = pad
        
        self.x = None
        self.arg_max = None

    def forward(self, x):
        N, C, H, W = x.shape
        out_h = int(1 + (H - self.pool_h) / self.stride)
        out_w = int(1 + (W - self.pool_w) / self.stride)

        col = im2col(x, self.pool_h, self.pool_w, self.stride, self.pad)
        col = col.reshape(-1, self.pool_h*self.pool_w)

        arg_max = np.argmax(col, axis=1)
        out = np.max(col, axis=1)
        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)

        self.x = x
        self.arg_max = arg_max

        return out

    def backward(self, dout):
        dout = dout.transpose(0, 2, 3, 1)
        
        pool_size = self.pool_h * self.pool_w
        dmax = np.zeros((dout.size, pool_size))
        #Durch Abflachen wird die Struktur wieder in ein eindimensionales Array eingefügt
        dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten()
        dmax = dmax.reshape(dout.shape + (pool_size,)) 
        
        dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1)
        dx = col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.pad)
        
        return dx

Implementierung von CNN

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  #Einstellungen zum Importieren von Dateien in das übergeordnete Verzeichnis
import pickle
import numpy as np
from collections import OrderedDict
from common.layers import *
from common.gradient import numerical_gradient

#Einfaches ConvNet
# conv - relu - pool - affine - relu - affine - softmax
class SimpleConvNet:

    
    #----------------------------------------------------
    # Parameters
    #   input_size :Eingabegröße (784 für MNIST)
    #   hidden_size_list :Liste der Anzahl der Neuronen in der verborgenen Schicht (e.g. [100, 100, 100])
    #   output_size :Ausgabegröße (10 für MNIST)
    #   activation : 'relu' or 'sigmoid'
    #   weight_init_std :Geben Sie die Standardabweichung des Gewichts an (e.g. 0.01)
    #                    'relu'Oder'he'Wenn angegeben, wird "Anfangswert von He" gesetzt.
    #                    'sigmoid'Oder'xavier'Wenn angegeben, wird "Anfangswert von Xavier" gesetzt.
    #----------------------------------------------------
    def __init__(self, input_dim=(1, 28, 28), 
                 conv_param={'filter_num':30, 'filter_size':5, 'pad':0, 'stride':1},
                 hidden_size=100, output_size=10, weight_init_std=0.01):

        #Initialisierung von Gewichten, Berechnung der Ausgabegröße der Faltungsschicht
        filter_num = conv_param['filter_num']
        filter_size = conv_param['filter_size']
        filter_pad = conv_param['pad']
        filter_stride = conv_param['stride']
        input_size = input_dim[1]
        conv_output_size = (input_size - filter_size + 2*filter_pad) / filter_stride + 1
        pool_output_size = int(filter_num * (conv_output_size/2) * (conv_output_size/2))

        #Gewichtsinitialisierung
        self.params = {}
        self.params['W1'] = weight_init_std * \
                            np.random.randn(filter_num, input_dim[0], filter_size, filter_size)
        self.params['b1'] = np.zeros(filter_num)
        self.params['W2'] = weight_init_std * \
                            np.random.randn(pool_output_size, hidden_size)
        self.params['b2'] = np.zeros(hidden_size)
        self.params['W3'] = weight_init_std * \
                            np.random.randn(hidden_size, output_size)
        self.params['b3'] = np.zeros(output_size)

        #Schichterzeugung
        self.layers = OrderedDict()
        self.layers['Conv1'] = Convolution(self.params['W1'], self.params['b1'],
                                           conv_param['stride'], conv_param['pad'])
        self.layers['Relu1'] = Relu()
        self.layers['Pool1'] = Pooling(pool_h=2, pool_w=2, stride=2)
        self.layers['Affine1'] = Affine(self.params['W2'], self.params['b2'])
        self.layers['Relu2'] = Relu()
        self.layers['Affine2'] = Affine(self.params['W3'], self.params['b3'])

        self.last_layer = SoftmaxWithLoss()

    #Machen Sie einen Abzug
    def predict(self, x):
        for layer in self.layers.values():
            x = layer.forward(x)

        return x

    #Finden Sie die Verlustfunktion
    def loss(self, x, t):
        """Finden Sie die Verlustfunktion
Argument x sind Eingabedaten, t ist Lehrerbezeichnung
        """
        y = self.predict(x)
        return self.last_layer.forward(y, t)

    def accuracy(self, x, t, batch_size=100):
        if t.ndim != 1 : t = np.argmax(t, axis=1)
        
        acc = 0.0
        
        for i in range(int(x.shape[0] / batch_size)):
            tx = x[i*batch_size:(i+1)*batch_size]
            tt = t[i*batch_size:(i+1)*batch_size]
            y = self.predict(tx)
            y = np.argmax(y, axis=1)
            acc += np.sum(y == tt) 
        
        return acc / x.shape[0]

    def numerical_gradient(self, x, t):
        """Finden Sie den Gradienten (numerische Differenzierung)

        Parameters
        ----------
        x :Eingabedaten
        t :Lehreretikett

        Returns
        -------
Wörterbuchvariable mit Farbverlauf jeder Ebene
            grads['W1']、grads['W2']、...Ist das Gewicht jeder Schicht
            grads['b1']、grads['b2']、...Ist die Vorspannung jeder Schicht
        """
        loss_w = lambda w: self.loss(x, t)

        grads = {}
        for idx in (1, 2, 3):
            grads['W' + str(idx)] = numerical_gradient(loss_w, self.params['W' + str(idx)])
            grads['b' + str(idx)] = numerical_gradient(loss_w, self.params['b' + str(idx)])

        return grads

    def gradient(self, x, t):
        """Finden Sie den Gradienten (Fehlerrückausbreitungsmethode)

        Parameters
        ----------
        x :Eingabedaten
        t :Lehreretikett

        Returns
        -------
Wörterbuchvariable mit Farbverlauf jeder Ebene
            grads['W1']、grads['W2']、...Ist das Gewicht jeder Schicht
            grads['b1']、grads['b2']、...Ist die Vorspannung jeder Schicht
        """
        # forward
        self.loss(x, t)

        # backward
        dout = 1
        dout = self.last_layer.backward(dout)

        layers = list(self.layers.values())
        layers.reverse()
        for layer in layers:
            dout = layer.backward(dout)

        #Aufbau
        grads = {}
        grads['W1'], grads['b1'] = self.layers['Conv1'].dW, self.layers['Conv1'].db
        grads['W2'], grads['b2'] = self.layers['Affine1'].dW, self.layers['Affine1'].db
        grads['W3'], grads['b3'] = self.layers['Affine2'].dW, self.layers['Affine2'].db

        return grads
        
    def save_params(self, file_name="params.pkl"):
        params = {}
        for key, val in self.params.items():
            params[key] = val
        with open(file_name, 'wb') as f:
            pickle.dump(params, f)

    def load_params(self, file_name="params.pkl"):
        with open(file_name, 'rb') as f:
            params = pickle.load(f)
        for key, val in params.items():
            self.params[key] = val

        for i, key in enumerate(['Conv1', 'Affine1', 'Affine2']):
            self.layers[key].W = self.params['W' + str(i+1)]
            self.layers[key].b = self.params['b' + str(i+1)]

Der Punkt ist, dass es einfach implementiert werden kann, indem die Anzahl der Ebenen und der Wert des in der verborgenen Ebene verwendeten Hyperparameters erhöht werden.

Führen Sie das Lernen durch Außerdem hatte mein Macbook Air eine hohe CPU-Auslastung, sodass ich die Datenreduktion auskommentierte und ausführte.

# coding: utf-8
import sys, os
sys.path.append(os.pardir)  #Einstellungen zum Importieren von Dateien in das übergeordnete Verzeichnis
import numpy as np
import matplotlib.pyplot as plt
from dataset.mnist import load_mnist
from simple_convnet import SimpleConvNet
from common.trainer import Trainer

#Daten lesen
(x_train, t_train), (x_test, t_test) = load_mnist(flatten=False)

#Daten reduzieren, wenn die Verarbeitung Zeit braucht
#x_train, t_train = x_train[:5000], t_train[:5000]
#x_test, t_test = x_test[:1000], t_test[:1000]

max_epochs = 20

network = SimpleConvNet(input_dim=(1,28,28), 
                        conv_param = {'filter_num': 30, 'filter_size': 5, 'pad': 0, 'stride': 1},
                        hidden_size=100, output_size=10, weight_init_std=0.01)
                        
trainer = Trainer(network, x_train, t_train, x_test, t_test,
                  epochs=max_epochs, mini_batch_size=100,
                  optimizer='Adam', optimizer_param={'lr': 0.001},
                  evaluate_sample_num_per_epoch=1000)
trainer.train()

#Parameter speichern
network.save_params("params.pkl")
print("Saved Network Parameters!")

#Zeichnen eines Diagramms
markers = {'train': 'o', 'test': 's'}
x = np.arange(max_epochs)
plt.plot(x, trainer.train_acc_list, marker='o', label='train', markevery=2)
plt.plot(x, trainer.test_acc_list, marker='s', label='test', markevery=2)
plt.xlabel("epochs")
plt.ylabel("accuracy")
plt.ylim(0, 1.0)
plt.legend(loc='lower right')
plt.show()

…… train loss:0.0145554384445 train loss:0.0275851756417 train loss:0.00785021651885 train loss:0.00986611950473 =============== Final Test Accuracy =============== test acc:0.956 Saved Network Parameters!

image.png

Visualisierung von CNN

Visualisierung von Gewichten in der ersten Schicht

Vor dem Lernen: Es gibt keine Regelmäßigkeit in Schwarz- und Weißtönen, da der Filter zufällig initialisiert wird. image.png

Nach dem Lernen: regelmäßig image.png

Was ist ein Filter mit einer solchen Regelmäßigkeit "betrachten"? ・ ** Kante **: Rand, an dem sich die Farbe ändert ・ ** Blob **: Lokal klumpiger Bereich

Extrahieren Sie Nachtinformationen in eine hierarchische Struktur

Faltung der ersten Schicht: Extrahiert Informationen auf niedriger Ebene wie Kanten und Blobs Mehrere Faltungsebenen stapeln: Komplexere und abstraktere Informationen extrahieren

Die folgende DEMO 1 wurde mit http://vision03.csail.mit.edu/cnn_art/index.html#v_single zitiert

In der Demo war es wie folgt. Cov1: Kante, Blob (Kante + Blob) Cov3: Textur Cov5: Objektteile Fc8: Objektklassen wie Hunde und Katzen

Wenn die Schicht tiefer wird, ändern sich die Neuronen von einfachen Formen zu "erweiterten" Informationen **. Mit anderen Worten, es ist der Tag, an dem sich das Objekt, das reagiert, ändert, damit Sie die "Bedeutung" der Dinge verstehen können.

Typisches CNN

Dieses Buch erklärt Folgendes ・ CNN, das erstmals 1998 vorgeschlagen wurde, ist auch das ursprüngliche LeNet ・ AlexNet im Jahr 2012, als tiefes Lernen Aufmerksamkeit erregte

LeNet

Die folgenden Punkte unterscheiden sich im Vergleich zu "Current CNN" ・ Verwenden Sie die Sigmoid-Funktion für die Aktivierungsfunktion (Derzeit ReLU-Funktion) ・ Die Größe der Zwischendaten wird durch Unterabtastung reduziert. (Derzeit Max Pooling) http://dx.doi.org/10.1109/5.726791

AlexNet

AlexNet stapelt die Faltungsschicht und die Poolschicht und gibt das Ergebnis schließlich über die vollständig verbundene Schicht aus. Die folgenden Punkte unterscheiden sich von LeNet

Jetzt und in der Vergangenheit

Es gibt keinen großen Unterschied zwischen LeNet und AlexNe in der Netzwerkkonfiguration, aber es wurden große Fortschritte in der Computertechnologie erzielt. Speziell ・ Eine große Datenmenge steht jetzt jedem zur Verfügung ・ GPUs, die sich auf große Mengen paralleler Berechnungen spezialisiert haben, sind weit verbreitet und ermöglichen es, große Mengen von Operationen mit hoher Geschwindigkeit auszuführen.

Recommended Posts

[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 / 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 Memo von Grund auf neu gemacht
Deep Learning / Deep Learning von Null 2 Kapitel 6 Memo
"Deep Learning from Grund" Memo zum Selbststudium (Teil 12) Deep Learning
Selbststudien-Memo "Deep Learning from Grund" (unlesbares Glossar)
Deep Learning von Grund auf 1-3 Kapitel
"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 from Grund" Memo zum Selbststudium (Nr. 19) Datenerweiterung
Anwendung von Deep Learning 2 von Grund auf neu Spam-Filter
Tiefes Lernen von Grund auf neu (Kostenberechnung)
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
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
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
Tiefes Lernen von Grund auf neu (Vorwärtsausbreitung)
Tiefes Lernen / Tiefes Lernen von Grund auf 2-Versuchen Sie, GRU zu bewegen
"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
Schreiben Sie Ihre Eindrücke von der Deep Learning 3 Framework Edition, die von Grund auf neu erstellt wurde
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
Kapitel 3 Neuronales Netz Schneiden Sie nur die guten Punkte des Deeplearning aus, die von Grund auf neu erstellt wurden
Django Memo # 1 von Grund auf neu
"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
Kapitel 2 Implementierung von Perceptron Schneiden Sie nur die guten Punkte des Deeplearning aus, die von Grund auf neu erstellt wurden
GitHub des guten Buches "Deep Learning von Grund auf neu"
Python vs Ruby "Deep Learning von Grund auf neu" Zusammenfassung
Python vs Ruby "Deep Learning von Grund auf neu" Kapitel 2 Logikschaltung von Perceptron