web-dev-qa-db-fra.com

Comment corriger une perte et une précision instable pendant la formation? (Classification binaire)

Je travaille actuellement sur un petit projet de classification binaire à l'aide de la nouvelle API Keras à Tensorflow. Le problème est une version simplifiée du défi Higgs Boson posté sur Kaggle.com quelques années de retour. La forme du jeu de données est de 2000x14, où les 13 premiers éléments de chaque ligne forment le vecteur d'entrée, et le 14ème élément est l'étiquette correspondante. Voici un échantillon dudit ensemble de données:

86.043,52.881,61.231,95.475,0.273,77.169,-0.015,1.856,32.636,202.068, 2.432,-0.419,0.0,0
138.149,69.197,58.607,129.848,0.941,120.276,3.811,1.886,71.435,384.916,2.447,1.408,0.0,1
137.457,3.018,74.670,81.705,5.954,775.772,-8.854,2.625,1.942,157.231,1.193,0.873,0.824,1

Je suis relativement nouveau à l'apprentissage de la machine et à Tensorflow, mais je connais les concepts de niveau supérieur tels que les fonctions de perte, les optimiseurs et les fonctions d'activation. J'ai essayé de construire divers modèles inspirés d'exemples de problèmes de classification binaire trouvés en ligne, mais j'ai des difficultés à former le modèle. Lors de la formation, la perte augmente de quelque chose dans la même époque, ce qui conduit à un apprentissage instable. La précision frappe un plateau autour de 70%. J'ai essayé de changer le taux d'apprentissage et d'autres hyperparamètres, mais en vain. En comparaison, j'ai un code de neuronal à terme d'alimentation complètement connecté qui atteint environ 80 à 85% de précision sur le même problème.

Voici mon modèle actuel:

import tensorflow as tf
from tensorflow.python.keras.layers.core import Dense
import numpy as np
import pandas as pd

def normalize(array):
    return array/np.linalg.norm(array, ord=2, axis=1, keepdims=True)

x_train = pd.read_csv('data/labeled.csv', sep='\s+').iloc[:1800, :-1].values
y_train = pd.read_csv('data/labeled.csv', sep='\s+').iloc[:1800, -1:].values

x_test = pd.read_csv('data/labeled.csv', sep='\s+').iloc[1800:, :-1].values
y_test = pd.read_csv('data/labeled.csv', sep='\s+').iloc[1800:, -1:].values

x_train = normalize(x_train)
x_test = normalize(x_test)

model = tf.keras.Sequential()
model.add(Dense(9, input_dim=13, activation=tf.nn.sigmoid)
model.add(Dense(6, activation=tf.nn.sigmoid))
model.add(Dense(1, activation=tf.nn.sigmoid))

model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])

model.fit(x_train, y_train, epochs=50)
model.evaluate(x_test, y_test)

Comme indiqué, certaines des époques commencent par une plus grande précision qu'elles ont fini avec un apprentissage instable.

  32/1800 [..............................] - ETA: 0s - loss: 0.6830 - acc: 0.5938
1152/1800 [==================>...........] - ETA: 0s - loss: 0.6175 - acc: 0.6727
1800/1800 [==============================] - 0s 52us/step - loss: 0.6098 - acc: 0.6861
Epoch 54/250

  32/1800 [..............................] - ETA: 0s - loss: 0.5195 - acc: 0.8125
1376/1800 [=====================>........] - ETA: 0s - loss: 0.6224 - acc: 0.6672
1800/1800 [==============================] - 0s 43us/step - loss: 0.6091 - acc: 0.6850
Epoch 55/250

Quelle pourrait être la cause de ces oscillations dans l'apprentissage dans un modèle aussi simple? Merci


ÉDITER:

J'ai suivi certaines suggestions des commentaires et j'ai modifié le modèle en conséquence. Cela ressemble maintenant plus à ceci:

model = tf.keras.Sequential()
model.add(Dense(250, input_dim=13, activation=tf.nn.relu))
model.add(Dropout(0.4))
model.add(Dense(200, activation=tf.nn.relu))
model.add(Dropout(0.4))
model.add(Dense(100, activation=tf.nn.relu))
model.add(Dropout(0.3))
model.add(Dense(50, activation=tf.nn.relu))
model.add(Dense(1, activation=tf.nn.sigmoid))

model.compile(optimizer='adadelta',
              loss='binary_crossentropy',
              metrics=['accuracy'])
8
Mustfled

Tous les points de Symon sont géniaux, mais une autre cause possible: vous mélangez votre jeu de données? Sinon et vos données contiennent un biais commandé, votre modèle peut vous adapter à une "extrémité" de l'ensemble de données, uniquement à faire mal à l'autre 'extrémité'.

0
DomJack

J'ai une fois formé un réseau siamois où je me suis rendu compte que si j'utilise des taux d'apprentissage plus élevés, la perte de formation a été lisse (comme prévu depuis que c'est ce que le réseau neuronal apprend), mais a vu d'énormes hauts et des bas avec la perte de Val.

Cela ne s'est jamais produit auparavant lorsque j'utilisais un taux d'apprentissage inférieur (dans l'ordre de 1E-05). Je crois que la perte de trains est réellement fausse puisque les documents récents ont prouvé que de grands réseaux de neurones (je veux dire que les réseaux de neurones avec plus de complexité) peuvent apprendre des données aléatoires parfaitement sans faille dans l'ensemble de formation, bien qu'elles ont été extrêmement pires tout en les validant, j'ai attaché le Papier pour votre référence ci-dessous qui explique clairement ces phénomènes liés à la survêtement. Donc, on ne peut pas conclure la performance du modèle global en observant simplement les données de formation.

Bien que d'autres paramètres mentionnés ci-dessus comptent également, mais je suppose que l'on devrait commencer à modifier les taux d'apprentissage initialement dans un tel cas avant de modifier le modèle lui-même.

Lien pour le papier: https://arxiv.org/pdf/1611.035

S'il vous plait corrigez moi si je me trompe...

0
Harish L