mercredi 9 décembre 2020

Régression linéaire en deep learning avec Keras et tensorflow

Dans des billets précédents, j'avais montré différentes manières de trouver une droite qui s'ajuste au mieux à une série de point. essayons maintenant avec de l'apprentissage profond. Les données seront les mêmes.

L'environnement d 'exécution est un notebook sous Jupyter (voir ici sa préparation) .

Un réseau simple.

Pour monter notre dispositif nous avons besoin de:

  • Un réseau avec des couches et des fonctions d'activation
  • Une fonction d'évaluation de coût (ou de perte) 
  • Un optimiseur :dispositif qui met à jour les paramètres afin d'atteindre une solution optimum

Et en option

  • Un indicateur de performance à surveiller

Le réseau sera très simple pour un premier essai: une couche en entrée et une en sortie: (utilisation de http://hilite.me/)

model = Sequential()
model.add(Dense(1, input_dim= 1, kernel_initializer =initializers.RandomNormal(seed= 1), activation='linear'))
model.add(Dense(1, input_dim= 1, kernel_initializer =initializers.random_normal(seed= 1)))
model.compile(loss="mean_squared_error", optimizer ='sgd')

Ici , l'optimisateur est  de  type SGD  "Gradient descent (with momentum) optimizer".

Une préparation des données.

Ici, pas question d'utiliser des données brutes. Il est nécessaire de les mettre à l'echelle ou de les normaliser. 

Ci dessous la fonction de normalisation :

def normalise(dataf):
    mu    = 0
    sigma = 0
    mu = dataf.mean()
    sigma = dataf.std( ddof=0)
    snorm = dataf
    snorm.columns = ['normalised']
    snorm =(snorm - mu )/ sigma
    dtnorm = pd.concat([dataf,snorm],  axis =1)
    dtnorm.columns = ['x', 'nx']
    print(mu, sigma)
    print(snorm.head(5))
    return dtnorm , mu , sigma

Lancement.

Pour l'exécution, on peut jouer sur deux paramètres: le nombre cycle d'apprentissage (epochs) et la taille de chaque lot de donnée (batch size) 
Si on fixe à 10 la taille des lots pour un jeu de 100 données, il faut 10 passages pour faire un cycle complet(epochs) 

history =model.fit(X,y, epochs =  epoch,  batch_size = bz,verbose  = 0)

Résultats.


J'ai essayé avec 10 cycles et des tailles de lot différentes (taille totale = 97 lignes)

les résultats sont les suivants:


Les 3 premières tailles sont les plus rapides à converger: 



Passons maintenant aux estimations  pour les 2 valeurs : 3500 et 70000
pour une taille de 1
écart de
[1952.696]  
[3562.5508]
pour une taille de 10
écart de
[1271.1694]
[1076.8672]

pour une taille de 15
écart de
[589.0293]
[125.20703]

Une taille de 15 semble la bonne valeur, elle correspond à une proportion de 10 à 20% de la taille totale des données d'apprentissage.

Explication des écarts: on a utilisé une fonction qui normalise les données et qui va avoir une action d'écrasement des données. Une mise à l'échelle aurait été peut être plus fidèle.

Recommandation: pour faire plusieurs essais, il est nécessaire de redémarrer le noyau Jupyter. Tensorflow stocke des résultats en cache et cela peut avoir un impact. Pour ma part, je stocke les résultats intermédiaires dans un fichier python (pickle).

Les deux notebook  (réseau et affichage des résultats) sont sur github .





Aucun commentaire: