IA : comprendre les outils mathématiques qui se cachent derrière
Article
Actu
Dans cette série sur l’IA (Intelligence Artificielle) Générative, nous vous présentons les principaux concepts mathématiques qui permettent de comprendre le fonctionnement des modèles. Puisque ces derniers reposent en grande partie sur des réseaux de neurones, les notions expliquées ici leur sont directement liées. 🙃
Qu’est-ce qu’un neurone artificiel ?
Un neurone artificiel, également appelé « unité » ou « perceptron », est l’élément de base des réseaux de neurones. Il fonctionne en trois étapes principales :
1. Il reçoit des données en entrées (notée x ).
2. Il applique une transformation (t), qui comprend :
La pondération de chaque entrée par un poids (w)
L’ajout d’un biais (b) pour affiner l’ajustement
Le passage dans une fonction d’activation (f) qui détermine si le neurone s’active.
3. Il produit une sortie (notée y ).
Et si on schématise un peu plus précisément :
En résumé, un neurone n’est rien de plus qu’une fonction mathématique !☺️
Schématiquement, cela peut s’écrire ainsi :
Qu’est-ce qu’une fonction d’activation ?
On vient de définir ce qu’était un neurone mais il y a un loup dans la description… En effet, on vient de parler de « fonction d’activation ». Ce terme un peu anecdotique correspond à la technique utilisée pour définir la manière dont une information en entrée est prise en compte par un neurone. Comme un neurone prend en entrée des nombres, on va appliquer une transformation dessus permettant d’explorer cette donnée sous différentes perspectives. Cela permet d’augmenter le spectre de recherche (de solutions explorées) et ainsi maximiser la probabilité de trouver la solution optimale. Pour renforcer ce caractère d’exploration, la transformation appliquée est une transformation non linéaire car elle modifie la représentation spatiale d’un nombre.
Illustrons cela par un exemple. Supposons que l’on fasse entrer deux nombres dans un neurone (dans le cadre de cet exemple on s’affranchit des poids et du biais mentionnés précédemment) : 10 et 50.
Bien évidemment tout le monde s’accorde à dire que 10 est inférieur à 50. Maintenant :
1. Appliquons une transformation linéaire à ces deux chiffres ; par exemple, multiplions-les par 10. On voit alors que la valeur a changé (10 x 10 = 100 et 50 x 10 = 500) mais pas leur représentation spatiale (100 est toujours inférieur à 500).
2. Appliquons une transformation non linéaire, par exemple une fonction qui annule toute valeur supérieure à et conserve la valeur sinon. On a alors g(10) et g(50) = 0. Dans ce cas, on a changé la valeur et la représentation spatiale (10 est supérieur à 0).
Un autre intérêt notable d’une fonction d’activation est d’éviter que les sorties des neurones ne deviennent trop grandes, car cela demanderait alors plus de temps de calculs et d’allocation de mémoire d’ordinateur.
Maintenant que l’on comprend un peu mieux à quoi servent les fonctions d’activation, citons-en quelques-unes parmi les plus connues en expliquant leur intérêt dans un réseau.😉
Fonction ReLU
Cette fonction permet d’appliquer un filtre en sortie de couche. Elle laisse passer les valeurs positives dans les couches suivantes et bloque les valeurs négatives. On peut donc la définir comme :
Ce filtre permet alors au modèle de se concentrer uniquement sur certaines caractéristiques des données, les autres étant éliminées.
Fonctions Sigmoïde et Softmax
Ces deux fonctions permettent de « convertir en probabilité » une valeur en entrée. Dans le cas de la fonction sigmoïde, la valeur en entrée est une valeur réelle et va donc servir pour des problèmes de classification binaire (ex : « 0 ou 1 », « chien ou chat »). La fonction softmax est, quant à elle, une généralisation de la fonction sigmoïde pour des problèmes de classification multi-classes (ex : « 0, 1, 2, … », « chien, chat, poule… »). Elles sont donc généralement utilisées en dernière couche d’un réseau de neurones construit pour effectuer une tâche de classification binaire :
Fonction tanh
La fonction tanh permet d’appliquer une normalisation à des valeurs fournies en entrée. Elle peut également être utilisée à la place de la fonction sigmoïde car elle a l’avantage d’être centrée autour de 0, ce qui peut accélérer l’apprentissage du modèle.
Pour se rendre compte des impacts de chaque fonction sur la sortie, n’hésitez pas à aller faire un tour dans cet article.
Les tenseurs : comment représenter les données ?
Qui ne s’est jamais demandé comment un modèle pouvait représenter un animal ? Un objet ? Un mot ? Une phrase ?🤔
Eh bien, tout tient en un mot : tenseur. Pour résumer très rapidement, un tenseur est une collection de valeurs numériques en plusieurs dimensions. Il existe des tenseurs en dimensions 0, 1, 2…
*Figure 1 : https://www.analyticsvidhya.com/blog/2022/07/data-representation-in-neural-networks-tensor/
Illustrons maintenant cela par quelques exemples. Pour des mots, on utilise généralement une représentation sous forme de « vecteurs » (le prochain article de cette série reviendra dessus), qui correspond à un tenseur de dimension 1.
Par exemple :
Chat = (0.5,1,0.8,0.6)
Chien = (0.5,0.5,0.7,0.2)
…
Ours = (0.1,0.5,0.2,0.65)
Pour décrire des températures au sol, on va utiliser une matrice (un tenseur en 2 dimensions) :
*Figure 2 : Niveau de chaleur en fonction de la zone et valeurs associées dans le tenseur 2D
Pour une image en couleur, on va représenter chaque pixel de l’image par un trio de valeurs (une valeur pour l’intensité du pixel « rouge », une pour le « vert », une pour le « bleu ») :
*Figure 3 : Zoom sur une image et visualisation des pixels
Figure 4 : Conversion d'une image en tenseur 3D
Aussi, chaque pixel est représenté par sa position dans l’image, il faut donc ajouter une dimension pour la hauteur et une dimension pour la largeur.
Finalement, on représente donc une image par un tenseur de dimension 3.
Et pour celles et ceux qui souhaitent avoir un mal de tête : Wikipedia - Tenseurs.
La rétropropagation du gradient : comment un modèle apprend-il ?
La phase d’apprentissage repose intégralement sur la “descente de gradient“. Suite à l’évaluation d’une entrée par le réseau de neurones (notons-la ), on peut la comparer à la réponse attendue (notons-la y) et dire de combien il s’est trompé. Par exemple, il est facile de comprendre qu’un modèle qui prédirait quand on attend de lui qu’il prédise y=1 commettrait une erreur. Mais comment quantifier cette erreur ? Et surtout, comment faire comprendre au modèle la direction à prendre pour la corriger ?
Tout d’abord, il faut définir une mesure d’erreur. Dans notre exemple, on peut envisager plusieurs possibilités :
De manière générale, cette étape s’appelle la définition de la norme d’erreur. Dans notre cas, on va choisir la solution b). On souhaite donc envoyer l’information « tu as fait une erreur de 0,3 » à tous les neurones du modèle.
Or, on connaît les étapes par lesquelles est passé le modèle pour produire cette valeur. On peut donc lui renvoyer l’information de son erreur par rétropropagation. Le reste est un peu théorique et pour celles et ceux qui sont intéressés nous vous renvoyons vers ce super article : Introduction au Deep Learning.😆
On met alors les poids à jour un par un à partir de cet écart, en partant de la fin et en remontant. Cette phase s’appuie sur les dérivées partielles (pour évaluer l’impact d’un changement de poids sur notre erreur).