Keras,以 sigmoid 结尾的 DNN - model.predict 产生的值 < 0.5。这表明……?

数据挖掘 喀拉斯
2022-03-10 03:58:35

我正在尝试一个简单的 Keras 项目,其中包含用于二进制分类的密集层。大约300000行数据,标签是

training_set['TARGET'].value_counts()    
0    282686
1     24825

我的模型看起来像这样

def build_model():
    model = models.Sequential()
    model.add(layers.Dense(64, activation='relu', kernel_regularizer=regularizers.l2(0.001),
                           input_shape=(train_data.shape[1],)))
    model.add(layers.Dropout(0.5))
    model.add(layers.Dense(32, kernel_regularizer=regularizers.l2(0.001), activation='relu'))
    model.add(layers.Dropout(0.5))
    model.add(layers.Dense(1, activation='sigmoid'))
    model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])

    return model

所以它是以 sigmoid 结尾的二元分类。我的理解是我应该得到接近 0 或接近 1 的值?我尝试了不同的模型架构、超参数、时期、批量大小等,但是当我在验证集上运行 model.predict 时,我的值永远不会超过 0.5。这里有一些样本。

20 epochs, 16384 batch size
max 0.458850622177124,  min 0.1022530049085617
max 0.47131556272506714,  min 0.057787925004959106 

20 epochs, 8192 batch size
max 0.42957592010498047,  min 0.060324762016534805
max 0.3811708390712738,  min 0.022215187549591064

20 epochs, 4096 batch size
max 0.3163970410823822,  min 0.0657803937792778 

20 epochs, 2048 batch size
max 0.21799422800540924,  min 0.03832605481147766 

这是否表明我做错了什么?

训练和验证损失 在此处输入图像描述

2个回答

我认为 dropout 有点高,如果是二进制分类,那为什么最后是单个节点?

使用 sigmoid 进行二进制分类是绝对可以的。因此,下面提供的答案并不恰当。

确保您的目标变量在 softmax 的情况下具有正确的形状......(一个 hot/ to_categorical()

def build_model():
    model = models.Sequential()
    model.add(layers.Dense(64, activation='relu', kernel_regularizer=regularizers.l2(0.001),
                           input_shape=(train_data.shape[1],)))
    model.add(layers.Dropout(0.3))
    model.add(layers.Dense(32, kernel_regularizer=regularizers.l2(0.001), activation='relu'))
    model.add(layers.Dropout(0.3))
    model.add(layers.Dense(**num_classes**, activation='softmax'))
    model.compile(optimizer='rmsprop',
              loss='binary_crossentropy',
              metrics=['accuracy'])
    
    return model

为了进一步改进它,您需要使用一些技术,例如交叉验证、批量标准化和增加 epochs(也许)。

与之前的答案相反,我会说您的输出层配置是正确的,尽管我同意之前的答案,即您的 dropout 太高。0.5 的 dropout 意味着 50% 如果你的神经元将被丢弃,所以基本上你在层中丢弃了一半的神经元,这反过来意味着你的模型将无法学习太多。

我想提到的另一点是,您应该将adam其用作优化器,因为它在大多数情况下都能提供更好的结果。

简而言之,为了提高您的准确性,请对层数神经元数、优化器学习率激活函数批量大小时期等进行超参数调整RandomizedSearchCV。用于此目的。