【问题标题】:cost function outputs 'nan' in tensorflow成本函数在张量流中输出“nan”
【发布时间】:2017-08-14 15:31:09
【问题描述】:

在研究 tensorflow 时,我遇到了一个问题。
成本函数输出“nan”。

如果您发现源代码中的任何其他错误,请告诉我相关链接。

我正在尝试将成本函数值发送到我经过训练的模型,但它不起作用。

tf.reset_default_graph()

tf.set_random_seed(777)

X = tf.placeholder(tf.float32, [None, 20, 20, 3])
Y = tf.placeholder(tf.float32, [None, 1])

with tf.variable_scope('conv1') as scope:
    W1 = tf.Variable(tf.random_normal([4, 4, 3, 32], stddev=0.01), name='weight1')      
    L1 = tf.nn.conv2d(X, W1, strides=[1, 1, 1, 1], padding='SAME')
    L1 = tf.nn.relu(L1)
    L1 = tf.nn.max_pool(L1, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
    L1 = tf.reshape(L1, [-1, 10 * 10 * 32])

    W1_hist = tf.summary.histogram('conv_weight1', W1)
    L1_hist = tf.summary.histogram('conv_layer1', L1)

with tf.name_scope('fully_connected_layer1') as scope:
    W2 = tf.get_variable('W2', shape=[10 * 10 * 32, 1], initializer=tf.contrib.layers.xavier_initializer())        
    b = tf.Variable(tf.random_normal([1]))
    hypothesis = tf.matmul(L1, W2) + b

    W2_hist = tf.summary.histogram('fully_connected_weight1', W2)
    b_hist = tf.summary.histogram('fully_connected_bias', b)
    hypothesis_hist = tf.summary.histogram('hypothesis', hypothesis)

with tf.name_scope('cost') as scope:
    cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis))
    cost_summary = tf.summary.scalar('cost', cost)

with tf.name_scope('train_optimizer') as scope:
    optimizer = tf.train.AdamOptimizer(learning_rate=0.0001).minimize(cost)  

predicted = tf.cast(hypothesis > 0.5, dtype=tf.float32)
accuracy = tf.reduce_mean(tf.cast(tf.equal(predicted, Y), dtype=tf.float32))
accuracy_summary = tf.summary.scalar('accuracy', accuracy)

train_data_batch, train_labels_batch = tf.train.batch([train_data, train_labels], enqueue_many=True , batch_size=100, allow_smaller_final_batch=True)

with tf.Session() as sess:
    # tensorboard --logdir=./logs/planesnet2_log
    merged_summary = tf.summary.merge_all()
    writer = tf.summary.FileWriter('./logs/planesnet2_log')   
    writer.add_graph(sess.graph)

    sess.run(tf.global_variables_initializer())
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(coord=coord)
    total_cost = 0

    for step in range(20):
        x_batch, y_batch = sess.run([train_data_batch, train_labels_batch])
        feed_dict = {X: x_batch, Y: y_batch}
        _, cost_val = sess.run([optimizer, cost], feed_dict = feed_dict)
        total_cost += cost_val
        print('total_cost: ', total_cost, 'cost_val: ', cost_val)
    coord.request_stop()
    coord.join(threads)

【问题讨论】:

    标签: python tensorflow neural-network deep-learning


    【解决方案1】:

    您对hypothesis 使用了没有 sigmoid 激活函数的交叉熵损失,因此您的值不受 ]0,1] 的限制。 log 函数没有为负值定义,它很可能得到一些。添加一个 sigmoid 和 epsilon 因子以避免负值或 0 值,你应该没问题。

    【讨论】:

    • 我理解'假设 = tf.sigmoid(tf.matmul(L1, W2) + b)'。
    • 但是,我无法理解“未为负值定义日志函数”和“epsilon 因子”。
    • 请告诉我该怎么做好吗?
    • 没有为负值和 0 定义 log 函数:* log(-1) 不存在,因此无法计算并导致 NaN。 * log (0) = - 无穷大,因此计算损失将导致 NaN 值。 epsilon 因子是我们添加的一小部分以防止 log(0) :cost = -tf.reduce_mean(Y * tf.log(hypothesis + epsilon) + (1 - Y) * tf.log(1 - hypothesis + epsilon)) epsilon 非常小,例如 10^-6。
    【解决方案2】:

    据我所知,

    交叉熵成本函数假设您要预测的假设是随机值。因为交叉熵使用对数函数和(1-Y_) 公式。因此,交叉熵损失应该只用于随机情况。

    所以你必须使用softmax函数来制作hypothesis概率的结果。

    W2 = tf.get_variable('W2', shape=[10 * 10 * 32, 1], 
    initializer=tf.contrib.layers.xavier_initializer())        
    b = tf.Variable(tf.random_normal([1]))
    
    # hypothesis = tf.matmul(L1, W2) + b
    hypothesis = tf.nn.softmax(tf.add(tf.matmul(L1, W2), b))
    cost = -tf.reduce_mean(Y * tf.log(hypothesis) + (1 - Y) * tf.log(1 - hypothesis))
    

    或者你可以使用这个代码

    W2 = tf.get_variable('W2', shape=[10 * 10 * 32, 1], 
    initializer=tf.contrib.layers.xavier_initializer())        
    b = tf.Variable(tf.random_normal([1]))
    
    hypothesis = tf.matmul(L1, W2) + b
    cost = tf.nn.softmax_cross_entropy_with_logits(labels=Y, logits=hypothesis)
    

    【讨论】:

    • 我知道你在评论中说明了这一点,但是如果有人复制这样的代码,他最终会得到双 softmax 计算 - 最好显示两种单独的方法,而不是合并它们以不兼容的方式,
    猜你喜欢
    • 2017-10-04
    • 2018-05-03
    • 1970-01-01
    • 2018-09-18
    • 1970-01-01
    • 1970-01-01
    • 2017-05-15
    • 2018-12-07
    • 2020-10-13
    相关资源
    最近更新 更多