0% ont trouvé ce document utile (0 vote)
70 vues11 pages

TP3 MLP Part II Régression

Transféré par

khalid.abdelqaoui
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
70 vues11 pages

TP3 MLP Part II Régression

Transféré par

khalid.abdelqaoui
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

TP n° 3 Réseau de neurones Multicouches-Part II: régression

Réseaux de neurones Multicouches


Part II: régression

1. But

Le but de ce TP est d'apprendre à construire et tester les performances des


réseaux de neurones multi-couches (multi-Layers perceptron (MLP)) dans des
problèmes de régression.

2. Problèmes de régression

A l'opposé d'un problème de classification (TP2) où la sortie (output) représente


des catégories (classes), dans un problème de régression la variable de sortie
est une variable continue. En machine learning, l'objectif principal dans un
problème de régression est de trouver un modèle qui prédit, aussi bien que
possible, la variable de sortie continue 𝑦 à partir d'une ou plusieurs entrées
𝑥1 , 𝑥2 , … , 𝑥𝑛 :

𝑦̂ = 𝑓(𝑥1 , 𝑥2 , … , 𝑥𝑛 )

𝑦̂ étant la sortie prédite par le modèle représenté par la fonction 𝑓.

La figure ci-dessous illustre un problème de régression où les points bleus représentent les valeurs
réelles de la variable et le trait en rouge le modèle :

3. Création d’un MLP à partir des librairies Scikit-learn et Keras

3.1 Data description

Pour comprendre comment on crée et on teste un réseau de neurones dans


un problème de régression, on commence par vous donner un exemple
d'application sur une base de données qui donne les prix des logements dans
la banlieue de la ville américaine de Boston. Ces prix sont fonction de
plusieurs paramètres :
Nom de la variable Description

crim taux de criminalité par habitant et par ville


proportion des terrains résidentiels zonés pour les lots de terrains de
zn
plus de 25 000 pieds au carré(100 ft^2 = 9,2903 m2).

1
TP n° 3 Réseau de neurones Multicouches-Part II: régression
indus proportion d'acres (1 acre = 4046,86 m2) non commerciales par ville.
Variable fictive Charles River (= 1 si le secteur délimite la rivière;
chas
0 sinon).
nox concentration d'oxydes d'azote (parties par 10 millions).
rm nombre moyen de pièces par logement.
proportion de logements occupés par leurs propriétaires et construits
age
avant 1940.
dis moyenne pondérée des distances à cinq centres d'emploi de Boston.
rad indice d'accessibilité aux autoroutes radiales.
tax taux d'imposition foncière de la valeur totale par \ 10 000 $.
ptratio ratio élèves-enseignant par ville.
black 1000(Bk - 0.63)^2 où Bk est la proportion de noirs par ville.
population en conditions inférieures (conditions dificiles)
lstat
(pourcentage).
medv prix médian des maisons occupées par leurs propriétaires \$1000s.

La base de données Boston comporte 506 exemples (506 lignes) et 14


colonnes. La variable de sortie Median Val occupe la 14ème colonne.
Pour tester un réseau de neurones sur cette base de données, on suivra les
étapes suivantes :

➢ Etape 1: Importation des librairies nécessaires

import numpy as np
import pandas as pd

from sklearn.preprocessing import MinMaxScaler


from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

from keras.models import Sequential


from keras.layers import Dense
from keras.wrappers.scikit_learn import KerasRegressor

import matplotlib.pyplot as plt


%matplotlib inline

➢ Etape 2: Importation des données

Pour importer la base "Boston", il suffit d'exécuter la commande


suivante :

# Load and examine the dataset


dataset = pd.read_csv('housing_data.csv')

# Input attributes (X) and output values (Y)


X=dataset.iloc[:,0:13]
y=dataset.iloc[:,13].values

➢ Etape 3 : Inspection des données

Pour inspecter les données, on peut procéder en une visualisation de


quelques caractéristiques en exécutant une ou plusieurs fonctions.

2
TP n° 3 Réseau de neurones Multicouches-Part II: régression
# Inspection des données
dataset.shape
dataset.head()
dataset.describe(include='all')

On peut visualiser les variations de la variable de sortie à l'aide du script


suivant :
# Plot of the output variable
fig = plt.subplots(figsize=(20,8))
t = np.arange(0,len(y))
plt.plot(t,y)
plt.grid()
# Set title and labels for axes
plt.xlabel("Index")
plt.ylabel("Output variable")
plt.title("Output variable")
plt.show()

➢ Etape 4: Normalisation Min-Max


Etant donné que les plages de variation des paramètres d'entrées sont très
différentes, on doit normaliser ces paramètres avant de passer au processus
d'apprentissage. Dans le présent cas, on va utiliser la technique min-max,
dont la formule est la suivante :
𝑋 − 𝑚𝑖𝑛(𝑋)
𝑋𝑛𝑜𝑟𝑚 =
𝑚𝑎𝑥(𝑋) − 𝑚𝑖𝑛(𝑋)
Ceci réduit les variations de la variable X à l'intervalle [0, 1].
Aussi, pour faire plus simple, on va normaliser l'ensemble de notre base de
données (avant la partition en ensemble d'entrainement et de test). Pour se
faire, on utilise le code suivant :

# Min-Max Normalisation
scaler = MinMaxScaler()
X = scaler.fit_transform(X)

➢ Etape 4: Partition des données en ensembles d'entraînement et de test


On divise notre ensemble de données en deux sous-ensembles (ensemble
d'entrainement (80%) et ensemble de test (20%).
# Split the dataset into training and testing dataset
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size = 0.20, random_state=0)

➢ Etape 5 : Création d'un réseau de neurones MLP

1) A partir de la librairie Scikit-learn


a. MLP Regressor
Nous allons créer un perceptron multicouche (MLP) à l'aide de la fonction
MLPRegressor de la librairie sklearn.neural_network (voir synthaxe en annexe).

3
TP n° 3 Réseau de neurones Multicouches-Part II: régression
Ce réseau sera alors entrainé sur les données du sous-ensemble
d'entrainement (X_train, y_train) :
from sklearn.neural_network import MLPRegressor
net = MLPRegressor(hidden_layer_sizes=(30), activation =
'tanh', solver='adam', max_iter=10000,
learning_rate_init=0.001)
net.fit(X_train, y_train)

Ici, on considère un MLP, baptisé net, avec une seule couche cachée de 30
neurones avec la fonction 'tanh' comme fonction d'activation. Les fonctions
d'activation qui peuvent être utilisées dans le MPLRegressor sont : {'identity',
'logistic', 'tanh', 'relu'}. La fonction 'relu' est celle utilisée par default. Vous
pouvez tester les autres fonctions d'activation à l'exception de la fonction
'identity', car, avec cette dernière, le MLP serait équivalent à un modèle
linéaire du fait que la fonction d'activation du neurone de sortie est, elle-aussi,
la fonction 'identity'.

b. Test des performances du réseau de neurones créé

Pour tester la validité de notre MLP, nous allons évaluer ses performances sur
les données des deux sous-ensembles de test et aussi d'entrainement. Pour se
faire, on procède ainsi:

c. Détermination des sorties prédites par le réseau


Pour tester les performances de notre réseau de neurones, on va
comparer ses sorties prédites (calculées) aux sorties réelles (sorties
désirées) pour les deux sous-ensembles d'entrainement et de test. Les
sorties prédites sur les deux sous-ensembles peuvent être calculées à
l'aide des deux commandes suivantes:

skl_train_pred = net.predict(X_train)
skl_test_pred = net.predict(X_test)

d. Calcul des performances de notre réseau de neurones

Pour les modèles de régression, on peut utiliser un grand nombre de


paramètres pour mesurer leurs performances. Dans le présent travail,
on va utiliser les NMAE (Normalized Mean Absolute Error), NRMSE
(Normalized Root Mean Squared Error) et le Coefficient de détermination
(Determination Coefficient) R2. Ces paramètres sont donnés par les
relations :
∑𝑁
𝑖=1|𝑦𝑖 − 𝑦
̂𝑖 |
𝑁𝑀𝐴𝐸(%) = 100 × 𝑁
𝑦𝑚𝑎𝑥 − 𝑦𝑚𝑖𝑛

𝑁 2
√∑𝑖=1(𝑦𝑖 −𝑦
̂ 𝑖)
𝑁
𝑁𝑅𝑀𝑆𝐸(%) = 100 × 𝑦𝑚𝑎𝑥 −𝑦𝑚𝑖𝑛

4
TP n° 3 Réseau de neurones Multicouches-Part II: régression
∑𝑁 ̂𝑖 )2
𝑖=1(𝑦𝑖 − 𝑦
𝑅2 = 1 −
∑𝑁 ̅)2
𝑖=1(𝑦𝑖 − 𝑦

où 𝑦𝑖 est la ième valeur de la variable observée (désirée), 𝑦̂𝑖 est la


ième valeur prédite (calculée), 𝑦𝑚𝑎𝑥 − 𝑦𝑚𝑖𝑛 est la différence entre les
valeurs maximale et minimale de la variable désirée, 𝑦̅ est la
moyenne des valeurs mesurées et N est la longueur de
l'échantillon des observations (longueur des vecteurs 𝑦 et 𝑦̂).

Les paramètres normalisés sont de bonnes métriques de mesure


des performances des modèles de régression du fait qu'elles ne
dépendent pas de l'échelle de la variable considérée. Elles sont
généralement données en %.

Pour le présent travail, on utilisera la fonction suivante pour


calculer les paramètres de performance de nos modèles :

def perf_param(y_target, y_ouput):


MAE = mean_absolute_error(y_target, y_ouput)
MSE = mean_squared_error(y_target, y_ouput)
RMSE = np.sqrt(MSE)
R2 = r2_score(y_target, y_ouput)
NMAE = 100*MAE/(max(y_target) - min(y_target))
NRMSE = 100*RMSE/(max(y_target) - min(y_target))
return np.round(NMAE,4), np.round(NRMSE,4), np.round(R2,4)
On calcule alors les performances de notre MLP net à l'aide des
commandes suivantes :
skl_train = perf_param(y_train, skl_train_pred)
skl_test = perf_param(y_test, skl_test_pred)
Les résultats obtenus seront étalés ci-dessous lorsqu'on les comparera
à ceux obtenus à l'aide d'un MLP créé à l'aide de la librairie Keras.

2) A partir de la librairie Keras

Comme pour le MLP Regressor (scikit-learn), on suivra les mêmes étapes pour
le mode Sequential de Keras. On donnera uniquement les scripts pour chaque
étape.
a) Création et entraînement du MLP

from keras.models import Sequential


from keras.layers import Dense

model = Sequential()
model.add(Dense(30, input_dim=13, activation='relu'))
model.add(Dense(1, activation='linear'))
model.compile(optimizer='adam', loss='mean_squared_error')

training_history = model.fit(X_train, y_train, batch_size=5,


epochs=200)

5
TP n° 3 Réseau de neurones Multicouches-Part II: régression
b) Evolution de la fonction coût au cours du processus d'entraînement

# Loss plot
plt.plot(training_history.history['loss'])
plt.show()
c) Calcul des valeurs prédites par notre modèle
keras_train_pred = model.predict(X_train)
keras_test_pred = model.predict(X_test)

d) Calcul des performances du modèle

keras_train = perf_param(y_train, keras_train_pred)


keras_test = perf_param(y_test, keras_test_pred)

3) Comparaison des performances des deux MLP

a) Visualisation des valeurs mesurées et estimées (test set)


compar = pd.DataFrame(np.concatenate((y_test.reshape(len(y_test),1),
keras_test_pred,skl_test_pred.reshape(len(skl_test_pred),1)),
axis=1))
compar.columns=["Real Values","Scikit Predictions","Keras Predictions"]
compar

b) Nuages de points de comparaison

Une manière de comparaison des performances de différents modèles


est d'afficher les nuages de points de régression entre les sorties prédites
par les modèles et les sorties réelles. Ici, on affichera les résultats pour
les ensembles d'entrainement et de test. Aussi, les paramètres mesurant
les performances (NMAE, NRMSE, R2) seront affichés sur les graphes :

f = plt.figure(figsize=(10,10))
ax1 = f.add_subplot(221)
ax2 = f.add_subplot(222)
ax3 = f.add_subplot(223)
ax4 = f.add_subplot(224)
ax1.scatter(y_train, keras_train_pred)
ax1.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=4)
ax1.set_xlabel('Train data')
ax1.set_ylabel('Predicted train data')
ax1.text(5, 48, 'NMAE = %0.2f' % keras_train[0], color = 'red')
ax1.text(5, 45, 'NRMSE = %0.2f' % keras_train[1], color = 'red')
ax1.text(5, 42, 'R-squared = %0.2f' % keras_train[2], color = 'red')
ax1.set_title('Keras Regressor')
ax2.scatter(y_train, skl_train_pred)
ax2.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=4)
ax2.set_xlabel('Train data')
ax2.set_ylabel('Predicted train data')
ax2.text(5, 48, 'NMAE = %0.2f' % skl_train[0], color = 'red')
ax2.text(5, 45, 'NRMSE = %0.2f' % skl_train[1], color = 'red')

6
TP n° 3 Réseau de neurones Multicouches-Part II: régression
ax2.text(5, 42, 'R-squared = %0.2f' % skl_train[2], color = 'red')
ax2.set_title('MLP Regressor')
ax3.scatter(y_test, keras_test_pred)
ax3.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=4)
ax3.text(5, 48, 'NMAE = %0.2f' % keras_test[0], color = 'red')
ax3.text(5, 45, 'NRMSE = %0.2f' % keras_test[1], color = 'red')
ax3.text(5, 42, 'R-squared = %0.2f' % keras_test[2], color = 'red')
ax3.set_xlabel('Test data')
ax3.set_ylabel('Predicted test data')
ax4.scatter(y_test, skl_test_pred)
ax4.plot([y.min(), y.max()], [y.min(), y.max()], 'k--', lw=4)
ax4.text(5, 48, 'NMAE = %0.2f' % skl_test[0], color = 'red')
ax4.text(5, 45, 'NRMSE = %0.2f' % skl_test[1], color = 'red')
ax4.text(5, 42, 'R-squared = %0.2f' % skl_test[2], color = 'red')
ax4.set_xlabel('Test data')
ax4.set_ylabel('Predicted test data')

c) Représentation des histogrammes d'erreurs


fig, ax =plt.subplots(1,2,figsize=(20,10))
sns.histplot(comparison["Real Values"] - comparison["MLP Predictions"],
bins=25, color = 'b', ax=ax[0])
ax[0].set_title("MLP Regressor", fontsize=20, fontweight='bold', color = 'k')
sns.histplot(comparison["Real Values"] - comparison["Keras Predictions"],
bins=25, color = 'b', ax=ax[1])
ax[1].set_title("Keras Regressor", fontsize=20, fontweight='bold', color = 'k')
fig.suptitle("Error Histograms", fontsize=30, fontweight='bold', color = 'g')

d) Variations des valeurs réelles et des valeurs prédites

fig, ax =plt.subplots(2,1,figsize=(20,10))
labels = ['Real Values','Predicted Values']
ax[0].plot(range(len(y_test)),y_test,range(len(y_test)),comparison["MLPPredictions"])
# Set title and labels for axes
ax[0].set_ylabel("Median Val")
ax[0].set_title("MLP Regressor",fontsize=20, fontweight='bold', color = 'k')
ax[0].legend(('Real', 'Predicted'), fontsize=20, loc='upper right', shadow=True)

ax[1].plot(range(len(y_test)), y_test,range(len(y_test)),
comparison["Keras Predictions"])
ax[1].set(xlabel="Index", ylabel="Median Val")
ax[1].set_title("Keras Regressor", fontsize=20, fontweight='bold', color = 'k')
ax[1].legend(('Real', 'Predicted'), fontsize=20, loc='upper right', shadow=True)
plt.show()

e) Tableaux des paramètres de performances


Ici, on présente différentes manières d'afficher les tableaux d'erreurs de
comparaison entre différents modèles :
model_performances = pd.DataFrame({
"Model" : ["Keras - Training set", "Keras - Test set", "Scikit –
Training set", "Scikit - Test set"],
"NMAE" : [str(keras_train[0]), str(skl_train[0]),
str(keras_test[0]), str(skl_test[0])],
"NMSE" : [str(keras_train[1]), str(skl_train[1]),
str(keras_test[1]), str(skl_test[1])],
"R Squared" : [str(keras_train[2]), str(skl_train[2]),
str(keras_test[2]), str(skl_test[2])]
})
model_performances.round(4)

7
TP n° 3 Réseau de neurones Multicouches-Part II: régression
4. Travail à faire
On vous demande d'appliquer des modèles réseaux de neurones MLP à la base
de données "Cereals". Cette base donne une évaluation (rating) de différents
types de céréales de petit-déjeuner en fonction des variables telles que le
contenu en calories, en protéines, en lipides, en sodium et en fibres. Le tableau
suivant montre les 4 premières lignes des données ainsi que les noms donnés
aux variables.
calories protein fat sodium fiber rating
70 4 1 130 10 68.402973
120 3 5 15 2 33.983679
70 4 1 260 9 59.425505
50 4 0 140 14 93.704912
Essayer de régler les différents hyperparamètres des réseaux pour obtenir les
meilleures performances possibles.

8
TP n° 3 Réseau de neurones Multicouches-Part II: régression
Annexe :

Multi-Layer Perceptron regressor

sklearn.neural_network.MLPRegressor

class sklearn.neural_network.MLPRegressor(hidden_layer_sizes =
(100,), activation='relu', *, solver='adam', alpha=0.0001, batch_size='auto', learnin
g_rate='constant', learning_rate_init=0.001, power_t=0.5, max_iter=200, shuffle=Tr
ue, random_state=None, tol=0.0001, verbose=False, warm_start=False, momentum
=0.9, nesterovs_momentum=True, early_stopping=False, validation_fraction=0.1, b
eta_1=0.9, beta_2=0.999, epsilon=1e-08, n_iter_no_change=10, max_fun=15000)

Parameters:
hidden_layer_sizes : array-like of shape(n_layers - 2,), default=(100,)
The ith element represents the number of neurons in the ith hidden layer.

activation : {‘identity’, ‘logistic’, ‘tanh’, ‘relu’}, default=’relu’


Activation function for the hidden layer.

• ‘identity’, no-op activation, useful to implement linear bottleneck, returns f(x)


=x
• ‘logistic’, the logistic sigmoid function, returns f(x) = 1 / (1 + exp(-x)).
• ‘tanh’, the hyperbolic tan function, returns f(x) = tanh(x).
• ‘relu’, the rectified linear unit function, returns f(x) = max(0, x)

solver : {‘lbfgs’, ‘sgd’, ‘adam’}, default=’adam’


The solver for weight optimization.
• ‘lbfgs’ is an optimizer in the family of quasi-Newton methods.
• ‘sgd’ refers to stochastic gradient descent.
• ‘adam’ refers to a stochastic gradient-based optimizer proposed by Kingma,
Diederik, and Jimmy Ba

Note: The default solver ‘adam’ works pretty well on relatively large datasets (with
thousands of training samples or more) in terms of both training time and validation
score. For small datasets, however, ‘lbfgs’ can converge faster and perform better.

alpha : float, default=0.0001


Strength of the L2 regularization term. The L2 regularization term is divided by the
sample size when added to the loss.

batch_size : int, default=’auto’


Size of minibatches for stochastic optimizers. If the solver is ‘lbfgs’, the regressor will
not use minibatch. When set to “auto”, batch_size=min(200, n_samples).

9
TP n° 3 Réseau de neurones Multicouches-Part II: régression
learning_rate : {‘constant’, ‘invscaling’, ‘adaptive’}, default=’constant’
Learning rate schedule for weight updates.

• ‘constant’ is a constant learning rate given by ‘learning_rate_init’.


• ‘invscaling’ gradually decreases the learning rate learning_rate_ at each time
step ‘t’ using an inverse scaling exponent of ‘power_t’. effective_learning_rate
= learning_rate_init / pow(t, power_t)
• ‘adaptive’ keeps the learning rate constant to ‘learning_rate_init’ as long as
training loss keeps decreasing. Each time two consecutive epochs fail to
decrease training loss by at least tol, or fail to increase validation score by at
least tol if ‘early_stopping’ is on, the current learning rate is divided by 5.
Only used when solver=’sgd’.

learning_rate_init : float, default=0.001


The initial learning rate used. It controls the step-size in updating the weights. Only
used when solver=’sgd’ or ‘adam’.

power_t : float, default=0.5


The exponent for inverse scaling learning rate. It is used in updating effective learning
rate when the learning_rate is set to ‘invscaling’. Only used when solver=’sgd’.

max_iter : int, default=200


Maximum number of iterations. The solver iterates until convergence (determined by
‘tol’) or this number of iterations. For stochastic solvers (‘sgd’, ‘adam’), note that this
determines the number of epochs (how many times each data point will be used), not
the number of gradient steps.

Shuffle : bool, default=True


Whether to shuffle samples (mélanger) in each iteration. Only used when solver=’sgd’
or ‘adam’.

random_state : int, RandomState instance, default=None


Determines random number generation for weights and bias initialization, train-test
split if early stopping is used, and batch sampling when solver=’sgd’ or ‘adam’. Pass
an int for reproducible results across multiple function calls.

tol : float, default=1e-4


Tolerance for the optimization. When the loss or score is not improving by at
least tol for n_iter_no_change consecutive iterations, unless learning_rate is set to
‘adaptive’, convergence is considered to be reached and training stops.

verbose : bool, default=False


Whether to print progress messages to stdout.

warm_start : bool, default=False


When set to True, reuse the solution of the previous call to fit as initialization,
otherwise, just erase the previous solution.

momentum : float, default=0.9

10
TP n° 3 Réseau de neurones Multicouches-Part II: régression
Momentum for gradient descent update. Should be between 0 and 1. Only used when
solver=’sgd’.

nesterovs_momentum : bool, default=True


Whether to use Nesterov’s momentum. Only used when solver=’sgd’ and momentum
> 0.

early_stopping : bool, default=False


Whether to use early stopping to terminate training when validation score is not
improving. If set to True, it will automatically set aside validation_fraction of
training data as validation and terminate training when validation score is not
improving by at least tol for n_iter_no_change consecutive epochs. Only effective
when solver=’sgd’ or ‘adam’.

validation_fraction : float, default=0.1


The proportion of training data to set aside as validation set for early stopping. Must
be between 0 and 1. Only used if early_stopping is True.

beta_1 : float, default=0.9


Exponential decay rate for estimates of first moment vector in adam, should be in [0,
1). Only used when solver=’adam’.

beta_2 : float, default=0.999


Exponential decay rate for estimates of second moment vector in adam, should be in
[0, 1). Only used when solver=’adam’.

Epsilon : float, default=1e-8


Value for numerical stability in adam. Only used when solver=’adam’.

n_iter_no_change : int, default=10


Maximum number of epochs to not meet tol improvement. Only effective when
solver=’sgd’ or ‘adam’.

max_fun : int, default=15000


Only used when solver=’lbfgs’. Maximum number of function calls. The solver iterates
until convergence (determined by tol), number of iterations reaches max_iter, or this
number of function calls. Note that number of function calls will be greater than or
equal to the number of iterations for the MLPRegressor.

11

Vous aimerez peut-être aussi