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]]
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