J'ai un modèle séquentiel Keras prenant des entrées à partir de fichiers csv. Lorsque je lance le modèle, sa précision reste nulle même après 20 époques.
J'ai parcouru ces deux threads de stackoverflow ( zéro-précision-formation et pourquoi-est-la-précision-pour-mon-modèle-keras-toujours-0 ) mais rien n'a résolu mon problème.
Comme mon modèle est une classification binaire, et je pense qu'il ne devrait pas fonctionner comme un modèle de régression pour rendre la métrique de précision inefficace. Voici le modèle
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 )
Qu'est-ce que je fais mal?
3 Réponses :
Êtes-vous sûr que la vôtre est une tâche de classification?
Parce que comme je peux le voir à partir de votre variable cible, celle que vous extrayez du csv, le type est un float
[0, 1, 0, 1, 0, 0, 0 ..., 1]
S'il s'agit d'une tâche de classification binaire, vérifiez également que les valeurs des valeurs cibles sont 0 et 1. Sinon, le modèle fonctionnera mal
Quelque chose comme ça:
#Output: <TakeDataset shapes: ((), (), ..., tf.float32)>
Parce que le crossentropy fonctionne avec 0 et 1
C'est la raison pour laquelle vous utilisez le sigmoïde comme fonction d'activation, qui affichera des valeurs dans la plage [0, 1]
Comme déjà suggéré, vous devez définir from_logits=False
Ok Cher, Cela semble être une solution correcte pour vous et Timbus Calin. J'ai créé une prime pour le même problème il y a quelques jours. Vous voudrez peut-être y répondre également. stackoverflow.com/questions/64725275/...
Bonjour Nikaido, je train_ds = training_dataset.map(preprocess).skip(10).take(90).batch(100).repeat()
mon expérience en appelant la répétition sur l'ensemble de données en tant que train_ds = training_dataset.map(preprocess).skip(10).take(90).batch(100).repeat()
mais je suis confus quand Je supprime reapeat () de la fin, la formation prend beaucoup de temps. Et en cas de répétition (), l'entraînement s'est terminé en quelques secondes, ce qui ne va pas selon moi ...! Peux-tu aider s'il te plait?
@DevLoverUmar, il est assez difficile de comprendre pourquoi. Je vous suggère d'ouvrir une nouvelle question car c'est un autre problème. Quoi qu'il en soit, essayez si possible de partager un instantané de vos données, avant et après l'élaboration, pour vérifier ce qui se passe à l'intérieur
Le problème est ici:
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
Vous avez deux solutions:
Soit défini from_logits=False
Ou laissez les layers.Dense(1) and (from_logits=True)
C'est la raison pour laquelle vous rencontrez le problème, puisque from_logits = True
implique qu'aucune fonction d'activation n'est utilisée.
Avec l'aide d'autres réponses de Nikaido et Timbus Calin, j'ai fait un changement mineur et c'est corrigé.
def preprocess(*fields): features=tf.stack(fields[:-1]) labels=tf.stack([int(x) for x in fields[-1:]]) return features,labels # x, y
Je viens de changer le type de données de l'étiquette de classe en int dans le prétraitement, pour le faire fonctionner comme un classificateur.
Votre réseau ne produit pas de logits car il a une activation sigmoïde en sortie, donc from_logits = True n'est pas correct.