Lösen einer grundlegenden mathematischen Gleichung mit RNN [mit Codierungsbeispiel]
Veröffentlicht: 2020-12-07Wenn dir das Leben RNN gibt, mache einen Taschenrechner
Ein rekurrentes neuronales Netzwerk ist eines der klassischen künstlichen neuronalen Netzwerke, bei dem die Verbindungen zwischen den Knoten einen sequentiellen gerichteten Graphen bilden. RNNs sind wegen ihres internen Zustandsspeichers zur Verarbeitung von Sequenzen variabler Länge für Anwendungen wie Spracherkennung, Handschrifterkennung usw. bekannt.
RNNs werden weiter in zwei Typen eingeteilt. Der erste ist ein endlicher Impuls, dessen neuronales Netzwerk die Form eines gerichteten azyklischen Graphen hat, bei dem ein Knoten mit einem oder mehreren Knoten verbunden werden kann, die ohne sichtbaren Zyklus im Netzwerk voraus sind. Ein anderer ist ein unendlicher Impuls, dessen neuronales Netzwerk die Form eines gerichteten zyklischen Graphen hat, der nicht in ein vorwärtsgerichtetes neuronales Netzwerk entrollt werden kann.
Inhaltsverzeichnis
Was werden wir tun?
Lassen Sie uns ein Modell erstellen, das die Ausgabe eines arithmetischen Ausdrucks vorhersagt. Wenn ich zum Beispiel als Eingabe '11+88' gebe, sollte das Modell das nächste Wort in der Folge als '99' vorhersagen. Die Ein- und Ausgabe ist eine Folge von Zeichen, da ein RNN mit sequentiellen Daten arbeitet.
Jetzt sieht das Entwerfen der Architektur des Modells im Vergleich zur Sammlung von Datensätzen wie eine einfache Aufgabe aus. Das Generieren von Daten oder das Sammeln von Datensätzen ist eine anstrengende Aufgabe, da datenhungrige KI-Modelle eine angemessene Datenmenge für eine akzeptable Genauigkeit benötigen.
Dieses Modell kann also in 6 grundlegenden Schritten implementiert werden:

- Daten generieren
- Modell bauen
- Vektorisieren und Devektorisieren der Daten
- Erstellen eines Datensatzes
- Trainieren des Modells
- Testen des Modells
Bevor wir uns mit der Implementierung des Modells befassen, importieren wir einfach alle erforderlichen Bibliotheken.
| importiere numpy als np Tensorflow als tf importieren aus tensorflow.keras.models import Sequential aus tensorflow.keras.layers import Dense, Dropout, SimpleRNN, RepeatVector, TimeDistributed aus tensorflow.keras.callbacks import EarlyStopping, LambdaCallback aus termcolor Import farbig |
1. Generieren von Daten
Lassen Sie uns eine Zeichenfolge definieren, die alle Zeichen enthält, die wir zum Schreiben einer einfachen arithmetischen Gleichung benötigen. Die Zeichenfolge besteht also aus allen Zeichen von 0-9 und allen arithmetischen Operatoren wie /, *, +, -, .(dezimal).
Wir können die numerischen Daten nicht direkt in unser Modell einspeisen, wir müssen die Daten in Form von Tensoren übergeben. Das Konvertieren der Zeichenfolge in den Daten in einen One-Hot-codierten Vektor gibt uns eine optimierte Modellleistung. Ein One-Hot-codierter Vektor ist ein Array mit einer Länge, die der Länge unserer Zeichenkette entspricht, jeder One-Hot-Vektor hat Einsen nur am jeweiligen Index der Zeichen, die in jeder Zeichenfolge vorhanden sind.
Nehmen wir zum Beispiel an, unsere Zeichenkette ist '0123456789', und wenn wir eine Zeichenkette wie '12' codieren wollen, dann wäre der One-Hot-Vektor [[0,1,0,0,0,0,0,0 ,0,0], [0,0,1,0,0,0,0,0,0,0] ]. Dazu müssen wir zwei Wörterbücher mit einem Index als Schlüssel und Zeichen als Werte und dem anderen als umgekehrt erstellen.
| char_string = ' 0123456789/*+-. ' num_chars = len (char_string) character_to_index = dict ((c, i) für i, c in enumerate (char_string)) index_to_character = dict ((i, c) für i, c in Aufzählung (char_string)) |
Lassen Sie uns nun eine Funktion schreiben, die eine zufällige arithmetische Gleichung zusammen mit dem Ergebnis dieser Gleichung zurückgibt.
| def Division (n, d): gib n / d zurück wenn d != 0 sonst 0 def datagen (): random1 = np.random.randint(low = 0 ,high = 100 ) random2 = np.random.randint(low = 0 ,high = 100 ) op = np.random.randint(low = 0 , high = 4 ) wenn op == 1 : arith = str (random1) + ' + ' + str (random2) res = str (zufällig1 + zufällig2) elif op == 1 : arith = str (zufällig1) + ' – ' + str (zufällig2) res = str (zufällig1 – zufällig2) elif op == 2 : arith = str (random1) + ' * ' + str (random2) res = str (zufällig1 * zufällig2) sonst : arith = str (zufällig1) + ' / ' + str (zufällig2) res = str ( round (division(random1, random2), 2 )) retour arith , res |
Lesen Sie auch: Interessante Projektideen für neuronale Netzwerke
2. Erstellen eines Modells
Das Modell wird einen Encoder und einen Decoder haben. Der Encoder ist ein einfaches RNN-Modell mit Eingabeform als (None,num_chars) und 128 versteckten Einheiten. Der Grund, warum wir versteckte Einheiten als 32,64,128 usw. wählen, liegt in der besseren Leistung von CPU oder GPU mit versteckten Einheiten als Potenzen von 2.
Unser Encoder wird ein vollständig verbundenes Netzwerk sein und die Ausgabe davon wird in das Netzwerk zurückgeführt, so funktioniert ein RNN. Eine RNN-Schicht verwendet standardmäßig die 'tanh'-Aktivierung, wir werden sie nicht ändern, weil sie am besten zum Encoder passt. Die Ausgabe dieser Ebene ist ein einzelner Vektor, und um einen einzelnen Vektor der gesamten Ausgabe zu erhalten, verwenden wir die RepeatVector()-Ebene mit der erforderlichen Anzahl von Malen als Parameter.
Jetzt hat der Ausgabevektor die Essenz der gegebenen Eingabe, und dieser Vektor wird in den Decoder eingespeist.
Der Decoder besteht aus einer einfachen RNN-Schicht, die die Ausgabesequenz generiert, da wir die RNN-Schicht benötigen, um die vorhergesagte Sequenz zurückzugeben, werden wir die 'return_sequences' als True kennzeichnen. Durch die Zuweisung von „return_sequences“ als „True“ gibt die RNN-Schicht die vorhergesagte Sequenz für jeden Zeitschritt (viele zu viele RNN) zurück.
Die Ausgabe dieser RNN-Schicht wird in eine dichte Schicht mit einer Anzahl von versteckten Einheiten von 'num_chars' eingespeist, und wir verwenden die Softmax-Aktivierung, da wir die Wahrscheinlichkeit jedes Zeichens benötigen. Bevor wir einen Dense-Layer bereitstellen, müssen wir diesen Layer in einen TimeDistributed-Layer kürzen, da wir den Dense-Layer für die Ausgabe jedes Zeitschritts bereitstellen müssen.
| versteckte_einheiten = 128 max_time_steps = 5 #Wir codieren die Ausgabe fest auf 5 Zeichen def -Modell (): Modell = Sequentiell () model.add (SimpleRNN (hidden_units, input_shape = ( None , num_chars))) model.add (RepeatVector (max_time_steps)) model.add (SimpleRNN (hidden_units, return_sequences = True )) model.add(TimeDistributed(Dense(num_chars, activation = ' softmax ' ))) Rückgabemodell _ modell = modell() model.summary() model.compile(loss = ' categorical_crossentropy ' , optimizer = ' adam ' , metrics = [ ' precision ' ]) |

Die Architektur des Modells wird wie oben gezeigt sein
Muss gelesen werden: Neuronales Netzwerk-Tutorial
3. Vektorisieren und Devektorisieren der Daten
Lassen Sie uns Funktionen zum Vektorisieren und Devektorisieren der Daten definieren.
Hier ist die Funktion zum gemeinsamen Vektorisieren des arithmetischen Ausdrucks und des Ergebnisses.
| def vektorisieren (arith, res): x = np.zeros((max_time_steps, num_chars)) y = np.zeros((max_time_steps, num_chars)) ![]() x_remaining = max_time_steps – len (arith) y_remaining = max_time_steps – len (res) für i, c in Aufzählung (arith): x[x_remaining + i, character_to_index[c]] = 1 für i im Bereich (x_remaining): x[i, zeichen_zu_index[ ' 0 ' ]] = 1 für i, c in aufzählen (res): y[y_remaining + i, character_to_index[c]] = 1 für i im Bereich (y_remaining): y[i, character_to_index[ ' 0 ' ]] = 1 gib x, y zurück |
In ähnlicher Weise ist hier die Funktion zum Devektorisieren der Zeichenfolge. Da die Ausgabe, die wir erhalten, ein Vektor von Wahrscheinlichkeiten ist, verwenden wir np.argmax(), um das Zeichen mit der höchsten Wahrscheinlichkeit auszuwählen. Jetzt wird das Wörterbuch index_to_character verwendet, um das Zeichen an diesem Index zurückzuverfolgen.
| def devektorisieren (Eingabe): res = [index_to_character[np.argmax(vec)] for i, vec in enumerate ( input )] return ' ' .join(res) |
Nun ist die Einschränkung, die wir mit der 'devectorize'-Funktion haben, dass sie die nachgestellten Zeichen mit Nullen auffüllen wird. Wenn beispielsweise der Eingabevektor ('1-20', '-19') ist, dann ist die devektorisierte Ausgabe ('01-20', '00-19'). Wir müssen uns um diese zusätzlichen aufgefüllten Nullen kümmern. Schreiben wir eine Funktion zum Strippen des Strings.
| def - Stripping (Eingang): Flagge = Falsch Ausgabe = ' ' für c in der Eingabe : wenn nicht flag und c == ' 0 ' : fortsetzen wenn c == ' + ' oder c == ' – ' oder c == ' * ' oder c == ' / ' oder c == ' . ' : Flagge = Falsch sonst : Flagge = wahr Ausgang += c Ausgabe zurückgeben |
4. Erstellen eines Datensatzes
Nachdem wir nun eine Funktion zum Generieren der Daten definiert haben, verwenden wir diese Funktion und erstellen einen Datensatz mit vielen solchen Paaren (arithmetischer Ausdruck, Ergebnis).
| def create_dataset (num_equations): x_train = np.zeros((num_equations, max_time_steps, num_chars)) y_train = np.zeros((num_equations, max_time_steps, num_chars)) für i im Bereich (num_equations): e, l = datagen() x, y = vektorisieren(e, l) x_Zug[i] = x y_Zug[i] = y gib x_train, y_train zurück |
5. Trainieren des Modells
Lassen Sie uns einen Datensatz mit 50.000 Proben erstellen, was eine angemessene Zahl ist, um unser Datenhungermodell zu trainieren. Wir verwenden 25 % dieser Daten für die Validierung. Lassen Sie uns auch einen Rückruf für eine intelligente Trainingsunterbrechung erstellen, wenn die Genauigkeit für 8 Epochen unverändert bleibt. Dies kann erreicht werden, indem der Geduldsparameter auf 8 gesetzt wird.

| x_train, y_train = create_dataset( 50000 ) simple_logger = LambdaCallback( on_epoch_end = lambda e, l: print ( ' {:.2f} ' .format(l[ ' val_accuracy ' ]), end = ' _ ' ) ) early_stopping = EarlyStopping(monitor = ' val_loss ' , geduldig = 8 ) model.fit(x_train, y_train, Epochen = 100 , Validation_Split = 0.25 , Verbose = 0 , callbacks = [simple_logger, early_stopping]) |
6. Testen des Modells
Lassen Sie uns nun unser Modell testen, indem wir einen Datensatz der Größe 30 erstellen.
| x_test, y_test = create_dataset(num_equations = 20 ) preds = model.predict(x_test) full_seq_acc = 0 für i, pred in enumerate (preds): pred_str = stripping(devectorize(pred)) y_test_str = stripping(devectorize(y_test[i])) x_test_str = stripping(devectorize(x_test[i])) col = ' green ' if pred_str == y_test_str else ' red ' full_seq_acc += 1 / len (preds) * int (pred_str == y_test_str) outstring = ' Eingabe: {}, Ausgabe: {}, Vorhersage: {} ' .format(x_test_str, y_test_str, pred_str) Druck (farbig(outstring, col)) print ( ' \n Vollständige Sequenzgenauigkeit: {:.3f} % ' .format( 100 * full_seq_acc)) |
Die Ausgabe wird wie folgt sein

Wir können sehen, dass die Genauigkeit hier etwas schlecht ist, aber wir können sie trotzdem optimieren, indem wir ein paar Hyperparameter wie die Anzahl der versteckten Einheiten, die Validierungsaufteilung, die Anzahl der Epochen usw. anpassen.
Fazit
Wir haben den grundlegenden Arbeitsablauf eines RNN verstanden, verstanden, dass RNNs am besten für sequentielle Daten geeignet sind, einen Datensatz zufälliger arithmetischer Gleichungen generiert, ein sequentielles Modell zur Vorhersage der Ausgabe eines grundlegenden arithmetischen Ausdrucks entwickelt und dieses Modell mit dem Datensatz trainiert, der Wir haben dieses Modell erstellt und schließlich mit einem kleinen Datensatz getestet, den das Modell noch nie zuvor gesehen hat.
Wenn Sie mehr über RNN und maschinelles Lernen erfahren möchten, schauen Sie sich das PG-Diplom in maschinellem Lernen und KI von IIIT-B & upGrad an, das für Berufstätige konzipiert ist und mehr als 450 Stunden strenge Schulungen, mehr als 30 Fallstudien und Aufgaben bietet. IIIT-B Alumni-Status, mehr als 5 praktische Schlusssteinprojekte und Arbeitsunterstützung bei Top-Unternehmen.
Was sind die verschiedenen Arten von neuronalen Netzen beim maschinellen Lernen?
Beim maschinellen Lernen sind künstliche neuronale Netze im Grunde Rechenmodelle, die so konzipiert sind, dass sie dem menschlichen Gehirn ähneln. Es gibt verschiedene Arten von künstlichen neuronalen Netzen, die maschinelles Lernen basierend auf der mathematischen Berechnung verwendet, die erreicht werden muss. Diese neuronalen Netze sind eine Teilmenge verschiedener maschineller Lerntechniken, die auf unterschiedliche Weise aus Daten lernen. Einige der am weitesten verbreiteten Arten von neuronalen Netzen sind – rekurrentes neuronales Netz – langes Kurzzeitgedächtnis, Feedforward-neuronales Netz – künstliches Neuron, neuronales Netz mit radialer Basisfunktion, selbstorganisierendes neuronales Kohonen-Netz, konvolutionelles neuronales Netz und modulares neuronales Netz, unter anderen.
Was sind die Vorteile eines rekurrenten neuronalen Netzes?
Rekurrente neuronale Netze gehören zu den am häufigsten verwendeten künstlichen neuronalen Netzen im Deep Learning und maschinellen Lernen. Bei dieser Art von neuronalem Netzwerkmodell wird das aus dem vorherigen Schritt erhaltene Ergebnis als Eingabe in den nachfolgenden Schritt eingespeist. Ein rekurrentes neuronales Netzwerk bietet mehrere Vorteile, z. B. – es kann alle Informationen im Laufe der Zeit speichern, einschließlich seiner vorherigen Eingaben, was es ideal für die Vorhersage von Zeitreihen macht. Dieser Typ ist die beste Instanz des Lang-Kurz-Gedächtnisses. Außerdem bieten rekurrente neuronale Netze eine konstruktive Pixelnachbarschaft durch die Verwendung von Faltungsschichten.
Wie werden neuronale Netze in realen Anwendungen eingesetzt?
Künstliche neuronale Netze sind ein integraler Bestandteil von Deep Learning, das wiederum ein hochspezialisierter Zweig des maschinellen Lernens und der künstlichen Intelligenz ist. Neuronale Netze werden in verschiedenen Branchen eingesetzt, um verschiedene kritische Ziele zu erreichen. Zu den interessantesten realen Anwendungen künstlicher neuronaler Netze gehören Börsenprognosen, Gesichtserkennung, Hochleistungs-Autopiloten und Fehlerdiagnose in der Luft- und Raumfahrtindustrie, Analyse bewaffneter Angriffe und Objektortung im Verteidigungssektor, Bildverarbeitung, Arzneimittelforschung und Krankheitserkennung im Gesundheitswesen, Unterschriftenprüfung, Handschriftenanalyse, Wettervorhersage und Trendprognosen für soziale Medien, unter anderem.

