Keras 바이너리 분류 모델에서 정확도가 0 인 이유는 무엇입니까?

Nov 15 2020

csv 파일에서 입력을받는 Keras Sequential 모델이 있습니다. 모델을 실행하면 20 에포크 후에도 정확도가 0으로 유지됩니다 .

나는이 두 개의 스택 오버플로 스레드 ( zero-accuracy-training 및 why-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
        )

내가 뭘 잘못하고 있니?

답변

1 Nikaido Nov 16 2020 at 00:48

당신의 것이 분류 작업이라고 확신합니까?

csv에서 추출한 대상 변수에서 볼 수 있듯이 유형은 float입니다.

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

이진 분류 작업 인 경우 대상 값의 값이 0과 1인지 확인하십시오. 그렇지 않으면 모델의 성능이 저하됩니다.

이 같은:

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

교차 엔트로피는 0과 1에서 작동하기 때문에

이것이 바로 시그 모이 드를 활성화 함수로 사용하는 이유이며 [0, 1] 범위의 값을 출력합니다.

또한 이미 제안한대로 설정해야합니다. from_logits=False

1 TimbusCalin Nov 16 2020 at 01:07

문제는 여기에 있습니다.

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입니다. 활성화 기능이 사용되지 않았 음을 의미하기 때문입니다.

1 DevLoverUmar Nov 16 2020 at 23:17

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로 변경하여 분류 자 ​​역할을합니다.