Psst... Contenu Exclusif Réservé aux Membres !
Ce mini-cours fait partie de notre espace premium. Rejoins dès maintenant le Cercle des Experts pour débloquer l’intégralité de nos ressources, analyses approfondies et guides pratiques.
👉 Clique ici pour découvrir les avantages et t’inscrire : Page d’adhésion.
⏱️ Temps de lecture : 25-30 minutes
Introduction
Dans le dossier de la semaine dernière, tu as découvert les rouages internes des Kolmogorov Arnold Networks (KAN) et leur fonctionnement.
À la fin de ce mini-cours, on avait annoncé un second volet consacré à l'implémentation concrète des KAN avec PyTorch. Le voici.
Pourquoi ce sujet ?
Ce dossier me semble important parce qu'on sait tous construire et entraîner un réseau de neurones avec des matrices de poids classiques.

Mais les KAN reposent sur une idée différente. Les matrices que possède un KAN dans une couche ne contiennent pas des poids, mais des fonctions, appliquées à l'entrée de cette couche.

En implémentant les KAN, tu vas donc comprendre comment on entraîne un réseau qui ne repose pas sur les matrices de poids traditionnelles, mais sur des fonctions univariées.

C'est parti !
Comme on l'a vu dans ce dossier précédent, les KAN remettent en question la conception classique des réseaux de neurones et proposent un nouveau paradigme pour les concevoir et les entraîner.

En résumé, l'idée est que plutôt que d'empiler simplement des couches les unes sur les autres (qui sont toujours des transformations linéaires, la non-linéarité étant introduite volontairement via des fonctions d'activation), les KAN proposent une approche alternative.
Les auteurs utilisent des fonctions apprenables complexes (appelées B-splines) qui permettent de représenter directement des transformations non linéaires de l'entrée, avec relativement moins de paramètres qu'un réseau traditionnel.

Si tu observes bien l'image ci-dessus :
Dans un réseau de neurones classique, les fonctions d'activation sont fixes sur tout le réseau, et elles existent sur chaque nœud (illustré ci-dessous).

Dans un KAN, en revanche, les fonctions d'activation existent sur les arêtes (qui correspondent aux poids d'un réseau traditionnel), et chaque arête possède sa propre fonction d'activation.

Il paraît donc logique de s'attendre à ce qu'un KAN soit beaucoup plus précis et interprétable, avec moins de paramètres.
Les KAN s'appuient sur le théorème de représentation de Kolmogorov-Arnold, qui affirme que toute fonction continue multivariée peut être représentée comme la composition d'un nombre fini de fonctions continues à une seule variable.

Si on développe les termes de la somme, on obtient ceci :

En résumé, tout ce qu'on fait dans une couche KAN, c'est prendre l'entrée (x₁, x₂, ..., xₙ) et lui appliquer une transformation φ.

φ₁ désigne la transformation de la première couche.
La matrice de transformation φ₁ (correspondant à la première couche) peut donc être représentée ainsi :

Dans cette matrice :
ndésigne le nombre d'entrées.mdésigne le nombre de nœuds de sortie de cette couche.[IMPORTANT] Les éléments de la matrice ne sont pas des nombres, ce sont des fonctions univariées. Par exemple :
φ₁₁pourrait être2x² − 3x + 4.φ₁₂pourrait être4x³ + 5x² + x − 2.et ainsi de suite...
Pour générer une transformation, il suffit donc de prendre le vecteur d'entrée et de le faire passer à travers les fonctions correspondantes de cette matrice de transformation :

On obtient alors le vecteur suivant :

Ce vecteur est la sortie de la première couche, qui est ensuite transmise à la couche suivante pour une nouvelle transformation.
Le réseau KAN complet peut donc se condenser en une seule formule :

Où :
xdésigne le vecteur d'entréeφₖdésigne la matrice de transformation fonctionnelle de la couchek.KAN(x)est la sortie du réseau KAN.
Dans un KAN, les matrices φₖ sont elles-mêmes des matrices de transformation non linéaires, et chaque fonction univariée peut être très différente d'une autre.

Mais comment estime-t-on les fonctions univariées de chacune de ces matrices de transformation ?

Comme on l'a vu dans le dossier d'introduction aux KAN, on utilise des B-splines pour cela.
Rappelle-toi que dès qu'on crée une B-spline, on dispose déjà de points de contrôle (P₁, P₂, …, Pₙ), ainsi que des fonctions de base sous-jacentes déterminées par le degré k.
Et en faisant varier la position des points de contrôle, on obtient différentes courbes, comme le montre l’animation ci-dessous :

Voici donc l'idée centrale des KAN :
Rendons les positions des points de contrôle apprenables au sein de la fonction d'activation, pour que le modèle soit libre d'apprendre n'importe quelle forme de fonction d'activation qui colle le mieux aux données.
C'est tout.
En ajustant la position des points de contrôle pendant l'entraînement, le modèle KAN peut façonner dynamiquement les fonctions d'activation qui correspondent le mieux aux données.
On part de positions initiales pour les points de contrôle, exactement comme on le fait pour des poids.
Pendant l'entraînement, on met à jour la position de ces points de contrôle par rétropropagation, de la même manière qu'on met à jour les poids d'un réseau de neurones.
On utilise un algorithme d'optimisation (par exemple la descente de gradient) pour ajuster les points de contrôle afin que le modèle minimise la fonction de perte.
Mathématiquement, dans un KAN, chaque fonction d'activation φ(x) est définie ainsi :

Où :

Le calcul fait intervenir une fonction de base
b(x)(un peu comme une connexion résiduelle).spline(x)est apprenable, plus précisément les paramètres cᵢ, qui désignent la position des points de contrôle.Il y a un autre paramètre, w. Les auteurs précisent que, en théorie, w est redondant puisqu'il peut être absorbé dans
b(x)etspline(x). Ils l'ont néanmoins conservé pour mieux contrôler l'amplitude globale de la fonction d'activation.
Une fois cette définition posée, le réseau s'entraîne exactement comme n'importe quel autre réseau de neurones.
Plus précisément :
On initialise chacune des matrices phi comme ceci :

On exécute la forward pass :

On calcule la perte et on effectue la rétropropagation.
Voilà !
Implémentation d'un KAN
Dans cette section, on va implémenter un KAN avec PyTorch.
Mais on va se limiter à une implémentation simplifiée des KAN.
👉 Par "simplifiée", on entend une implémentation plus simple, qui ne correspond pas exactement à l'implémentation originale. L'objectif de cet article est de te donner une intuition de la manière dont on entraîne un réseau qui ne repose pas sur des matrices de poids traditionnelles, mais sur des fonctions univariées.
Le plan de travail
Voici les étapes :
On doit d'abord définir une entité "arête" (
edge) du réseau, qui sera une fonction univariée composée d'une spline, d'une SiLU, et d'un unique paramètre de poids :

Ensuite, on doit définir une couche personnalisée du réseau, composée d'un arrangement matriciel de ces fonctions univariées :

On définira ensuite notre classe réseau, qui sera une composition de ces couches personnalisées connectées entre elles.

Enfin, on créera un jeu de données factice, on définira un optimiseur et une fonction de perte, et on entraînera le modèle.
Cela posé, passons à l'implémentation.
💡 En continuant, tu vas découvrir :
Comment coder, arête par arête, une fonction d'activation univariée (spline apprenable + SiLU) en PyTorch
Comment assembler ces fonctions en une KANLayer complète, avec un exemple chiffré, indice par indice
Comment entraîner ce KAN "from scratch" sur un jeu de données, et lire sa courbe de convergence
Comment utiliser le package officiel pykan pour construire et visualiser un vrai KAN
Le vrai goulot d'étranglement des KAN (10x plus lent qu'un MLP) et comment efficient-KAN le résout
La suite de ce mini-cours est réservée aux membres du Cercle des Experts.
Tu as déjà le début. Pour accéder à l’explication complète et aux autres mini-cours, rejoins le Cercle des Experts.
Rejoindre le Cercle des ExpertsEn devenant membre, tu débloques :
- L’intégralité de ce mini-cours, sans coupure
- Tous les mini-cours et les ressources associées
- Chaque nouveau mini-cours dès sa sortie

