3

Ich habe einige Probleme versuchen, ein mehrschichtiges Perzeptron für die binäre Klassifizierung mit Tensorflow einzurichten.Einrichten eines MLP für binäre Klassifizierung mit Tensorflow

Ich habe einen sehr großen Datensatz (ca. 1,5 * 10^6 Beispiele) jeweils mit einem binären (0/1) Label und 100 Features. Was ich tun muss, ist ein einfaches MLP einzurichten und dann zu versuchen, die Lernrate und das Initialisierungsmuster zu ändern, um die Ergebnisse zu dokumentieren (es ist eine Aufgabe). Ich bekomme jedoch seltsame Ergebnisse, da mein MLP mit niedrigen, aber nicht sehr hohen Kosten früh stecken bleibt und nie davon kommt. Mit relativ niedrigen Werten der Lernrate gehen die Kosten NAN fast sofort. Ich weiß nicht, ob das Problem darin liegt, wie ich das MLP strukturiert habe (ich habe ein paar Versuche gemacht, werde den Code für das letzte schreiben) oder wenn mir etwas mit meiner Tensorflow-Implementierung fehlt.

CODE

import tensorflow as tf 
import numpy as np 
import scipy.io 

# Import and transform dataset 
print("Importing dataset.") 
dataset = scipy.io.mmread('tfidf_tsvd.mtx') 

with open('labels.txt') as f: 
    all_labels = f.readlines() 

all_labels = np.asarray(all_labels) 
all_labels = all_labels.reshape((1498271,1)) 

# Split dataset into training (66%) and test (33%) set 
training_set = dataset[0:1000000] 
training_labels = all_labels[0:1000000] 
test_set  = dataset[1000000:1498272] 
test_labels  = all_labels[1000000:1498272] 

print("Dataset ready.") 

# Parameters 
learning_rate = 0.01 #argv 
mini_batch_size = 100 
training_epochs = 10000 
display_step = 500 

# Network Parameters 
n_hidden_1 = 64 # 1st hidden layer of neurons 
n_hidden_2 = 32 # 2nd hidden layer of neurons 
n_hidden_3 = 16 # 3rd hidden layer of neurons 
n_input  = 100 # number of features after LSA 

# Tensorflow Graph input 
x = tf.placeholder(tf.float64, shape=[None, n_input], name="x-data") 
y = tf.placeholder(tf.float64, shape=[None, 1], name="y-labels") 

print("Creating model.") 

# Create model 
def multilayer_perceptron(x, weights): 
    # First hidden layer with SIGMOID activation 
    layer_1 = tf.matmul(x, weights['h1']) 
    layer_1 = tf.nn.sigmoid(layer_1) 
    # Second hidden layer with SIGMOID activation 
    layer_2 = tf.matmul(layer_1, weights['h2']) 
    layer_2 = tf.nn.sigmoid(layer_2) 
    # Third hidden layer with SIGMOID activation 
    layer_3 = tf.matmul(layer_2, weights['h3']) 
    layer_3 = tf.nn.sigmoid(layer_3) 
    # Output layer with SIGMOID activation 
    out_layer = tf.matmul(layer_2, weights['out']) 
    return out_layer 

# Layer weights, should change them to see results 
weights = { 
    'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1], dtype=np.float64)),  
    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2], dtype=np.float64)), 
    'h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3],dtype=np.float64)), 
    'out': tf.Variable(tf.random_normal([n_hidden_2, 1], dtype=np.float64)) 
} 

# Construct model 
pred = multilayer_perceptron(x, weights) 

# Define loss and optimizer 
cost = tf.nn.l2_loss(pred-y,name="squared_error_cost") 
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) 

# Initializing the variables 
init = tf.initialize_all_variables() 

print("Model ready.") 

# Launch the graph 
with tf.Session() as sess: 
    sess.run(init) 

    print("Starting Training.") 

    # Training cycle 
    for epoch in range(training_epochs): 
     #avg_cost = 0. 
     # minibatch loading 
     minibatch_x = training_set[mini_batch_size*epoch:mini_batch_size*(epoch+1)] 
     minibatch_y = training_labels[mini_batch_size*epoch:mini_batch_size*(epoch+1)] 
     # Run optimization op (backprop) and cost op 
     _, c = sess.run([optimizer, cost], feed_dict={x: minibatch_x, y: minibatch_y}) 

     # Compute average loss 
     avg_cost = c/(minibatch_x.shape[0]) 

     # Display logs per epoch 
     if (epoch) % display_step == 0: 
     print("Epoch:", '%05d' % (epoch), "Training error=", "{:.9f}".format(avg_cost)) 

    print("Optimization Finished!") 

    # Test model 
    # Calculate accuracy 
    test_error = tf.nn.l2_loss(pred-y,name="squared_error_test_cost")/test_set.shape[0] 
    print("Test Error:", test_error.eval({x: test_set, y: test_labels})) 

OUTPUT

python nn.py 
Importing dataset. 
Dataset ready. 
Creating model. 
Model ready. 
Starting Training. 
Epoch: 00000 Training error= 0.331874878 
Epoch: 00500 Training error= 0.121587482 
Epoch: 01000 Training error= 0.112870921 
Epoch: 01500 Training error= 0.110293652 
Epoch: 02000 Training error= 0.122655269 
Epoch: 02500 Training error= 0.124971940 
Epoch: 03000 Training error= 0.125407845 
Epoch: 03500 Training error= 0.131942481 
Epoch: 04000 Training error= 0.121696954 
Epoch: 04500 Training error= 0.116669835 
Epoch: 05000 Training error= 0.129558477 
Epoch: 05500 Training error= 0.122952110 
Epoch: 06000 Training error= 0.124655344 
Epoch: 06500 Training error= 0.119827300 
Epoch: 07000 Training error= 0.125183779 
Epoch: 07500 Training error= 0.156429254 
Epoch: 08000 Training error= 0.085632880 
Epoch: 08500 Training error= 0.133913128 
Epoch: 09000 Training error= 0.114762624 
Epoch: 09500 Training error= 0.115107805 
Optimization Finished! 
Test Error: 0.116647016708 

Dies ist, was MMN beraten

weights = { 
    'h1': tf.Variable(tf.random_normal([n_input, n_hidden_1], stddev=0, dtype=np.float64)),  
    'h2': tf.Variable(tf.random_normal([n_hidden_1, n_hidden_2], stddev=0.01, dtype=np.float64)), 
    'h3': tf.Variable(tf.random_normal([n_hidden_2, n_hidden_3], stddev=0.01, dtype=np.float64)), 
    'out': tf.Variable(tf.random_normal([n_hidden_2, 1], dtype=np.float64)) 
} 

Dies ist die Ausgabe

Epoch: 00000 Training error= 0.107566668 
Epoch: 00500 Training error= 0.289380907 
Epoch: 01000 Training error= 0.339091784 
Epoch: 01500 Training error= 0.358559815 
Epoch: 02000 Training error= 0.122639698 
Epoch: 02500 Training error= 0.125160135 
Epoch: 03000 Training error= 0.126219718 
Epoch: 03500 Training error= 0.132500418 
Epoch: 04000 Training error= 0.121795254 
Epoch: 04500 Training error= 0.116499476 
Epoch: 05000 Training error= 0.124532673 
Epoch: 05500 Training error= 0.124484790 
Epoch: 06000 Training error= 0.118491177 
Epoch: 06500 Training error= 0.119977633 
Epoch: 07000 Training error= 0.127532511 
Epoch: 07500 Training error= 0.159053519 
Epoch: 08000 Training error= 0.083876224 
Epoch: 08500 Training error= 0.131488483 
Epoch: 09000 Training error= 0.123161189 
Epoch: 09500 Training error= 0.125011362 
Optimization Finished! 
Test Error: 0.129284643093 

Connected dritte versteckte Schicht dank MMN

Es war ein Fehler in meinem Code und ich hatte zwei verborgene Schichten anstelle von drei. Ich korrigierte tun:

'out': tf.Variable(tf.random_normal([n_hidden_3, 1], dtype=np.float64)) 

und

out_layer = tf.matmul(layer_3, weights['out']) 

ich auf den alten Wert für stddev zurück obwohl, wie es weniger Schwankungen in der Kostenfunktion zu verursachen scheint.

Der Ausgang ist immer noch beunruhigend

Epoch: 00000 Training error= 0.477673073 
Epoch: 00500 Training error= 0.121848744 
Epoch: 01000 Training error= 0.112854530 
Epoch: 01500 Training error= 0.110597624 
Epoch: 02000 Training error= 0.122603499 
Epoch: 02500 Training error= 0.125051472 
Epoch: 03000 Training error= 0.125400717 
Epoch: 03500 Training error= 0.131999354 
Epoch: 04000 Training error= 0.121850889 
Epoch: 04500 Training error= 0.116551533 
Epoch: 05000 Training error= 0.129749704 
Epoch: 05500 Training error= 0.124600464 
Epoch: 06000 Training error= 0.121600218 
Epoch: 06500 Training error= 0.121249676 
Epoch: 07000 Training error= 0.132656938 
Epoch: 07500 Training error= 0.161801757 
Epoch: 08000 Training error= 0.084197352 
Epoch: 08500 Training error= 0.132197409 
Epoch: 09000 Training error= 0.123249055 
Epoch: 09500 Training error= 0.126602369 
Optimization Finished! 
Test Error: 0.129230736355 

Zwei weitere Änderungen dank Steven So vorgeschlagen Steven Sigmoid-Aktivierungsfunktion mit relu, zu ändern, und so habe ich versucht. In der Zwischenzeit bemerkte ich, dass ich keine Aktivierungsfunktion für den Ausgangsknoten eingestellt hatte, also tat ich das auch (sollte leicht zu sehen sein, was ich geändert habe).

Starting Training. 
Epoch: 00000 Training error= 293.245977809 
Epoch: 00500 Training error= 0.290000000 
Epoch: 01000 Training error= 0.340000000 
Epoch: 01500 Training error= 0.360000000 
Epoch: 02000 Training error= 0.285000000 
Epoch: 02500 Training error= 0.250000000 
Epoch: 03000 Training error= 0.245000000 
Epoch: 03500 Training error= 0.260000000 
Epoch: 04000 Training error= 0.290000000 
Epoch: 04500 Training error= 0.315000000 
Epoch: 05000 Training error= 0.285000000 
Epoch: 05500 Training error= 0.265000000 
Epoch: 06000 Training error= 0.340000000 
Epoch: 06500 Training error= 0.180000000 
Epoch: 07000 Training error= 0.370000000 
Epoch: 07500 Training error= 0.175000000 
Epoch: 08000 Training error= 0.105000000 
Epoch: 08500 Training error= 0.295000000 
Epoch: 09000 Training error= 0.280000000 
Epoch: 09500 Training error= 0.285000000 
Optimization Finished! 
Test Error: 0.220196439287 

Das ist, was es tut mit der Sigmoid-Aktivierungsfunktion auf jedem Knoten, Ausgang enthielt

Epoch: 00000 Training error= 0.110878121 
Epoch: 00500 Training error= 0.119393080 
Epoch: 01000 Training error= 0.109229532 
Epoch: 01500 Training error= 0.100436962 
Epoch: 02000 Training error= 0.113160662 
Epoch: 02500 Training error= 0.114200962 
Epoch: 03000 Training error= 0.109777990 
Epoch: 03500 Training error= 0.108218725 
Epoch: 04000 Training error= 0.103001394 
Epoch: 04500 Training error= 0.084145737 
Epoch: 05000 Training error= 0.119173495 
Epoch: 05500 Training error= 0.095796251 
Epoch: 06000 Training error= 0.093336573 
Epoch: 06500 Training error= 0.085062860 
Epoch: 07000 Training error= 0.104251661 
Epoch: 07500 Training error= 0.105910949 
Epoch: 08000 Training error= 0.090347288 
Epoch: 08500 Training error= 0.124480612 
Epoch: 09000 Training error= 0.109250224 
Epoch: 09500 Training error= 0.100245836 
Optimization Finished! 
Test Error: 0.110234139674 

ich diese Zahlen sehr seltsam gefunden, im ersten Fall, es in einem höheren stecken Kosten als Sigmoid, obwohl Sigmoid sehr früh gesättigt werden sollte. Im zweiten Fall beginnt es mit einem Trainingsfehler, der fast der letzte ist ... also konvergiert es im Grunde mit einem Mini-Batch. Ich beginne zu denken, dass ich die Kosten nicht korrekt in dieser Zeile berechne: avg_cost = c/(minibatch_x.shape [0])

+0

Haben Sie versucht, Ihre Zeile 'cost = tf.nn.l2_loss (pred-y, name =" squared_error_cost ")' zu 'cost = tf.nn.square (tf (pred, y))' '? – Kashyap

+0

Können Sie während des Trainings Genauigkeit (Prozent der korrekt klassifizierten Proben) drucken? –

+0

@Kashyap: Ich bekomme einen Fehler "nicht leere Formatzeichenfolge an Objekt übergeben .__ Format__" Fehler beim Drucken der Kosten, und das scheint nicht in der Lage, es zu lösen. – Darkobra

Antwort

1

So könnte es ein paar Dinge:

  1. Sie die S-förmige Einheiten werden könnte sättigen (wie MMN erwähnt) würde ich relu Einheiten versuchen stattdessen vorschlagen.

ersetzen:

tf.nn.sigmoid(layer_n) 

mit:

tf.nn.relu(layer_n) 
  1. Ihr Modell die Ausdruckskraft nicht haben können Sie Ihre Daten, um tatsächlich zu lernen. I.e. es müsste tiefer gehen.
  2. Sie können auch einen anderen Optimierer wie Adam() als solche

ersetzen versuchen:

optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost) 

mit:

optimizer = tf.train.AdamOptimizer().minimize(cost) 

ein paar andere Punkte:

  1. Sie sollten ein Bias-Term auf Ihre Gewicht

wie so hinzufügen:

biases = { 
'b1': tf.Variable(tf.random_normal([n_hidden_1], dtype=np.float64)),  
'b2': tf.Variable(tf.random_normal([n_hidden_2], dtype=np.float64)), 
'b3': tf.Variable(tf.random_normal([n_hidden_3],dtype=np.float64)), 
'bout': tf.Variable(tf.random_normal([1], dtype=np.float64)) 
} 

def multilayer_perceptron(x, weights): 
    # First hidden layer with SIGMOID activation 
    layer_1 = tf.matmul(x, weights['h1']) + biases['b1'] 
    layer_1 = tf.nn.sigmoid(layer_1) 
    # Second hidden layer with SIGMOID activation 
    layer_2 = tf.matmul(layer_1, weights['h2']) + biases['b2'] 
    layer_2 = tf.nn.sigmoid(layer_2) 
    # Third hidden layer with SIGMOID activation 
    layer_3 = tf.matmul(layer_2, weights['h3']) + biases['b3'] 
    layer_3 = tf.nn.sigmoid(layer_3) 
    # Output layer with SIGMOID activation 
    out_layer = tf.matmul(layer_2, weights['out']) + biases['bout'] 
    return out_layer 
  1. und Sie können die Lernrate im Laufe der Zeit aktualisieren

wie folgt:

learning_rate = tf.train.exponential_decay(INITIAL_LEARNING_RATE, 
              global_step, 
              decay_steps, 
              LEARNING_RATE_DECAY_FACTOR, 
              staircase=True) 

Sie müssen nur die Dez definieren ay Schritte, d. h. wann sie abfallen und LEARNING_RATE_DECAY_FACTOR, d. h. um wieviel abfallen.

+0

Ich habe die Antwort mit Ihren Vorschlägen bearbeitet. Beachten Sie, dass: 1. Reluz gibt sehr seltsame Werte, können Sie es in der Bearbeitung der Frage lesen. 2. Ich habe das Modell tiefer gemacht, da es vorher zwei versteckte Ebenen hatte, aufgrund eines Fehlers von mir und es hat jetzt 3 versteckte Ebenen. 3. Ich kann Adam Optimizer wirklich nicht verwenden, da es gegen den Zweck meiner Aufgabe gehen würde, nämlich mit der Lernrate und einigen Initialisierungsparametern zu spielen. Denkst du, ich berechne die Kosten korrekt, nach jedem mini_batch? – Darkobra

+0

Es gibt verschiedene Kostenfunktionen, also hängt es wirklich von Ihrer Aufgabe ab. Ich kann diese Frage nicht wirklich beantworten, ohne die Aufgabe zu kennen zu sagen, ob der Verlust richtig ist oder vielleicht die Entropie oder etwas anderes. Sie verwenden l2 Verlust jedoch korrekt. – Steven

+0

Eine andere einfache Sache, die "offensichtlich" ist, aber manchmal unbemerkt bleibt, stellen Sie sicher, dass Ihre Etiketten den richtigen Trainingseingaben entsprechen. – Steven

1

Ihre Gewichte bei initialisiert mit einer stddev von 1, so dass die Ausgabe von Schicht 1 eine stddev von 10 oder so haben wird. Dies könnte die Sigmoid-Funktionen bis zu dem Punkt sättigen, an dem die meisten Gradienten 0 sind.

Können Sie versuchen, die versteckten Gewichte mit einer Stddev von .01 zu initialisieren?

+0

Sieht aus wie dieses 00000 Tr err = 0,107566 00500 Tr err = 0,289380 01000 Tr err = 0,339091 01500 Tr err = 0,358559 02000 Tr err = 0,122639 02500 Tr err = 0,125160 03000 Tr err = 0,126219 03500 Tr err = 0.132500 04000 Tr err = 0,121795 04500 Tr err = 0,116499 05000 Tr err = 0,124532 05500 Tr err = 0,124484 06000 Tr err = 0,118491 06500 Tr err = 0,119977 07000 Tr err = 0,127532 07500 Tr err = 0,159053 08000 Tr err = 0,083876 08500 Tr err = 0,131488 09000 Tr err = 0,123161 09500 Tr err = 0,125011 Te Err: 0,129284643 – Darkobra

+0

Uhm, kann nicht die richtige Form geben Kommentare, aber ich kann Ihnen sagen, dass dies nicht mein Problem lösen. – Darkobra

+0

hmm, vielleicht ist das das Beste, was Sie mit einem zweischichtigen Netzwerk bekommen? Wolltest du nicht h3 benutzen? – MMN

1

Zusammen mit oben genannten Antworten, werde ich Ihnen vorschlagen, dass eine Kostenfunktion versuchen tf.nn.sigmoid_cross_entropy_with_logits (Logits, Ziele, name = None)

als binäre Klassifizierung, müssen Sie versuchen, die sigmoid_cross_entropy_with_logits Kosten Funktion

Ich schlage auch vor, Sie müssen auch Liniendiagramm der Genauigkeit der Zug und Test vs Anzahl der Epochen plotten. d. h. prüfen, ob das Modell überbaut ist?

Wenn es nicht übermäßig ist, versuchen Sie, Ihr neuronales Netz komplexer zu machen. Das ist durch die zunehmende Anzahl von Neuronen, zunehmende Anzahl von Schichten.Sie werden einen solchen Punkt darüber hinaus erhalten, dass Ihre Trainingsgenauigkeit weiter steigt, aber die Validierung wird diesen Punkt nicht das beste Modell geben.

+0

Hey Pramod, danke für deine Antwort. Ich habe über diese Kostenfunktion gelesen, die Sie erwähnt haben, aber die Beschreibungen sagen, dass es am besten geeignet ist, wo die Etiketten sich nicht gegenseitig ausschließen - aber in meinem Modell sind sie. Ich passe jetzt mein Netzwerk mit Hilfe von TensorBoard an und werde sicher versuchen, mein Netz komplexer zu machen. – Darkobra

+0

Wie bei Frage "Ich habe einen sehr großen Datensatz (ca. 1,5 * 10^6 Beispiele) jeweils mit einer binären (0/1) Bezeichnung". Es ist eine binäre Klassenklassifikation, bei der jede Instanz entweder wahr (1) oder falsch (0) ist. Was meinst du mit sich gegenseitig ausschließen? Ich kann es nicht bekommen. –

+0

Ich denke, du sprichst darüber "Misst den Wahrscheinlichkeitsfehler in diskreten Klassifikationsaufgaben, in denen jede Klasse unabhängig ist und sich nicht gegenseitig ausschließt." Und ich denke, dass Ihre Bezeichnungen sich gemäß Ihrer Beschreibung nicht gegenseitig ausschließen und unabhängig sind. Überprüfen Sie dies: http: //stats.stackexchange.com/questions/107768/Was ist der Unterschied zwischen einer Multi-Label- und einer Multi-Class-Klassifikation? –

Verwandte Themen