Descente de gradient à travers un ensemble de données simple

Feb 22 2023
Comprendre comment effectuer une descente de gradient de base à travers un jeu de données simple. La vue d'ensemble : Hello World ! Dans ma première incursion tenace dans le monde de la publication d'articles en ligne, je vais démontrer Gradient Descent in Machine Learning à travers un simple ensemble de données.

Comprendre comment effectuer une descente de gradient de base à travers un jeu de données simple.

L'aperçu:

Bonjour le monde! Dans ma première incursion tenace dans le monde de la publication d'articles en ligne, je vais démontrer Gradient Descent in Machine Learning à travers un simple ensemble de données. Le mot « Gradient » a plusieurs significations selon le contexte dans lequel il est utilisé. Cependant, au sens général, cela signifie quelque chose qui change progressivement. Dans le langage des mathématiques et de l'apprentissage automatique, le gradient est appelé la "pente" qui indique à quel point une ligne (ou une fonction) est raide ou peu profonde, à un point particulier, dans un plan à n dimensions. Une pente raide indique un taux élevé de changement d'un facteur par rapport à un autre facteur, tandis que l'inverse est vrai pour une pente peu profonde.

Les cours de mathématiques dans les écoles ont enseigné que l'équation de la ligne est y = mx + c (les notations peuvent varier selon les livres) , où y est le point sur l'axe des y, x est le point sur l'axe des x, m est la pente et c est l'ordonnée à l'origine sur l'axe des ordonnées. Si l'interception sur l'axe y est à 0, c peut être ignoré. Dans Machine Learning, cette équation est un problème de base de régression linéaire. S'il n'y a qu'une seule ligne dans un plan bidimensionnel, la pente et l'interception peuvent être trouvées à l'aide de formules, remplacez-les par m et c et résolvez l'équation. Il a donc une solution unique.

En réalité, chaque problème d'apprentissage automatique implique des centaines ou des milliers d'équations qui, le plus souvent, ne s'accordent pas sur une seule solution. Chaque équation est une « Observation » et chaque axe est une « Fonctionnalité ». Lorsqu'un système d'équations a plus d'observations que de caractéristiques, il est appelé un système surdéterminé . Par conséquent, la plupart des problèmes d'apprentissage automatique impliquent un système surdéterminé. Gradient Descent est utilisé pour trouver une solution (coefficient) pour chaque caractéristique, sur laquelle toutes les observations peuvent s'accorder, qui minimisera la "différence collective" entre les résultats observés et les résultats prédits. La « différence collective » est calculée à l'aide de nombreuses « fonctions de coût ». L'une d'entre elles est l'erreur quadratique moyenne (MSE) , qui est utilisée dans le problème ML de cet article.

Le programme:

Un jeu de données synthétique simple est préparé pour ce problème de descente de gradient. Tous les blocs de code sont en langage de programmation Python. Le programme commence par importer les packages Python requis.

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

Définissez l'équation en Python et générez le jeu de données.

def f(x):
    return 2.3*x
x = np.arange(-20, 20, 2) #Generate feature x
Y = []
for x_i in x:
    Y.append(np.round(f(x_i),2)) #Generate Observed value Y
fulldata = pd.Series(zip(x,Y))
n=len(fulldata)

En remplaçant y_bar,

Une fonction Python est créée pour faciliter le calcul du coût en fournissant les paramètres d'entrée nécessaires.

def costfunc(Y_i, x_i, m, n):
    return (1/n)*sum(pow(Y_i-(m*x_i),2))

Mais comment savoir si la pente est raide ou peu profonde à un point particulier de la courbe de la fonction de coût ? C'est là que les produits dérivés entrent en scène. Les dérivés permettent de comprendre le taux de variation d'une valeur par rapport à une autre valeur à un instant donné. Dans le cas de la fonction de coût, les dérivés permettent de déterminer l'ampleur de MSE pour une instance de m . Par conséquent, les dérivés sont utilisés pour ajuster la valeur de m à un point tel qu'il en résulte l'erreur la plus faible. En appliquant les règles dérivées à notre fonction de coût ( MSE ), l'équation dérivée devient,

En appliquant cela comme une fonction python,

def der_costfunc(Y_i, x_i, m, n):
    return (2/n)*sum(x_i*((m*x_i)-Y_i))

Si la valeur de l'étape est trop élevée, la valeur de la fonction de coût peut rebondir entre plusieurs pics et ne jamais converger. Cela peut également induire les gens en erreur en leur faisant croire qu'il y a un problème avec leur programme ou leur formule dérivée plutôt que de se rendre compte que la valeur Step n'est pas appropriée et que cela entrave la convergence. Inversement, si la valeur de Step est trop faible, la fonction de coût peut mettre longtemps à converger au minimum.

L'autre variable utilisée dans Gradient Descent est la tolérance . Étant donné que Gradient Descent tente de réduire le MSE à travers plusieurs itérations, il doit y avoir un moyen de déterminer quand le MSE est acceptable et d'arrêter les itérations. L'une des façons est d'utiliser la tolérance. Il peut y avoir plusieurs façons de définir la tolérance pour un problème de descente de gradient. Dans cet article, la différence de MSE entre les itérations consécutives est déterminée et si elle est inférieure à une valeur spécifique, les itérations sont arrêtées.

Enfin, la valeur initiale du coefficient m est fixée de manière à pouvoir être ajustée à chaque itération pour réduire la MSE. Mettre tout cela dans le code Python comme ci-dessous.

ms = []        #Hold the coefficients for each iteration for plotting purpose
errors = []    #Hold the MSE for each iteration for plotting purpose
m = 0          #Initial value of the coefficient
step = 0.001   #Ensure step is appropriate else costfunc will wildly swing.
tol=0.0001     #Acceptable difference in MSE between consecutive iterations to stop the Descent

1. Calculez le coût en utilisant la valeur initiale du coefficient.

2. Calculez la valeur dérivée pour la valeur initiale de m en utilisant la première équation dérivée de la fonction de coût. Multipliez cette valeur par la valeur Step pour déterminer la valeur suivante du coefficient m .

3. Calculez à nouveau le coût avec la nouvelle valeur du coefficient m . Trouvez la différence entre le MSE obtenu à l'étape 1 et à l'étape 3.

4. Répétez les étapes 1 à 3 jusqu'à ce que la différence entre les coûts consécutifs soit dans la limite de tolérance.

En appliquant ces étapes sous forme de code python,

prevcost = costfunc(Y, x, m, n)
for i in range(200):
    der_m = der_costfunc(Y, x, m, n)
    m = m - (der_m*step)
    currcost = costfunc(Y, x, m, n)
    ms.append(m)
    errors.append(currcost)
    if((prevcost-currcost) < tol):
        print(f'm: {np.round(m,5)}, currcost: {currcost}, prevcost: {prevcost}')
        plt.plot(ms, errors)
        plt.xlabel("coefficient")
        plt.ylabel("MSE")
        plt.show()
        break
    prevcost = currcost

Coefficient vs MSE(Coût) pour chaque itération

Rassembler tout le code python.

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt

def f(x):
    return 2.3*x
x = np.arange(-20, 20, 2)
Y = []
for x_i in x:
    Y.append(np.round(f(x_i),2))
fulldata = pd.Series(zip(x,Y))
n=len(fulldata)

def costfunc(Y_i, x_i, m, n):
    return (1/n)*sum(pow(Y_i-(m*x_i),2))

def der_costfunc(Y_i, x_i, m, n):
    return (2/n)*sum(x_i*((m*x_i)-Y_i))

ms = []        #Hold the coefficients for each iteration for plotting purpose
errors = []    #Hold the MSE for each iteration for plotting purpose
m = 0          #Initial value of the coefficient
step = 0.001   #Ensure step is appropriate else costfunc will wildly swing.
tol=0.0001     #Acceptable difference in MSE between consecutive iterations to stop the Descent

prevcost = costfunc(Y, x, m, n)
for i in range(200):
    der_m = der_costfunc(Y, x, m, n)
    m = m - (der_m*step)
    currcost = costfunc(Y, x, m, n)
    ms.append(m)
    errors.append(currcost)
    if((prevcost-currcost) < tol):
        print(f'm: {np.round(m,5)}, currcost: {currcost}, prevcost: {prevcost}')
        plt.plot(ms, errors)
        plt.xlabel("coefficient")
        plt.ylabel("MSE")
        plt.show()
        break
    prevcost = currcost

J'espère que cet article a été utile pour fournir une introduction de base aux non-initiés. N'hésitez pas à nous faire part de vos questions, commentaires ou recommandations sur cet article. Merci et passez une bonne journée!