【问题标题】:my simple loss function cause NAN我的简单损失函数导致 NAN
【发布时间】:2019-01-15 05:20:51
【问题描述】:

我给自己写了一个客户损失,但是经过几个步骤,损失变成了nan,我的代码是

def my_loss(label_batch, logits_batch, alpha=1.3, beta=0.5):
    softmax_logits_batch = tf.nn.softmax(logits_batch, axis=-1)

    indices_not_0 = tf.where(tf.not_equal(label_batch, 0))  # not-zero indices
    indices_0 = tf.where(tf.equal(label_batch, 0))  # zero indices

    predict_not_0 = tf.gather_nd(softmax_logits_batch, indices_not_0)
    predict_0 = tf.gather_nd(softmax_logits_batch, indices_0)
    avg_p_not_0 = tf.reduce_mean(predict_not_0, axis=0)
    avg_p_0 = tf.reduce_mean(predict_0, axis=0)

    euclidean_distance = tf.sqrt(tf.reduce_sum(tf.square(avg_p_0 - avg_p_not_0)))
    max_value = tf.maximum(alpha - euclidean_distance, 0)
    return max_value

背后的一些基本想法是:

  1. 我的损失是语义分割,它只有 2 个类别

  2. label_batch的形状是(?, H, W),里面的值都是0或者1。logits_batch的形状是(?, H, W , 2) logits_batch的值是FCN的logits(没有Softmax)

  3. 我想通过 all 分别找到标签值为 0 或 1 的 logits 值(predict_0predict_not_0) strong>indices_0 或 indices_not_0

  4. predict_not_0 和 predict_0 的形状都应该是 (?, 2)

  5. 分别计算 predict_not_0 和 predict_0 的平均值(表示类别 0 和类别 1 的欧几里得空间的中心点坐标)。它们的形状应该是(2,)

  6. 计算两个中心点坐标之间的欧式距离,它应该大于某个alpha值(例如alpha = 1.3)

现在,问题是经过几个步骤,损失值变成了 nan。

代码的输出是(我用了一个很小的学习率参数)

Epoch[0],step[1],train batch loss = 2.87282,train acc = 0.486435.
Epoch[0],step[2],train batch loss = 2.87282,train acc = 0.485756.
Epoch[0],step[3],train batch loss = 2.87281,train acc = 0.485614.
Epoch[0],step[4],train batch loss = 2.87282,train acc = 0.485649.
Epoch[0],step[5],train batch loss = 2.87282,train acc = 0.485185.
Epoch[0],step[6],train batch loss = 2.87279,train acc = 0.485292.
Epoch[0],step[7],train batch loss = 2.87281,train acc = 0.485222.
Epoch[0],step[8],train batch loss = 2.87282,train acc = 0.484989.
Epoch[0],step[9],train batch loss = 2.87282,train acc = 0.48406.
Epoch[0],step[10],train batch loss = 2.8728,train acc = 0.483306.
Epoch[0],step[11],train batch loss = 2.87281,train acc = 0.483426.
Epoch[0],step[12],train batch loss = 2.8728,train acc = 0.482954.
Epoch[0],step[13],train batch loss = 2.87281,train acc = 0.482535.
Epoch[0],step[14],train batch loss = 2.87281,train acc = 0.482225.
Epoch[0],step[15],train batch loss = 2.87279,train acc = 0.482005.
Epoch[0],step[16],train batch loss = 2.87281,train acc = 0.48182.
Epoch[0],step[17],train batch loss = 2.87282,train acc = 0.48169.
Epoch[0],step[18],train batch loss = 2.8728,train acc = 0.481279.
Epoch[0],step[19],train batch loss = 2.87281,train acc = 0.480878.
Epoch[0],step[20],train batch loss = 2.87281,train acc = 0.480607.
Epoch[0],step[21],train batch loss = 2.87278,train acc = 0.480186.
Epoch[0],step[22],train batch loss = 2.87281,train acc = 0.479925.
Epoch[0],step[23],train batch loss = 2.87282,train acc = 0.479617.
Epoch[0],step[24],train batch loss = 2.87282,train acc = 0.479378.
Epoch[0],step[25],train batch loss = 2.87281,train acc = 0.479496.
Epoch[0],step[26],train batch loss = 2.87281,train acc = 0.479354.
Epoch[0],step[27],train batch loss = 2.87282,train acc = 0.479262.
Epoch[0],step[28],train batch loss = 2.87282,train acc = 0.479308.
Epoch[0],step[29],train batch loss = 2.87282,train acc = 0.479182.
Epoch[0],step[30],train batch loss = 2.22282,train acc = 0.478985.
Epoch[0],step[31],train batch loss = nan,train acc = 0.494112.
Epoch[0],step[32],train batch loss = nan,train acc = 0.508811.
Epoch[0],step[33],train batch loss = nan,train acc = 0.523289.
Epoch[0],step[34],train batch loss = nan,train acc = 0.536233.
Epoch[0],step[35],train batch loss = nan,train acc = 0.548851.
Epoch[0],step[36],train batch loss = nan,train acc = 0.561351.
Epoch[0],step[37],train batch loss = nan,train acc = 0.573149.
Epoch[0],step[38],train batch loss = nan,train acc = 0.584382.
Epoch[0],step[39],train batch loss = nan,train acc = 0.595006.
Epoch[0],step[40],train batch loss = nan,train acc = 0.605065.
Epoch[0],step[41],train batch loss = nan,train acc = 0.614475.
Epoch[0],step[42],train batch loss = nan,train acc = 0.623371.
Epoch[0],step[43],train batch loss = nan,train acc = 0.632092.
Epoch[0],step[44],train batch loss = nan,train acc = 0.640199.
Epoch[0],step[45],train batch loss = nan,train acc = 0.647391.

我之前使用了完全相同的代码,除了损失函数是 tf.nn.sparse_softmax_cross_entropy_with_logits() 并且一切正常,所以我认为我的新损失函数有问题。

我有一个猜测,可能某些批次数据只有一个类别的标签(只有 0 或 1),因此 predict_not_0 和 predict_0 之一将没有数据,但我不知道如何用于验证 predict_not_0 和 predict_0

中是否有数据的代码

谁能帮我找出问题出在哪里,我该如何改进我的损失函数来避免 nan?

【问题讨论】:

    标签: python-3.x tensorflow nan loss-function


    【解决方案1】:

    这可能是由于使用了tf.sqrt,它具有在 0 附近具有爆炸梯度的不良特性。因此,当你收敛时,你会逐渐遇到更多的数值不稳定性。

    解决办法是去掉tf.sqrt。例如,您可以最小化平方欧几里得距离。

    另一个潜在的错误来源是tf.reduce_mean,它在对空列表进行操作时可能返回 NaN。当这种情况发生时,你需要弄清楚你希望你的损失是什么。

    【讨论】:

    • 感谢您的建议,我将“tf.sqrt”更改为“tf.square”,但问题仍然存在,仍然是从第 31 步开始。(我使用了相同的随机种子)
    • 如何实现“如果predict_not_0中存在item则计算predict_not_0的平均值,否则给predict_not_0一定的Tensor值”?
    • 'tf.sqrt(tf.reduce_sum(tf.square(avg_p_0 - avg_p_not_0)))'、'tf.reduce_sum(tf.square(avg_p_0 - avg_p_not_0))'和'tf.square (tf.reduce_sum(tf.square(avg_p_0 - avg_p_not_0)))' 不起作用
    【解决方案2】:

    nan 是由许多编程语言中的0.0/0.0log(0.0) 或其他一些计算引起的,因为浮点数计算通常非常大或非常小(由于准确性而被视为无穷大或零)。

    tf.nn.softmax 在训练时不够安全,请尝试一些其他功能,例如tf.log_softmaxtf.softmax_cross_entropy_with_logits 等。

    【讨论】:

    • 如何实现“如果 predict_not_0 中存在项目,则计算 predict_not_0 的平均值,否则为 predict_not_0 提供 [0,1] 的张量”?那就是我想避免 predict_not_0 在每次迭代中都变成 None 。
    猜你喜欢
    • 1970-01-01
    • 2016-08-02
    • 2021-07-13
    • 2017-08-04
    • 1970-01-01
    • 2020-08-25
    • 2023-04-03
    • 2017-08-10
    • 2017-12-14
    相关资源
    最近更新 更多