Keras 为什么使用softmax和LSTM时model.predict(x)之和小于1?

Keras 为什么使用softmax和LSTM时model.predict(x)之和小于1?,keras,Keras,我使用的是keras,最后一层使用“softmax”激活功能。 然而,当我使用“预测”和“求和”概率时,我得不到1。 为什么呢 注意: 我真的离1很远: >>> m <keras.models.Sequential object at 0x1083fdf60> >>> m.layers[-1].activation <function softmax at 0x1092bfea0> >>> X.shape (1940,

我使用的是keras,最后一层使用“softmax”激活功能。 然而,当我使用“预测”和“求和”概率时,我得不到1。 为什么呢

注意: 我真的离1很远:

>>> m
<keras.models.Sequential object at 0x1083fdf60>
>>> m.layers[-1].activation
<function softmax at 0x1092bfea0>
>>> X.shape
(1940, 10, 48)
>>> m.input
<tf.Tensor 'lstm_1_input:0' shape=(?, 10, 48) dtype=float32>
>>> model.predict(X)[:10].sum(axis=-1)
array([ 0.46206102,  0.43193966,  0.4252567 ,  0.44023705,  0.46344867,
        0.48820126,  0.50369406,  0.49789378,  0.46433908,  0.44102359], dtype=float32)
>>> y=model.predict(X)
>>> y[0]
array([  0.00000000e+00,   6.10233226e-04,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00,   1.12394022e-03,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00,   0.00000000e+00,   0.00000000e+00,
         0.00000000e+00,   1.55960268e-04,   0.00000000e+00,
         4.60170895e-01], dtype=float32)
我得到的结果是

[ 0.50027865  0.49804032  0.49545377  0.50514281  0.50069857]
好的,用稠密和简单,我得到了1。问题可能仅仅在于,由于GRU具有相同的问题,所以激活与重复层的行为不同。
我在GitHub上问到:

根据构造,softmax预测值应为1。然而,在实践中,由于机器精度的限制,它们的总和可能不精确。你的累积概率离1有多远

我运行了Keras example/目录中的mnist_mlp.py示例,后台是Theano。然后,我用训练好的模型预测测试集概率。正如预期的那样,概率总和几乎为1

y_pred = model.predict(x_test)
y_sum = y_pred.sum(axis=1)
print('Min={}, Max={}, Range={}'.format(y_sum.min(),y_sum.max(),y_sum.max()-y_sum.min()))
# Min=0.9999999403953552, Max=1.0000001192092896, Range=1.7881393432617188e-07
观察到的范围与32位浮点的机器ε的顺序相同

import numpy as np
print(np.finfo(np.float32).eps)
#1.19209e-07
这与使用

      "floatx": "float32",

在我的~/.keras/keras.hjson文件中。如果需要额外的精度,可以将“float32”更改为“float64”

@joelthchao在GitHub()上说:

这里的激活直接应用于每个隐藏单元。但是,我们不会以这种方式使用LSTM。通常,我们通过以下方式进行:

最后,我找到了更符合逻辑的用法:

m.add(Lambda(K.softmax))

对不起,我应该更准确一点!我离1很远…@Labo这可能是一个下溢/溢出问题吗?这可能与健壮的softmax解决方案有关。我在Keras中有溢出,它通常会导致“nan”显示为值。我不知道这里发生了什么。正如你在我的编辑中看到的,即使是一个简单的模型,我也有同样的问题。
m.add(LSTM(hidden_unit, input_shape=(3,2)))
m.add(Dense(3, activation='softmax'))
m.add(Lambda(K.softmax))