In diesem Beitrag möchte ich über die Muster sprechen, die neuronale Netze finden können. Viele Anfängerhandbücher konzentrieren sich auf die Technik des Schreibens von Code für neuronale Netze, während Fragen der „Logik“ (was können neuronale Netze? Welche Architekturen eignen sich besser für welche Aufgaben und warum?) Oft am Rande bleiben. Ich hoffe, mein Beitrag wird Anfängern helfen, die Fähigkeiten neuronaler Netze besser zu verstehen. Dazu werden wir versuchen zu sehen, wie sie mit einigen Modellaufgaben umgehen. Beispielcode wird in Python mithilfe der Keras-Bibliothek bereitgestellt.
Aufgabe 1. Beginnen wir mit einer einfachen. Wir bauen ein neuronales Netzwerk auf, das sich dem Sinus annähert.
import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, np.pi, n) y = np.sin(X) return X, y n = 40 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(6, input_dim=1, activation='relu')) model.add(Dense(4, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mean_squared_error']) model.fit(X, y, epochs=1000, batch_size=4) X_test = np.linspace(start=0, stop=np.pi, num=500) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Sinus approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show()
Wir erhalten die folgende Tabelle:

Wie Sie sehen, hat das neuronale Netzwerk die Aufgabe der Approximation einer einfachen Funktion erfolgreich gemeistert.
Aufgabe 2. Mal sehen, wie das neuronale Netzwerk mit einer komplexeren Aufgabe fertig wird. Wir werden x-Werte eingeben, die gleichmäßig über das Intervall [0, 1] verteilt sind, und y wird zufällig eingestellt: Für x <0,6 ist y eine Zufallsvariable mit dem Wert 0 mit einer Wahrscheinlichkeit von 0,75 und 1 mit einer Wahrscheinlichkeit von 0,25 (dh einem binomischen Zufallswert mit p = 0,25). Für x> 0,6 ist y eine Zufallsvariable, die den Wert 0 mit einer Wahrscheinlichkeit von 0,3 und den Wert 1 mit einer Wahrscheinlichkeit von 0,7 annimmt. Als optimierte Funktion nehmen wir den Standardfehler.
import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, 1, n) y0 = np.random.binomial(size=n, n=1, p=0.25) y1 = np.random.binomial(size=n, n=1, p=0.7) y = np.where(X < 0.6, y0, y1) return X, y n_inputs = 1 n_hidden1 = 100 n_hidden2 = 50 n_outputs = 1 n = 2000 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(n_hidden1, input_dim=1, activation='relu')) model.add(Dense(n_hidden2, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy']) model.fit(X, y, epochs=200, batch_size=100) X_test = np.linspace(start=0, stop=1, num=100) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Binomial distribution approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show()
Wir erhalten den folgenden Graphen eines neuronalen Netzwerks mit angenäherter Funktion:

Wie Sie sehen können, hat das neuronale Netzwerk die mathematische Erwartung unserer Zufallsvariablen y angenähert. So können neuronale Netze (im Prinzip) die Durchschnittswerte von Zufallsvariablen approximieren, die von den Parametern abhängen. Zum Beispiel können wir erwarten, dass sie das folgende Problem lösen: Menschen mit einem Einkommen von bis zu 1.000 USD sind im Durchschnitt unglücklich, und Menschen mit einem Einkommen von über 1.000 USD sind im Durchschnitt glücklich; man muss lernen, das "Glücksniveau" je nach Einkommen vorherzusagen. Das neuronale Netz wird in der Lage sein, die Abhängigkeit des durchschnittlichen Glücksniveaus vom Einkommen zu ermitteln, obwohl es bei Menschen mit jedem Einkommensniveau sowohl glückliche als auch unglückliche gibt.
Aufgabe 3. Nun wenden wir uns der Vorhersage von Sequenzen zu. Wir werden Sequenzen von 0 und 1 betrachten, die durch die folgende Regel gegeben sind: 10 Mitglieder - wahrscheinlich 0 oder 1, und das elfte ist gleich 1, wenn der vorherige Term 0 ist, und ebenso wahrscheinlich 0 oder 1, wenn der vorherige Term 1. Wir werden solche Sequenzen der Länge 11 (10 Eingabe) erzeugen Sequenzmitglieder und eines, das letzte, das wir vorhersagen) und trainieren sie in unserem wiederkehrenden neuronalen Netzwerk. Lassen Sie uns nach dem Training überprüfen, wie sie mit der Vorhersage neuer Sequenzen (auch Länge 11) umgeht.
import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense def get_X_y(m, n): X = np.random.binomial(size=(m,n), n=1, p=0.5) y0 = np.ones(m) y1 = np.random.binomial(size=m, n=1, p=0.5) y = np.where(X[:, n-1]==0, y0, y1) X = np.reshape(X, (X.shape[0], X.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=50)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000, 10) model.fit(X_train, y_train, epochs = 20, batch_size = 32) m_test = 12 n_test = 10 X_test, y_test = get_X_y(m_test, n_test) y_predicted = model.predict(X_test) for i in range(m_test): print("x_last=", X_test[i, n_test-1, 0], "y_predicted=", y_predicted[i, 0])
Mal sehen, welche Vorhersagen unser neuronales Netzwerk für die getesteten Sequenzen gibt (Ihre Ergebnisse werden unterschiedlich sein, da hier Zufälligkeit sowohl bei der Auswahl der Sequenzen als auch beim Training des neuronalen Netzwerks vorhanden ist).
Wie Sie sehen können, sagt das neuronale Netzwerk einen Wert nahe 1 voraus, wenn das vorletzte Mitglied der Sequenz 0 ist, und wenn es 1 ist, dann einen Wert nahe 0,5. Dies liegt nahe an der optimalen Prognose. Ein ähnliches Beispiel aus dem "Leben" könnte so aussehen: "Wenn ich heute ins Kino gehe, werde ich morgen in einem Restaurant zu Mittag essen; Wenn ich heute ins Theater gehe, werde ich morgen überall zu Mittag essen. " Wie wir gesehen haben, kann ein neuronales Netzwerk Muster dieser Art erfassen und eine Reise in ein Restaurant vorhersagen, indem es ins Kino geht (und ins Theater geht, um „etwas dazwischen“ vorherzusagen).
Aufgabe 4. Wir erschweren die Aufgabe des neuronalen Netzes. Alles sei wie im vorherigen Beispiel, nur das elfte Mitglied der Sequenz wird nicht vom vorherigen, sondern vom zweiten Mitglied der Sequenz bestimmt (nach derselben Regel). Wir werden den Code hier nicht angeben, da er sich praktisch nicht vom vorherigen unterscheidet. Mein Experiment zeigte, dass das neuronale Netzwerk immer noch ein Muster findet, aber für mehr Zeit (ich musste 100 Epochen anstelle von 20 für das Training verwenden).
Auf diese Weise können neuronale Netze (im Prinzip wieder klarstellen) ziemlich langfristige Abhängigkeiten erkennen (in unserem „Lebensbeispiel“ können sie Muster wie „Ich gehe heute in ein Restaurant, wenn ich vor einer Woche in einem Film war“ erfassen).
Aufgabe 5. Lassen Sie uns sehen, wie das neuronale Netzwerk die verfügbaren Informationen für die Vorhersage verwendet.
Dazu werden wir an Sequenzen der Länge 4 trainieren. Insgesamt werden wir 3 verschiedene gleich wahrscheinliche Sequenzen haben:
0, 0, 1, 1
0, 1, 0, 1
0, 1, 1, 0
Nach der anfänglichen Kombination von 0, 0 treffen wir also immer zwei Einheiten, nach der Kombination von 0, 1 treffen wir wahrscheinlich gleich 0 oder 1, aber wir werden die letzte Zahl sicher kennen. Wir werden nun unser neuronales Netzwerk bitten, Sequenzen zurückzugeben, indem wir return_sequences = True setzen. Als vorhergesagte Sequenzen nehmen wir dieselben Sequenzen, die um einen Schritt verschoben und rechts durch Null ergänzt wurden. Jetzt können wir bereits davon ausgehen, was passieren wird: Im ersten Schritt erzeugt das neuronale Netzwerk eine Zahl nahe 2/3 (da der zweite Term mit einer Wahrscheinlichkeit von 2/3 1 ist) und dann für eine Kombination von 0, 0 zwei Zahlen nahe Einheit, und für 0, 1 wird zuerst eine Zahl nahe 0,5 ausgegeben, und dann wird eine Zahl nahe 0 oder 1 ausgegeben, je nachdem, ob wir die Folge 0, 1, 0 oder 0, 1, 1 erhalten haben. Am Ende des neuronalen Netzwerks wird immer eine Zahl nahe 0 erzeugen. Die Überprüfung mit dem folgenden Code zeigt, dass unsere Annahmen korrekt sind.
import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense import random def get_X_y(n): X = np.zeros((n, 4)) z = np.array([random.randint(0, 2) for i in range(n)]) X[z == 0, :] = [0, 0, 1, 1] X[z == 1, :] = [0, 1, 0, 1] X[z == 2, :] = [0, 1, 1, 0] y = np.zeros((n, 4)) y[:, :3] = X[:, 1:] X = np.reshape(X, (X.shape[0], X.shape[1], 1)) y = np.reshape(y, (y.shape[0], y.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=20, return_sequences=True)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000) model.fit(X_train, y_train, epochs = 100, batch_size = 32) X_test = np.zeros((3, 4)) X_test[0, :] = [0, 0, 1, 1] X_test[1, :] = [0, 1, 0, 1] X_test[2, :] = [0, 1, 1, 0] X_test = np.reshape(X_test, (3, 4, 1)) y_predicted = model.predict(X_test) print(y_predicted)
Aus diesem Beispiel geht hervor, dass das neuronale Netzwerk die Prognose abhängig von den empfangenen Informationen dynamisch ändern kann. Wir würden dasselbe tun und versuchen, eine bestimmte Reihenfolge vorherzusagen: Wenn die verfügbaren Informationen es uns ermöglichen, die Wahrscheinlichkeiten der Ergebnisse im nächsten Schritt abzuschätzen, sagen wir dies basierend auf diesen Informationen voraus. Wenn wir jedoch im nächsten Schritt zusätzliche Informationen erhalten, ändern wir die Prognose abhängig davon.
Wenn wir also sehen, dass jemand aus der Dunkelheit zu uns kommt, sagen wir: "Dies ist eine Person, die wir nicht genauer kennen." Wenn wir anfangen, lange Haare im Dunkeln zu unterscheiden, sagen wir: "Dies ist wahrscheinlich eine Frau." Aber wenn wir danach denken, dass eine Person einen Schnurrbart hat, dann sagen wir, dass dies wahrscheinlich ein Mann ist (wenn auch mit langen Haaren). Wie wir gesehen haben, verhält sich ein neuronales Netzwerk ähnlich und verwendet die Gesamtheit der derzeit verfügbaren Informationen für die Vorhersage.
Wir haben uns also einfache Beispiele angesehen, wie neuronale Netze funktionieren und welche Muster sie finden können. Im Allgemeinen haben wir gesehen, dass sich neuronale Netze oft recht „vernünftig“ verhalten und Vorhersagen treffen, die denen einer Person nahe kommen. Es sollte jedoch beachtet werden, dass sie viel mehr Daten benötigen als Menschen, um einfache Muster zu erfassen.