[PYTHON] Versuchen Sie, ein Deep Learning / Neuronales Netzwerk mit Scratch aufzubauen

1. Zuallererst

Dieses Mal werde ich versuchen, ein sich tatsächlich bewegendes neuronales Netzwerk mit Scratch zu implementieren, um die Vorwärtsausbreitung und die Fehlerrückausbreitung zu verstehen. Der Datensatz verwendet MNIST.

2. Neuronale Netzspezifikationen

Bei einem neuronalen Netzwerk mit 28 x 28 = 784 Eingangsschichten, 10 Zwischenschichten und 2 Ausgangsschichten ist die Aktivierungsfunktion / Fehlerfunktion sigmoid und die Optimierungsmethode ist die Gradientenabstiegsmethode.

Für den Datensatz werden "1" und "7" aus MNIST extrahiert und eine binäre Klassifizierung durchgeführt. スクリーンショット 2020-03-16 09.00.03.png

3. Vorwärtsausbreitung

Erstens, wenn Sie $ a ^ 0_0 $ berechnen, gibt es 784 Eingaben von $ x ^ 0_0 $ bis $ x ^ 0_ {783} $, jede mit den Gewichten $ w ^ 0_ {00} $ bis $ w ^ 0_ {783,0} $ ist also aufgehängt スクリーンショット 2020-03-16 09.12.07.png

Als Matrix ausgedrückt können alle Berechnungen von $ a ^ 0_0 $ bis $ a ^ 0_9 $ leicht dargestellt werden. スクリーンショット 2020-03-16 09.19.28.png

Da $ x ^ 1_0 $ bis $ x ^ 1_9 $ das Ergebnis der Übergabe von $ a ^ 0_0 $ an $ a ^ 0_9 $ durch die Aktivierungsfunktion Sigmoid ist, スクリーンショット 2020-03-16 09.21.38.png

Wenn Sie als nächstes $ a ^ 1_0 $ berechnen, gibt es 10 Eingaben von $ x ^ 1_0 $ bis $ x ^ 1_9 $ mit jeweils Gewichten von $ w ^ 1_ {00} $ bis $ w ^ 1_ {90. } $ Ist aufgehängt, also スクリーンショット 2020-03-16 09.25.48.png

Wenn $ a ^ 1_0 $ und $ a ^ 1_1 $ durch eine Matrix dargestellt werden, スクリーンショット 2020-03-16 18.33.38.png

Schließlich sind $ y ^ 0 $ und $ y ^ 1 $ スクリーンショット 2020-03-16 19.29.15.png

Auf diese Weise kann die Vorwärtsausbreitung leicht durch das innere Produkt der Matrix oder Addition durchgeführt werden.

4. Fehlerrückübertragung (von der Zwischenschicht zur Ausgangsschicht)

Aktualisieren Sie zunächst die Gewichte und Verzerrungen von der mittleren Ebene zur Ausgabeebene.

Der Aktualisierungsausdruck für das Gewicht w kann durch $ w = w- \ eta * \ frac {\ partielles E} {\ partielles w} $ dargestellt werden. Wobei $ \ eta $ die Lernrate ist und $ \ frac {\ partielles E} {\ partielles w} $ der Fehler E ist, der durch das Gewicht w differenziert wird.

Geben wir ein konkretes Beispiel für $ \ frac {\ partielles E} {\ partielles w} $ und drücken es mit einer allgemeinen Formel aus, um es zu implementieren. Zunächst die Gewichte von der mittleren Ebene zur Ausgabeebene.

スクリーンショット 2020-03-15 19.10.21.png Suchen Sie $ \ frac {\ partielles E ^ 0} {\ partielles w ^ 1_ {00}} $, um das Gewicht $ w ^ 1_ {00} $ zu aktualisieren. Aus dem Kettenverhältnis der Differenzierung スクリーンショット 2020-03-15 19.14.30.png Ausgedrückt als allgemeine Formel, k = 0 bis 9, j = 0 bis 1, スクリーンショット 2020-03-16 08.44.27.png Dadurch kann das Gewicht $ w ^ 1_ {kj} $ aktualisiert werden. Was die Verzerrung betrifft, ist $ b ^ 1 $ 1, also ersetzt $ x ^ 1_k $ in der obigen Formel nur 1. スクリーンショット 2020-03-16 10.02.58.png Dadurch kann der Bias $ b ^ 1_j $ aktualisiert werden.

5. Fehlerrückausbreitung (von der Eingabeschicht zur Zwischenschicht)

Als nächstes werden die Gewichte und Verzerrungen von der Eingabeebene zur mittleren Ebene aktualisiert.

スクリーンショット 2020-03-16 10.15.30.png

Um das Gewicht $ w ^ 0_ {00} $, $ \ frac {\ partielles E ^ 0} {\ partielles w ^ 0_ {00}} $ und $ \ frac {\ partielles E ^ 1} {\ zu aktualisieren Sie müssen teilweise w ^ 0_ {00}} $ finden. Aus dem Kettenverhältnis der Differenzierung スクリーンショット 2020-03-16 08.32.17.png Ausgedrückt als allgemeine Formel, k = 0 bis 783, j = 0 bis 9, スクリーンショット 2020-03-16 08.33.56.png Dadurch kann das Gewicht $ w ^ 0_ {kj} $ aktualisiert werden. Was die Verzerrung betrifft, ist $ b ^ 0 $ 1, also ersetzt $ x ^ 0_k $ in der obigen Formel nur 1. スクリーンショット 2020-03-16 10.11.34.png Dadurch kann der Bias $ b ^ 0_j $ aktualisiert werden.

6. Implementierung des Vorwärtsausbreitungs- und Fehlerrücklaufausbreitungsteils

Implementieren Sie basierend auf der zuvor erhaltenen allgemeinen Formel die Teile Vorwärtsausbreitung und Fehlerrückausbreitung.

#Sigmaid-Funktion
def sigmoid(a):
    return 1 / (1 + np.exp(-a))

#Differenzierung der Sigmoidfunktion
def sigmoid_d(a):
    return (1 - sigmoid(a)) * sigmoid(a)

#Fehler bei der Weitergabe
def back(l, j):
    if l == max_layer - 1:
        return (y[j] - t[j]) * sigmoid_d(A[l][j])
    else:
        output = 0
        m = A[l+1].shape[0]   
        for i in range(m):
            output += back(l+1, i) * W[l+1][i,j] * sigmoid_d(A[l][j])
        return output

Die spezifische Bewegung von def back (l, j): ist

Wenn "l = 1", (y [j] -t [j]) * sigmoid_d (A [1] [j]) wird zurückgegeben.

Wenn "l = 0",  (y[0]-t[0])*sigmoid_d(A[1][0])*W[1][0,j]*sigmoid_d(A[0][j])  +(y[1]-t[1])*sigmoid_d(A[1][1])*W[1][1,j]*sigmoid_d(A[0][j]) Ist zurück gekommen.

#Gewicht W Einstellung
np.random.seed(seed=7)
w0 = np.random.normal(0.0, 1.0, (10, 784))
w1 = np.random.normal(0.0, 1.0, (2, 10))
W = [w0, w1]

#Bias b Einstellung
b0 = np.ones((10, 1))
b1 = np.ones((2, 1))
B = [b0, b1]

#Andere Einstellungen
max_layer = 2 #Festlegen der Anzahl der Ebenen
n = 0.5  #Einstellung der Lernrate

Stellen Sie das Gewicht W, die Vorspannung b und andere Einstellungen ein.

スクリーンショット 2020-03-16 19.48.21.png Jeder Term der Gewichtsmatrix w0 und w1 ist eine Zufallszahl, die einer Normalverteilung von 0 bis 1 folgt, damit das Lernen reibungslos beginnen kann. Übrigens, wenn Sie den Startwert = Anzahl von np.random.seed (seed = 7) ändern, ändert sich die Startbedingung des Lernens (ob es reibungslos beginnt oder etwas träge ist). Jeder Term der Vorspannungsmatrizen b0 und b1 ist 1.

#Lernschleife
count = 0 
acc = []

for x, t in zip(xs, ts):
    
    #Vorwärtsausbreitung
    x0 = x.flatten().reshape(784, 1)
    a0 = W[0].dot(x0) + B[0]
    x1 = sigmoid(a0)
    a1 = W[1].dot(x1) + B[1]
    y = sigmoid(a1)

    #X für Parameteraktualisierung,Liste a
    X = [x0, x1]
    A = [a0, a1]

    #Parameteraktualisierung
    for l in range(len(X)):
        for j in range(W[l].shape[0]):
            for k in range(W[l].shape[1]):
                W[l][j, k] = W[l][j, k] - n * back(l, j) * X[l][k]  
            B[l][j] = B[l][j] - n * back(l, j) 

Es ist eine Lernschleife. Die Vorwärtsausbreitung kann leicht durch das innere Produkt der Matrix, Addition usw. durchgeführt werden. In der Parameteraktualisierung

Wenn "l = 0" im Bereich von "j = 0 bis 9" ist, ist k = 0 bis 783 "  W[0][j,k] = W[0][j,k] - n * back(0,j) * X[0][k]  B[0][j] = B[0][j] - n * back(0,j) Wird Aktualisiert.

Wenn "l = 1" im Bereich von "j = 0 bis 1" ist, ist k = 0 bis 9 "  W[1][j,k] = W[1][j,k] - n * back(0,j) * X[0][k]  B[1][j] = B[1][j] - n * back(0,j) Wird Aktualisiert.

7. Datensatzvorbereitung

Lesen Sie den MNIST-Datensatz mit Keras und extrahieren Sie nur "1" und "7".

import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils
import matplotlib.pyplot as plt

#Numerische Anzeige
def show_mnist(x):
    fig = plt.figure(figsize=(7, 7))   
    for i in range(100):
        ax = fig.add_subplot(10, 10, i+1, xticks=[], yticks=[])
        ax.imshow(x[i].reshape((28, 28)), cmap='gray')
    plt.show()

#Datensatz lesen
(x_train, y_train), (x_test, y_test) = mnist.load_data()
show_mnist(x_train)

# 1,7 extrahiert
x_data, y_data = [], []
for i in range(len(x_train)):  
    if y_train[i] == 1 or y_train[i] == 7:
       x_data.append(x_train[i])
       if y_train[i] == 1:
          y_data.append(0)
       if y_train[i] == 7:
          y_data.append(1)

show_mnist(x_data)

#Konvertieren Sie vom Listenformat in das Numpy-Format
x_data = np.array(x_data)
y_data = np.array(y_data)

# x_Normalisierung von Daten, y_One-Hot-Darstellung von Daten
x_data = x_data.astype('float32')/255
y_data = np_utils.to_categorical(y_data)

#Lernen Sie, erhalten Sie Testdaten
xs = x_data[0:200]
ts = y_data[0:200]  
xt = x_data[2000:3000]  
tt = y_data[2000:3000] 

スクリーンショット 2020-03-16 14.42.10.png スクリーンショット 2020-03-16 14.42.25.png Die Daten von 0 bis 9 und die Daten, aus denen 1 und 7 extrahiert werden, werden von Anfang an angezeigt.

Bereiten Sie 200 Trainingsdaten xs und ts sowie 1.000 Testdaten xt und tt vor.

8. Ganze Implementierung

Es ist die gesamte Implementierung mit der Hinzufügung einer Genauigkeitsbestätigung durch Testdaten und einer Anzeige des Genauigkeitsübergangsdiagramms für jedes Lernen.

import numpy as np
from keras.datasets import mnist
from keras.utils import np_utils

#Datensatz lesen
(x_train, y_train), (x_test, y_test) = mnist.load_data()

# 1,Extrahieren Sie nur 7 Zahlen
x_data, y_data = [], []
for i in range(len(x_train)):  
    if y_train[i] == 1 or y_train[i] == 7:
       x_data.append(x_train[i])
       if y_train[i] == 1:
          y_data.append(0)
       if y_train[i] == 7:
          y_data.append(1)

#Konvertieren Sie vom Listenformat in das Numpy-Format
x_data = np.array(x_data)
y_data = np.array(y_data)

# x_Normalisierung von Daten, y_Eine heiße Daten
x_data = x_data.astype('float32')/255
y_data = np_utils.to_categorical(y_data)

#Erfassung von Trainingsdaten und Testdaten
xs = x_data[0:200]  
ts = y_data[0:200]  
xt = x_data[2000:3000]  
tt = y_data[2000:3000]  


#Sigmaid-Funktion
def sigmoid(a):
    return 1 / (1 + np.exp(-a))

#Differenzierung der Sigmoidfunktion
def sigmoid_d(a):
    return (1 - sigmoid(a)) * sigmoid(a)

#Fehler bei der Weitergabe
def back(l, j):
    if l == max_layer - 1:
        return (y[j] - t[j]) * sigmoid_d(A[l][j])
    else:
        output = 0
        m = A[l+1].shape[0]   
        for i in range(m):
            output += back(l + 1, i) * W[l + 1][i, j] * sigmoid_d(A[l][j])
        return output

#Gewicht W Einstellung
np.random.seed(seed=7)
w0 = np.random.normal(0.0, 1.0, (10, 784))
w1 = np.random.normal(0.0, 1.0, (2, 10))
W = [w0, w1]

#Bias b Einstellung
b0 = np.ones((10, 1))
b1 = np.ones((2, 1))
B = [b0, b1]

#Andere Einstellungen
max_layer = 2 #Festlegen der Anzahl der Ebenen
n = 0.5  #Einstellung der Lernrate

#Lernschleife
count = 0 
acc = []

for x, t in zip(xs, ts):
    
    #Vorwärtsausbreitung
    x0 = x.flatten().reshape(784, 1)
    a0 = W[0].dot(x0) + B[0]
    x1 = sigmoid(a0)
    a1 = W[1].dot(x1) + B[1]
    y = sigmoid(a1)

    #X für Parameteraktualisierung,Liste a
    X = [x0, x1]
    A = [a0, a1]

    #Parameteraktualisierung
    for l in range(len(X)):
        for j in range(W[l].shape[0]):
            for k in range(W[l].shape[1]):
                W[l][j, k] = W[l][j, k] - n * back(l, j) * X[l][k]  
            B[l][j] = B[l][j] - n * back(l, j) 
            
    #Genauigkeitsprüfung durch Testdaten
    correct, error = 0, 0

    for i in range(1000):

        #Rückschluss auf gelernte Parameter
        x0 = xt[i].flatten().reshape(784, 1)
        a0 = W[0].dot(x0) + B[0]
        x1 = sigmoid(a0)
        a1 = W[1].dot(x1) + B[1]
        y = sigmoid(a1)
    
        if np.argmax(y) == np.argmax(tt[i]):
           correct += 1
        else:
           error += 1
    calc = correct/(correct+error)
    acc.append(calc)
    count +=1
    print("\r[%s] acc: %s"%(count, calc))
   
#Anzeige des Genauigkeitsübergangsdiagramms
import matplotlib.pyplot as plt
plt.plot(acc, label='acc')
plt.legend()
plt.show()   

スクリーンショット 2020-03-16 17.21.46.png In 200 Schritten betrug die Klassifizierungsgenauigkeit 97,8%. Es wäre großartig, wenn das neuronale Netzwerk, das ich durch Scratchen implementiert habe, ordnungsgemäß funktioniert.

Recommended Posts

Versuchen Sie, ein Deep Learning / Neuronales Netzwerk mit Scratch aufzubauen
Verstärkungslernen 10 Versuchen Sie es mit einem trainierten neuronalen Netz.
[Deep Learning von Grund auf neu] Informationen zu den Ebenen, die für die Implementierung der Backpropagation-Verarbeitung in einem neuronalen Netzwerk erforderlich sind
Versuchen Sie es mit TensorFlow
Versuchen Sie Deep Learning mit FPGA
Probieren Sie Deep Learning mit FPGA-Select-Gurken aus
[Evangelion] Versuchen Sie, mit Deep Learning automatisch Asuka-ähnliche Linien zu erzeugen
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 16) Ich habe versucht, SimpleConvNet mit Keras zu erstellen
Versuchen Sie es mit TensorFlow Part 2
(Jetzt) Erstellen Sie eine GPU Deep Learning-Umgebung mit GeForce GTX 960
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 17) Ich habe versucht, DeepConvNet mit Keras zu erstellen
[Deep Learning] Bildklassifizierung mit Faltungsnetz [DW Tag 4]
Ich habe versucht, in einem tief erlernten Sprachmodell zu schreiben
Lua-Version Deep Learning von Grund auf neu Teil 6 [Inferenzverarbeitung für neuronale Netze]
Einführung in Deep Learning (2) - Versuchen Sie Ihre eigene nichtlineare Regression mit Chainer-
Komponieren Sie mit einem neuronalen Netzwerk! Führen Sie Magenta aus
Tiefes Lernen / Tiefes Lernen von Grund auf 2-Versuchen Sie, GRU zu bewegen
Probieren Sie die Bitcoin-Preisprognose mit Deep Learning aus
Versuchen Sie es mit Chainer Deep Q Learning - Launch
Versuchen Sie mit Kipoi tiefes Erlernen der Genomik
Erstellen Sie mithilfe des TensorFlow-Faltungsnetzwerks einen Klassifikator mit einer Handschrifterkennungsrate von 99,2%
PPLM: Eine einfache Deep-Learning-Technik zum Generieren von Sätzen mit bestimmten Attributen
Erstellen Sie mit Cloud9 (jupyter miniconda python3) eine Lernumgebung für "Deep Learning von Grund auf neu".
Experimentieren Sie mit verschiedenen Optimierungsalgorithmen im neuronalen Netz
Deep Learning von Grund auf neu ① Kapitel 6 "Lerntechniken"
Versuchen Sie, mit Python eine Lebenskurve zu zeichnen
Versuchen Sie, in Python einen "Entschlüsselungs" -Code zu erstellen
Versuchen Sie, mit Python eine Diedergruppe zu bilden
Erstellen Sie eine Python-Umgebung für maschinelles Lernen mit Containern
Python vs Ruby "Deep Learning von Grund auf neu" Kapitel 3 Implementierung eines dreischichtigen neuronalen Netzwerks
Erstellen Sie eine Python-Umgebung, um die Theorie und Implementierung von Deep Learning zu erlernen
Ich habe versucht, die Strichzeichnung mit Deep Learning aus dem Bild zu extrahieren
[Deep Learning von Grund auf neu] Anfangswert des Gewichts des neuronalen Netzwerks unter Verwendung der Sigmoid-Funktion
Deep Learning von Grund auf neu
Eine Geschichte über die Vorhersage des Wechselkurses mit Deep Learning
Trainieren Sie MNIST-Daten mit PyTorch mithilfe eines neuronalen Netzwerks
Lassen Sie uns ein Befehls-Standby-Tool mit Python erstellen
Versuchen Sie, mit Tkinter in Python dynamisch einen Checkbutton zu erstellen
Ich möchte mit verstärkendem Lernen einen Berg besteigen
Versuchen Sie, den Wechselkurs (FX) mit nicht tiefem maschinellem Lernen vorherzusagen
Erstellen Sie mit Python eine Entwicklungsumgebung für maschinelles Lernen
Ein Beispiel, um Faktorisierungsmaschinen schnell mit fastFM auszuprobieren
Anfänger des maschinellen Lernens versuchen, einen Entscheidungsbaum zu erstellen
[Deep Learning] Führen Sie die neuronale SONY-Netzwerkkonsole über CUI aus
Grundlagen von PyTorch (2) - Wie erstelle ich ein neuronales Netzwerk?
Learning Deep Forest, ein neues Lerngerät, das mit DNN vergleichbar ist
Ich habe versucht, Dropout zu erklären
Erstellen Sie mit Winsows 10 eine maschinelle Lernumgebung von Grund auf neu
Wagen Sie es, mit Ruby zu lernen "Deep Learning from Grund von Grund auf neu" Importieren von Pickle-Dateien aus verbotenem PyCall
Erstellen Sie durch tiefes Lernen einen "Bot, der Ihnen AV-Schauspielerinnen mit ähnlichen Gesichtern sagt"
Schritte zum schnellen Erstellen einer umfassenden Lernumgebung auf einem Mac mit TensorFlow und OpenCV
[Deep Learning von Grund auf neu] Anfangsgewicht des neuronalen Netzwerks bei Verwendung der Relu-Funktion
Ich habe versucht, das grundlegende Modell des wiederkehrenden neuronalen Netzwerks zu implementieren
Implementieren Sie ein dreischichtiges neuronales Netzwerk
Erstellen Sie eine Web-App, die Zahlen mit einem neuronalen Netzwerk erkennt
Versuchen Sie, den Boden durch Rekursion herauszufordern
Deep Learning von Grund auf 1-3 Kapitel
Eine Python-Probe zum Lernen von XOR mit einem genetischen Algorithmus in einem neuronalen Netz
Erstellen Sie mit VirtualBox und Ubuntu eine Scikit-Lernumgebung für maschinelles Lernen
[Deep Learning] Untersuchen Sie, wie jede Funktion des Faltungsnetzes verwendet wird [DW Tag 3]