Я написал простую многослойную программу персептрона, используя TensorFlow. Эта программа была сделана для прогнозирования следующего числа после 5-й последовательности. (например, 1 4 9 14 19 [24]) Да, это очень просто.Стоимость всех эпох равна нулю, даже до обучения
Но я блуждаю до смерти не менее 4 часов. Потому что стоимость всех эпох равна нулю, даже если я делаю. Удивительно, но я убедился, что веса и смещения инициализируются отличным от нуля (с использованием tf.ones
), это не помогло.
Как я могу не видеть стоимость с нулевым значением, больше?
Код
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]]}))
выход консоли
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]]
Я заметил, что вы инициализации переменных с 'tf.ones()', т.е. одинаковое значение для всех весов. Это необычайно плохая идея, так как она заставит все весы обновляться одинаково, поскольку каждый вес имеет одинаковый градиент ошибки - исключая предвзятость, вы эффективно изучаете только один вес на каждый слой. Используйте 'tf.truncated_normal()' или что-то подобное вместо веса, смещения тогда прекрасны. – sunside