微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

机器学习 CTC 丢失对数概率 将日志概率更改为实际概率的示例:

如何解决机器学习 CTC 丢失对数概率 将日志概率更改为实际概率的示例:

我有一个训练有素的 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!我做错了什么??

解决方法

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

如果您想知道为什么我们使用对数概率而不是概率本身,这主要与缩放问题有关,但是,您可以阅读主题 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]
,

来自我的代码的简短示例:

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],dtype=float32)

我认为重要的是,在使用参数 greedy=True 时,返回的 log_probability 是正数,因此需要将其取反。

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

predictions_beam,log_probabilities_beam = keras.backend.ctc_decode(pred,top_paths=1)

对比

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。