Letztes Mal habe ich geschrieben, wie man das Regressionsanalysemodell in Keras verwendet. Dieses Mal werde ich ein wenig über das Klassifizierungsmodell schreiben.
Zunächst gibt es verschiedene Informationen zum Erstellen eines Klassifizierungsmodells in Keras, aber ich habe auf den folgenden Blog verwiesen.
Beispiel für extrem einfaches Deep Learning von Keras
Ich verweise auch auf die offizielle Keras-Website.
Die verwendeten Informationen sind die gleichen wie beim letzten Mal, die Daten eines Tages von Amedas. Es wird unten noch einmal gezeigt. (Ich denke, die Art und Weise, wie man es macht, wurde um diesen herum geschrieben)
data_out.csv
year,month,day,hour,temp,wind,angle,weather,
2019,8,13,1,24.9,1.4,0,2
2019,8,13,2,24.1,2.2,0,2
2019,8,13,3,23.8,1.4,0,2
2019,8,13,4,23.5,1.2,0,2
2019,8,13,5,23.2,1.8,0,2
2019,8,13,6,23.9,0.7,15,2
2019,8,13,7,25.1,0.9,13,2
2019,8,13,8,26.7,1.0,10,2
2019,8,13,9,28.6,1.6,5,2
2019,8,13,10,30.3,1.2,8,2
2019,8,13,11,30.6,1.3,11,2
2019,8,13,12,31.4,2.5,1,2
2019,8,13,13,33.3,2.0,5,2
2019,8,13,14,33.0,2.3,16,2
2019,8,13,15,33.9,1.8,3,2
2019,8,13,16,32.2,3.2,13,2
2019,8,13,17,29.4,1.0,15,10
2019,8,13,18,27.1,4.4,11,10
2019,8,13,19,25.9,3.7,13,10
2019,8,13,20,26.0,2.4,16,4
2019,8,13,21,26.0,0.9,16,4
2019,8,13,22,25.6,1.3,16,2
2019,8,13,23,25.4,2.6,0,2
Ich habe mich gefragt, was ich klassifizieren soll, aber wenn die Windgeschwindigkeit über einem bestimmten Wert liegt (z. B. ** 2 m **), werde ich sie in zwei Muster unterteilen: starker Wind und wenn nicht, Brise / kein Wind.
Die Datenaufbereitung (Aufnahme, Normalisierung usw.) ist wie folgt.
import pandas as pd
import numpy as np
# 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.
#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)
x = (x - np.min(x,axis=0))/(np.max(x,axis=0) - np.min(x,axis=0))
# y > 2[m] : strong
# y <= 2[m] : weak
y_new = np.zeros(len(y),dtype=int)
for k in range(len(y)):
if y[k] > 2:
y_new[k] = 1
y = y_new.reshape(y.shape)
y enthält die Ausgabedaten
――Wenn 1 → Als starker Wind beurteilt --Wenn 0 → Als Brise / kein Wind beurteilt
Es ist geworden. Um dies zu lernen, erstellen wir in Keras ein Modell mit dem folgenden Code.
#Machen Sie ein Modell zum Lernen
model = Sequential()
#Vollständig verbundene Schicht(1 Schicht->30 Schichten)
model.add(Dense(input_dim=1, output_dim=30, bias=True))
#Aktivierungsfunktion(Sigmoidfunktion)
model.add(Activation("sigmoid"))
#Vollständig verbundene Schicht(30 Schichten->1 Schicht)
model.add(Dense(output_dim=1))
#Aktivierungsfunktion(Sigmoidfunktion)
model.add(Activation("sigmoid"))
#Kompilieren Sie das Modell
model.compile(loss="binary_crossentropy", optimizer="sgd", metrics=["accuracy"])
#Führen Sie das Lernen durch
model.fit(x, y, epochs=5000, batch_size=32, verbose=1)
Wenn es nur einen letzten Ausgabeteil gibt, scheint die Auswahl von binary_crossentropy die richtige Antwort zu sein. Folgendes wird als Fehlerfunktion angenommen. (Vereinfachte Gleichung 5.23 auf S.236 für Mustererkennung und maschinelles Lernen)
E(\textbf{w}) = - \sum_{n=1}^{N}
\{ t_{n} \ln y (x_n,\textbf{w}) + (1-t_{n})\ln (1-y (x_n,\textbf{w})) \}
Der Index n gibt die Anzahl der Abtastwerte an, und t_n ist der korrekte Wert (1 oder 0), der x_n entspricht. y (x_n, w) bedeutet die Inferenzausgabe, wenn die Eingabe = x_n und der neuronale Netzparameter = w (zu diesem Zeitpunkt ist E (w) = 0 und der Minimalwert wird genommen). Der Lernprozess besteht darin, w so zu finden, dass t_n = y (x_n, w) für jedes x_n gilt.
Bereiten Sie hier für die Ergebnisbewertung eine Funktion vor, die die zuvor angegebene korrekte Antwortrate angibt. (Obwohl es im Keras-Protokoll angezeigt wird, habe ich es selbst für die Übung vorbereitet.)
# y:predict
# t:true
def checkOKPercent(y,t):
# from predict param
sign_newral = np.sign(np.array(y).reshape([len(t),1]) - 0.5)
# from true param
sign_orig = np.sign(np.array(t.reshape([len(t),1])) - 0.5)
# are there same sign??
NGCNT = np.sum(np.abs(sign_newral-sign_orig))/2
# calc NG percent in [0.0-1.0]
NGPer = NGCNT / len(t)
# return OK percent [0.0-1.0]
return 1.0-NGPer
Die Ausgabe des neuronalen Netzwerks y (x_n, w) nimmt tatsächlich einen beliebigen Wert (float ???) zwischen [0,1] an. Wenn es 0,5 oder mehr ist, ist es ein starker Wind, und wenn es weniger als 0,5 ist, ist es eine Brise / Es bedeutet kein Wind.
Fassen Sie das Obige zusammen und fügen Sie die eine Quelle unten ein.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Activation, Dense
# y:predict
# t:true
def checkOKPercent(y,t):
# from predict param
sign_newral = np.sign(np.array(y).reshape([len(t),1]) - 0.5)
# from true param
sign_orig = np.sign(np.array(t.reshape([len(t),1])) - 0.5)
# are there same sign??
NGCNT = np.sum(np.abs(sign_newral-sign_orig))/2
# calc NG percent in [0.0-1.0]
NGPer = NGCNT / len(t)
# return OK percent [0.0-1.0]
return 1.0-NGPer
# 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.
#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)
x = (x - np.min(x,axis=0))/(np.max(x,axis=0) - np.min(x,axis=0))
# y > 2[m] : strong
# y <= 2[m] : weak
y_new = np.zeros(len(y),dtype=int)
for k in range(len(y)):
if y[k] > 2:
y_new[k] = 1
y = y_new.reshape(y.shape)
#Machen Sie ein Modell zum Lernen
model = Sequential()
#Vollständig verbundene Schicht(1 Schicht->30 Schichten)
model.add(Dense(input_dim=1, output_dim=30, bias=True))
#Aktivierungsfunktion(Sigmoidfunktion)
model.add(Activation("sigmoid"))
#Vollständig verbundene Schicht(30 Schichten->1 Schicht)
model.add(Dense(output_dim=1))
#Aktivierungsfunktion(Sigmoidfunktion)
model.add(Activation("sigmoid"))
#Kompilieren Sie das Modell
model.compile(loss="binary_crossentropy", optimizer="sgd", metrics=["accuracy"])
#Führen Sie das Lernen durch
model.fit(x, y, epochs=5000, batch_size=32, verbose=1)
#True Value Plot
plt.plot(x,y,marker='x',label="true")
#Berechnen Sie die Keras-Ergebnisse mit Inferenz,Anzeige
y_predict = model.predict(x)
#Keras Berechnungsergebnisplot
plt.plot(x,y_predict,marker='x',label="predict")
#Legendenanzeige
plt.legend()
# display result
print('OK %.2f[percent]' % (checkOKPercent(y_predict,y)*100.0))
Wenn Sie bemerken, können Sie Tensorflow aus dem Import entfernen ... Wenn ich nun das Ergebnis zeichne, sieht es wie folgt aus.
Die horizontale Achse ist die (normalisierte) Zeit und die vertikale Achse gibt an, ob der Wind stark ist oder nicht. Die blaue ist die richtige Antwort und die orange ist das Ergebnis des neuronalen Netzwerks. Irgendwie ... Immerhin fühlt es sich wie eine geradlinige Annäherung an.
Der Konvergenzgrad wird auf der Konsole angezeigt. Überprüfen wir ihn also.
Epoch 4994/5000
23/23 [==============================] - 0s 87us/step - loss: 0.6013 - acc: 0.6522
Epoch 4995/5000
23/23 [==============================] - 0s 87us/step - loss: 0.6012 - acc: 0.6522
Epoch 4996/5000
23/23 [==============================] - 0s 43us/step - loss: 0.6012 - acc: 0.6522
Epoch 4997/5000
23/23 [==============================] - 0s 43us/step - loss: 0.6012 - acc: 0.6522
Epoch 4998/5000
23/23 [==============================] - 0s 43us/step - loss: 0.6012 - acc: 0.6522
Epoch 4999/5000
23/23 [==============================] - 0s 43us/step - loss: 0.6012 - acc: 0.6522
Epoch 5000/5000
23/23 [==============================] - 0s 43us/step - loss: 0.6012 - acc: 0.6522
OK 65.22[percent]
Da der Verlust um 0,6012 konvergiert, scheint er als Logik zu funktionieren. Die korrekte Antwortrate beträgt jedoch 65,22%. Selbst wenn ich es beiden Seiten vorhersage, habe ich das Gefühl, dass es so weitergehen wird, daher ist die Leistung nicht gut.
Also habe ich es mit dem Muster versucht, das den Anfangswert des neuronalen Netzwerks wie beim letzten Mal festlegt. Plötzlich werde ich den gesamten Quellcode veröffentlichen.
import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Activation, Dense
from keras.utils.np_utils import to_categorical
from keras import backend as K
import keras
# y:predict
# t:true
def checkOKPercent(y,t):
# from predict param
sign_newral = np.sign(np.array(y).reshape([len(t),1]) - 0.5)
# from true param
sign_orig = np.sign(np.array(t.reshape([len(t),1])) - 0.5)
# are there same sign??
NGCNT = np.sum(np.abs(sign_newral-sign_orig))/2
# calc NG percent in [0.0-1.0]
NGPer = NGCNT / len(t)
# return OK percent [0.0-1.0]
return 1.0-NGPer
# init infomation for keras layers or models
class InitInfo:
# constractor
# x:input y:output
def __init__(self,x,y):
self.x = x
self.y = y
# calc coefficient of keras models(1st layer)
# input s:changing point in [0,1]
# sign:[1]raise,[0]down
# return b:coefficient of bias
# w:coefficient of x
# notice - it can make like step function using this return values(s,sign)
def calc_b_w(self,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
# calc coefficient of keras models(1st and 2nd layer)
def calc_w_h(self):
K = len(self.x)
# coefficient of 1st layer(x,w)
w_array = np.zeros([K*2,2])
# coefficient of 2nd layer
h_array = np.zeros([K*2,1])
w_idx = 0
for k in range(K):
# x[k] , y[k]
# make one step function
# startX : calc raise point in [0,1]
if k > 0:
startX = self.x[k] + (self.x[k-1] - self.x[k])/2
else:
startX = 0
# endX : calc down point in [0,1]
if k < K-1:
endX = self.x[k] + (self.x[k+1] - self.x[k])/2
else:
endX = 1
# calc b,w
if k > 0:
b,w = self.calc_b_w(startX,1)
else:
# init???
b = 100
w = 1
# stepfunction 1stHalf
# __________
# 0 ________|
#
w_array[w_idx,0] = w
w_array[w_idx,1] = b
h_array[w_idx,0] = self.y[k]
w_idx += 1
# stepfunction 2ndHalf
#
# 0 __________
# |________
b,w = self.calc_b_w(endX,1)
w_array[w_idx,0] = w
w_array[w_idx,1] = b
h_array[w_idx,0] = self.y[k]*-1
# shape of 1st + 2nd is under wave
# _
# 0 ________| |________
#
w_idx += 1
# record param
self.w = w_array
self.h = h_array
self.w_init = w_array[:,0]
self.b_init = w_array[:,1]
self.paramN = len(h_array)
return
# for bias coefficients setting
def initB(self, shape, name=None):
value = self.b_init
value = value.reshape(shape)
return K.variable(value, name=name)
# for w coefficients (x) setting
def initW(self, shape, name=None):
value = self.w_init
value = value.reshape(shape)
return K.variable(value, name=name)
# for h coefficients setting
def initH(self, shape, name=None):
value = self.h
value = value.reshape(shape)
return K.variable(value, name=name)
# 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"]])
print(y.shape)
# num of records
N = len(x)
#Normalisierung
x_max = np.max(x,axis=0)
x_min = np.min(x,axis=0)
x = (x - np.min(x,axis=0))/(np.max(x,axis=0) - np.min(x,axis=0))
# y > 2[m] : strong
# y <= 2[m] : weak
y_new = np.zeros(len(y),dtype=int)
for k in range(len(y)):
if y[k] > 2:
y_new[k] = 1
y_new = y_new.reshape(y.shape)
y = np.array(y_new,dtype=float)
# create InitInfo object
objInitInfo = InitInfo(x,y_orig)
# calc init value of w and h(and bias)
objInitInfo.calc_w_h()
#Machen Sie ein Modell zum Lernen
model = Sequential()
#Vollständig verbundene Schicht(1 Schicht->XXX Schicht)
model.add(Dense(input_dim=1, output_dim=objInitInfo.paramN,
bias=True,
kernel_initializer=objInitInfo.initW,
bias_initializer=objInitInfo.initB))
#Aktivierungsfunktion(Sigmoidfunktion)
model.add(Activation("sigmoid"))
#Vollständig verbundene Schicht(XXX Schicht->2 Schichten)
model.add(Dense(output_dim=1,kernel_initializer=objInitInfo.initH))
#Aktivierungsfunktion(Softmax-Funktion)
model.add(Activation("sigmoid"))
sgd_ = keras.optimizers.SGD(lr=0.05)
cb = keras.callbacks.EarlyStopping(monitor='loss',
min_delta=0.0004,
patience=1,
verbose=0,
mode='auto',
baseline=None)
#Kompilieren Sie das Modell
model.compile(loss="binary_crossentropy", optimizer=sgd_, metrics=["accuracy"])
#Führen Sie das Lernen durch
model.fit(x, y, epochs=5000, batch_size=32, verbose=1,callbacks=[cb])
#True Value Plot
plt.plot(x,y,marker='x',label="true")
#Berechnen Sie die Keras-Ergebnisse mit Inferenz,Anzeige
y_predict = model.predict(x)
#Keras Berechnungsergebnisplot
plt.plot(x,y_predict,marker='x',label="predict")
#Legendenanzeige
plt.legend()
# display result
print('OK per %.2f ' % (checkOKPercent(y_predict,y)*100.0))
Wir haben auch eine Rückrufeinstellung hinzugefügt, mit der Sie das Programm beenden können, wenn festgestellt wird, dass es konvergiert hat. Ergebnis ist ???
23/23 [==============================] - 0s 0us/step - loss: 0.2310 - acc: 1.0000
NG per 100.00
Großartig, die richtige Antwortrate ist jetzt 100%! !! !! Es stellte sich heraus, dass auch der Anfangswert gut eingestellt sein sollte. Es scheint jedoch, dass es nicht vielseitig ist? ?? ??
Ich habe versucht, den Koeffizienten zufällig zu löschen, und es schien mit den folgenden Einstellungen zu funktionieren.
# for bias coefficients setting
def initB(shape, name=None):
L = np.prod(shape)
value = np.ones(L).reshape(shape)*(-1000)
return K.variable(value, name=name)
# for w coefficients (x) setting
def initW(shape, name=None):
value = 1000/(np.random.random(shape))
return K.variable(value, name=name)
Es ist ein Koeffizient, der von x in die mittlere Schicht gelegt wird, aber die Vorspannungsseite ist auf 1000 festgelegt, die x-Seite (w) ergibt eine Zufallszahl von [0,1] und weist sie 1000 / Zufallszahl (mehr als 1000) entsprechend zu ( Es tut mir leid, wenn ich zu null Prozent aufwache.
import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Activation, Dense
from keras.utils.np_utils import to_categorical
from keras import backend as K
import keras
# y:predict
# t:true
def checkOKPercent(y,t):
# from predict param
sign_newral = np.sign(np.array(y).reshape([len(t),1]) - 0.5)
# from true param
sign_orig = np.sign(np.array(t.reshape([len(t),1])) - 0.5)
# are there same sign??
NGCNT = np.sum(np.abs(sign_newral-sign_orig))/2
# calc NG percent in [0.0-1.0]
NGPer = NGCNT / len(t)
# return OK percent [0.0-1.0]
return 1.0-NGPer
# for bias coefficients setting
def initB(shape, name=None):
L = np.prod(shape)
value = np.ones(L).reshape(shape)*(-1000)
return K.variable(value, name=name)
# for w coefficients (x) setting
def initW(shape, name=None):
value = 1000/(np.random.random(shape))
return K.variable(value, name=name)
# deta making???
csv_input = pd.read_csv(filepath_or_buffer="data_out.csv",
encoding="ms932",
sep=",")
#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)
x = (x - np.min(x,axis=0))/(np.max(x,axis=0) - np.min(x,axis=0))
# y > 2[m] : strong
# y <= 2[m] : weak
y_new = np.zeros(len(y),dtype=int)
for k in range(len(y)):
if y[k] > 2:
y_new[k] = 1
y_new = y_new.reshape(y.shape)
y = np.array(y_new,dtype=float)
#Machen Sie ein Modell zum Lernen
model = Sequential()
#Vollständig verbundene Schicht(1 Schicht->XXX Schicht)
model.add(Dense(input_dim=1, output_dim=50,
bias=True,
kernel_initializer=initW,
bias_initializer=initB))
#Aktivierungsfunktion(Sigmoidfunktion)
model.add(Activation("sigmoid"))
#Vollständig verbundene Schicht(XXX Schicht->2 Schichten)
model.add(Dense(output_dim=1))
#Aktivierungsfunktion(Softmax-Funktion)
model.add(Activation("sigmoid"))
sgd_ = keras.optimizers.SGD(lr=0.3)
cb = keras.callbacks.EarlyStopping(monitor='loss',
min_delta=0.0001,
patience=1,
verbose=0,
mode='auto',
baseline=None)
#Kompilieren Sie das Modell
model.compile(loss="binary_crossentropy", optimizer=sgd_, metrics=["accuracy"])
#Führen Sie das Lernen durch
model.fit(x, y, epochs=5000, batch_size=32, verbose=1,callbacks=[cb])
#True Value Plot
plt.plot(x,y,marker='x',label="true")
#Berechnen Sie die Keras-Ergebnisse mit Inferenz,Anzeige
y_predict = model.predict(x)
#Keras Berechnungsergebnisplot
plt.plot(x,y_predict,marker='x',label="predict")
#Legendenanzeige
plt.legend()
# display result
print('OK per %.2f ' % (checkOKPercent(y_predict,y)*100.0))
Das Ergebnis war auch gut.
Epoch 1032/5000
23/23 [==============================] - 0s 87us/step - loss: 0.1018 - acc: 1.0000
NG per 100.00
Die Anzahl der Knoten in der mittleren Schicht wurde auf 50 festgelegt, aber in vielen Fällen erreichte die richtige Antwortrate nicht 100%. Es scheint, dass die Stabilität durch Erhöhen der Anzahl der Knoten erhöht wird (gemäß den experimentellen Ergebnissen).
■ Wenn die Anzahl der Knoten 150 beträgt
Epoch 5000/5000
23/23 [==============================] - 0s 0us/step - loss: 0.0058 - acc: 1.0000
OK per 100.00
Dieses Mal habe ich eine einfache Zwei-Klassen-Klassifizierung in Keras implementiert. Es scheint eine Möglichkeit zu geben, die Softmax-Funktion zu verwenden (der zu Beginn eingeführte Artikel wurde hauptsächlich in Softmax implementiert), daher habe ich darüber nachgedacht, dies auch zu schreiben, aber da es etwas mehr geworden ist, möchte ich eine andere Gelegenheit nutzen Überlegen.
Recommended Posts