[PYTHON] Spielen wir mit Amedas Daten - Teil 2

Fortsetzung der vorherigen Sitzung.

Ich habe versucht, Amedas-Daten in Python zu importieren. Dieses Mal werde ich über das Thema des Versuchs einer Regressionsanalyse mit einem neuronalen Netzwerk schreiben.

Ich beschloss, die Beziehung zwischen Zeit und Windgeschwindigkeit eines Tages sehr einfach zu analysieren. Ist es in gewissem Sinne möglich, eine Funktion zu erstellen, die einer Tabelle mit einem neuronalen Netzwerk entspricht? Es ist wie damit zu experimentieren.

Ziehen Sie zunächst nur den Windgeschwindigkeits- und Zeitteil aus der zuletzt erstellten CSV-Datei. Es wird davon ausgegangen, dass die CSV-Datei nur Daten für einen Tag enthält.

import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

# deta making???
csv_input = pd.read_csv(filepath_or_buffer="data_out.csv", encoding="ms932", sep=",")
#Anzahl der Eingabeelemente (Anzahl der Zeilen)*Die Anzahl der Spalten) wird zurückgegeben.
print(csv_input.size)
#Gibt das DataFrame-Objekt zurück, das nur für die angegebene Spalte extrahiert wurde.
x = np.array(csv_input[["hour"]])
y = np.array(csv_input[["wind"]])


#Normalisierung
x_max = np.max(x,axis=0)
x_min = np.min(x,axis=0)
y_max = np.max(y,axis=0)
y_min = np.min(y,axis=0)
x = (x - np.min(x,axis=0))/(np.max(x,axis=0) - np.min(x,axis=0))
y = (y - np.min(y,axis=0))/(np.max(y,axis=0) - np.min(y,axis=0))

Da es normalisiert ist, liegen sowohl x als auch y innerhalb von [0,1]. Lassen Sie uns überprüfen, wie es aussieht.

plt.plot(x,y,marker='x',label="true")
plt.legend()

Wenn Sie dies so überprüfen, sieht es wie folgt aus. matsu_1.jpg

Es gibt 24 Punkte auf dem Grundstück, dh 24 Stunden. Es wird jeweils nur ein Punkt als Beispieldaten eingegeben. Mit anderen Worten, es handelt sich um Zeitreihen-Windgeschwindigkeitsdaten. Wenn Sie dies versuchen, schwankt es ziemlich.

Um es einfach auszudrücken: Wenn Sie sich dies als eine Tabelle mit 24 Stichproben vorstellen, können Sie die vertikale Achse y aus dem Wert auf der horizontalen Achse x vorhersagen. Lassen Sie uns dies als Beispiel eines neuronalen Netzwerks erstellen.

Nach der Untersuchung verschiedener Dinge scheint es, dass ein neuronales Netzwerk ... oder besser gesagt Deep Running eine Bibliothek namens Keras verwenden sollte. Ich war jedoch ein wenig süchtig nach der Installation, daher ist sie der Einfachheit halber am Tensorflow befestigt. tensorflow.layers Ich habe mich für so etwas entschieden. In diesem Fall scheint es verwendet werden zu können, solange der Tensorflow funktioniert.

Dieses Mal haben wir ein einfaches einschichtiges neuronales Netzwerk aufgebaut. Es gibt eine Eingabe, eine Ausgabe, und die Anzahl der Knoten in der mittleren Schicht ist angemessen. matsu_2.jpg

In der Formel wird y wie folgt geschätzt.

y = \sum_{k=1}^{N} \left( h_k \phi( z_k ) \right)\\
= \sum_{k=1}^{N} \left( h_k \phi( w_{1k}x + w_{2k}) \right)

Die Vorspannungskomponente ist in der Figur jedoch weggelassen, und φ ist die Aktivierungsfunktion. Alles ist in Ordnung, aber lassen Sie uns einmal über die Sigmoid-Funktion nachdenken.

Das obige neuronale Netzwerkmodell schien wie folgt in Tensorflow-Schichten aufgebaut zu sein.

# make placeholder
x_ph = tf.placeholder(tf.float32, [None, 1])
y_ph = tf.placeholder(tf.float32, [None, 1])
# create newral parameter(depth=1,input:2 > output:1)
hidden1 = tf.layers.dense(x_ph, 24, activation=tf.nn.sigmoid)
newral_out = tf.layers.dense(hidden1, 1)

x_ph ist die Eingabe. newral_out ist der vorhergesagte Wert von y, der basierend auf x_ph berechnet wird. Y_ph, das hier nicht verwendet wird, wird für die Eingabe des richtigen Antwortwerts verwendet. hidden1 ist die z-Schicht (Zwischenschicht). Ich habe die Anzahl der Knoten auf 24 festgelegt, kann sie aber später ändern. Es ist ein wunderbares Wort, ein neuronales Netzwerk mit nur zwei Leitungen aufbauen zu können.

Wenn Sie dies bisher tun können, sollten Sie anscheinend die zu minimierenden Parameter definieren und eine Lernschleife erstellen. Bei der Wiederverwendung der zuvor verwendeten Probe lautet der Teil der Lernformel wie folgt.

# Minimize the mean squared errors.
loss = tf.reduce_mean(tf.square(newral_out - y_ph))
optimizer = tf.train.GradientDescentOptimizer(0.06)
train = optimizer.minimize(loss)

Der Loop-Teil ist ???

for k in range(10001):

    
    if np.mod(k,1000) == 0:
        # get Newral predict data
        y_newral = sess.run( newral_out
                         ,feed_dict = {
                         x_ph: x, #Ich habe die Eingabedaten in x gesetzt
                         y_ph: y.reshape(len(y),1) #Ich habe die richtigen Antwortdaten in t eingegeben
                         })
        
        # errcheck??? ([newral predict] vs [true value])
        err = y_newral - y
        err = np.matmul(np.transpose(err),err)
        # display err
        print('[%d] err:%.5f' % (k,err))

    # shuffle train_x and train_y
    n = np.random.permutation(len(train_x))
    train_x = train_x[n]
    train_y = train_y[n].reshape([len(train_y), 1])

    # execute train process
    sess.run(train,feed_dict = {
                     x_ph: train_x, # x is input data
                     y_ph: train_y # y is true data
                     })

# check result infomation
y_newral = sess.run( newral_out
                 ,feed_dict = {
                 x_ph: x, #Ich habe die Eingabedaten in x gesetzt
                 y_ph: y.reshape(len(y),1) #Ich habe die richtigen Antwortdaten in t eingegeben
                 })
# true info
plt.plot(x,y,marker='x',label="true")
# predict info
plt.plot(x,y_newral,marker='x',label="predict")
plt.legend()

Als Bonus ist auch ein Plot für die Endkontrolle enthalten. Jetzt hast du alles.

Lass es uns bewegen. Unterhalb der Konsolenausgabe.

[0] err:12.74091
[1000] err:1.21210
[2000] err:1.21163
[3000] err:1.21162
[4000] err:1.21162
[5000] err:1.21161
[6000] err:1.21161
[7000] err:1.21161
[8000] err:1.21160
[9000] err:1.21160
[10000] err:1.21159

Ich werde auch die Grafik einfügen. matsu_3.jpg

Erster Eindruck ... Ernsthaft! !! !! !! (Enttäuscht) Es scheint nur eine lineare Annäherung zu sein. Wenn man die Bewegung betrachtet, nimmt der Fehler allmählich ab und konvergiert, so dass das Lernen selbst kein Problem zu sein scheint. Am Ende scheint es jedoch bei err = 1,2116 konvergiert zu haben. Damit macht es keinen Sinn, ein neuronales Netzwerk zu verwenden (lacht)

Ich denke, es ist eine schlechte Idee, die Ausgabe von z zu einer Sigmoid-Funktion zu machen, deshalb werde ich die Einstellung unten ein wenig ändern.

hidden1 = tf.layers.dense(x_ph, 24, activation=tf.nn.relu)

Was ist dann das Ergebnis?

[0] err:2.33927
[1000] err:1.18943
[2000] err:1.16664
[3000] err:1.13903
[4000] err:1.11184
[5000] err:1.09177
[6000] err:1.07951
[7000] err:1.06986
[8000] err:1.06280
[9000] err:1.05912
[10000] err:1.05760

matsu_4.jpg

Hmmm, es ist unterwegs kaputt gegangen (lacht) Ist es so etwas? ?? ?? Das mag in Ordnung sein, aber der erste Zweck war "eine Funktion anstelle einer Tabelle", also unterscheidet es sich ein wenig von dem, was ich tun möchte. Ich habe mir verschiedene Optionen in tensorflow.layers angesehen, aber ich wusste nicht, wie ich das machen soll, also habe ich einen etwas anderen Ansatz gewählt.

Was für eine Theorie ist das sogenannte neuronale Netzwerk? Es gab eine großartige Seite, um dies zu untersuchen.

■ Visueller Beweis, dass das neuronale Netzwerk beliebige Funktionen darstellen kann https://nnadl-ja.github.io/nnadl_site_ja/chap4.html

Es scheint, dass es sich um eine Übersetzung von Michael Nielsens Artikel handelt, aber ist es wirklich ein wunderbarer Inhalt, der die Essenz durchdringt, und kann ich ihn kostenlos sehen? Es geht darum. Weitere Informationen finden Sie im obigen Artikel, aber hier werde ich nur die wichtigen Schlussfolgerungen notieren.

Die erste, die Summe der Schrittfunktionen, wurde im Artikel kurz erwähnt. Ich war sehr froh, die nostalgischen Namen "Hahn Banachs Theorem" und "Reeses Ausdruckssatz" (ich habe Mathematik studiert) zu sehen. Diese Theoreme tauchten in der Funktionsanalyse auf (die Theorie, die Thematik in eine Reihe von Funktionen einzuteilen). Grob gesagt zeigte "Hahn-Banachs Theorem" Erweiterbarkeit, und "Reeses Ausdruckssatz" zeigte Existenz. Ich habe nur den Eindruck, dass "Reeses Ausdruckssatz" eine sehr schöne Theorie war (lacht). Zum Zeitpunkt der Schrittfunktion kam jedoch persönlich das Bild der Rubeg-Integration heraus, und ich interpretierte erweitert, dass es möglich wäre, eine sogenannte Rubeg-integrierbare Funktion auszudrücken. (Ich frage mich, ob die Rubeg-Integration auf der Existenz einer konvergenten Schrittfunktion basiert ~)

Bisher ist die Welt der Theorie, aber die zweite ist wichtig. Der Punkt war, dass die beiden Knoten in der mittleren Schicht als Einzelschrittfunktion fungieren konnten. Mit anderen Worten, wenn die Parameter gut bestimmt sind, kann ein neuronales Netzwerk als die Summe der Schrittfunktionen aufgebaut werden. Ich habe sofort eine Funktion erstellt, um die Parameter wie folgt zu bestimmen.

def calc_b_w(s,sign):

    N = 1000 #Zwischenlagerung
    # s = -b/w
    if sign > 0:
        b = -N
    else:
        b = N
    if s != 0:
        w = -b/s
    else:
        w = 1
    return b,w
 
def calc_w_h(x,y):

    #Sortiert in aufsteigender Reihenfolge von x, x in[0,1]Zu
    K = len(x)
    w_array = np.zeros([K*2,2])
    h_array = np.zeros([K*2,1])
    w_idx = 0
    for k in range(K):
        # x[k] , y[k]
        if k > 0:
            startX = x[k] +  (x[k-1] - x[k])/2
        else:
            startX = 0

        if k < K-1:
            endX = x[k] + (x[k+1] - x[k])/2
        else:
            endX = 1

        if k > 0:
            b,w = calc_b_w(startX,1)
        else:
            b = 100
            w = 1

        # stepfunction 1stHalf
        w_array[w_idx,0] = w
        w_array[w_idx,1] = b
        h_array[w_idx,0] = y[k]
        w_idx += 1
        
        # stepfunction 2ndHalf
        b,w = calc_b_w(endX,1)
        w_array[w_idx,0] = w
        w_array[w_idx,1] = b
        h_array[w_idx,0] = y[k]*-1
        w_idx += 1

Eine Funktion namens calc_b_w bestimmt den Koeffizienten des Umwandlungsteils des neuronalen Netzwerks von der Eingangsschicht x zur Zwischenschicht z. Je größer N ist, desto näher ist die Schrittfunktion. Der Punkt, an dem sich s ändert. (0 <s <1) Vorzeichen ist eine Angabe, dass +1 oder 0 gesetzt ist, Erhöhen, wenn +1 und Ab, wenn 0. Ein Beispiel für s = 0,5 ist in der folgenden Abbildung dargestellt.

matsu_5.jpg

Mit anderen Worten, die Ausgabe von calc_b_w ist nur eine Seite (Seite vergrößern oder verkleinern) der Schrittfunktion, deren Größe +1 beträgt. Nur erhöhen, aber durch Kombinieren von zwei wird eine Schrittfunktion konstruiert. Wenn Sie den Änderungspunkt ein wenig verschieben und den mit umgekehrtem Ausgangscode hinzufügen, erhalten Sie eine impulsartige Wellenform. Bei dieser Rate bleibt die Ausgabegröße 1, multiplizieren Sie sie also mit dem Koeffizienten (h-Teil), um den Vorgang abzuschließen. Dann habe ich es basierend auf den in calc_w_h eingegebenen x und y möglich gemacht, diesen Parameter entsprechend zu berühren. Lassen Sie uns das Ergebnis überprüfen.

w_param,h_param = calc_w_h(x,y)

test_x = np.array(range(200))/200
test_y = np.zeros(len(test_x))

for k in range(len(test_x)):
    test_y[k] = calc_New(test_x[k],h_param,w_param)

plt.plot(x,y,marker='x',label='input_info')
plt.plot(test_x,test_y,marker='x',label='predict')
plt.legend()

matsu_6.jpg

Es scheint, dass die Schrittfunktion erfolgreich konstruiert wurde. Zusätzlich ist die Funktion, die das neuronale Netzwerk unter Verwendung der eingestellten Parameter (w, h) berechnet, wie folgt definiert. (Super geeignet, tut mir leid)

def calc_New(x,h,w):

    tmpx = np.array([x,1])
    tmpx = tmpx.reshape(2,1)

    longX = np.matmul(w,tmpx)

    sigOUT = 1/(1+np.exp(-longX))
    output = sigOUT * h

    return np.sum( output )

Mit dem oben Gesagten wird ein neuronales Netzwerk wie eine Tabelle erstellt, die einer genauen Übereinstimmung nahe kommt. Lassen Sie es für alle Fälle als Programm ausführen, um die oben genannten Informationen zu erhalten. Ich denke es ist okay, aber ...

Sumimasen wird lange Zeit die Quelle einschließlich aller oben genannten Punkte schreiben.

import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt

def calc_b_w(s,sign):

    N = 1000 #Zwischenlagerung
    # s = -b/w
    if sign > 0:
        b = -N
    else:
        b = N
    if s != 0:
        w = -b/s
    else:
        w = 1
    return b,w
 
def calc_w_h(x,y):

    #Sortiert in aufsteigender Reihenfolge von x, x in[0,1]Zu
    K = len(x)
    w_array = np.zeros([K*2,2])
    h_array = np.zeros([K*2,1])
    w_idx = 0
    for k in range(K):
        # x[k] , y[k]
        if k > 0:
            startX = x[k] +  (x[k-1] - x[k])/2
        else:
            startX = 0

        if k < K-1:
            endX = x[k] + (x[k+1] - x[k])/2
        else:
            endX = 1

        if k > 0:
            b,w = calc_b_w(startX,1)
        else:
            b = 100
            w = 1

        # stepfunction 1stHalf
        w_array[w_idx,0] = w
        w_array[w_idx,1] = b
        h_array[w_idx,0] = y[k]
        w_idx += 1
        
        # stepfunction 2ndHalf
        b,w = calc_b_w(endX,1)
        w_array[w_idx,0] = w
        w_array[w_idx,1] = b
        h_array[w_idx,0] = y[k]*-1
        w_idx += 1

    return w_array,h_array

def calc_New(x,h,w):

    tmpx = np.array([x,1])
    tmpx = tmpx.reshape(2,1)

    longX = np.matmul(w,tmpx)

    sigOUT = 1/(1+np.exp(-longX))
    output = sigOUT * h

    return np.sum( output )

# deta making???
csv_input = pd.read_csv(filepath_or_buffer="data_out.csv", encoding="ms932", sep=",")

#Anzahl der Eingabeelemente (Anzahl der Zeilen)*Die Anzahl der Spalten wird zurückgegeben.
print(csv_input.size)

#Gibt das DataFrame-Objekt zurück, das nur für die angegebene Spalte extrahiert wurde.
x = np.array(csv_input[["hour"]])
y = np.array(csv_input[["wind"]])

# num of records
N = len(x)

#Normalisierung
x_max = np.max(x,axis=0)
x_min = np.min(x,axis=0)
y_max = np.max(y,axis=0)
y_min = np.min(y,axis=0)
x = (x - np.min(x,axis=0))/(np.max(x,axis=0) - np.min(x,axis=0))
y = (y - np.min(y,axis=0))/(np.max(y,axis=0) - np.min(y,axis=0))

train_x = x
train_y = y

w_init,h_init = calc_w_h(x,y)

test_x = np.array(range(200))/200
test_y = np.zeros(len(test_x))

for k in range(len(test_x)):
    #print('k=%d' % k)
    test_y[k] = calc_New(test_x[k],h_init,w_init)


x_ph = tf.placeholder(tf.float32, [None, 2])
y_ph = tf.placeholder(tf.float32, [None, 1])

W = tf.Variable(w_init,dtype=tf.float32)
h = tf.Variable(h_init,dtype=tf.float32)


# Before starting, initialize the variables.  We will 'run' this first.
init = tf.global_variables_initializer()

# Launch the graph.
sess = tf.Session()
sess.run(init)


longX = tf.transpose(tf.matmul(W,tf.transpose(x_ph)))
sigOUT = tf.math.sigmoid(longX)
output = tf.matmul(sigOUT,h)
loss = tf.reduce_mean(tf.square(output - y_ph))
optimizer = tf.train.GradientDescentOptimizer(0.05)
train = optimizer.minimize(loss)


plt.plot(x,y,marker='x',label="true")
for k in range(201):

    
    if np.mod(k,10) == 0:
    #if 1:
        # get Newral predict data
        tmpX = np.hstack([x,np.ones(N).reshape([N,1])])
        err = sess.run( loss
                         ,feed_dict = {
                         x_ph: tmpX, #Ich habe die Eingabedaten in x gesetzt
                         y_ph: y.reshape(len(y),1) #Ich habe die richtigen Antwortdaten in t eingegeben
                         })
        
        print('[%d] err:%.5f' % (k,err))

        if np.mod(k,100) == 0 and k > 0:
            tmpX = np.hstack([x,np.ones(N).reshape([N,1])])
            newral_y =  sess.run(output,feed_dict = {
                         x_ph: tmpX, # x is input data
                         y_ph: train_y # y is true data
                         })
    
            plt.plot(x,newral_y,marker='x',label="k=%d" % k)
        
    # shuffle train_x and train_y
    n = np.random.permutation(len(train_x))
    train_x = train_x[n]
    train_y = train_y[n].reshape([len(train_y), 1])
    
    tmpX = np.hstack([train_x,np.ones(N).reshape([N,1])])

    # execute train process
    sess.run(train,feed_dict = {
                     x_ph: tmpX, # x is input data
                     y_ph: train_y # y is true data
                     })

plt.legend()

Ergebnis ist ???

[0] err:0.00287
[10] err:0.00172
[20] err:0.00134
[30] err:0.00111
[40] err:0.00094
[50] err:0.00081
[60] err:0.00070
[70] err:0.00061
[80] err:0.00054
[90] err:0.00048
[100] err:0.00043
[110] err:0.00038
[120] err:0.00034
[130] err:0.00031
[140] err:0.00028
[150] err:0.00025
[160] err:0.00023
[170] err:0.00021
[180] err:0.00019
[190] err:0.00018
[200] err:0.00016

Es ist gegen fast Null konvergiert! Toll. Das Diagramm sieht auch wie folgt aus und ist optisch fast identisch.

matsu_7.jpg

(Irgendwie ist der Anfangswert des letzten Punktes fehlerhaft ...)

Sie haben die Tabellenfunktion erfolgreich implementiert. Es war ein Ansatz, der mit normalem maschinellem Lernen nicht möglich wäre, aber wenn Sie die Anfangswerte gut einstellen können, können Sie dies ohne Probleme tun. Dies ist jedoch wahrscheinlich ein Phänomen, das allgemein als Überlernen bezeichnet wird. Es ist nur zum Üben, also hoffe ich, dass Sie es sehen können.

Nächstes Mal werde ich etwas mehr über die Fortsetzung dieses Themas schreiben.

Recommended Posts

Spielen wir mit Amedas Daten - Teil 1
Spielen wir mit Amedas Daten - Teil 4
Spielen wir mit Amedas Daten - Teil 3
Spielen wir mit Amedas Daten - Teil 2
Spielen wir mit der 4. Dimension der 4. Dimension
Lass uns mit Python mit Python spielen [Anfänger]
Spiel mit dem Propheten
[Einführung in WordCloud] Spielen Sie mit Scraping ♬
[Ergänzung] [PySide] Spielen wir mit Qt Designer
Spielen Sie mit 2016-Python
Spielen Sie mit CentOS 8
Spiel mit der Pyramide
Spiel mit Fathom
Python-Handspiel (Beginnen wir mit AtCoder?)
[Lass uns mit Python spielen] Ein Haushaltsbuch erstellen
Spielen wir mit JNetHack 3.6.2, das einfacher zu kompilieren ist!
[Piyopiyokai # 1] Lass uns mit Lambda spielen: Holen Sie sich einen Twitter-Account
[Piyopiyokai # 1] Spielen wir mit Lambda: Erstellen eines Python-Skripts
Spielen Sie mit Push-Benachrichtigungen mit imap4lib
Machen wir Othello mit wxPython
Spielen Sie mit Jupyter Notebook (IPython Notebook)
[Python] Spielen Sie mit Discords Webhook.
Schreiben wir Python mitinema4d.
Lassen Sie uns Git-Cat mit Python bauen
Spielen Sie mit dem MD-Modul von ASE
Spielen Sie mit A3RT (Textvorschlag)
[Lass uns mit Python spielen] Ziel ist die automatische Satzgenerierung ~ Abschluss der automatischen Satzgenerierung ~
Lassen Sie uns eine GUI mit Python erstellen.
Spielen Sie mit Poancare-Serien und SymPy
HTTPS mit Django und Let's Encrypt
Lass uns mit Selene Deep SEA lernen
Machen wir einen Blockbruch mit wxPython
Spielen Sie mit der Pythonista-UI-Implementierung [Action-Implementierung]
Spielen Sie mit Linux-Partitionen herum ~ Fortsetzung ~
Lassen Sie uns mit Python Image Scraping durchführen
Lassen Sie uns ein Diagramm mit Python erstellen! !!
Machen wir mit xCAT einen Spacon
Machen wir Othellos KI mit Chainer-Teil 2-
Funken spielen mit WSL Anaconda Jupyter (2)
Lassen Sie uns mit Azure Face Emotionen erkennen
Spielen Sie mit Turtle auf Google Colab
Spiele mit Dämonen, weil es ein Abschnitt ist
Lassen Sie uns die Stimme mit Python # 1 FFT analysieren
Spielen wir mit dem von TIS erstellten Unternehmensanalysedatensatz "CoARiJ"
Lassen Sie uns ein Bilderkennungsmodell mit Ihren eigenen Daten erstellen und spielen!
[Lass uns mit Python spielen] Ziel ist die automatische Satzgenerierung ~ Morphologische Analyse durchführen ~
Spielen wir mit dem von TIS erstellten Unternehmensanalysedatensatz "CoARiJ"