【问题标题】:Machine Learning CTC loss log probability机器学习 CTC 损失日志概率
【发布时间】:2021-04-15 06:10:20
【问题描述】:

我有一个训练有素的 CRNN 模型,它应该能够识别图像中的文本。 它真的很有效,到目前为止一切都很好。

我的输出是一个 CTC 损失层,我使用 tensorflow 函数 keras.backend.ctc_decode 对其进行解码,如文档所述 (https://code.i-harness.com/en/docs/tensorflow~python/tf/keras/backend/ctc_decode),该函数返回一个带有解码结果的 Tuple 和一个带有日志的 Tensor预测的概率。

通过对模型进行一些测试,我得到了以下结果:

True value: test0, prediction: test0, log_p: 1.841524362564087
True value: test1, prediction: test1, log_p: 0.9661365151405334
True value: test2, prediction: test2, log_p: 1.0634151697158813
True value: test3, prediction: test3, log_p: 2.471940755844116
True value: test4, prediction: test4, log_p: 1.4866207838058472
True value: test5, prediction: test5, log_p: 0.7630811333656311
True value: test6, prediction: test6, log_p: 0.35642576217651367
True value: test7, prediction: test7, log_p: 1.5693446397781372
True value: test8, prediction: test8, log_p: 0.9700028896331787
True value: test9, prediction: test9, log_p: 1.4783780574798584

预测总是正确的。然而,我认为它的可能性似乎不是我所期望的。它们看起来完全是随机数,甚至比 1 或 2 还要大!我做错了什么??

【问题讨论】:

    标签: tensorflow machine-learning keras conv-neural-network ctc


    【解决方案1】:

    好吧,我猜你把ProbabilityLog Probability 混在一起了。虽然您的直觉是正确的,但高于或低于 0-1 的概率值会很奇怪。但是,您的函数不是为您提供 probabilities 而是 log probabilities,这实际上只是对数标度中的概率。所以你的模型一切都很好。

    如果您想知道为什么我们使用对数概率而不是概率本身,这主要与缩放问题有关,但是,您可以阅读线程 here

    将日志概率更改为实际概率的示例:

    import numpy as np
    
    # some random log probabilities
    log_probs = [-8.45855173, -7.45855173, -6.45855173, -5.45855173, -4.45855173, -3.45855173, -2.45855173, -1.45855173, -0.45855173]
    
    # Let's turn these into actual probabilities (NOTE: If you have "negative" log probabilities, then simply negate the exponent, like np.exp(-x))
    probabilities = np.exp(log_probs)
    
    print(probabilities)
    
    # Output:
    [2.12078996e-04, 5.76490482e-04, 1.56706360e-03, 4.25972051e-03, 1.15791209e-02, 3.14753138e-02, 8.55587737e-02, 2.32572860e-01, 6.32198578e-01] # everything is between [0-1]
    

    【讨论】:

    • 非常感谢。但是我不明白如何解释这些数字。我的意思是对数概率 2.4 比 0.97 更好吗?对数概率函数的范围是多少?
    • 回答关于解释的问题,对数概率越高越好。但是,您可以通过取这些日志概率的指数 (np.exp()) 将日志概率转换为实际概率(我在上面的答案中添加了一个示例)。如果它回答了您的问题,请告诉我。
    • 再次感谢,但在您的情况下,您使用了负数。我总是得到积极的结果,有了这些数字,我通过使用 np.exp() 来反转它们,得到超出 [0, 1] 概率范围的结果
    • 你是对的,在我看来,这些都是“负”对数概率,因为你所有的值都是正的,如果你查看 log(x) 图表,你会在 [0 -1] 区间函数值为负,所以在你的情况下它应该是-log(x)。因此,要将这些转换为概率,只需在指数中添加一个“负”号(如 np.exp(-x)),应该可以。
    • 我一直在研究这个,这是一个有趣的现象。对于贪心搜索,返回的对数概率总是一个正整数。对于束搜索,比如 beam_width = 5,返回的数字都是负数,因此 np.exp(x) 很容易返回介于 0 和 1 之间的良好概率。
    【解决方案2】:

    我的代码中的简短示例:

    predictions, log_probabilities = keras.backend.ctc_decode(pred, input_length=input_len, greedy=False,top_paths=5)
    The Log-probabilites are:  tf.Tensor([-0.00242825 -6.6236324  -7.3623376  -9.540713   -9.54832   ], shape=(5,), dtype=float32)
    
    
    probabilities = tf.exp(log_probabilities)
    The probabilities are:  tf.Tensor([0.9975747  0.0013286  0.00063471 0.00007187 0.00007132], shape=(5,), dtype=float32)
    

    我认为这里要概述的重要一点是,当使用参数greedy=True 时,返回的log_probability 是正数,因此需要否定它。

    本质上,beam_searchbeam_width 为 1 等价于贪婪搜索。然而,以下两种方法给出的结果是不同的:

    predictions_beam, log_probabilities_beam = keras.backend.ctc_decode(pred, input_length=input_len, greedy=False,top_paths=1)
    

    predictions_greedy, log_probabilities_greedy = keras.backend.ctc_decode(pred, input_length=input_len, greedy=True)
    

    因为后者总是返回一个正数,因此有必要在np.exp(log_probabilities)/tf.exp(log_probabilities)之前取反。

    【讨论】:

      猜你喜欢
      • 2013-11-21
      • 2016-11-11
      • 2019-12-09
      • 2021-11-02
      • 1970-01-01
      • 2016-11-27
      • 2020-05-15
      • 2020-10-29
      • 2014-09-13
      相关资源
      最近更新 更多