0

我有一个训练有素的CRNN模型,应该可以识别图像中的文本。它确实有效,到目前为止还不错。

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

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

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 还要大!我究竟做错了什么??

4

2 回答 2

1

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

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

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

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]
于 2021-01-10T05:13:20.480 回答
0

我的代码中的简短示例:

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_searchabeam_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)

于 2021-03-11T07:04:51.500 回答