mirror of
https://forge.apps.education.fr/phroy/mes-scripts-de-ml.git
synced 2024-01-27 11:30:36 +01:00
170 lines
6.4 KiB
Python
170 lines
6.4 KiB
Python
import time
|
|
import numpy as np
|
|
import sklearn
|
|
from sklearn.linear_model import Perceptron
|
|
from sklearn import datasets
|
|
import matplotlib.pyplot as plt
|
|
from matplotlib.colors import ListedColormap
|
|
|
|
###############################################################################
|
|
# 01-perceptron.py
|
|
# @title: Introduction aux réseaux de neurones - Perceptron
|
|
# @project: Mes scripts de ML
|
|
# @lang: frg
|
|
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
|
|
# @copyright: Copyright (C) 2023 Philippe Roy
|
|
# @license: GNU GPL
|
|
###############################################################################
|
|
|
|
###
|
|
# Commandes NumPy :
|
|
# - np.array : créer un tableau à partir d'une liste de listes
|
|
# - np.c_ : concatène les colonnes des tableaux
|
|
# - np.ones : créer un tableau de 1
|
|
# - np.linalg.inv : inversion de matrice
|
|
# - .T : transposé de matrice
|
|
# - .dot : produit de matrice
|
|
###
|
|
|
|
###
|
|
# Commandes Scikit-Learn :
|
|
# - sklearn.linear_model.LinearRegression() : créer un modèle de régression linéaire (méthode des moindres carrés)
|
|
# - .fit : entrainement du modèle
|
|
# - .predict : prédiction du modèle
|
|
###
|
|
|
|
###############################################################################
|
|
# Initialisation
|
|
###############################################################################
|
|
|
|
# Init du temps
|
|
t_debut = time.time()
|
|
|
|
# Init des plots
|
|
fig = plt.figure(figsize=(15, 5))
|
|
fig.suptitle("Classificateur par perceptron")
|
|
donnees_ax = fig.add_subplot(2,3,(1,4)) # Observations : x1 et cibles : y1
|
|
# f_activ_ax = fig.add_subplot(2,3,2)
|
|
# df_activ_ax = fig.add_subplot(2,3,5)
|
|
|
|
###############################################################################
|
|
# Observations
|
|
###############################################################################
|
|
|
|
# Observations d'apprentisage
|
|
iris = sklearn.datasets.load_iris() # Jeu de données Iris
|
|
x1 = iris['data'][:, 2].reshape(-1, 1) # Longueur de pétale
|
|
x2 = iris['data'][:, 3].reshape(-1, 1) # Largeur de pétale
|
|
X = iris['data'][:, (2, 3)] # Matrice de données
|
|
y1 = (iris["target"] == 2).astype(np.int32) # Si Iris virginica -> 1 sinon -> 0
|
|
y = (iris["target"]) # Type d'Iris
|
|
|
|
# Plot x1,x2 et y1 (longeur de pétale, largeur de pétale et probabilité d'être Iris virginica (format de la marque))
|
|
donnees_ax.plot(x1[y1==1], x2[y1==1], "g^" , label="Iris virginica")
|
|
donnees_ax.plot(x1[y1==0], x2[y1==0], "rs", label="Iris non-virginica")
|
|
|
|
# Nouvelles observations
|
|
x1_new=np.linspace(0, 8, 1000).reshape(-1, 1)
|
|
x2_new=np.linspace(0, 3.5, 1000).reshape(-1, 1)
|
|
x1_new_mg, x2_new_mg = np.meshgrid(x1_new, x2_new)
|
|
X_new = np.c_[x1_new_mg.ravel(), x2_new_mg.ravel()]
|
|
|
|
###############################################################################
|
|
# Phase d'apprentissage
|
|
###############################################################################
|
|
|
|
# model= sklearn.linear_model.Perceptron(max_iter=1000, tol=1e-3, random_state=42)
|
|
model = sklearn.linear_model.Perceptron() # Modèle régression logistique
|
|
model.fit(X, y1) # Entrainement
|
|
|
|
###############################################################################
|
|
# Phase d'inférence
|
|
###############################################################################
|
|
|
|
y_predict=model.predict(X_new) # Prédiction
|
|
|
|
# Frontière de décision
|
|
model_a = -model.coef_[0][0] / model.coef_[0][1]
|
|
model_b = -model.intercept_ / model.coef_[0][1]
|
|
donnees_ax.plot(x1_new, model_a * x1_new + model_b, "k--")
|
|
|
|
# Carte
|
|
y_predict_map = y_predict.reshape(x1_new_mg.shape)
|
|
custom_cmap = ListedColormap(['#fafab0','#9898ff','#a0faa0'])
|
|
donnees_ax.contourf(x1_new_mg, x2_new_mg, y_predict_map, cmap=custom_cmap)
|
|
|
|
###############################################################################
|
|
# Résultats
|
|
###############################################################################
|
|
|
|
# Plot x1,x2 et y1 (longeur de pétale, largeur de pétale et probabilité d'être Iris virginica)
|
|
donnees_ax.set_title("Perceptron")
|
|
donnees_ax.set(xlim=(0, 7.5), ylim=(0, 3.5))
|
|
donnees_ax.set_xlabel(r'$x_1$'+" - Longueur de pétale")
|
|
donnees_ax.set_ylabel(r'$x_2$'+" - Largeur de pétale")
|
|
donnees_ax.legend(loc="upper left")
|
|
|
|
###############################################################################
|
|
# Fonctions d'activation
|
|
###############################################################################
|
|
|
|
def sigmoid(_x):
|
|
return 1 / (1 + np.exp(-_x))
|
|
|
|
def echelon(_x): # Heaviside
|
|
return (_x >= 0).astype(_x.dtype)
|
|
|
|
def relu(_x):
|
|
return np.maximum(0, _x)
|
|
|
|
def derivation(f, _x, eps=0.000001):
|
|
return (f(_x + eps) - f(_x))/eps
|
|
|
|
# Fonctions d'activation
|
|
f_activ_ax = fig.add_subplot(2,3,2)
|
|
f_activ_ax.set_title("Fonctions d'activation")
|
|
f_activ_x = np.linspace(-5, 5, 200)
|
|
f_activ_ax.set(xlim=(-5,5), ylim=(0, 1.25))
|
|
f_activ_ax.plot(f_activ_x, sigmoid(f_activ_x), "g-", label="Sigmoïde")
|
|
f_activ_ax.plot(f_activ_x, echelon(f_activ_x), "b-", label="Échelon")
|
|
# f_activ_ax.plot(f_activ_x, relu(f_activ_x), "m-", label="ReLU")
|
|
f_activ_ax.legend()
|
|
|
|
# Dérivée
|
|
df_activ_ax = fig.add_subplot(2,3,5)
|
|
df_activ_ax.plot(f_activ_x, derivation(sigmoid, f_activ_x), "g-", label="f'(Sigmoïde)")
|
|
df_activ_ax.plot(f_activ_x, derivation(echelon, f_activ_x), "b-", label="f'(Échelon)")
|
|
# df_activ_ax.plot(f_activ_x, derivation(relu, f_activ_x), "m-", label="f'(ReLU)")
|
|
df_activ_ax.legend()
|
|
|
|
###############################################################################
|
|
# Perceptron multi-couches (pmc)
|
|
###############################################################################
|
|
|
|
def pmc_xor(x1, x2, activation=echelon):
|
|
return activation(-activation(x1 + x2 - 1.5) + activation(x1 + x2 - 0.5) - 0.5)
|
|
|
|
x1_mg, x2_mg = np.meshgrid(np.linspace(-0.2, 1.2, 100), np.linspace(-0.2, 1.2, 100))
|
|
|
|
z1_pmc_xor = pmc_xor(x1_mg, x2_mg, activation=echelon)
|
|
z2_pmc_xor = pmc_xor(x1_mg, x2_mg, activation=sigmoid)
|
|
|
|
pmc_xor_echelon_ax = fig.add_subplot(2,3,3)
|
|
pmc_xor_echelon_ax.set_title("Xor (perceptron multi-couches) - Activation par Échelon")
|
|
pmc_xor_echelon_ax.contourf(x1_mg, x2_mg, z1_pmc_xor)
|
|
pmc_xor_echelon_ax.plot([0, 1], [0, 1], "rs", markersize=15)
|
|
pmc_xor_echelon_ax.plot([0, 1], [1, 0], "g^", markersize=15)
|
|
pmc_xor_echelon_ax.grid(True)
|
|
|
|
pmc_xor_sigmoid_ax = fig.add_subplot(2,3,6)
|
|
# pmc_xor_sigmoid_ax.set_title("Xor (perceptron multi-couches) - Activation par Sigmoïde)")
|
|
pmc_xor_sigmoid_ax.contourf(x1_mg, x2_mg, z2_pmc_xor)
|
|
pmc_xor_sigmoid_ax.plot([0, 1], [0, 1], "rs", markersize=15)
|
|
pmc_xor_sigmoid_ax.plot([0, 1], [1, 0], "g^", markersize=15)
|
|
pmc_xor_sigmoid_ax.grid(True)
|
|
pmc_xor_sigmoid_ax.set_xlabel("Xor (perceptron multi-couches) - Activation par Sigmoïde", fontsize=12)
|
|
|
|
|
|
plt.show()
|
|
|