【问题标题】:Increase sigmoid prediction output values?增加 sigmoid 预测输出值?
【发布时间】:2019-08-23 11:22:53
【问题描述】:

我为文本分类创建了一个 Conv1D 模型。

当在最后一个密集处使用 softmax / sigmoid 时,它产生的结果为

softmax => [0.98502016 0.0149798 ]
sigmoid => [0.03902826 0.00037046]

我只希望 sigmoid 结果的第一个索引应该至少大于 0.8。只是希望多类应该有独立的结果。我如何实现这一目标?

模型摘要:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
embedding (Embedding)        (None, 128, 100)          600       
_________________________________________________________________
conv1d (Conv1D)              (None, 126, 128)          38528     
_________________________________________________________________
max_pooling1d (MaxPooling1D) (None, 63, 128)           0         
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 61, 128)           49280     
_________________________________________________________________
max_pooling1d_1 (MaxPooling1 (None, 30, 128)           0         
_________________________________________________________________
conv1d_2 (Conv1D)            (None, 28, 128)           49280     
_________________________________________________________________
max_pooling1d_2 (MaxPooling1 (None, 14, 128)           0         
_________________________________________________________________
flatten (Flatten)            (None, 1792)              0         
_________________________________________________________________
dense (Dense)                (None, 2)                 3586      
=================================================================
Total params: 141,274
Trainable params: 141,274
Non-trainable params: 0
_________________________________________________________________
model.add(keras.layers.Dense(num_class, activation='sigmoid'))
model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop', metrics=['acc'])

【问题讨论】:

  • 我有一段时间没有使用 keras,但我认为您需要使用与 sigmoid 不同的损失函数,因为 categorical_crossentropy 用于依赖类。所以可能binary_crossentropy 应该适合你。

标签: python tensorflow keras


【解决方案1】:

我同意@blue-phoenox 的评论,即您不应该使用具有交叉熵的 sigmoid,因为类的概率之和不等于 1。但是如果你有理由使用sigmoid,你可以通过向量元素的总和来归一化你的输出,使其等于1:

output = output/tf.reshape(tf.reduce_sum(output, 1), (-1, 1))

你会得到:

import tensorflow as tf

output = tf.Variable([[0.03902826, 0.00037046]])
output = output/tf.reshape(tf.reduce_sum(output, 1), (-1, 1))
summedup = tf.reduce_sum(output, axis=1)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(output.eval()) # [[0.9905971  0.00940284]] - new output
    print(summedup.eval()) # [1.] -  summs up to 1

要在keras 中实现它,您可以像这样创建tf.keras.layers.Layer 的子类:

from tensorflow.keras import layers

class NormLayer(layers.Layer):
    def __init__(self):
        super(NormLayer, self).__init__()

    def call(self, inputs):
        return inputs / tf.reshape(tf.reduce_sum(inputs, 1), (-1, 1))

然后在您的 Sequential() 模型中使用它:

# using dummy data to illustrate
x_train = np.array([[-1.551, -1.469], [1.022, 1.664]], dtype=np.float32)
y_train = np.array([[0, 1], [1, 0]], dtype=np.int32)

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Dense(units=2, activation=tf.nn.sigmoid, input_shape=(2, )))
model.add(NormLayer())

model.compile(loss='categorical_crossentropy',
              optimizer='rmsprop',
              metrics=['accuracy'])

model.fit(x=x_train,
          y=y_train,
          epochs=2,
          batch_size=2)
# ...

【讨论】:

  • 加起来为 1 意味着它就像 softmax。我将熵更改为分类。输出。,[0.25759184 0.00109715 0.09936374 0.04078476] 输出应该所有值都应该大于 0.5
  • How do I apply this with predicted result? - 你是什么意思?在 keras 中如何应用?
  • Summing upto 1 means it goes like softmax. - 不完全是。从某种意义上说,概率总和为 1 - 是的。但函数和导数不同。
  • 你是对的。我将这个函数应用到结果中。所有这些都产生 1. 意味着,带有 binary_crossentropy 的 sigmoid 返回的总和为 1,类似于 softmax
  • 好的 两者都是不同的派生词。在那种情况下,我们如何在不影响彼此的情况下提取每个类别的概率?调整图层可以解决这个问题吗?最后一层是返回它们的概率。
【解决方案2】:

Sigmoid 产生介于 0 和 1 之间的输出。如果您对 softmax 和 sigmoid 使用相同的损失函数,那么它将不起作用。尝试 binary_crossentropy 代替。如果你有两个以上的课程,我认为 sigmoid 不是你要找的。

【讨论】:

  • 我有 10 个班级,需要独立于每个班级的概率结果。所以我不能使用 binary_crossentropy?
  • 我试过 binary_crossentropy。预测概率的总和等于 1。有什么方法可以改变最后一个密集来获得每个类别的独立概率? @melowgs
  • 从技术上讲,您可以将 densr 层与 10 个神经元(如果您有 10 个类)和 sigmoid 函数一起使用。但这与我认为的 softmax 几乎相同。
  • 我们也试试
  • 产生这样的结果。单层的精度没有提高。 [0.3011694 0.3035295 0.19065315 0.20597214] 0.3011 应该是 0.85 或更大
猜你喜欢
  • 2013-08-17
  • 2021-09-28
  • 1970-01-01
  • 2021-05-27
  • 2021-04-25
  • 2017-09-16
  • 1970-01-01
  • 1970-01-01
  • 2014-03-26
相关资源
最近更新 更多