L'étude de l'apprentissage automatique va nous faire découvrir le calcul différentiel. Car en effet, un moyen d'apprentissage canonique consiste à ajuster petit-à-petit des paramètres en mesurant leurs effets. Et ces petites variations, si elles sont infiniment petites, s'appellent des éléments différentiels. Cela nous amène à redécouvrir le calcul différentiel avec ses notations spécifiques. Puis du calcul différentiel, du calcul des dérivées, nait le calcul des tangentes et l'étude des transformations linéaires. Aussi, il est naturel que du calcul différentiel nait l'algèbre linéaire et les espaces vectoriels. Voir les chapitres :
Etant donné une fonction de coût à un seul paramètre, notée `J(".")`. On chercher une valeur du paramètre `a` telle que `J(a)` soit minimum, en procèdant à une succession de petits ajustements de `a` pour diminuer la valeur `J(a)`.
On précise les notations afin de lever les ambiguités. On déclare que `J` dépend de `a` en notant le neurone `J"←"a`. Après cette déclaration, `J"="J(a)`.
L'algorithme de descente de gradient est une méthode d'optimisation itérative pour trouver les minima d'une fonction différentiable. Dans le cas d'un seul paramètre `a` le gradient selon `a`, noté `"grad"` ou `nabla` correspond à l'opérateur de dérivée selon `a` :
`"grad" = nabla = d/(da)`
Le gradient de `J` selon `a`, noté `"grad"(J)` ou `"∇"J` ou `dJ"/"da`, est utilisé pour mettre à jour le paramètre `a` en le déplaçant dans le sens qui réduit `J`. La mise à jour du paramètre est définie comme suit :
`J←a`
`a := a + Delta a`
`Delta a = "-" beta (dJ)/(da)`
Ce qui correspond à une variation du paramètre `a` proportionnelle à l'opposé de la dérivée de `J` donc dans le sens de la pente. Le paramètre de proportionnalité `beta` est fixé arbitrairement .
Dans le cas générale il y a `n` paramètres `vec a=(a_1,a_2,...,a_n)`. L'algorithme est vectorialisé. Le gradient selon `vec a`, noté `vec"grad"` ou `vec nabla` correspond à l'opérateur de dérivée à plusieurs variables :
`vec "grad" = vec nabla = ((del/(dela_1)),(del/(dela_2)),(⫶),(del/(dela_n)))`
Etant donné une fonction de coût `J(a_1,a_2,...,a_n)` que l'on note `J(vec a)`, le gradient de `J` selon `vec a`, noté `vec"grad"(J)` ou `vec∇J` ou `vec(dJ"/"d vec a)`, est utilisé pour mettre à jour le paramètre vectoriel `vec a` en le déplaçant dans la direction de la plus grande pente de `J` et, toujours proportionnellement à la pente. La mise à jour du paramètre est définie comme suit :
`J←vec a`
`vec a := vec a + Delta veca`
`Delta veca = - beta vec nabla J`
`((Delta a_1),(Delta a_2),(⫶),(Delta a_n)) = - beta( ((delJ)/(del a_1)), ((delJ)/(dela_2)),(⫶),((delJ)/(dela_n)) )`
Ce qui correspond à une variation des paramètres `veca` proportionnelle à l'opposé de la dérivée de `J`, donc dans le sens de la plus grande pente.
On utilise cette méthode pour l'apprentissage supervisé générale, c'est à dire pour optimiser les paramètres d'une fonction de prédiction d'une variable `y` en fonction des variables `vec x=(x_1,x_2,x_3,...,x_n)`
La fonction de prédiction `f(vecx,vec a)` comprend les paramètres `veca = (a_1,a_2,a_3,...,a_d)` que l'on veut ajuster. L'équation du modèle est
`y = f(vecx,veca) - epsilon`
La fonction de coût que l'on minimise est la moyenne des carrés des erreurs :
`J(veca)=1/Nsum_(i=1)^N (f(vecx_i,veca) - y_i)^2`
On utilise un jeux de données d'entrainement de `N` observations. On note les vecteurs `vec x_1, vec x_2, vec x_3,....vecx_n` et `vec y` comprenant toutes les observations :
`vec x_1 = ((x_(1,1)),(x_(2,1)),(⫶),(x_(N,1))), vec x_2 = ((x_(1,2)),(x_(2,2)),(⫶),(x_(N,2))), vec x_3 = ((x_(1,3)),(x_(2,3)),(⫶),(x_(N,3))), vec y = ((y_1),(y_2),(⫶),(y_N))`
On modifie `veca` commme suit :
`vec a := vec a + Delta veca`
`Delta veca = - beta vec nabla J`
`((Delta a_1),(Delta a_2),(⫶),(Delta a_n)) = - beta( ((delJ)/(del a_1)), ((delJ)/(dela_2)),(⫶),((delJ)/(dela_n)) ) ≃ - beta ( ( (J(veca+epsilon vec u_1)-J(veca))/epsilon ), ((J(veca+epsilon vec u_2)-J(veca))/epsilon),(⫶),((J(veca+epsilon vec u_n)-J(veca))/epsilon) )`
`Delta a_j = -beta (delJ)/(del a_j) ≃ (J(veca"+"epsilon vec u_j)-J(veca))/epsilon`
Où `vec u_j` représente le veteur unitaire pour désigner la `j`-ième composante. On calcule les dérivées, soit théoriquement ou soit empiriquement avec un petit `epsilon`. Le facteur d'apprentissage `beta` ainsi que l'éventuel facteur `epsilon` sont des hyperparamètres du modèle.
Dans le cas affine `f(vecx,vec a)= a_0+a_1x_1+a_2x_2+...+a_nx_n`
`J(veca)=1/Nsum_(i=1)^N (a_0+a_1x_(i,1)+a_2x_(i,2)+...+a_nx_(i,n) - y_i)^2`
`(delJ)/(dela_j) = 1/Nsum_(i=1)^N (del (a_0+a_1x_(i,1)+a_2x_(i,2)+...+a_nx_(i,n) - y_i)^2)/(dela_j)`
`(delJ)/(dela_j) = 1/Nsum_(i=1)^N 2(a_0+a_1x_(i,1)+a_2x_(i,2)+...+a_nx_(i,n) - y_i) (del (a_0+a_1x_(i,1)+a_2x_(i,2)+...+a_nx_(i,n) - y_i))/(dela_j)`
`(delJ)/(dela_j) = 1/Nsum_(i=1)^N 2x_(i,j)(a_0+a_1x_(i,1)+a_2x_(i,2)+...+a_nx_(i,n) - y_i)`
On note les moyennes avec une barre. Ainsi `bary` désigne la moyenne des valeurs cibles, et `bar(x_jx_k)` désigne la moyenne des produits de la composante `j` de l'observation et la compositante `k` de l'observation.
`bar (x_j) = 1/Nsum_jx_(i,j)` `bar (x_jx_k) = 1/Nsumx_(i,j)x_(i,k)` `bar y = 1/Nsum_jy_i` `bar (x_jy) = 1/Nsumx_(i,j)y_i`
On peut alors exprimer l'ajustement de `vec a` c'est à dire de chacune de ses composantes `a_j`, en fonction de ces différentes moyennes :
`(delJ)/(dela_j) = 2a_0bar(x_j) + 2a_1bar(x_1x_j) + 2a_2bar(x_2x_j)+...+2a_nbar(x_nx_j) - 2bar(x_jy)`
`Delta a_j = - 2beta(a_0bar(x_j) + a_1bar(x_1x_j) + a_2bar(x_2x_j)+...+a_nbar(x_nx_j) - bar(yx_j))`
où le facteur d'apprentissage `beta` est un hyperparamètres :
Pour éviter le surapprentissage, on ajoute une pénalité à la fonction de coût fonction des paramètres.La régularisation Lasso (ou regression L1) tend à effectuer une sélection de variables en forçant certain coefficient à être eactement zéro, simplifiant ainsi le modèle :
`lambda_1sum_j|a_j|`
La régulation Ridge tend (ou regression L2) tend à distribuer une réduction de poids sur tous les coefficients, limitant ainsi l'influence des variables moins informatives :
`lambda_2sum_j a_j^2`
On peut utiliser les deux, avec ainsi deux hyperparamètres `lambda_1, lambda_2` qui reste à adapter :
`J(veca)=1/Nsum_(i=1)^N (a_0+a_1x_(i,1)+a_2x_(i,2)+...+a_nx_(i,n) - y_i)^2 + lambda_1sum_(j=1)^n |a_j| + lambda_2sum_(j=1)^n a_j^2`
Pour évaluer la performance du modèle, voir le chapitre Mesure de performance de la prédiction. On utilise le coefficient de détermination `R` :
`R^2 = 1-(sigma^2(f-y))/(sigma^2(y)) = 1-(sum_i(f(vecx_i,veca)-y_i)^2)/(sum_i(bary - y_i)^2) = 1-(sum_i(f_i-y_i)^2)/(sum_i(bar y - y_i)^2)`
`R^2 = 1-(sum_i f_i^2 + sum_i y_i^2-2sum_i f_iy_i)/(sum_i bary_i^2 + sum_i y_i^2-2sum_ibary_iy_i) = 1-(bar(f^2)+bar(y^2)-2bar(fy))/(bary^2+bar(y^2)-2bar(bary y)) = 1-(bar(f^2)+bar(y^2)-2bar(fy))/(bar(y^2)-bary^2) `
D'une manière générale, une fonction prédictive `f` voulant prédire la variable `y` à partir de `n` variables `(x_1,x_2,x_3,...,x_n)`, constitue un neurone :
`f ← (x_1,x_2,x_3,...,x_n)`
et l'on note `f= f(x_1,x_2,x_3,...,x_n)` sans mentionner les paramètres ni les hyperparamètres pourtant bien présents. La valeur `f` est la prédiction de `y`. L'erreur de prédiction est `f"-"y` car si on la retire de la prédiction `f` on doit retrouver la valeur `y` exacte.
La plus part des neurones procèdent à une somme des entrées et transforme le résultat de cette somme à l'aide d'une fonction inversible dite (fonction d'activation) qui correspond à la tête du neurone et plus précisement à l'opération effectuée juste avant la sortie de la prédiction. Exemple avec comme fonction d'activation la sigmoïde :
`s(x) = 1/(1+e^-x)`
`f = s(a_0+a_1x_1+a_2x_2+...+a_nx_n)`