Skip to main content
 首页 » 编程设计

python之Tensorflow 损失在我的 RNN 中出现分歧

2024年08月22日31itcoder

我试图通过解决这个挑战来尝试使用 Tensorflow:https://www.kaggle.com/c/integer-sequence-learning .

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

可以在此处找到一个完整的工作示例(包含我的数据):https://github.com/bottiger/Integer-Sequence-Learning运行示例会打印出很多调试信息。运行执行 rnn-lstm-my.py 。 (需要 tensorflow 和 pandas)

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

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

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

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

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

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

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

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

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

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 (由于 body 限制,我无法在这里发布)

第一次看到NaN是在这里:

I tensorflow/core/kernels/logging_ops.cc:79] Last: [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 nan nan nan nan 0 0 nan nan 1 0 nan 0 0.76159418 nan nan nan 1 0 nan 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 -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]

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

请您参考如下方法:

RNN 存在梯度爆炸问题,因此您应该剪裁 RNN 参数的梯度。看看这个帖子:

How to effectively apply gradient clipping in tensor flow?