2023-06-18 01:00:05 +02:00
|
|
|
import numpy as np
|
|
|
|
import matplotlib.pyplot as plt
|
2023-06-18 10:16:13 +02:00
|
|
|
import time
|
2023-06-18 01:00:05 +02:00
|
|
|
|
|
|
|
###############################################################################
|
|
|
|
# 02-descente_gradient.py
|
|
|
|
# @title: Apprentissage par descente de gradient
|
|
|
|
# @project: Mes scripts de ML
|
|
|
|
# @lang: fr
|
|
|
|
# @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
|
|
|
|
###
|
|
|
|
|
2023-06-18 10:16:13 +02:00
|
|
|
# Init du temps
|
|
|
|
t_debut = time.time()
|
|
|
|
|
2023-06-18 01:00:05 +02:00
|
|
|
# Observations d'apprentisage
|
2023-06-18 10:16:13 +02:00
|
|
|
m = 1000 # Nombre d'observations
|
2023-06-18 10:39:03 +02:00
|
|
|
bg = 1 # Quantité du bruit gaussien
|
2023-06-18 01:00:05 +02:00
|
|
|
x = 2*np.random.rand(m, 1) # Liste des observations x1
|
2023-06-18 10:16:13 +02:00
|
|
|
y = 4 + 3*x + bg * np.random.rand(m, 1) # Liste des cibles y
|
2023-06-18 01:00:05 +02:00
|
|
|
X = np.c_[np.ones((m, 1)), x] # Matrice des observations, avec x0=1
|
|
|
|
plt.plot(x, y, 'b.')
|
|
|
|
|
|
|
|
# Nouvelles observations
|
|
|
|
x_new=np.array([[0], [2]])
|
|
|
|
X_new = np.c_[np.ones((2, 1)), x_new] # Matrice des observations, avec x0=1
|
|
|
|
|
|
|
|
# Phase d'apprentissage par descente de gradient
|
2023-06-18 10:16:13 +02:00
|
|
|
# - theta : vecteur paramètres du modèle
|
|
|
|
# - gradient : gradient du coût en fonction de theta
|
|
|
|
# - eta : taux d'appentissage
|
|
|
|
|
|
|
|
eta = 0.01 # Taux d'appentissage (valeur par défaut : 0.1)
|
|
|
|
n = 5000 # Nombre d'itérations (valeur par défaut : 1000)
|
2023-06-18 01:00:05 +02:00
|
|
|
theta= np.random.randn(2,1) # Initialisation aléatoire
|
|
|
|
|
|
|
|
for i in range(n):
|
|
|
|
|
|
|
|
# Calcul du pas
|
|
|
|
gradients = 2/m * X.T.dot(X.dot(theta) - y)
|
|
|
|
theta = theta - eta * gradients
|
|
|
|
|
|
|
|
# Prédiction du pas
|
|
|
|
y_predict=X_new.dot(theta)
|
2023-06-18 10:16:13 +02:00
|
|
|
plt.plot(x_new, y_predict, 'c-', linewidth=0.5)
|
2023-06-18 01:00:05 +02:00
|
|
|
|
|
|
|
# Phase d'inférence (dernier pas)
|
|
|
|
plt.plot(x_new, y_predict, 'r-')
|
|
|
|
plt.show()
|
2023-06-18 10:16:13 +02:00
|
|
|
|
|
|
|
# Performance
|
|
|
|
print ("Theta th : theta0 : "+str(4)+" ; theta1 : "+str(3))
|
|
|
|
print ("Theta : theta0 : "+str(round(float(theta[0]),3))+" ; theta1 : "+str(round(float(theta[1]),3)))
|
|
|
|
print ("Erreurs : theta0 : "+str(round(float(theta[0]-4),3))+" ; theta1 : "+str(round(float(theta[1]-3),3)))
|
|
|
|
print ("Temps : "+str(time.time()-t_debut))
|