为什么使用softmax和LSTM,model.predict(x)的总和小于1?

时间:2017-04-13 21:52:17

标签: keras

我使用keras,最后一层使用了' softmax'激活功能。 但是,当我使用预测并对概率求和时,我得不到1。 那是为什么?

N.B。 : 我真的远离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)

编辑: 我用简单的代码测试了

import numpy as np
from keras.models import *
from keras.layers import *
m = Sequential()
m.add(LSTM(3, input_shape=(3,2), activation='softmax'))
print(m.predict(np.random.rand(5,3,2)).sum(axis=-1))

我得到了像

这样的结果
[ 0.50027865  0.49804032  0.49545377  0.50514281  0.50069857]

好的,所以使用Dense和SimpleRNN,我差不多1.问题可能只是激活与循环图层的行为不同,因为GRU有同样的问题。 我在GitHub上问道:https://github.com/fchollet/keras/issues/6255

2 个答案:

答案 0 :(得分:2)

@joelthchao在GitHub(https://github.com/fchollet/keras/issues/6255)上说:

  

此处的激活直接适用于每个隐藏单元。但是,我们不会以这种方式使用LSTM。通常,我们通过以下方式完成:

m.add(LSTM(hidden_unit, input_shape=(3,2)))
m.add(Dense(3, activation='softmax'))

最后,我发现使用起来更符合逻辑:

m.add(Lambda(K.softmax))

答案 1 :(得分:1)

通过构造,softmax预测应该总和为1。然而,在实践中,由于机器精度的限制,它们可能不总是恰好相加一个。你的累积概率距离1有多远?

我运行了在Keras示例/目录中找到的mnist_mlp.py示例,其中Theano作为后端。然后我用训练模型预测了测试集概率。正如预期的那样,概率总和几乎为一。

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位浮点数,观察范围与机器epsilon的顺序相同。

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

的使用一致
      "floatx": "float32",

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