Tensorflow 损失在我的 RNN 中有所不同

Posted

技术标签:

【中文标题】Tensorflow 损失在我的 RNN 中有所不同【英文标题】:Tensorflow loss is diverging in my RNN 【发布时间】:2016-12-10 06:25:38 【问题描述】:

我正在尝试通过解决这个挑战来接触 Tensorflow:https://www.kaggle.com/c/integer-sequence-learning。

我的工作基于这些博客文章:

https://danijar.com/variable-sequence-lengths-in-tensorflow/ https://gist.github.com/evanthebouncy/8e16148687e807a46e3f

可以在这里找到完整的工作示例 - 包含我的数据:https://github.com/bottiger/Integer-Sequence-Learning 运行该示例将打印出大量调试信息。运行执行 rnn-lstm-my.py 。 (需要 tensorflow 和 pandas)

方法非常简单。我加载了所有的火车序列,将它们的长度存储在一个向量中,并将最长的长度存储在一个我称之为“max_length”的变量中。

在我的训练数据中,我去掉了所有序列中的最后一个元素,并将其存储在一个名为“train_solutions”的向量中

I 将所有序列(用零填充)存储在一个形状为:[n_seq, max_length] 的矩阵中。

因为我想预测序列中的下一个数字,所以我的输出应该是一个数字,而我的输入应该是一个序列。

我使用带有 BasicLSTMCell 作为单元的 RNN (tf.nn.rnn),具有 24 个隐藏单元。输出被输入到一个基本的线性模型 (xW+B) 中,该模型应该会产生我的预测。

我的成本函数只是我模型的预测数量,我这样计算成本:

    cost = tf.nn.l2_loss(tf_result - prediction)

基本维度似乎是正确的,因为代码实际运行。然而,只经过一两次迭代后,一些 NaN 开始出现并迅速传播,一切都变成了 NaN。

这是我定义和运行图表的代码的重要部分。但是,我省略了发布的数据加载/准备。请查看 git repo 以了解详细信息 - 但我很确定那部分是正确的。

cell = tf.nn.rnn_cell.BasicLSTMCell(num_hidden, state_is_tuple=True)

num_inputs = tf.placeholder(tf.int32, name='NumInputs')
seq_length = tf.placeholder(tf.int32, shape=[batch_size], name='NumInputs')

# Define the input as a list (num elements = batch_size) of sequences
inputs = [tf.placeholder(tf.float32,shape=[1, max_length], name='InputData') for _ in range(batch_size)]

# Result should be 1xbatch_szie vector
result = tf.placeholder(tf.float32, shape=[batch_size, 1], name='OutputData')

tf_seq_length = tf.Print(seq_length, [seq_length, seq_length.get_shape()], 'SequenceLength: ')

outputs, states = tf.nn.rnn(cell, inputs, dtype=tf.float32) 

# Print the output. The NaN first shows up here
outputs2 = tf.Print(outputs, [outputs], 'Last: ', name="Last", summarize=800)

# Define the model
tf_weight = tf.Variable(tf.truncated_normal([batch_size, num_hidden, frame_size]), name='Weight')
tf_bias   = tf.Variable(tf.constant(0.1, shape=[batch_size]), name='Bias')

# Debug the model parameters
weight = tf.Print(tf_weight, [tf_weight, tf_weight.get_shape()], "Weight: ")
bias = tf.Print(tf_bias, [tf_bias, tf_bias.get_shape()], "bias: ")

# More debug info
print('bias: ', bias.get_shape())
print('weight: ', weight.get_shape())
print('targets ', result.get_shape())
print('RNN input ', type(inputs))
print('RNN input len()', len(inputs))
print('RNN input[0] ', inputs[0].get_shape())

# Calculate the prediction
tf_prediction = tf.batch_matmul(outputs2, weight) + bias
prediction = tf.Print(tf_prediction, [tf_prediction, tf_prediction.get_shape()], 'prediction: ')

tf_result = result

# Calculate the cost
cost = tf.nn.l2_loss(tf_result - prediction)

#optimizer = tf.train.AdamOptimizer()
learning_rate  = 0.05
optimizer = tf.train.GradientDescentOptimizer(learning_rate)


minimize = optimizer.minimize(cost)

mistakes = tf.not_equal(tf.argmax(result, 1), tf.argmax(prediction, 1))
error = tf.reduce_mean(tf.cast(mistakes, tf.float32))

init_op = tf.initialize_all_variables()
sess = tf.Session()
sess.run(init_op)

no_of_batches = int(len(train_input)) / batch_size
epoch = 1

val_dict = get_input_dict(val_input, val_output, train_length, inputs, batch_size)

for i in range(epoch):
    ptr = 0
    for j in range(no_of_batches):

    print('eval w: ', weight.eval(session=sess))

    # inputs batch
    t_i = train_input[ptr:ptr+batch_size]

    # output batch
    t_o = train_output[ptr:ptr+batch_size]

    # sequence lengths
    t_l = train_length[ptr:ptr+batch_size]

    sess.run(minimize,feed_dict=get_input_dict(t_i, t_o, t_l, inputs, batch_size))

    ptr += batch_size

    print("result: ", tf_result)
    print("result len: ", tf_result.get_shape())
    print("prediction: ", prediction)
    print("prediction len: ", prediction.get_shape())


    c_val = sess.run(error, feed_dict = val_dict )
    print "Validation cost: , on Epoch ".format(c_val,i)


    print "Epoch ",str(i)

print('test input: ', type(test_input))
print('test output: ', type(test_output))

incorrect = sess.run(error,get_input_dict(test_input, test_output, test_length, inputs, batch_size))

sess.close()

这是它产生的(第一行)输出。可以看到一切都变成了NaN:http://pastebin.com/TnFFNFrr(由于正文限制,这里不能发)

我第一次看到NaN是在这里:

I tensorflow/core/kernels/logging_ops.cc:79] 最后:[0 0.76159418 0 0 0 0 0 -0.76159418 0 -0.76159418 0 0 0 0.76159418 0.76159418 0 -0.76159418 0.76159418 0 0 0 0.76159418 0 0 0 南 南 南 0 0 南 1 0 0 0.76159418 南 南 1 0 0 0 0.76159418 南 南 - 南 -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan nan nan nan nan楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠楠摊 南-南-南-南-南-南-南-南-南-南-南-南-南-南 -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南 -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan 南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南南 -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan -nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan nan楠楠楠楠]

我希望我把我的问题说清楚了。提前致谢

【问题讨论】:

【参考方案1】:

RNN 受到梯度爆炸的影响,因此您应该剪裁 RNN 参数的梯度。看看这个帖子:

How to effectively apply gradient clipping in tensor flow?

【讨论】:

【参考方案2】:

改用 AdamOptimizer

optimizer = tf.train.AdamOptimizer()

【讨论】:

以上是关于Tensorflow 损失在我的 RNN 中有所不同的主要内容,如果未能解决你的问题,请参考以下文章

在 Tensorflow RNN 中,logits 和标签必须是可广播的错误

使用Tensorflow后端的Keras LSTM RNN中令人费解的训练损失与纪元...行为的任何原因

tensorflow.我的概念理解_ZC

RNN入门识别验证码

在我的 tensorflow CNN 的第一轮,损失变成了 NAN

TensorFlow 多个损失值