PRML Kapitel 5 Python-Implementierung für neuronale Netze

In Kapitel 5 von PRML werden die kürzlich populären neuronalen Netze vorgestellt. Es gibt viele Arten von Dingen, bei denen ich versucht habe, ein neuronales Netzwerk im Netz zu implementieren. Deshalb wollte ich etwas verwenden, mit dem ich nicht so gut wie möglich vertraut war. Deshalb habe ich beschlossen, ein Netzwerk mit gemischter Dichte fast ausschließlich mit Numpy zu implementieren. Da die Codemenge jedoch ziemlich groß geworden ist, werde ich sie in zwei Teile teilen, und in diesem Artikel werde ich schließlich ein normales neuronales Netzwerk implementieren und das nächste Mal das Netzwerk mit gemischter Dichte ausführen.

neurales Netzwerk

Netzwerkstruktur

2000px-Artificial_neural_network.svg.png Dies bedeutet, dass die Eingabeeinheit 3D $ {\ bf x} = (x_1, x_2, x_3) $ ist, die verborgene Einheit 4D $ {\ bf z} = (z_1, z_2, z_3, z_4) $ und die Ausgabeeinheit 2 ist. Dies ist eine schematische Darstellung eines zweischichtigen neuronalen Netzwerks mit den Dimensionen $ {\ bf z} = (z_1, z_2) . Von der Eingabe ist die verborgene Einheit die erste Ebene ( {\ bf x} \ bis {\ bf z} ), und von der verborgenen Einheit ist die Ausgabe die zweite Ebene ( {\ bf z} \ bis {\ bf y} $). Es ist geworden. Die Abmessungen der Einheit, die Anzahl der Schichten usw. müssen je nach Problem geändert werden.

Vorwärtsausbreitung

Die Vorwärtsausbreitung ist der Schritt der Berechnung der Ausgabe des Netzwerks aus der Eingabe. Berechnen Sie die versteckte Einheit $ {\ bf z} $ aus der Eingabe $ {\ bf x} $ und dann die Ausgabe $ {\ bf y} $ aus der versteckten Einheit $ {\ bf z} $.

Eine der versteckten Einheiten der ersten Ebene, $ z_1 $,

\begin{align}
a_{z_1} &= w_{11}^{(1)}x_1+w_{12}^{(1)}x_2+w_{13}^{(1)}x_3 + b_1^{(1)}\\
z_1 &= f^{(1)}(a_{z_1})
\end{align}

Ist berechnet. Wo $ a_ {z_1} $ die Aktivität der ersten versteckten Einheit ist, ist $ w_ {1j} ^ {(1)} $ das Gewicht von der j-ten Eingabeeinheit zur ersten versteckten Einheit, $ b_1 $ ist Die Vorspannung der ersten verborgenen Einheit, $ f ^ {(1)} $, ist die Aktivierungsfunktion der ersten Schicht.

Es ist möglich, die gleichen Formeln für $ z_2, z_3, z_4 $ zu formulieren, aber es wird kompliziert, drei Formeln zu haben, daher verwende ich oft eine Matrix.

\begin{align}
\begin{bmatrix}
a_{z_1}\\
a_{z_2}\\
a_{z_3}\\
a_{z_4}
\end{bmatrix}
&=
\begin{bmatrix}
w_{11}^{(1)} & w_{12}^{(1)} & w_{13}^{(1)}\\
w_{21}^{(1)} & w_{22}^{(1)} & w_{23}^{(1)}\\
w_{31}^{(1)} & w_{32}^{(1)} & w_{33}^{(1)}\\
w_{41}^{(1)} & w_{42}^{(1)} & w_{43}^{(1)}
\end{bmatrix}
\begin{bmatrix}
x_1\\
x_2\\
x_3
\end{bmatrix}
+
\begin{bmatrix}
b_1^{(1)}\\
b_2^{(1)}\\
b_3^{(1)}\\
b_4^{(1)}
\end{bmatrix}
\\
\begin{bmatrix}
z_1\\
z_2\\
z_3\\
z_4
\end{bmatrix}
&=
\begin{bmatrix}
f^{(1)}(a_{z_1})\\
f^{(1)}(a_{z_2})\\
f^{(1)}(a_{z_3})\\
f^{(1)}(a_{z_4})
\end{bmatrix}
\end{align}

Machen Sie dies prägnanter

\begin{align}
{\bf a}_z &= W^{(1)}{\bf x} + {\bf b}^{(1)}\\
{\bf z} &= f^{(1)}({\bf a}_z)
\end{align}

Auch ausgedrückt als. Dies vervollständigt die Vorwärtsausbreitung der ersten Schicht.

In gleicher Weise die zweite Schicht

\begin{align}
{\bf a}_y &= W^{(2)}{\bf y} + {\bf b}^{(2)}\\
{\bf y} &= f^{(2)}({\bf a}_y)
\end{align}

Kann ausgedrückt werden als.

Übrigens, um diese zusammenzufassen,

{\bf y} = f^{(2)}(W^{(2)}f^{(1)}(W^{(1)}{\bf x} + {\bf b}^{(1)}) + {\bf b}^{(2)})

Es wird sein. Auf diese Weise können Sie von Eingabe zu Ausgabe berechnen.

Backpropagation

Das neuronale Netzwerk hat viele Parameter (26 in diesem Beispiel). Backpropagation ist eine effiziente Methode zur Berechnung dieser Gradienten. Eingang und sein Zielpaar\\{{\bf x}, {\bf t}\\}Und die Kostenfunktion, die Sie minimieren möchtenENachdenken über. Erstens Eingabe durch Vorwärtsausbreitung{\bf x}Netzwerkausgabe von{\bf y}Berechnen. Dann kann zum Beispiel die Kostenfunktion berechnet werdenE=||{\bf t} - {\bf y}||^2Und das Ziel{\bf t}Es wird ein Fehler mit auftreten. Dieser Fehler wird an den Eingang weitergegeben. Der Fehler in der Ausgabeschicht, eigentlich die teilweise Differenzierung in der Ausgabe der Kostenfunktion, ist

{\partial E\over\partial y_i}

ist. Dabei wird der Fehler von $ {\ bf a} \ _y $ und die teilweise Differenzierung der Kostenfunktion bei $ {\ bf a} \ _y $

\begin{align}
{\partial E\over\partial a_{y_i}} &= {\partial E\over\partial y_i}{\partial y_i\over\partial a_{y_i}}\\
&= {\partial E\over\partial y_i}f'^{(2)}(a_{y_i})\\
(&= y_i - t_i)
\end{align}

Es wird erhalten als. Wenn die Aktivierungsfunktion der Ausgabeschicht $ f ^ {(2)} $ eine kanonische Verkettungsfunktion ist, wie z. B. eine konstante Zuordnung, eine Sigmoidfunktion oder eine Softmax-Funktion, ist der Fehler von ** $ {\ bf a} _y $ einfach. Der Unterschied zwischen der Ausgabe und dem Ziel **. Wenn der Fehler von $ {\ bf a} _y $ gefunden wird, kann der Gradient des Gewichts in der zweiten Schicht gefunden werden. weil

\begin{align}
{\partial a_{y_i}\over\partial w_{ij}^{(2)}} &= z_j\\
{\partial a_{y_i}\over\partial b_i^{(2)}} &= 1
\end{align}

Als,

\begin{align}
{\partial E\over\partial w_{ij}^{(2)}} &= {\partial E\over\partial a_{y_i}}{\partial a_{y_i}\over\partial w_{ij}^{(2)}}\\
&= {\partial E\over\partial a_{y_i}}z_j\\
{\partial E\over\partial b_i^{(2)}} &= {\partial E\over\partial a_{y_i}}{\partial a_{y_i}\over\partial b_i^{(2)}}\\
&= {\partial E\over\partial a_{y_i}}
\end{align}

Und kann berechnet werden. Der Ausgabefehler wurde weitergegeben, um den Fehler der Aktivität $ {\ bf a} _ {y} $ zu erhalten, und der Fehler wurde verwendet, um den Gradienten des Parameters zu berechnen. Wenn der Fehler von $ {\ bf a} \ _ y $ erhalten wird, kann außerdem nicht nur der Gradient des Gewichts, sondern auch der Fehler der Eingabe $ {\ bf z} $ der zweiten Schicht berechnet werden.

\begin{align}
{\partial E\over\partial z_j} &= \sum_{i=1}^2 {\partial E\over\partial a_{y_i}}{\partial a_{y_i}\over\partial z_j}\\
&= \sum_{i=1}^2 {\partial E\over\partial a_{y_i}}w_{ij}^{(2)}
\end{align}

Auf diese Weise kann der Fehler von der Ausgabe $ {\ bf y} $ der zweiten Schicht auf die Eingabe $ {\ bf z} $ übertragen werden. Der Fehler der Eingabe $ {\ bf z} $ der zweiten Schicht ist auch der Fehler der Ausgabe der ersten Schicht, so dass durch Wiederholen des Obigen auch der Fehler in der Aktivität der ersten Schicht und der Gradient des Gewichts erhalten werden können. Du kannst es haben.

\begin{align}
{\partial E\over\partial a_{z_i}} &= {\partial E\over\partial z_i}{\partial z_i\over\partial a_{z_i}}\\
&= {\partial E\over\partial z_i}f'^{(2)}(a_{z_i})\\
{\partial E\over\partial x_j} &= \sum_{i=1}^4 {\partial E\over\partial a_{z_i}}{\partial a_{z_i}\over\partial x_j}\\
&= \sum_{i=1}^4 {\partial E\over\partial a_{z_i}}w_{ij}^{(1)}\\
{\partial E\over\partial w_{ij}^{(1)}} &= {\partial E\over\partial a_{z_i}}{\partial a_{z_i}\over\partial w_{ij}^{(1)}}\\
&= {\partial E\over\partial a_{z_i}}x_j\\
{\partial E\over\partial b_i^{(1)}} &= {\partial E\over\partial a_{z_i}}{\partial a_{y_i}\over\partial b_i^{(1)}}\\
&= {\partial E\over\partial a_{z_i}}\\
\end{align}

Auf diese Weise können Sie den Fehler in der Ausgabeebene auf die Eingabe übertragen und den Gradienten berechnen, der zum Aktualisieren der Gewichtsparameter im Prozess erforderlich ist.

Zusammenfassung der Backpropagation

Ausbreitung in die entgegengesetzte Richtung vom Fehler in der Ausgabeeinheit

Ausgabeeinheit Aktivität der zweiten Schicht
{\partial E\over\partial y_i} {\partial E\over\partial a_{y_i}}={\partial E\over\partial y_i}f'^{(2)}(a_{y_i})~~~(=y_i - t_i)

Berechnen Sie den Gradienten im Parameter aus dem Aktivitätsfehler.

\begin{align}
{\partial E\over\partial w_{ij}^{(2)}} &= {\partial E\over\partial a_{y_i}}z_j\\
{\partial E\over\partial b_i^{(2)}} &= {\partial E\over\partial a_{y_i}}
\end{align}

Dies wird auch auf die erste Schicht übertragen.

Versteckte Einheit Aktivität der ersten Schicht
{\partial E\over\partial z_j}=\sum_{i=1}^2 {\partial E\over\partial a_{y_i}}w_{ij}^{(2)} {\partial E\over\partial a_{z_j}}={\partial E\over\partial z_j}f'^{(1)}(a_{j_1})

Und der Gradient des Parameters ergibt sich aus dem Fehler in der Aktivität.

\begin{align}
{\partial E\over\partial w_{ij}^{(1)}} &= {\partial E\over\partial a_{z_i}}x_j\\
{\partial E\over\partial b_i^{(1)}} &= {\partial E\over\partial a_{z_i}}
\end{align}

Code

Bibliothek

Dieses Mal habe ich etwas anderes als Numpy verwendet, um die Schnittnormalverteilung für die Gewichtsinitialisierung zu verwenden. Normalerweise verwende ich Tensorflow beim Aufbau eines neuronalen Netzwerks, aber Tensorflow verwendet eine Schnittnormalverteilung, um Gewichte zu initialisieren. Deshalb habe ich beschlossen, auch diesem zu folgen.

import numpy as np
from scipy.stats import truncnorm

Schicht

Eine Klasse, die eine Schicht eines neuronalen Netzwerks darstellt. Gewichte werden initialisiert, wenn eine Instanz erstellt wird, eine Eingabe eingegeben wird, eine Vorwärtsausbreitung durchgeführt wird und dann eine Rückausbreitung von Fehlern durchgeführt wird. Basierend auf dieser Klasse werden wir eine Schicht erstellen, die zur tatsächlichen Modellierung des neuronalen Netzwerks verwendet wird.

class Layer(object):

    def __init__(self, dim_input, dim_output, std=1., bias=0.):
        self.w = truncnorm(a=-2 * std, b=2 * std, scale=std).rvs((dim_input, dim_output))
        self.b = np.ones(dim_output) * bias

    def __call__(self, X):
        self.input = X
        return self.forward_propagation(X)

    def back_propagation(self, delta, learning_rate):
        # derivative with respect to activation
        delta = delta * self.activation_derivative()

        w = np.copy(self.w)
        self.w -= learning_rate * self.input.T.dot(delta)
        self.b -= learning_rate * np.sum(delta, axis=0)

        # derivative with respect to input
        return delta.dot(w.T)
Layer Erläuterung
__init__ Initialisieren Sie die Parameter, indem Sie die Eingabe- und Ausgabereihenfolgen dieser Ebene eingeben
__call__ Berechnen Sie die Ausgabe dieser Ebene, indem Sie sich von der Eingabe dieser Ebene vorwärts ausbreiten
back_propagation Berechnen Sie den Eingabefehler dieser Ebene, indem Sie die Parameter aktualisieren, einschließlich des Ausgabefehlers dieser Ebene und des Lernkoeffizienten.

Schicht: Konstante Zuordnung

Schicht mit konstanter Aktivierungsfunktion $ f (a) = a $. Wir werden Schichten aufbauen, indem wir neue Methoden zur Berechnung der Vorwärtsausbreitung und zur Differenzierung von Aktivierungsfunktionen definieren.

class LinearLayer(Layer):

    def forward_propagation(self, X):
        return X.dot(self.w) + self.b

    def activation_derivative(self):
        return 1

Schicht: Logistische Sigmoidfunktion

Schicht, in der die Aktivierungsfunktion die logistische Sigmoidfunktion $ f (x) = {1 \ over1 + \ exp (-x)} $ ist. Die Differenzierung der logistischen Sigmoidfunktion ist $ f '(x) = f (x) (1-f (x)) $.

class SigmoidLayer(Layer):

    def forward_propagation(self, X):
        activation = X.dot(self.w) + self.b
        self.output = 1 / (1 + np.exp(-activation))
        return self.output

    def activation_derivative(self):
        return self.output * (1 - self.output)

Auf diese Weise können Sie auch eine Ebene erstellen, die die Zweikurventangensfunktion $ \ tanh (x) $ und die normalisierte lineare Funktion $ \ max (x, 0) $ als Aktivierungsfunktion verwendet.

Kostenfunktion: Summe der Fehlerquadrate

Dies ist eine Fehlerfunktion, die häufig bei der Lösung von ** Regressionsproblemen ** verwendet wird.

class SumSquaresError(object):

    def activate(self, X):
        return X

    def __call__(self, X, targets):
        return 0.5 * np.sum((X - targets) ** 2)

    def delta(self, X, targets):
        return X - targets

Kostenfunktion: Sigmoid-Kreuzentropie

Dies ist eine Fehlerfunktion, die verwendet wird, wenn Sie ** 2 Klassen ** klassifizieren möchten. Die Kreuzentropie wird nach Durchführung einer nichtlinearen Transformation mit der logistischen Sigmoidfunktion berechnet.

class SigmoidCrossEntropy(object):

    def activate(self, logits):
        return 1 / (1 + np.exp(-logits))

    def __call__(self, logits, targets):
        probs = self.activate(logits)
        p = np.clip(probs, 1e-10, 1 - 1e-10)
        return np.sum(-targets * np.log(p) - (1 - targets) * np.log(1 - p))

    def delta(self, logits, targets):
        probs = self.activate(logits)
        return probs - targets

Auf diese Weise wird auch die für die Klassifizierung mehrerer Klassen verwendete Softmax-Kreuzentropie implementiert.

neurales Netzwerk

Da die Kostenfunktion eine Aktivierungsfunktion hat, sollte die letzte Ebene LinearLayer verwenden. Durch Verwendung der Näherung durch die Differenz der endlichen Breite kann bestätigt werden, ob die Fehlerrückausbreitung korrekt implementiert ist.

class NeuralNetwork(object):

    def __init__(self, layers, cost_function):
        self.layers = layers
        self.cost_function = cost_function

    def __call__(self, X):
        for layer in self.layers:
            X = layer(X)
        return self.cost_function.activate(X)

    def fit(self, X, t, learning_rate):
        for layer in self.layers:
            X = layer(X)

        delta = self.cost_function.delta(X, t)
        for layer in reversed(self.layers):
            delta = layer.back_propagation(delta, learning_rate)

    def cost(self, X, t):
        for layer in self.layers:
            X = layer(X)
        return self.cost_function(X, t)

    def _gradient_check(self, X=None, t=None, eps=1e-6):
        if X is None:
            X = np.array([[0.5 for _ in xrange(np.size(self.layers[0].w, 0))]])
        if t is None:
            t = np.zeros((1, np.size(self.layers[-1].w, 1)))
            t[0, 0] = 1.

        e = np.zeros_like(X)
        e[:, 0] += eps
        x_plus_e = X + e
        x_minus_e = X - e
        grad = (self.cost(x_plus_e, t) - self.cost(x_minus_e, t)) / (2 * eps)

        for layer in self.layers:
            X = layer(X)
        delta = self.cost_function.delta(X, t)
        for layer in reversed(self.layers):
            delta = layer.back_propagation(delta, 0)

        print "==================================="
        print "checking gradient"
        print "finite difference", grad
        print " back propagation", delta[0, 0]
        print "==================================="
NueralNetwork Erläuterung
__init__ Definition von Netzwerkstruktur und Kostenfunktion
__call__ Vorwärtsausbreitungsberechnung
fit Das Netzwerk lernen
cost Berechnen Sie den Wert der Kostenfunktion
_gradient_check Bestätigung des Backpropagation-Gradienten

Ganzer Code

Der ganze Code ist hier. Importieren Sie nur das, was Sie von diesem Modul benötigen, und erstellen Sie Code, um Regressions- und Klassifizierungsprobleme zu lösen.

neural_network.py


import numpy as np
from scipy.stats import truncnorm


class Layer(object):

    def __init__(self, dim_input, dim_output, std=1., bias=0.):
        self.w = truncnorm(a=-2 * std, b=2 * std, scale=std).rvs((dim_input, dim_output))
        self.b = np.ones(dim_output) * bias

    def __call__(self, X):
        self.input = X
        return self.forward_propagation(X)

    def back_propagation(self, delta, learning_rate):
        # derivative with respect to activation
        delta = delta * self.activation_derivative()

        w = np.copy(self.w)
        self.w -= learning_rate * self.input.T.dot(delta)
        self.b -= learning_rate * np.sum(delta, axis=0)

        # derivative with respect to input
        return delta.dot(w.T)


class LinearLayer(Layer):

    def forward_propagation(self, X):
        return X.dot(self.w) + self.b

    def activation_derivative(self):
        return 1


class SigmoidLayer(Layer):

    def forward_propagation(self, X):
        activation = X.dot(self.w) + self.b
        self.output = 1 / (1 + np.exp(-activation))
        return self.output

    def activation_derivative(self):
        return self.output * (1 - self.output)


class TanhLayer(Layer):

    def forward_propagation(self, X):
        activation = X.dot(self.w) + self.b
        self.output = np.tanh(activation)
        return self.output

    def activation_derivative(self):
        return 1 - self.output ** 2


class ReLULayer(Layer):

    def forward_propagation(self, X):
        activation = X.dot(self.w) + self.b
        self.output = activation.clip(min=0)
        return self.output

    def activation_derivative(self):
        return (self.output > 0).astype(np.float)


class SigmoidCrossEntropy(object):

    def activate(self, logits):
        return 1 / (1 + np.exp(-logits))

    def __call__(self, logits, targets):
        probs = self.activate(logits)
        p = np.clip(probs, 1e-10, 1 - 1e-10)
        return np.sum(-targets * np.log(p) - (1 - targets) * np.log(1 - p))

    def delta(self, logits, targets):
        probs = self.activate(logits)
        return probs - targets


class SoftmaxCrossEntropy(object):

    def activate(self, logits):
        a = np.exp(logits - np.max(logits, 1, keepdims=True))
        a /= np.sum(a, 1, keepdims=True)
        return a

    def __call__(self, logits, targets):
        probs = self.activate(logits)
        p = probs.clip(min=1e-10)
        return - np.sum(targets * np.log(p))

    def delta(self, logits, targets):
        probs = self.activate(logits)
        return probs - targets


class SumSquaresError(object):

    def activate(self, X):
        return X

    def __call__(self, X, targets):
        return 0.5 * np.sum((X - targets) ** 2)

    def delta(self, X, targets):
        return X - targets


class NeuralNetwork(object):

    def __init__(self, layers, cost_function):
        self.layers = layers
        self.cost_function = cost_function

    def __call__(self, X):
        for layer in self.layers:
            X = layer(X)
        return self.cost_function.activate(X)

    def fit(self, X, t, learning_rate):
        for layer in self.layers:
            X = layer(X)

        delta = self.cost_function.delta(X, t)
        for layer in reversed(self.layers):
            delta = layer.back_propagation(delta, learning_rate)

    def cost(self, X, t):
        for layer in self.layers:
            X = layer(X)
        return self.cost_function(X, t)

    def _gradient_check(self, X=None, t=None, eps=1e-6):
        if X is None:
            X = np.array([[0.5 for _ in xrange(np.size(self.layers[0].w, 0))]])
        if t is None:
            t = np.zeros((1, np.size(self.layers[-1].w, 1)))
            t[0, 0] = 1.

        e = np.zeros_like(X)
        e[:, 0] += eps
        x_plus_e = X + e
        x_minus_e = X - e
        grad = (self.cost(x_plus_e, t) - self.cost(x_minus_e, t)) / (2 * eps)

        for layer in self.layers:
            X = layer(X)
        delta = self.cost_function.delta(X, t)
        for layer in reversed(self.layers):
            delta = layer.back_propagation(delta, 0)

        print "==================================="
        print "checking gradient"
        print "finite difference", grad
        print " back propagation", delta[0, 0]
        print "==================================="

2 Klassenklassifikation

Legen Sie die obige Datei neural_network.py und diese Datei im selben Verzeichnis ab.

binary_classification.py


import pylab as plt
import numpy as np
from neural_network import TanhLayer, LinearLayer, SigmoidCrossEntropy, NeuralNetwork


def create_toy_dataset():
    x = np.random.uniform(-1., 1., size=(1000, 2))
    labels = (np.prod(x, axis=1) > 0).astype(np.float)
    return x, labels.reshape(-1, 1)


def main():
    x, labels = create_toy_dataset()
    colors = ["blue", "red"]
    plt.scatter(x[:, 0], x[:, 1], c=[colors[int(label)] for label in labels])

    layers = [TanhLayer(2, 4), LinearLayer(4, 1)]
    cost_function = SigmoidCrossEntropy()
    nn = NeuralNetwork(layers, cost_function)
    nn._gradient_check()
    for i in xrange(100000):
        if i % 10000 == 0:
            print "step %6d, cost %f" % (i, nn.cost(x, labels))
        nn.fit(x, labels, learning_rate=0.001)

    X_test, Y_test = np.meshgrid(np.linspace(-1, 1, 100), np.linspace(-1, 1, 100))
    x_test = np.array([X_test, Y_test]).transpose(1, 2, 0).reshape(-1, 2)
    probs = nn(x_test)
    Probs = probs.reshape(100, 100)
    levels = np.linspace(0, 1, 11)
    plt.contourf(X_test, Y_test, Probs, levels, alpha=0.5)
    plt.colorbar()
    plt.xlim(-1, 1)
    plt.ylim(-1, 1)
    plt.show()


if __name__ == '__main__':
    main()

Rückkehr

Legen Sie dies in das gleiche Verzeichnis wie neural_network.py oben.

regression.py


import pylab as plt
import numpy as np
from neural_network import TanhLayer, LinearLayer, SumSquaresError, NeuralNetwork


def create_toy_dataset(func, n=100):
    x = np.random.uniform(size=(n, 1))
    t = func(x) + np.random.uniform(-0.1, 0.1, size=(n, 1))
    return x, t


def main():

    def func(x):
        return x + 0.3 * np.sin(2 * np.pi * x)

    x, t = create_toy_dataset(func)

    layers = [TanhLayer(1, 6, std=1., bias=-0.5), LinearLayer(6, 1, std=1., bias=0.5)]
    cost_function = SumSquaresError()
    nn = NeuralNetwork(layers, cost_function)
    nn._gradient_check()
    for i in xrange(100000):
        if i % 10000 == 0:
            print "step %6d, cost %f" % (i, nn.cost(x, t))
        nn.fit(x, t, learning_rate=0.001)

    plt.scatter(x, t, alpha=0.5, label="observation")
    x_test = np.linspace(0, 1, 1000)[:, np.newaxis]
    y = nn(x_test)
    plt.plot(x_test, func(x_test), color="blue", label="$x+0.3\sin(2\pi x)$")
    plt.plot(x_test, y, color="red", label="regression")
    plt.legend(loc="upper left")
    plt.xlabel("x")
    plt.ylabel("y")
    plt.show()


if __name__ == '__main__':
    main()

Ergebnis

Wenn Sie den Code ausführen, der das neuronale Netzwerk trainiert, das eine Zwei-Klassen-Klassifizierung durchführt, lautet die Ausgabe wie folgt.

Terminalausgang


===================================
checking gradient
finite difference 0.349788735199
 back propagation 0.349788735237
===================================

Die Implementierung sieht in Ordnung aus, da der aus der endlichen Breitendifferenz berechnete Gradient und der durch Fehlerrückausbreitung berechnete Fehlerwert nahe beieinander liegen.

Ein neuronales Netzwerk, das zwei Klassen unter Verwendung von blauen und roten Punkten als Trainingsdaten klassifiziert, wird trainiert, und die zweidimensionale Ebene wird entsprechend der Ausgabe farbcodiert. Das Video zeigt den Lernprozess des neuronalen Netzwerks. (Der obige Zwei-Klassen-Klassifizierungscode zeigt jedoch nur das Standbild als Ergebnis des Lernens an.) anime_xor_classification.gif

Dies ist das Ergebnis, wenn ein neuronales Netzwerk für die Regression verwendet wird. Der blaue Punkt wird als Trainingsdaten zum Trainieren des neuronalen Netzwerks verwendet, und die Änderung der Ausgabe des neuronalen Netzwerks wird dargestellt. (Der Code des obigen Regressionsproblems zeigt jedoch auch nur das Standbild als Ergebnis des Lernens an.) anime_regression.gif

Am Ende

Dieses Mal habe ich ein neuronales Netzwerk implementiert und es trainiert. Das nächste Mal werden wir diesen Code verwenden, um ein Netzwerk mit gemischter Dichte zu implementieren. Bei Verwendung eines normalen neuronalen Netzwerks für Regressionsprobleme wird die Kostenfunktion einer Gaußschen Funktion mit einem Peak nachempfunden, sodass sie nicht mit Situationen mit mehreren Peaks umgehen kann. Netzwerke mit gemischter Dichte lösen dieses Problem, indem sie gemischte Gauß als Kostenfunktion verwenden.

Recommended Posts

PRML Kapitel 5 Python-Implementierung für neuronale Netze
PRML Kapitel 5 Python-Implementierung eines Netzwerks mit gemischter Dichte
Implementierung eines neuronalen Netzwerks in Python
PRML Kapitel 3 Evidence Ungefähre Python-Implementierung
PRML Kapitel 8 Summe der Produkte Algorithmus Python-Implementierung
PRML Kapitel 4 Bayesianische logistische Regression Python-Implementierung
PRML Kapitel 9 Mixed Gaussian Distribution Python-Implementierung
PRML Kapitel 14 Bedingte gemischte Modell-Python-Implementierung
PRML Kapitel 6 Gaussian Return Python-Implementierung
PRML Kapitel 2 Python-Implementierung von Student t-Distribution
PRML Kapitel 1 Bayesian Curve Fitting Python-Implementierung
Implementiert in Python PRML Kapitel 5 Neuronales Netzwerk
PRML Kapitel 11 Implementierung der Markov-Kette Monte Carlo Python
PRML Kapitel 12 Bayesianische Hauptanalyse Python-Implementierung
Neuronales Netzwerk mit Python (Scikit-Learn)
Implementierung eines neuronalen Netzwerks (nur NumPy)
Python vs Ruby "Deep Learning von Grund auf neu" Kapitel 3 Implementierung eines dreischichtigen neuronalen Netzwerks
Einfache Implementierung eines neuronalen Netzwerks mit Chainer
Erläuterung und Implementierung von PRML Kapitel 4
Neuronales Netzwerk mit OpenCV 3 und Python 3
Implementierung eines zweischichtigen neuronalen Netzwerks 2
Einfache Theorie und Implementierung des neuronalen Netzes
[Sprachverarbeitung 100 Schläge 2020] Kapitel 8: Neuronales Netz
PRML Kapitel 7 Verwandte Vector Machine Python-Implementierung für Regressionsprobleme
PRML Kapitel 13 Wahrscheinlichste Schätzung Python-Implementierung des Hidden-Markov-Modells
PRML-Implementierung Kapitel 3 Lineares Basisfunktionsmodell
Implementierung eines 3-Schicht-Neuronalen Netzwerks (kein Lernen)
Implementiert in Python PRML Kapitel 7 Nichtlineare SVM
Implementierung von "verschwommenen" neuronalen Netzen mit Chainer
Einfache Implementierung eines neuronalen Netzwerks mithilfe der Chainer-Datenaufbereitung
Python & Machine Learning Study Memo ③: Neuronales Netz
Implementiert in Python PRML Kapitel 1 Bayesianische Schätzung
Einfache Implementierung eines neuronalen Netzwerks mithilfe der Beschreibung des Chainer-Modells
Python-Lernnotiz für maschinelles Lernen von Chainer Kapitel 13 Training für neuronale Netze ~ Chainer abgeschlossen
Parametrisches neuronales Netzwerk
Implementiert in Python PRML Kapitel 3 Bayesianische lineare Regression
Einfache Implementierung eines neuronalen Netzwerks mit Chainer ~ Optimierungsalgorithmus einstellen ~
[Python / Maschinelles Lernen] Warum Deep Learning # 1 Perceptron Neural Network
Implementiert in Python PRML Kapitel 1 Polygonkurvenanpassung
RNN-Implementierung in Python
Implementiert in Python PRML Kapitel 4 Klassifizierung nach Perceptron-Algorithmus
ValueObject-Implementierung in Python
Implementieren Sie das Convolutional Neural Network
Bayesianische Optimierungsimplementierung von Hyperparametern des neuronalen Netzwerks (Chainer + GPyOpt)
Implementieren Sie das neuronale Netzwerk von Grund auf neu
Erfahrung mit faltbaren neuronalen Netzen
Implementierung eines Faltungs-Neuronalen Netzwerks mit nur Numpy
[Python] Kapitel 01-01 Über Python (Erster Python)
SVM-Implementierung in Python
Rank Learning über ein neuronales Netzwerk (RankNet-Implementierung von Chainer)
Eine Python-Probe zum Lernen von XOR mit einem genetischen Algorithmus in einem neuronalen Netz
Versuchen Sie, ein neuronales Netzwerk in Python aufzubauen, ohne eine Bibliothek zu verwenden
Implementieren Sie ein dreischichtiges neuronales Netzwerk
Kapitel 7 [Deep Learning für neuronale Netze] P252 ~ 275 (erste Hälfte) [Lernen Sie, indem Sie sich mit Python bewegen! Neues Lehrbuch für maschinelles Lernen]
Python für die Datenanalyse Kapitel 4
3. Normalverteilung mit neuronalem Netz!
100 Sprachverarbeitung Knock Kapitel 1 (Python)
100 Sprachverarbeitung Knock Kapitel 2 (Python)
Neuronales Netz beginnend mit Chainer
Python-Implementierung des Partikelfilters
Python-Implementierung gemischte Bernoulli-Verteilung