Keras二进制分类 - Sigmoid激活函数

时间:2018-03-06 16:43:17

标签: python tensorflow neural-network keras sigmoid

我在Keras中使用tensorflow实现了一个基本的MLP,我正在尝试解决二进制分类问题。对于二进制分类,似乎sigmoid是推荐的激活函数,我不太明白为什么,以及Keras如何处理这个。

我理解sigmoid函数将产生0到1范围内的值。我的理解是对于使用sigmoid的分类问题,将使用某个阈值来确定输入的类(通常为0.5)。在Keras,我没有看到任何方法来指定这个阈值,所以我认为它是在后端隐式完成的?如果是这种情况,Keras如何区分二进制分类问题中sigmoid的使用或回归问题?使用二进制分类,我们需要二进制值,但是回归需要标称值。我只能看到这可能表明这是损失函数。这是否告知Keras如何处理数据?

此外,假设Keras隐式应用阈值,为什么当我使用模型预测新数据时它会输出名义值?

例如:

y_pred = model.predict(x_test)
print(y_pred)

给出:

  

[7.4706882e-02] [8.3481872e-01] [2.9314638e-04] [5.2297767e-03]   [2.1608515e-01] ... [4.4894204e-03] [5.1120580e-05] [7.0263929e-04]

我可以在预测获得二进制输出时自己应用阈值,但是为了正确分类,Keras肯定必须这样做吗?也许Keras在训练模型时应用了一个阈值,但是当我用它来预测新值时,不使用阈值,因为损失函数不用于预测?或者根本没有应用阈值,输出的标称值恰好与我的模型一起工作?我已经检查过这种情况发生在Keras的二进制分类示例中,所以我认为我的代码没有出现任何错误,特别是因为它准确预测。

如果有人能解释这是如何运作的,我将不胜感激。

这是我的模型作为参考点:

model = Sequential()
model.add(Dense(124, activation='relu', input_shape = (2,)))
model.add(Dropout(0.5))
model.add(Dense(124, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(1, activation='sigmoid'))
model.summary()

model.compile(loss='binary_crossentropy',
              optimizer=SGD(lr = 0.1, momentum = 0.003),
              metrics=['acc'])

history = model.fit(x_train, y_train,
                    batch_size=batch_size,
                    epochs=epochs,
                    verbose=1,
                    validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)

2 个答案:

答案 0 :(得分:4)

二进制分类的输出是样本属于一个类的概率。

  

Keras如何区分二进制分类问题中sigmoid的使用或回归问题?

它不需要。它使用损失函数计算损失,然后使用导数并更新权重。

换句话说:

  • 在培训期间,框架可以最大限度地减少损失。用户必须指定损失函数(由框架提供)或提供自己的。网络只关心此函数输出的标量值,并且预测其2个参数y^和实际y
  • 每个激活功能实现前向传播和反向传播功能。该框架仅对这两个功能感兴趣。它并不关心函数究竟做了什么。唯一的要求是激活功能是非线性的。

答案 1 :(得分:1)

您可以使用以下方法在compile()中显式分配阈值:

tf.keras.metrics.BinaryAccuracy(
    name="binary_accuracy", dtype=None, threshold=0.5
)

如下所示:

model.compile(optimizer='sgd',
              loss='mse',
              metrics=[tf.keras.metrics.BinaryAccuracy()])