Dies ist ein Lernrekord, als ich die Rabbit Challenge mit dem Ziel absolvierte, die Qualifikation der Japan Deep Learning Association (JDLA) E zu bestehen, die am 19. und 20. Januar 2021 stattfinden wird.
Rabbit Challenge ist ein Kurs, der die Unterrichtsmaterialien verwendet, die aus dem aufgezeichneten Video des Schulbesuchskurses "Deep Learning-Kurs, der vor Ort zerstört werden kann" bearbeitet wurden. Es gibt keine Unterstützung für Fragen, aber es ist ein billiger Kurs (der niedrigste Preis ab Juni 2020) für die E-Qualifikationsprüfung.
Bitte überprüfen Sie die Details über den unten stehenden Link.
Angewandte Mathematik Maschinelles Lernen Deep Learning (Tag 1) Deep Learning (Tag 2) Deep Learning (Tag 3) Deep Learning (Tag 4)
Das Recurrent Neural Network (RNN) ist ein neuronales Netzwerk, das Zeitreihendaten verarbeiten kann. Zeitreihendaten sind Datenreihen, die in regelmäßigen Abständen in chronologischer Reihenfolge beobachtet werden, statistisch voneinander abhängig sind und Audiodaten und Textdaten enthalten.
Da RNN Zeitreihendaten verarbeitet, benötigt es eine rekursive Struktur, die den Anfangszustand und den Zustand von $ t-1 $ in der Vergangenheit enthält und beim nächsten Mal den Zustand von $ t $ findet.
Als Parameteranpassungsmethode in RNN gibt es BPTT, eine Art Fehlerrückausbreitung.
[Parameteraktualisierungsformel]
simple_RNN (binäre Addition)
import sys, os
sys.path.append(os.pardir) #Einstellungen zum Importieren von Dateien in das übergeordnete Verzeichnis
import numpy as np
from common import functions
import matplotlib.pyplot as plt
def d_tanh(x):
return 1/(np.cosh(x) ** 2)
#Daten vorbereiten
#Anzahl der Binärziffern
binary_dim = 8
#Maximalwert+ 1
largest_number = pow(2, binary_dim)
# largest_Bereiten Sie Binärzahlen bis zur Nummer vor
binary = np.unpackbits(np.array([range(largest_number)],dtype=np.uint8).T,axis=1)
input_layer_size = 2
hidden_layer_size = 16
output_layer_size = 1
weight_init_std = 1
learning_rate = 0.1
iters_num = 10000
plot_interval = 100
#Gewichtsinitialisierung(Die Vorspannung ist der Einfachheit halber weggelassen)
W_in = weight_init_std * np.random.randn(input_layer_size, hidden_layer_size)
W_out = weight_init_std * np.random.randn(hidden_layer_size, output_layer_size)
W = weight_init_std * np.random.randn(hidden_layer_size, hidden_layer_size)
# Xavier
# W_in = np.random.randn(input_layer_size, hidden_layer_size) / (np.sqrt(input_layer_size))
# W_out = np.random.randn(hidden_layer_size, output_layer_size) / (np.sqrt(hidden_layer_size))
# W = np.random.randn(hidden_layer_size, hidden_layer_size) / (np.sqrt(hidden_layer_size))
# He
# W_in = np.random.randn(input_layer_size, hidden_layer_size) / (np.sqrt(input_layer_size)) * np.sqrt(2)
# W_out = np.random.randn(hidden_layer_size, output_layer_size) / (np.sqrt(hidden_layer_size)) * np.sqrt(2)
# W = np.random.randn(hidden_layer_size, hidden_layer_size) / (np.sqrt(hidden_layer_size)) * np.sqrt(2)
#Steigung
W_in_grad = np.zeros_like(W_in)
W_out_grad = np.zeros_like(W_out)
W_grad = np.zeros_like(W)
u = np.zeros((hidden_layer_size, binary_dim + 1))
z = np.zeros((hidden_layer_size, binary_dim + 1))
y = np.zeros((output_layer_size, binary_dim))
delta_out = np.zeros((output_layer_size, binary_dim))
delta = np.zeros((hidden_layer_size, binary_dim + 1))
all_losses = []
for i in range(iters_num):
# A,B-Initialisierung(a + b = d)
a_int = np.random.randint(largest_number/2)
a_bin = binary[a_int] # binary encoding
b_int = np.random.randint(largest_number/2)
b_bin = binary[b_int] # binary encoding
#Richtige Antwortdaten
d_int = a_int + b_int
d_bin = binary[d_int]
#Binär ausgeben
out_bin = np.zeros_like(d_bin)
#Fehler über Zeitreihen
all_loss = 0
#Zeitreihenschleife
for t in range(binary_dim):
#Eingegebener Wert
X = np.array([a_bin[ - t - 1], b_bin[ - t - 1]]).reshape(1, -1)
#Richtige Antwortdaten zum Zeitpunkt t
dd = np.array([d_bin[binary_dim - t - 1]])
u[:,t+1] = np.dot(X, W_in) + np.dot(z[:,t].reshape(1, -1), W)
z[:,t+1] = functions.sigmoid(u[:,t+1])
# z[:,t+1] = functions.relu(u[:,t+1])
# z[:,t+1] = np.tanh(u[:,t+1])
y[:,t] = functions.sigmoid(np.dot(z[:,t+1].reshape(1, -1), W_out))
#Error
loss = functions.mean_squared_error(dd, y[:,t])
delta_out[:,t] = functions.d_mean_squared_error(dd, y[:,t]) * functions.d_sigmoid(y[:,t])
all_loss += loss
out_bin[binary_dim - t - 1] = np.round(y[:,t])
for t in range(binary_dim)[::-1]:
X = np.array([a_bin[-t-1],b_bin[-t-1]]).reshape(1, -1)
delta[:,t] = (np.dot(delta[:,t+1].T, W.T) + np.dot(delta_out[:,t].T, W_out.T)) * functions.d_sigmoid(u[:,t+1])
# delta[:,t] = (np.dot(delta[:,t+1].T, W.T) + np.dot(delta_out[:,t].T, W_out.T)) * functions.d_relu(u[:,t+1])
# delta[:,t] = (np.dot(delta[:,t+1].T, W.T) + np.dot(delta_out[:,t].T, W_out.T)) * d_tanh(u[:,t+1])
#Verlaufsaktualisierung
W_out_grad += np.dot(z[:,t+1].reshape(-1,1), delta_out[:,t].reshape(-1,1))
W_grad += np.dot(z[:,t].reshape(-1,1), delta[:,t].reshape(1,-1))
W_in_grad += np.dot(X.T, delta[:,t].reshape(1,-1))
#Gradientenanwendung
W_in -= learning_rate * W_in_grad
W_out -= learning_rate * W_out_grad
W -= learning_rate * W_grad
W_in_grad *= 0
W_out_grad *= 0
W_grad *= 0
if(i % plot_interval == 0):
all_losses.append(all_loss)
print("iters:" + str(i))
print("Loss:" + str(all_loss))
print("Pred:" + str(out_bin))
print("True:" + str(d_bin))
out_int = 0
for index,x in enumerate(reversed(out_bin)):
out_int += x * pow(2, index)
print(str(a_int) + " + " + str(b_int) + " = " + str(out_int))
print("------------")
lists = range(0, iters_num, plot_interval)
plt.plot(lists, all_losses, label="loss")
plt.xlabel("iters_num", fontsize=14)
plt.ylabel("loss", fontsize=14)
plt.show()
--Changed weight_init_std → Wenn weight_init_std von 1,0 auf 0,5 verringert oder auf 2,0 erhöht wurde, konvergierten beide langsam.
Geänderte Lernrate → Das Verringern der Lernrate von 0,1 auf 0,01 verlangsamte das Lernen, aber das Erhöhen auf 1,0 beschleunigte das Lernen und das Erhöhen auf 3,0 brachte das Lernen nicht voran.
Versteckte_Layer_Größe geändert → Das Verringern von hidden_layer_size von 16 auf 8 verlangsamte das Lernen, aber das Erhöhen auf 32 beschleunigte das Lernen und das Erhöhen auf 128 verlangsamte das Lernen.
Die Gewichtsinitialisierungsmethode wurde geändert ・ Wechseln Sie zu Xavier ・ Wechseln Sie zu Er → Beide Initialisierungsmethoden verlangsamten das Lernen.
Die Aktivierungsfunktion der mittleren Schicht wurde geändert
・ Wechseln Sie zu ReLU
・ Wechseln Sie zu tanh
Section2:LSTM(Long Short-Term Memory) Mit einem einfachen RNN können Fernabhängigkeiten aufgrund des Verschwindens des Gradienten bei der Durchführung der Fehlerrückübertragung nicht gut gelernt werden. LSTM wird als Methode zur Lösung des Problems verwendet.
Input gate:$ i_t = \sigma(W^{(i)}x_t + U^{(i)}h_{t-1} + b^{(i)} ) $
Forget gate:$ f_t = \sigma(W^{(f)}x_t + U^{(f)}h_{t-1} + b^{(f)} ) $
output gate:$ o_t = \sigma(W^{(o)}x_t + U^{(o)}h_{t-1} + b^{(o)} ) $
Speicherzelle: $ \ tilde c_t = tanh (W ^ {(\ tilde c)} x_t + U ^ {(\ tilde c)} h_ {t-1} + b ^ {(\ tilde c)}, \ quad c_t = i_t \ circ \ tilde c_t + f_t \ circ c_ {t-1} $
Statusaktualisierung: $ h_t = o_t \ circ tanh (c_t) $
CEC(Constant Error Carousel) Als Lösung für das Verschwinden des Gradienten und die Explosion des Gradienten kann es gelöst werden, wenn der Gradient 1 ist. Problem: Das Gewicht der Eingabedaten ist unabhängig von der Zeitabhängigkeit einheitlich. → Es gibt keine Lerncharakteristik des neuronalen Netzwerks.
Eingangsgatter und Ausgangsgatter Das Problem der CEC wird gelöst, indem ein Eingangsgatter und ein Ausgangsgatter hinzugefügt werden und das Gewicht des Eingangswerts zu jedem Gatter durch die Gewichtsmatrizen W und U variabel gemacht wird.
Vergessenheitstor CEC speichert alle vergangenen Informationen, aber wenn die vergangenen Informationen nicht mehr benötigt werden, können sie nicht gelöscht werden und bleiben gespeichert. Wenn die Informationen der Vergangenheit nicht mehr benötigt werden, wurde das Vergessen-Tor wie gestern geboren, um die Informationen zu diesem Zeitpunkt zu vergessen.
Gucklochverbindung Ich möchte die in CEC gespeicherten Informationen aus der Vergangenheit jederzeit an andere Knoten weitergeben oder vergessen. Der Wert von CEC selbst hat keinen Einfluss auf die Gate-Steuerung. → Gucklochverbindung als Struktur, die die Ausbreitung auf den Wert von CEC selbst über eine Gewichtsmatrix ermöglicht.
Section3:GRU(Gated Recurrent Unit) Bei der herkömmlichen LSTM war der Berechnungszusatz groß, da es viele Parameter gab. Daher hat GRU eine Struktur, in der die Parameter signifikant reduziert sind und erwartet werden kann, dass die Genauigkeit gleich oder höher als diese ist.
Ein Modell zur Verbesserung der Genauigkeit, indem nicht nur vergangene, sondern auch zukünftige Informationen hinzugefügt werden. Wird für die Textausarbeitung und maschinelle Übersetzung verwendet.
Section5:Seq2Seq Normale RNNs müssen dieselbe Eingangs- und Ausgangslänge und -reihenfolge haben. Andererseits ist Seq2Seq eine Art Encoder-Decoder-Modell und verwendet unterschiedliche RNNs auf der Eingangs- und der Ausgangsseite. Wird für maschinelle Dialoge und maschinelle Übersetzung verwendet.
Encoder RNN Eine Struktur, in der vom Benutzer eingegebene Textdaten in Token wie Wörter unterteilt und übergeben werden. Geben Sie vec1 in RNN ein und geben Sie den verborgenen Zustand aus. Dieser versteckte Zustand und der nächste Eingang vec2 wurden erneut in RNN eingegeben. Stellen Sie den verborgenen Zustand ein, wenn der letzte VEC als Endzustand eingefügt wird. Dieser Endzustand wird als Gedankenvektor bezeichnet und wird zu einem Vektor, der die Bedeutung des Eingabesatzes ausdrückt.
Decoder RNN Eine Struktur, in der das System Ausgabedaten für jedes Token generiert, z. B. ein Wort.
[Decoder RNN-Verarbeitungsverfahren]
HRED Generieren Sie die nächste Äußerung aus den letzten n-1 Äußerungen. In Seq2seq wurde die Antwort durch Ignorieren des Konversationskontexts gegeben, in HRED folgt die Antwort dem Fluss des vorherigen Wortes, sodass ein menschlicherer Satz erzeugt wird. Mit einer Struktur, die Seq2seq und Context RNN kombiniert (eine Struktur, die die von Encoder zusammengestellte Satzreihe kombiniert und in einen Vektor konvertiert, der den gesamten bisherigen Konversationskontext darstellt), wird eine Antwort generiert, die die Geschichte vergangener Äußerungen berücksichtigt. Es gibt. Problem 1: Es gibt nur buchstäbliche Vielfalt, nicht den „Fluss“ der Konversation. → Auch wenn derselbe Kontext (Sprachliste) angegeben ist, kann der Inhalt der Antwort jedes Mal nur dem Gesprächsfluss entsprechen. Übung 2: Es handelt sich in der Regel um eine kurze und informationsarme Antwort. → Neigt dazu, kurze und allgemeine Antworten zu lernen.
VHRED Eine Struktur, die die Probleme von HRED löst, indem das Konzept der latenten Variablen von VAE zu HRED hinzugefügt wird.
VAE Annahme einer Wahrscheinlichkeitsverteilung für die latente Variable z.
Section6:Word2vec In RNN ist es nicht möglich, NN eine Zeichenfolge variabler Länge wie ein Wort zu geben. In word2vec wurde ein Vokabular aus Trainingsdaten erstellt, und eine gewichtete Matrix aus "Anzahl der Vokabeln x Anzahl der Dimensionen eines beliebigen Wortvektors" ermöglichte es, das Lernen der verteilten Darstellung großer Datenmengen mit einer realistischen Berechnungsgeschwindigkeit und Speichermenge zu realisieren. Der resultierende numerische Vektor kann verwendet werden, um Rohtext in eine numerische Darstellung umzuwandeln, die für Datenvisualisierung, maschinelles Lernen und tiefes Lernen geeignet ist.
Section7:Attention Mechanism Ein Mechanismus, um den Grad der Relevanz zu erfahren, "welches Wort der Eingabe und Ausgabe in Beziehung steht". Indem der gewichtete Durchschnitt des verborgenen Zustands jedes Wortes in Encoder als Eingabe als Information verwendet wird, wenn der Decoder jedes Wort ausgibt, können die Kontextinformationen des Übersetzungsquellensatzes detaillierter erfasst werden. Mit der Einführung des Aufmerksamkeitsmechanismus wurde die Genauigkeit der neuronalen maschinellen Übersetzung erheblich verbessert und die Leistung herkömmlicher statistischer maschineller Übersetzungsmodelle übertroffen.
Recommended Posts