[PYTHON] Deep Learning / LSTM Scratch Code

1. Zuallererst

Dieses Mal werde ich, um das Verständnis von LSTM zu vertiefen, LSTM mit Scratch in TensorFlow schreiben.

2. LSTM-Blockdiagramm

Das Blockdiagramm von LSTM mit Forget_gate sieht wie folgt aus, und Sie können sehen, dass es aus 4 kleinen Netzwerken besteht (** output_gate, input_gate, forget_gate, z **).

スクリーンショット 2020-03-10 17.11.49.png ** Z ** möchte das Gewicht W erhöhen, damit es nicht vergessen wird, wenn es eine Eingabe gibt, an die Sie sich erinnern möchten. Wenn Sie jedoch W erhöhen, werden Sie sich auch an Informationen erinnern, an die Sie sich nicht erinnern müssen, also am Ende an die Informationen, an die Sie sich erinnern möchten Wird überschrieben. Dies wird als ** Eingabegewichtskonflikt ** bezeichnet. Um dies zu vermeiden, blockiert ** input_gate ** irrelevante Informationen und verhindert, dass sie in die Speicherzelle C geschrieben werden.   ** forget_gate ** löscht bei Bedarf Informationen in der Speicherzelle C. Dies liegt daran, dass sich die Reihe von Zeitreihendaten sofort ändern kann, wenn bestimmte Bedingungen erfüllt sind, und dass die zu diesem Zeitpunkt gespeicherten Informationen zurückgesetzt werden müssen.

** output_gate ** liest nicht den gesamten Inhalt der Speicherzelle C, löscht jedoch unnötige Inhalte, wie im Fall der Eingabe, um ** Konflikte mit dem Ausgabegewicht ** zu vermeiden.

3. LSTM-Zwischenschicht-Kratzschnur

Die vier Netzwerkgewichte self.W und Bias self.B haben dieselbe Form, daher deklarieren wir sie zusammen.

  self.W = tf.Variable(tf.zeros([input_size + hidden_size, hidden_size *4 ]))
  self.B = tf.Variable(tf.zeros([hidden_size * 4 ]))

Weiterleitungscode weiterleiten. Dieses Mal werden zur Vereinfachung der Nachbearbeitung h und c gestapelt. Stellen Sie sie daher zuerst wieder her. Anschließend wird die gewichtete lineare Summe der vier Netzwerke zusammen berechnet und das Ergebnis in vier geteilt.

  def forward(self, prev_state, x):
      
    # h,Wiederherstellen c
    h, c = tf.unstack(prev_state)
    
    #Berechnen Sie die gewichtete lineare Summe von vier Netzwerken zusammen
    inputs = tf.concat([x, h], axis=1)  
    inputs = tf.matmul(inputs, self.W) + self.B
    z, i, f, o = tf.split(inputs, 4, axis=1)  

Führen Sie Sigmoid durch die Signale von den drei Toren.

    #Führen Sie Sigmoid durch das Signal jedes Tors
    input_gate = tf.sigmoid(i)
    forget_gate = tf.sigmoid(f)
    output_gate = tf.sigmoid(o)

Aktualisieren Sie die Speicherzelle basierend auf den Gate- und Middle-Layer-Eingängen, um den Middle-Layer-Ausgang zu berechnen. Es gibt kein Problem, auch wenn vor output_gate kein tanh steht, daher wird es weggelassen.

    #Speicherzellenaktualisierung, Zwischenausgangsberechnung
    next_c = c * forget_gate + tf.nn.tanh(z) * input_gate  
    next_h = next_c * output_gate
    
    #Stapel aufgrund von Nachbearbeitung
    return tf.stack([next_h, next_c])

4. Ganzer Code

Verwenden wir nun dieses LSTM, um den Code zu schreiben, der die Vorhersage tatsächlich ausführt. Der Datensatz verwendet ein Bild von ** Dagits ** mit ** Zahlen 0-9 ** (kleine 8 * 8 Pixel).

Lassen Sie LSTM basierend auf dem Ergebnis des achtmaligen Scannens einer Datenzeile Zeile für Zeile die Anzahl vorhersagen.

import numpy as np
import tensorflow as tf
from sklearn import datasets
from sklearn.model_selection import train_test_split
from matplotlib import pyplot as plt

class LSTM(object):
  def __init__(self, input_size, hidden_size, output_size):
    self.input_size = input_size
    self.hidden_size = hidden_size
    self.output_size = output_size
    
    #Eingabeebene
    self.inputs = tf.placeholder(tf.float32, shape=[None, None, self.input_size], name='inputs')
    self.W = tf.Variable(tf.zeros([input_size + hidden_size, hidden_size *4 ]))
    self.B = tf.Variable(tf.zeros([hidden_size * 4 ]))
      
    #Ausgabeschicht
    self.Wv = tf.Variable(tf.truncated_normal([hidden_size, output_size], mean=0, stddev=0.01))
    self.bv = tf.Variable(tf.truncated_normal([output_size], mean=0, stddev=0.01))    
    self.init_hidden = tf.matmul(self.inputs[:,0,:], tf.zeros([input_size, hidden_size]))
    self.init_hidden = tf.stack([self.init_hidden, self.init_hidden])    
    self.input_fn = self._get_batch_input(self.inputs)
    
  def forward(self, prev_state, x):
      
    # h,Wiederherstellen c
    h, c = tf.unstack(prev_state)
    
    #Berechnen Sie die gewichtete lineare Summe von vier Netzwerken zusammen
    inputs = tf.concat([x, h], axis=1)  
    inputs = tf.matmul(inputs, self.W) + self.B
    z, i, f, o = tf.split(inputs, 4, axis=1)  
    
    #Führen Sie Sigmoid durch das Signal jedes Tors
    input_gate = tf.sigmoid(i)
    forget_gate = tf.sigmoid(f)
    output_gate = tf.sigmoid(o)
    
    #Speicherzellenaktualisierung, Zwischenausgangsberechnung
    next_c = c * forget_gate + tf.nn.tanh(z) * input_gate  
    next_h = next_c * output_gate
    
    #Stapel aufgrund von Nachbearbeitung
    return tf.stack([next_h, next_c])
  
  
  def _get_batch_input(self, inputs):
    return tf.transpose(tf.transpose(inputs, perm=[2, 0, 1]))
    
  def calc_all_layers(self):
    all_hidden_states = tf.scan(self.forward, self.input_fn, initializer=self.init_hidden, name='states')
    return all_hidden_states[:, 0, :, :]
  
  def calc_output(self, state):
    return tf.nn.tanh(tf.matmul(state, self.Wv) + self.bv)
  
  def calc_outputs(self):
    all_states = self.calc_all_layers()
    all_outputs = tf.map_fn(self.calc_output, all_states)
    
    return all_outputs


#Datensatz laden( 8*8 image of a digit)
digits = datasets.load_digits()
X = digits.images
Y_= digits.target
Y=tf.keras.utils.to_categorical(Y_, 10)
X_train, X_test, y_train, y_test = train_test_split(X, Y, test_size=0.2, random_state=42)
print(Y.shape)


#Vorausschauende Ausführung
hidden_size = 50
input_size = 8
output_size = 10

y = tf.placeholder(tf.float32, shape=[None, output_size], name='inputs')
lstm = LSTM(input_size, hidden_size, output_size)
outputs = lstm.calc_outputs()
last_output = outputs[-1]
output = tf.nn.softmax(last_output)
loss = -tf.reduce_sum(y * tf.log(output))

train_step = tf.train.AdamOptimizer().minimize(loss)
correct_predictions = tf.equal(tf.argmax(y, 1), tf.argmax(output, 1))
acc = (tf.reduce_mean(tf.cast(correct_predictions, tf.float32)))

sess=tf.InteractiveSession()
sess.run(tf.global_variables_initializer())

log_loss = []
log_acc = []
log_val_acc = []

for epoch in range(100):
    
    start=0
    end=100
    for i in range(14):
        
        X=X_train[start:end]
        Y=y_train[start:end]
        start=end
        end=start+100
        sess.run(train_step,feed_dict={lstm.inputs:X, y:Y})
    
    log_loss.append(sess.run(loss,feed_dict={lstm.inputs:X, y:Y}))
    log_acc.append(sess.run(acc,feed_dict={lstm.inputs:X_train[:500], y:y_train[:500]}))
    log_val_acc.append(sess.run(acc,feed_dict={lstm.inputs:X_test, y:y_test}))
        
    print("\r[%s] loss: %s acc: %s val acc: %s"%(epoch, log_loss[-1], log_acc[-1], log_val_acc[-1])),

#acc Grafik
plt.ylim(0., 1.)
plt.plot(log_acc, label='acc')
plt.plot(log_val_acc, label = 'val_acc')
plt.legend()    
plt.show()

スクリーンショット 2020-03-10 20.01.50.png Es ist eine relativ gute Genauigkeit.

Recommended Posts

Deep Learning / LSTM Scratch Code
Deep Learning von Grund auf neu
Deep Learning von Grund auf 1-3 Kapitel
Tiefes Lernen
Tiefes Lernen von Grund auf neu (Kostenberechnung)
Deep Learning Memo von Grund auf neu gemacht
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 7]
Tiefes Lernen von Grund auf neu (Vorwärtsausbreitung)
Tiefes Lernen / Tiefes Lernen von Grund auf 2-Versuchen Sie, GRU zu bewegen
Deep Learning Memorandum
Deep Learning / Deep Learning von Grund auf neu Kapitel 6 Memo
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 5]
Starten Sie Deep Learning
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 6]
Python Deep Learning
"Deep Learning von Grund auf neu" mit Haskell (unvollendet)
Deep Learning × Python
Deep Learning / Deep Learning von Grund auf neu Kapitel 7 Memo
[Windows 10] Aufbau einer "Deep Learning from Scratch" -Umgebung
Lernbericht über das Lesen von "Deep Learning von Grund auf neu"
[Deep Learning von Grund auf neu] Über die Optimierung von Hyperparametern
"Deep Learning from Grund" Memo zum Selbststudium (Teil 12) Deep Learning
[Lernnotiz] Deep Learning von Grund auf neu gemacht [~ Kapitel 4]
Selbststudien-Memo "Deep Learning from Grund" (unlesbares Glossar)
Deep Learning von Grund auf neu ① Kapitel 6 "Lerntechniken"
GitHub des guten Buches "Deep Learning von Grund auf neu"
[Lernnotiz] Deep Learning von Grund auf ~ Implementierung von Dropout ~
Python vs Ruby "Deep Learning von Grund auf neu" Zusammenfassung
"Deep Learning from Grund" Memo zum Selbststudium (10) MultiLayerNet-Klasse
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 11) CNN
Erstes tiefes Lernen ~ Kampf ~
Python: Deep Learning-Praxis
Deep Learning / Aktivierungsfunktionen
Deep Learning 1 Übung des Deep Learning
Deep Learning / Cross Entropy
Erstes tiefes Lernen ~ Vorbereitung ~
Erstes tiefes Lernen ~ Lösung ~
[AI] Deep Metric Learning
Ich habe versucht, tief zu lernen
Python: Deep Learning Tuning
Deep Learning Großtechnologie
Deep Learning / Softmax-Funktion
[Deep Learning von Grund auf neu] Ich habe die Affine-Ebene implementiert
Anwendung von Deep Learning 2 von Grund auf neu Spam-Filter
Ich habe versucht, Dropout zu erklären
[Deep Learning von Grund auf neu] Implementierung der Momentum-Methode und der AdaGrad-Methode
Versuchen Sie, ein Deep Learning / Neuronales Netzwerk mit Scratch aufzubauen
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 1
Deep Learning Gaiden ~ GPU-Programmierung ~
<Kurs> Tiefes Lernen: Day2 CNN
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 5
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 2
Deep Running 2 Tuning von Deep Learning
Erstellen Sie mit Docker eine Umgebung für "Deep Learning von Grund auf neu"
<Kurs> Tiefes Lernen: Tag 1 NN
Deep Kernel Learning mit Pyro
Versuchen Sie Deep Learning mit FPGA
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 3
Deep Learning für die Bildung von Verbindungen?