Ich habe vom letzten Mal an versucht, über neuronale Netze zu lernen.
Dieses Mal forderten wir heraus, ein einfaches Klassifizierungsmodell zu erstellen. Bereiten Sie die folgenden zwei Variablen vor.
0 \le x_1,x_2 \le 1
Dann klassifizieren wir wie folgt nach der Summe der beiden.
t(x_1,x_2) =
\left\{
\begin{matrix}
0 & (x_1 + x_2 < 1) \\
1 & (x_1 + x_2 \ge 1)
\end{matrix}
\right.
Lassen Sie uns ein so einfaches Modell implementieren. Betrachten Sie als 0-Schicht-neuronales Konzept die folgende Formel.
y(x_1,x_2) = \sigma(w_1 x_1 + w_2 x_2 + w_0)
Σ ist jedoch eine Sigmoidfunktion und ihre Ausgabe ist auf [0,1] begrenzt. Dies ist wirklich charakteristisch, und es scheint, dass es eine Bedeutung wie Klassifikation A hat, wenn y <0,5 ist, und Klassifikation B, wenn y> 0,5. Eigentlich habe ich das Gefühl, dass dies ein ziemlicher Teil der Leber ist. Im neuronalen Netz ein Mechanismus, der eine Antwort durch Einstellen von w1, w2, w0 gibt. In Anbetracht der Funktion, die den Fehler schätzt, scheint es in diesem Fall eine Kreuzentropie zu sein. Insbesondere wenn die richtige Antwort t auf x1 und x2 gegeben wird, wird die Schnittpunktentropie wie folgt ausgedrückt.
E(w_1,w_2,w_0) = - (t \ln y + (1-t) \ln (1-y) )
Einzelheiten finden Sie unter "Mustererkennung und maschinelles Lernen" (um S.235), aber als grobes Bild ... Achten Sie auf 0 <y <1
Dann ist die Wahrscheinlichkeit p (t), wenn t gegeben ist, durch Vereinheitlichen der Formel unter Verwendung von X ^ 0 = 1.
p(t)= y^t (1-y)^{1-t}
Es scheint so als. Wenn Sie danach protokollieren, wird die Formel von E (w1, w2, w0) abgeleitet. Dies wird für jede Stichprobe multipliziert, also für jedes yi
p(t)= \prod_i y_i^t (1-y_i)^{1-t}
Also nimm ein Protokoll
\ln p(t)= \sum_i (t \ln y_i + (1-t) \ln (1-y_i) )
Es wird sein. Dies entspricht der Summe der richtigen Antwortraten. Je mehr Sie übereinstimmen, desto größer ist der Wert. Daher haben wir E definiert, indem wir das Vorzeichen invertiert haben, um es als Optimierungsproblem (Minimierungsproblem) zu lösen. Wieder ist die Kreuzentropie: (Mehrere Beispielversionen)
E(w_1,w_2,w_0) = - \sum_i (t \ln y_i + (1-t) \ln (1-y_i) )
Lassen Sie uns nun den Quellcode schreiben. Erstens der variable Teil.
# make placeholder
x_ph = tf.placeholder(tf.float32, [None, 3])
t_ph = tf.placeholder(tf.float32, [None, 1])
x_ph ist der Eingabeteil, es sollten zwei sein, aber ich habe eine Dummy-Variable (fest auf 1) für w0 gesetzt. Vielleicht brauchst du das nicht? t_ph ist der Ausgabeteil und dient zur korrekten Beantwortung. Enthält 0 oder 1.
Dann werden die darin enthaltenen Beispieldaten entsprechend mit Zufallszahlen eingestellt.
# deta making???
N = 1000
x = np.random.rand(N,2)
# sum > 1.0 -> 1 : else -> 0
t = np.floor(np.sum(x,axis=1))
# ext x
x = np.hstack([x,np.ones(N).reshape(N,1)])
Nachdem Sie zwei x gemacht haben, machen Sie y und fügen Sie dann eine Dummy-Variable hinzu. Infolgedessen ist x in einer Probe dreidimensional. y wird durch Verwendung einer gebrochenen Kürzung erstellt, sodass x1 + x2 1 ist, wenn es 1 oder mehr ist, und 0, wenn es kleiner als 1 ist.
Bereiten Sie vorerst etwa zwei Schichten des neuronalen Netzwerks vor.
# create newral parameter(depth=2,input:3 > middle:30 > output:1)
hidden1 = tf.layers.dense(x_ph, 30, activation=tf.nn.relu)
newral_out = tf.layers.dense(hidden1, 1, activation=tf.nn.sigmoid)
Definieren wir nun die Kreuzentropie und das Lernen, um sie zu minimieren. Es ist nur eine Kopie. Ich bin mir immer noch nicht sicher über die Einstellungen des Konvergenzalgorithmus.
# Minimize the cross entropy
ce = -tf.reduce_sum(t_ph * tf.log(newral_out) + (1-t_ph)*tf.log(1-newral_out) )
optimizer = tf.train.AdamOptimizer()
train = optimizer.minimize(ce)
Also habe ich versucht, die gesamte Quelle zu erstellen, indem ich die oben genannten entsprechend kombiniert habe.
import numpy as np
import tensorflow as tf
# deta making???
N = 1000
x = np.random.rand(N,2)
# sum > 1.0 > 1 : else > 0
t = np.floor(np.sum(x,axis=1))
# ext x
x = np.hstack([x,np.ones(N).reshape(N,1)])
train_x = x
train_t = t
# make placeholder
x_ph = tf.placeholder(tf.float32, [None, 3])
t_ph = tf.placeholder(tf.float32, [None, 1])
# create newral parameter(depth=2,input:3 > middle:30 > output:1)
hidden1 = tf.layers.dense(x_ph, 30, activation=tf.nn.relu)
newral_out = tf.layers.dense(hidden1, 1, activation=tf.nn.sigmoid)
# Minimize the cross entropy
ce = -tf.reduce_sum(t_ph * tf.log(newral_out) + (1-t_ph)*tf.log(1-newral_out) )
optimizer = tf.train.AdamOptimizer()
train = optimizer.minimize(ce)
# initialize tensorflow session
sess = tf.Session()
sess.run(tf.global_variables_initializer())
for k in range(1001):
if np.mod(k,100) == 0:
# get Newral predict data
y_newral = sess.run( newral_out
,feed_dict = {
x_ph: x, #Ich habe die Eingabedaten in x gesetzt
})
ce_newral = sess.run( ce
,feed_dict = {
x_ph: x, #Ich habe die Eingabedaten in x gesetzt
t_ph: t.reshape(len(t),1) #Ich habe die richtigen Antwortdaten in y eingegeben
})
sign_newral = np.sign(np.array(y_newral).reshape([len(t),1]) - 0.5)
sign_orig = np.sign(np.array(t.reshape([len(t),1])) - 0.5)
NGCNT = np.sum(np.abs(sign_newral-sign_orig))/2
# check predict NewralParam
print('[%d] loss %.2f hit_per:%.2f' % (k,ce_newral,(N-NGCNT)/N))
# shuffle train_x and train_t
n = np.random.permutation(len(train_x))
train_x = train_x[n]
train_t = train_t[n].reshape([len(train_t), 1])
# execute train process
sess.run(train,feed_dict = {
x_ph: train_x, # x is input data
t_ph: train_t # t is true data
})
#Zum Test
x = np.array([0.41,0.5,1]).reshape([1,3])
loss_newral = sess.run( newral_out
,feed_dict = {
x_ph: x, #Ich habe die Eingabedaten in x gesetzt
})
# <0.Ist 5 ein Erfolg?
print(loss_newral)
Wenn Sie dies verschieben, wird es wie folgt sein.
[0] loss 727.36 hit_per:0.35
[100] loss 587.68 hit_per:0.78
[200] loss 465.78 hit_per:0.89
[300] loss 358.70 hit_per:0.93
[400] loss 282.45 hit_per:0.94
[500] loss 230.54 hit_per:0.96
[600] loss 194.34 hit_per:0.97
[700] loss 168.11 hit_per:0.98
[800] loss 148.34 hit_per:0.98
[900] loss 132.93 hit_per:0.99
[1000] loss 120.56 hit_per:0.99
[[0.27204064]]
Wenn ein Verlust geschrieben wird, können Sie sehen, dass der Kreuzentropiewert allmählich abnimmt. (Ändern Sie den Variablennamen ...) Und hit_per ist die richtige Antwortrate für die Trainingsdaten. Bei 1,00 wird es 100%, aber es scheint, dass die Erfolgsquote 99% beträgt. Schließlich wird die Ausgabe des neuronalen Netzes eingegeben, wenn ein geeigneter Test, x1 = 0,45, x2 = 0,5, eingegeben wird. In diesem Fall sollte es Klasse B t = 0 sein. Wenn also die Ausgabe kleiner als 0,5 ist, ist sie korrekt, und wenn sie näher an 0,5 liegt, kann gelesen werden, dass sie verloren geht. Diesmal ist es 0,27, also bin ich ziemlich zuversichtlich, darauf zu antworten.
Abschließend werde ich ein wenig darüber schreiben, wie man die richtige Antwort erhält. Ich denke, der Punkt ist, dass wir die Anzahl der NG herausgeben. Einige Pickups unten.
# get Newral predict data
y_newral = sess.run( newral_out
,feed_dict = {
x_ph: x, #Ich habe die Eingabedaten in x gesetzt
})
sign_newral = np.sign(np.array(y_newral).reshape([len(t),1]) - 0.5)
sign_orig = np.sign(np.array(t.reshape([len(t),1])) - 0.5)
NGCNT = np.sum(np.abs(sign_newral-sign_orig))/2
y_newral enthält Klassifizierungsinformationen, die aus x im Bereich [0,1] geschätzt werden. Diese Zahl bedeutet, ob sie in die Kategorie größer oder kleiner als 0,5 fällt. Daher muss sie in eine Form umgewandelt werden, die unterschieden werden kann. Daher subtrahierte ich den Wert von 0,5, verschob ihn parallel zum Bereich von [-0,5, 0,5] und extrahierte dann nur den Code, sodass entweder +1 oder -1 ausgewählt wurde. Der gleiche Vorgang wird für t (richtige Antwort) ausgeführt, um einen + 1 / -1 korrekten Antwortwert zu erzeugen. Diese beiden sind richtig, wenn sie den gleichen Wert haben, und falsch, wenn sie unterschiedliche Werte haben, aber wenn das Muster ausgeschrieben ist, haben sie die folgende Beziehung.
Geschätzter Wert | Richtiger Antwortwert | Geschätzte Richtigkeit | Geschätzter Wert-Richtiger Antwortwert |
---|---|---|---|
1 | 1 | OK | 0 |
1 | -1 | NG | 2 |
-1 | 1 | NG | -2 |
-1 | -1 | OK | 0 |
Daher kann die Anzahl der NGs durch Berechnung der Summe (abs (geschätzter Wert - korrekter Antwortwert)) / 2 gezählt werden. Auf diese Weise konnte die richtige Antwortrate berechnet werden.
Es hat so gut funktioniert, aber wenn ich das neuronale Netz einfacher und ohne die Zwischenschicht eingestellt habe, schien es lange zu dauern, bis es konvergierte, oder es war übertrieben und so etwas wie null Prozent ??? Zum Beispiel, wenn Sie mit den folgenden Einstellungen gehen ...
newral_out = tf.layers.dense(x_ph, 1, activation=tf.nn.sigmoid)
Ergebnis ist ???
[0] loss 761.80 hit_per:0.50
[100] loss 732.66 hit_per:0.50
[200] loss 706.48 hit_per:0.50
[300] loss 682.59 hit_per:0.50
[400] loss 660.61 hit_per:0.50
[500] loss 640.24 hit_per:0.54
[600] loss 621.26 hit_per:0.62
[700] loss 603.52 hit_per:0.70
[800] loss 586.88 hit_per:0.76
[900] loss 571.22 hit_per:0.80
[1000] loss 556.44 hit_per:0.84
[[0.52383685]]
Es scheint, dass es nicht gut genug ist. Was ist gut und wie funktioniert es? Mir fehlt immer noch das Verständnis, aber es scheint, dass etwas passiert ist und mit einer Mittelklasse gut läuft. Wie viel sollten wir erhöhen, damit es so aussieht? Ich möchte auch die Theorie dazu studieren.
Recommended Posts