2017-05-07 6 views
0

Ich habe eine einfache Struktur, die ich aus einem Video von Siraj Raval von einem einschichtigen Perzeptron im Tensorflow gelernt habe. Ich habe versucht, es auf eine größere Anzahl von Schichten zu erweitern, und ich habe Schwierigkeiten.Mehrschichtiges Perzeptron im Tensorfluss verhält sich nicht wie erwartet

Das erste Beispiel besteht aus 2 Eingängen und 2 Ausgängen, wobei Gewichtungen und Verzerrungen einmal angewendet werden und dann die Softmax-Funktion auf den Ausgang angewendet wird.

Das zweite Beispiel ist 2 Eingänge und 2 Ausgänge mit einer versteckten Schicht (2 Einheiten) dazwischen, also gibt es zwei Sätze von Gewichten und Verzerrungen und die Softmax-Funktion wird nach jedem von ihnen angewendet.

Ich versuche, den einfachen Fall zu einem N-versteckten Layer Fall zu erweitern, habe aber begrenzten Erfolg als wenn ich zusätzliche Layer hinzufügen, scheinen sie vom Optimierer ignoriert werden.

Eingang ist von der Form:

inputX = np.array([[ 2.10400000e+03, 3.00000000e+00], 
        [ 1.60000000e+03, 3.00000000e+00], 
        [ 2.40000000e+03, 3.00000000e+00], 
        [ 1.41600000e+03, 2.00000000e+00], 
        [ 3.00000000e+03, 4.00000000e+00], 
        [ 1.98500000e+03, 4.00000000e+00], 
        [ 1.53400000e+03, 3.00000000e+00], 
        [ 1.42700000e+03, 3.00000000e+00], 
        [ 1.38000000e+03, 3.00000000e+00], 
        [ 1.49400000e+03, 3.00000000e+00]]) 

und Ausgang Etikett sind von der Form:

inputY = np.array([[1, 0], 
        [1, 0], 
        [1, 0], 
        [0, 1], 
        [0, 1], 
        [1, 0], 
        [0, 1], 
        [1, 0], 
        [1, 0], 
        [1, 0]]) 

ein Ausschnitt aus meinem Code, korrekt ausführt (Abhängigkeiten sind numpy und tensorflow):

#input and output placeholder, feed data to x, feed labels to y_ 
x = tf.placeholder(tf.float32, [None, 2]) 
y_ = tf.placeholder(tf.float32, [None, 2]) 

#first layer weights and biases 
W = tf.Variable(tf.zeros([2,2])) 
b = tf.Variable(tf.zeros([2])) 

# vector form of x*W + b 
y_values = tf.add(tf.matmul(x, W), b) 

#activation function 
y = tf.nn.softmax(y_values) 

cost = tf.reduce_sum(tf.pow(y_ - y, 2))/(n_samples) #sum of squared errors 
optimizer = tf.train.AdamOptimizer(alpha).minimize(cost) 

init = tf.global_variables_initializer() 
sess = tf.Session() 
sess.run(init) 

for i in range(training_epochs): 
    sess.run(optimizer, feed_dict = {x: inputX, y_:inputY}) 

    #log training 
    if i % display_step == 0: 
     cc = sess.run(cost, feed_dict = {x: inputX, y_:inputY}) 

     print("Training step:", '%04d' % (i), "cost=", "{:.9f}".format(cc)) 

print("Optimization Finished!") 
training_cost = sess.run(cost, feed_dict = {x: inputX, y_: inputY}) 
print("Training cost = ", training_cost, "\nW=", sess.run(W), "\nb=", sess.run(b)) 


#check what it thinks when you give it the input data 
print(sess.run(y, feed_dict = {x:inputX})) 

Ich bekomme die Ausgabe von:

W= [[ 0.00021142 -0.00021142] 
    [ 0.00120122 -0.00120122]] 

b= [ 0.00103542 -0.00103542] 

label_predictions = [[ 0.71073025 0.28926972] 
        [ 0.66503692 0.33496314] 
        [ 0.73576927 0.2642307 ] 
        [ 0.64694035 0.35305965] 
        [ 0.78248388 0.21751612] 
        [ 0.70078063 0.2992194 ] 
        [ 0.65879178 0.34120819] 
        [ 0.6485498 0.3514502 ] 
        [ 0.64400673 0.3559933 ] 
        [ 0.65497971 0.34502029]] 

Nicht großartig, also wollte ich versuchen, die Anzahl der Schichten zu erhöhen, um zu sehen, ob es Dinge verbessern würde.

ich durch den Einsatz neuer Variablen von W2, b2 und hidden_layer eine zusätzliche Schicht hinzugefügt:

#input and output placeholder, feed data to x, feed labels to y_ 
x = tf.placeholder(tf.float32, [None, 2]) 
y_ = tf.placeholder(tf.float32, [None, 2]) 

#first layer weights and biases 
W = tf.Variable(tf.zeros([2,2])) 
b = tf.Variable(tf.zeros([2])) 

#second layer weights and biases 
W2 = tf.Variable(tf.zeros([2,2])) 
b2 = tf.Variable(tf.zeros([2])) 

#flow through first layer 
hidden_layer = tf.add(tf.matmul(x, W), b) 
hidden_layer = tf.nn.softmax(hidden_layer) 

#flow through second layer 
y_values = tf.add(tf.matmul(hidden_layer, W2), b2) 
y = tf.nn.softmax(y_values) 

cost = tf.reduce_sum(tf.pow(y_ - y, 2))/(n_samples) #sum of squared errors 
optimizer = tf.train.AdamOptimizer(alpha).minimize(cost) 

init = tf.global_variables_initializer() 
sess = tf.Session() 
sess.run(init) 

for i in range(training_epochs): 
    sess.run(optimizer, feed_dict = {x: inputX, y_:inputY}) 

    #log training 
    if i % display_step == 0: 
     cc = sess.run(cost, feed_dict = {x: inputX, y_:inputY}) 

     print("Training step:", '%04d' % (i), "cost=", "{:.9f}".format(cc)) 

print("Optimization Finished!") 
training_cost = sess.run(cost, feed_dict = {x: inputX, y_: inputY}) 
print("Training cost = ", training_cost, "\nW=", sess.run(W), "\nW2=", sess.run(W2),\ 
      "\nb=", sess.run(b), "\nb2=", sess.run(b2)) 


#check what it thinks when you give it the input data 
print(sess.run(y, feed_dict = {x:inputX})) 

bin ich dann gesagt, dass meine erste Schichtgewichte und spannt alle Nullen sind und dass die Vorhersagen sind jetzt etwa über halb und halb bei jedem Trainingsbeispiel, viel schlechter als vorher.

Ausgabe:

W= [[ 0. 0.] 
    [ 0. 0.]] 

W2= [[ 0.00199614 -0.00199614] 
    [ 0.00199614 -0.00199614]] 

b= [ 0. 0.] 
b2= [ 0.00199614 -0.00199614] 

label_predictions = [[ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384] 
        [ 0.5019961 0.49800384]] 

Warum ist nur eine Schicht von Gewichten und Vorurteile beeinflusst zu werden? Warum wird keine Ebene hinzugefügt, die das Modell verbessert?

Antwort

0

Ich habe ein paar Vorschläge, um die Leistung des Modells zu verbessern:

1.) Randomly initialisierten Variablen oft besser funktionieren als Nullen, zumindest für die Matrixelemente. Sie könnten normal verteilte Variablen ausprobieren.

2.) Sie sollten Ihre Eingabedaten normalisieren, da die beiden Spalten unterschiedliche Größenordnungen haben. Im Prinzip sollte dies kein Problem sein, da die Gewichte unterschiedlich eingestellt werden können, aber bei zufälliger Initialisierung ist es wahrscheinlich, dass das Netzwerk nur auf die erste Spalte achtet. Wenn Sie die Daten normalisieren, haben beide Spalten die gleiche Größenordnung.

3.) Vielleicht sollten Sie die Anzahl der Neuronen in der verborgenen Schicht auf einen Wert von etwa 10.

Mit diesen Modifikationen erhöhen, funktionierte es ganz gut für mich.Ich habe ein komplettes Arbeits Beispiel unten geschrieben:

import tensorflow as tf 
import numpy as np 
alpha = 0.02 
training_epochs = 20000 
display_step = 2000 
inputX = np.array([[ 2.10400000e+03, 3.00000000e+00], 
        [ 1.60000000e+03, 3.00000000e+00], 
        [ 2.40000000e+03, 3.00000000e+00], 
        [ 1.41600000e+03, 2.00000000e+00], 
        [ 3.00000000e+03, 4.00000000e+00], 
        [ 1.98500000e+03, 4.00000000e+00], 
        [ 1.53400000e+03, 3.00000000e+00], 
        [ 1.42700000e+03, 3.00000000e+00], 
        [ 1.38000000e+03, 3.00000000e+00], 
        [ 1.49400000e+03, 3.00000000e+00]]) 
n_samples = inputX.shape[0] 

# Normalize input data 
means = np.mean(inputX, axis=0) 
stddevs = np.std(inputX, axis=0) 
inputX[:,0] = (inputX[:,0] - means[0])/stddevs[0] 
inputX[:,1] = (inputX[:,1] - means[1])/stddevs[1] 

# Define target labels 
inputY = np.array([[1, 0], 
        [1, 0], 
        [1, 0], 
        [0, 1], 
        [0, 1], 
        [1, 0], 
        [0, 1], 
        [1, 0], 
        [1, 0], 
        [1, 0]]) 

#input and output placeholder, feed data to x, feed labels to y_ 
x = tf.placeholder(tf.float32, [None, 2]) 
y_ = tf.placeholder(tf.float32, [None, 2]) 

#first layer weights and biases 
W = tf.Variable(tf.random_normal([2,10], stddev=1.0/tf.sqrt(2.0))) 
b = tf.Variable(tf.zeros([10])) 

#second layer weights and biases 
W2 = tf.Variable(tf.random_normal([10,2], stddev=1.0/tf.sqrt(2.0))) 
b2 = tf.Variable(tf.zeros([2])) 

#flow through first layer 
hidden_layer = tf.add(tf.matmul(x, W), b) 
hidden_layer = tf.nn.softmax(hidden_layer) 

#flow through second layer 
y_values = tf.add(tf.matmul(hidden_layer, W2), b2) 
y = tf.nn.softmax(y_values) 

cost = tf.reduce_sum(tf.pow(y_ - y, 2))/(n_samples) #sum of squared errors 
optimizer = tf.train.AdamOptimizer(alpha).minimize(cost) 

init = tf.global_variables_initializer() 
sess = tf.Session() 
sess.run(init) 

for i in range(training_epochs): 
    sess.run(optimizer, feed_dict = {x: inputX, y_:inputY}) 

    #log training 
    if i % display_step == 0: 
     cc = sess.run(cost, feed_dict = {x: inputX, y_:inputY}) 
     #check what it thinks when you give it the input data 
     print(sess.run(y, feed_dict = {x:inputX})) 

     print("Training step:", '%04d' % (i), "cost=", "{:.9f}".format(cc)) 

print("Optimization Finished!") 
training_cost = sess.run(cost, feed_dict = {x: inputX, y_: inputY}) 
print("Training cost = ", training_cost, "\nW=", sess.run(W), "\nW2=", sess.run(W2),\ 
      "\nb=", sess.run(b), "\nb2=", sess.run(b2)) 

Die Ausgabe sieht sehr ähnlich wie die Etiketten:

[[ 1.00000000e+00 2.48446125e-10] 
[ 9.99883890e-01 1.16143732e-04] 
[ 1.00000000e+00 2.48440435e-10] 
[ 1.65703295e-05 9.99983430e-01] 
[ 6.65045518e-05 9.99933481e-01] 
[ 9.99985337e-01 1.46147468e-05] 
[ 1.69444829e-04 9.99830484e-01] 
[ 1.00000000e+00 6.85981003e-12] 
[ 1.00000000e+00 2.05180339e-12] 
[ 9.99865890e-01 1.34040893e-04]] 
Verwandte Themen