2017-02-11 3 views
0

Ich schrieb einfache Multi-Layer-Perceptron-Programm mit TensorFlow. Dieses Programm wurde erstellt, um die folgende Nummer nach 5 Sequenz vorherzusagen. (z.B. 1 4 9 14 19 [24]) Ja, es ist sehr einfach.Kosten in allen Epochen sind Null, noch vor dem Training

Aber ich wandern während mindestens 4 Stunden zum Tod. Weil die Kosten in allen Epochen null sind, auch wenn das was ich mache. Überraschenderweise habe ich sichergestellt, dass Gewichte und Verzerrungen auf nicht Null (mit tf.ones) initialisiert werden, es wurde nicht geholfen.

Wie kann ich keine nullwertigen Kosten mehr sehen?

-Code

import tensorflow as tf 

n_input = 5 
n_output = 1 
n_hidden1 = 10 
n_hidden2 = 10 
learning_rate = 0.001 
training_epochs = 20 
batch_size = 100 
display_step = 1 

x = tf.placeholder(tf.float32, [None, n_input], name='X') 
y = tf.placeholder(tf.float32, [None, n_output], name='Y') 

with tf.name_scope('H1'): 
    w1 = tf.Variable(tf.ones([n_input, n_hidden1]), name='W1') 
    b1 = tf.Variable(tf.ones([n_hidden1]), name='b1') 
    h1 = (tf.matmul(x, w1) + b1) 

with tf.name_scope('H2'): 
    w2 = tf.Variable(tf.ones([n_hidden1, n_hidden2]), name='W2') 
    b2 = tf.Variable(tf.ones([n_hidden2]), name='b2') 
    h2 = (tf.matmul(h1, w2) + b2) 

with tf.name_scope('H3'): 
    w3 = tf.Variable(tf.ones([n_hidden2, n_output]), name='W3') 
    b3 = tf.Variable(tf.ones([n_output]), name='b3') 
    pred = tf.matmul(h2, w3) + b3 

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y)) 
optimizer = tf.train.AdadeltaOptimizer(learning_rate).minimize(cost) 
init = tf.global_variables_initializer() 


def generate_sequences(size): 
    def generate_sequence(): 
     from random import uniform 
     start = uniform(0, 10000) 
     seq = [start + i * (4 + uniform(0, 1)) for i in range(6)] 
     return seq[:-1], [seq[-1]] 
    seq = list(map(lambda _: generate_sequence(), range(size))) 
    return [s[0] for s in seq], [s[1] for s in seq] 

with tf.Session() as sess: 
    sess.run(init) 

    print('Before:', cost.eval(feed_dict={x: [[1, 5, 9, 14, 19]], y: [[24]]})) 
    for epoch in range(1, training_epochs + 1): 
     batch_x, batch_y = generate_sequences(batch_size) 
     _, c = sess.run([optimizer, cost], feed_dict={x: batch_x, y: batch_y}) 
     if epoch % display_step == 0: 
      print('Epoch:', '%04d' % epoch, 'cost=', '{:.9f}'.format(c)) 
    print('Optimization Finished!') 

    print(pred.eval(feed_dict={x: [[8, 12, 16, 20, 24]]})) 

Konsolenausgabe

Before: 0.0 
Epoch: 0001 cost= 0.000000000 
Epoch: 0002 cost= 0.000000000 
Epoch: 0003 cost= 0.000000000 
Epoch: 0004 cost= 0.000000000 
Epoch: 0005 cost= 0.000000000 
Epoch: 0006 cost= 0.000000000 
Epoch: 0007 cost= 0.000000000 
Epoch: 0008 cost= 0.000000000 
Epoch: 0009 cost= 0.000000000 
Epoch: 0010 cost= 0.000000000 
Epoch: 0011 cost= 0.000000000 
Epoch: 0012 cost= 0.000000000 
Epoch: 0013 cost= 0.000000000 
Epoch: 0014 cost= 0.000000000 
Epoch: 0015 cost= 0.000000000 
Epoch: 0016 cost= 0.000000000 
Epoch: 0017 cost= 0.000000000 
Epoch: 0018 cost= 0.000000000 
Epoch: 0019 cost= 0.000000000 
Epoch: 0020 cost= 0.000000000 
Optimization Finished! 
[[ 8142.25683594]] 
+0

ich bemerkt, dass Sie die Variablen sind die Initialisierung mit 'tf.ones()', dh ein identischer Wert für alle Gewichte. Dies ist eine außerordentlich schlechte Idee, da alle Gewichte auf die gleiche Weise aktualisiert werden, da jedes Gewicht den gleichen Fehlergradienten hat - mit Ausnahme der Verzerrung lernt man effektiv nur ein Gewicht pro Schicht. Verwenden Sie stattdessen 'tf.truncated_normal()' oder etwas Ähnliches für die Gewichte, die Verzerrungen sind dann in Ordnung. – sunside

Antwort

2

Das Problem ist Sie verwenden Verlustfunktion für die Klassifizierung (softmax im Allgemeinen für die Einstufung verwendet wird), während das Netzwerk eine beliebige produzieren könnte einzelne reelle Zahl, also Regression, nicht Klassifizierung. Verwenden Sie angemessene Kosten (z. B. mittlerer quadratischer Fehler), und Ihr Netzwerk beginnt zu konvergieren.

In diesem speziellen Fall nur diese Zeile ändern:

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(pred, y)) 

etwas wie folgt aus:

cost = tf.reduce_mean(tf.squared_difference(y, pred)) 
+0

Danke! Ich kannte neue Wahrheit; Die Unterklassifizierung von (un) überwachtem Lernen wird auch im Deep Learning angewendet. Recht? – signal

+2

Wirklich nicht, was du meinst. Deep Learning ist nicht etwas wirklich Besonderes, es verwendet dieselben Prinzipien, die im klassischen maschinellen Lernen verwendet werden, allerdings mit viel größeren Netzwerken. –

Verwandte Themen