【问题标题】:Why I'm getting zero accuracy in Keras binary classification model?为什么我在 Keras 二进制分类模型中的准确率为零?
【发布时间】:2025-12-25 09:15:06
【问题描述】:

我有一个从 csv 文件中获取输入的 Keras Sequential 模型。当我运行模型时,即使经过 20 个 epoch,其准确性仍然为零

我已经完成了这两个 * 线程(zero-accuracy-trainingwhy-is-the-accuracy-for-my-keras-model-always-0),但没有解决我的问题。

由于我的模型是二元分类,我认为它不应该像回归模型那样使准确度指标无效。 这是模型

def preprocess(*fields):
    return tf.stack(fields[:-1]), tf.stack(fields[-1:]) # x, y


import tensorflow as tf
from tensorflow.keras import layers
from tensorflow import feature_column

import pathlib

csvs =  sorted(str(p) for p in pathlib.Path('.').glob("My_Dataset/*/*/*.csv"))

data_set=tf.data.experimental.CsvDataset(
    csvs, record_defaults=defaults, compression_type=None, buffer_size=None,
    header=True, field_delim=',', use_quote_delim=True, na_value=""
)
print(type(data_set))

#Output: <class 'tensorflow.python.data.experimental.ops.readers.CsvDatasetV2'>

data_set.take(1)

#Output: <TakeDataset shapes: ((), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), (), ()), types: (tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32, tf.float32)>

validate_ds = data_set.map(preprocess).take(10).batch(100).repeat()
train_ds = data_set.map(preprocess).skip(10).take(90).batch(100).repeat()

model = tf.keras.Sequential([
    layers.Dense(256,activation='elu'),  
    layers.Dense(128,activation='elu'),  
    layers.Dense(64,activation='elu'),  
    layers.Dense(1,activation='sigmoid') 
])


model.compile(optimizer='adam',
            loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
            metrics=['accuracy'])    #have to find the related evaluation metrics


model.fit(train_ds,
        validation_data=validate_ds,
        validation_steps=5,
        steps_per_epoch= 5,
        epochs=20,
        verbose=1
        )

我做错了什么?

【问题讨论】:

  • 您的网络不会产生 logits,因为它在输出端有一个 sigmoid 激活,所以 from_logits=True 是不正确的。

标签: python tensorflow machine-learning keras deep-learning


【解决方案1】:

你确定你的任务是分类任务吗?

因为我可以从您的目标变量中看到,即您从 csv 中提取的变量,类型是浮点数

#Output: <TakeDataset shapes: ((), (), ..., tf.float32)>

如果是二进制分类任务,还要检查目标值中的值是否为 0 和 1。否则模型将表现不佳

类似这样的:

[0, 1, 0, 1, 0, 0, 0 ..., 1]

因为交叉熵适用于 0 和 1

这就是你使用 sigmoid 作为激活函数的原因,它会输出 [0, 1] 范围内的值

同样如前所述,您应该设置from_logits=False

【讨论】:

  • 好的,亲爱的,这似乎是您和 Timbus Calin 的正确解决方案。几天前,我为同样的问题创建了一个赏金。你可能也想回答这个问题。 *.com/questions/64725275/…
  • 嗨 Nikaido,我正在运行我的实验,将数据集上的重复调用为 train_ds = training_dataset.map(preprocess).skip(10).take(90).batch(100).repeat(),但是当我从最后删除 reapeat() 时我很困惑,训练需要很长时间。如果重复()训练在几秒钟内完成,我认为这是错误的......!你能帮忙吗?
  • @DevLoverUmar 很难理解为什么。我建议你打开一个新问题,因为这是另一个问题。无论如何,如果可能,请尝试在详细说明之前和之后分享您的数据快照,以检查内部发生的情况
【解决方案2】:

问题出在这里:

model = tf.keras.Sequential([
    layers.Dense(256,activation='elu'),  
    layers.Dense(128,activation='elu'),  
    layers.Dense(64,activation='elu'),  
    layers.Dense(1,activation='sigmoid') 
])


model.compile(optimizer='adam',
              #Here is the problem
              loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),
              metrics=['accuracy'])    #Have to find the related evaluation metrics

您有两种解决方案:

  1. 任意设置from_logits=False

  2. 或离开layers.Dense(1) and (from_logits=True)

这就是你遇到问题的原因,因为from_logits = True 暗示没有使用激活函数。

【讨论】:

    【解决方案3】:

    在 Nikaido 和 Timbus Calin 的其他答案的帮助下,我做了一个小改动,它已经修复了。

    def preprocess(*fields):
        features=tf.stack(fields[:-1])
        labels=tf.stack([int(x) for x in fields[-1:]])
        return features,labels  # x, y
    
    

    只是在预处理中将类标签数据类型更改为int,使其作为分类器工作。

    【讨论】:

      最近更新 更多