- pykan ist das GitHub-Repository zu den Papers „KAN: Kolmogorov-Arnold Networks“ und „KAN 2.0: Kolmogorov-Arnold Networks Meet Science“ und bietet KAN-Training, Tutorials, Dokumentation und Beispiele
- KAN wird als Alternative zu MLP vorgestellt; so wie MLP auf dem universellen Approximationstheorem basiert, beruht KAN auf dem Kolmogorov-Arnold-Darstellungssatz
- Strukturell haben MLPs Aktivierungsfunktionen an den Knoten, während KANs Aktivierungsfunktionen an den Kanten haben; diese Änderung könne die Modellgenauigkeit und Interpretierbarkeit verbessern
- Machine-Learning-Nutzer, die den Zweig für symbolisches Rechnen nicht verwenden, sollten vor dem Training
model.speed()aufrufen; andernfalls kann es wegen des nicht parallelisierten symbolic branch sehr langsam werden - Diese Implementierung zielt vor allem auf kleine wissenschaftliche Probleme ab; sie ist schwerlich als Plug-in zu verstehen, das sich direkt in Machine-Learning-Aufgaben einstecken lässt, und erfordert Hyperparameter-Tuning sowie anwendungsspezifische Techniken
Überblick über pykan und KAN
- pykan ist das Repository zu „KAN: Kolmogorov-Arnold Networks“ und „KAN 2.0: Kolmogorov-Arnold Networks Meet Science“
- Einen schnellen Einstieg bietet hellokan, weitere Beispiele gibt es in den tutorials, die Dokumentation in der offiziellen Dokumentation
- KANs werden als vielversprechende Alternative zu Multi-Layer Perceptrons (MLPs) vorgestellt
- MLP basiert auf dem universal approximation theorem
- KAN basiert auf dem Kolmogorov-Arnold representation theorem
- KAN und MLP werden als duale Strukturen beschrieben
- KAN hat Aktivierungsfunktionen an den Kanten
- MLP hat Aktivierungsfunktionen an den Knoten
- Diese Strukturänderung könne dazu führen, dass KANs MLPs bei Genauigkeit und Interpretierbarkeit überlegen sind
Installation und Laufzeitumgebung
- pykan kann über PyPI oder GitHub installiert werden
- Voraussetzungen sind Python 3.9.7 oder höher und
pip - Installation für Entwickler:
git clone https://github.com/KindXiaoming/pykan.gitcd pykanpip install -e .
- Installation über GitHub:
pip install git+https://github.com/KindXiaoming/pykan.git
- Installation über PyPI:
pip install pykan
- Zu den wichtigsten erforderlichen Paketen gehören
matplotlib,numpy,scikit_learn,sympy,torch,tqdm,pandas,seaborn,pyyamlund weitere - Conda-Nutzer können eine Umgebung mit
python=3.9.7erstellen und anschließend über GitHub oder PyPI installieren
Performance-Modus und Rechenanforderungen
- Wenn Machine-Learning-Nutzer eine eigene Trainingsschleife schreiben,
model.fit()nicht verwenden und den symbolic branch nicht nutzen, ist es wichtig, vor dem Trainingmodel.speed()aufzurufen - Wird
model.speed()nicht aufgerufen, bleibt der symbolic branch aktiviert; da symbolisches Rechnen nicht parallelisiert ist, kann dies sehr langsam sein - Die Beispiele in den tutorials lassen sich in der Regel auf einer einzelnen CPU in unter 10 Minuten ausführen
- Alle im Paper enthaltenen Beispiele lassen sich auf einer einzelnen CPU in unter einem Tag ausführen
- Das Training von KANs für PDEs ist am teuersten und kann auf einer einzelnen CPU mehrere Stunden bis Tage dauern
- Der Grund für die Nutzung der CPU beim Modelltraining war, dass Parameter-Sweeps über Tausende kleiner Modelle durchgeführt wurden, um die Pareto Frontier von MLP und KAN zu erhalten
- Für Aufgaben in größerem Maßstab wird die Nutzung einer GPU empfohlen
Hyperparameter-Tuning für KAN
- Intuitionen aus MLPs und anderen Netzwerken lassen sich möglicherweise nicht direkt auf KAN übertragen
- Der grundlegende Rat lautet, mit einfachen Einstellungen zu beginnen
- kleine KAN shape
- kleine grid size
- kleine Datenmenge
- keine Regularisierung,
lamb=0
- Bei einer Aufgabe mit beispielsweise 5 Eingaben und 1 Ausgabe kann man zunächst eine sehr einfache Einstellung wie
KAN(width=[5,1,1], grid=3, k=3)ausprobieren - Wenn das nicht funktioniert, wird empfohlen, zuerst die width zu erhöhen und, falls das weiterhin nicht reicht, anschließend die depth zu erhöhen
- Sobald die Performance ein akzeptables Niveau erreicht hat, kann man das Modell zu einem genaueren oder besser interpretierbaren KAN verfeinern
- Wenn Genauigkeit im Vordergrund steht, kann man die Technik grid extension ausprobieren, sollte aber auf Overfitting achten
- Wenn Interpretierbarkeit im Vordergrund steht, kann man das Netzwerk etwa mit
model.train(lamb=0.01)sparsifizieren- Es wird empfohlen,
lambschrittweise zu erhöhen - Wenn im Plot nach dem Training offensichtlich nutzlose Neuronen zu sehen sind, kann man mit
pruned_model = model.prune()ein beschnittenes Modell erhalten - Danach kann man für Genauigkeit oder Sparsity weitertrainieren oder symbolic regression durchführen
- Es wird empfohlen,
- Genauigkeit, Interpretierbarkeit und Parametereffizienz stehen nicht immer im Widerspruch zueinander; je nach Fall kann es eine positive Korrelation geben oder auch einen Trade-off
- Wenn zwischen train/test loss eine große Differenz besteht, sollte man erwägen, die Datenmenge zu erhöhen oder das Modell zu verkleinern
- Da
gridwichtiger ist alswidth, wird vorgeschlagen, zuerstgridund danachwidthzu reduzieren
- Da
- Empfohlen wird, mit einem einfachen Modell zu beginnen, zunächst Underfitting zu bestätigen und es dann schrittweise zu erweitern, um in einen geeigneten Bereich zu gelangen
Anwendungsbereich und Grenzen
- Der Code wurde mit Blick auf kleine wissenschaftliche Probleme wie mathematische und physikalische Beispiele entworfen
- Da Effizienz und Wiederverwendbarkeit nicht stark berücksichtigt wurden, erklären die Autoren, Kritik an diesen Punkten zu akzeptieren
- Die ursprüngliche Zielgruppe sind Nutzer mit Interesse an wissenschaftlicher Entdeckung und wissenschaftlichem Rechnen; das Repository soll diesen Zweck voraussichtlich auch hauptsächlich beibehalten
- Als Implementierungen mit Effizienzverbesserungen werden efficientkan und FourierKAN erwähnt
- Für Machine-Learning-orientierte Nutzer ist KAN derzeit noch kein einfaches Out-of-the-box-Plug-in
- Hyperparameter-Tuning ist erforderlich
- Anwendungsspezifische Spezialtechniken können hinzukommen
- GraphKAN schlägt vor, KAN besser im latent space zu verwenden, und erwähnt, dass hinter der Eingabe und vor der Ausgabe embedding/unembedding linear layer nötig sind
- KANRL schlägt vor, im Reinforcement Learning einige trainierbare Parameter zu fixieren, um die Trainingsstabilität zu erhöhen
- Zur Frage, ob KANs die nächste Generation von LLMs werden, geben die Autoren an, keine gute Intuition zu haben
- KANs sind für Anwendungen konzipiert, in denen hohe Genauigkeit und Interpretierbarkeit wichtig sind
- Interpretierbarkeit in LLMs und Interpretierbarkeit in der Wissenschaft können sich stark unterscheiden
- Die Schlussfolgerungen des Papers lassen sich ihrer Ansicht nach nur schwer direkt auf LLMs oder allgemeine Machine-Learning-Aufgaben übertragen
- KAN und MLP können einander nicht ersetzen; beide haben je nach Setting jeweils Vorteile und Grenzen
1 Kommentare
Meinungen auf Hacker News
Ich habe das Paper kurz überflogen und wollte es weiter vereinfachen, also habe ich einen PyTorch-Layer gebaut: https://github.com/GistNoesis/FourierKAN/
Der Kern besteht wirklich nur aus ein paar Zeilen. Im Paper wirkt der Code so, als sei er für kleinere Größenordnungen gedacht: Um eindimensionale Funktionen darzustellen, wird Spline-Interpolation verwendet und das Ergebnis aufsummiert.
Stattdessen habe ich eine andere Darstellung gewählt, bei der Fourier-Koeffizienten zur Interpolation der Funktionen der einzelnen Koordinaten verwendet werden; das dürfte helfen, ein Gefühl für die Ausdrucksstärke von Kolmogorov-Arnold-Netzen zu bekommen. Die Konvergenz könnte einfacher sein als bei der Spline-Version, aber die Spline-Variante benötigt weniger Rechenoperationen.
Natürlich heißt es nicht, dass der Ansatz aus dem Paper nicht funktioniert, nur weil mein Code nicht funktioniert. Wer möchte, kann damit experimentieren und ein Paper daraus machen.
Fourier-Koeffizienten lassen sich zwar gut parallelisieren und sind einfach zu schreiben, deshalb habe ich sie ausprobiert; das Trainingsverhalten war mit radialen Basisfunktionen aber besser.
efficientKAN berechnet zunächst gemeinsame Basisfunktionen für alle Kantenaktivierungen, und die Ausgabe wird als Linearkombination dieser Basis berechnet.
Wenn die Basisfunktionen Fourier-Funktionen sind, lässt sich ein KAN-Layer als Linear-Layer mit festen Gewichten + Sin-Aktivierung + Linear-Layer mit trainierbaren Gewichten auffassen; das ist eine spezielle Form von Siren.
Das könnte ein Beispiel sein, das die Verbindung zwischen KAN und MLP zeigt.
Du sagst zwar: „Nur weil mein Code nicht funktioniert, heißt das nicht, dass der Ansatz aus dem Paper nicht funktioniert“, aber mich interessiert, ob er tatsächlich funktioniert.
Ich habe ein wenig mit den Jupyter-Notebooks der Autoren herumgespielt, und persönlich fand ich Example_3_classfication.ipynb (https://github.com/KindXiaoming/pykan/blob/master/tutorials/Example_3_classfication.ipynb) am nützlichsten.
Mit den von den Autoren gewählten Parametern funktioniert es wie beschrieben, aber wenn man im Klassifikations-Setup im späteren Teil des Tutorials die Netzform von (2, 2) auf (2, 2, 2) ändert, scheitert die Generalisierung.
Der Trainingsverlust fällt bis auf 1e-9, aber der Testverlust bleibt in der Nähe von 3e-1, und auch größere Netze haben nicht geholfen.
Es braucht Beispiele mit deutlich größerer Parameter- und Datenkomplexität, und ich würde gern sehen, ob das in der Praxis trainierbar ist. MNIST wäre ein guter Ausgangspunkt.
Update: Nachdem ich die Größe des Trainingsdatensatzes um den Faktor 100 erhöht habe, ist das Overfitting zurückgegangen, aber jetzt bekomme ich den Trainingsverlust nicht unter 1e-2. Ich experimentiere weiter, und GPU-Beschleunigung ist dringend nötig. Im Moment bremst die CPU-Geschwindigkeit den Fortschritt.
Geändert habe ich drei Dinge: Ich habe den Trainingssatz von 1.000 auf 100k Samples vergrößert und damit das Overfitting gelöst; außerdem habe ich das Rauschen bei der Datengenerierung leicht von 0,1 auf 0,07 reduziert, damit die Klassen sich nicht überlappen.
Der wichtigste und KAN-spezifische Teil war, zunächst 30 Schritte mit grid=5 zu trainieren, dann aus dem vorherigen Modell zu initialisieren und 30 Schritte mit grid=10 zu trainieren, anschließend noch einmal 30 Schritte mit grid=20. Das ist bei KAN eine gängige Vorgehensweise und wird in Example_1_function_fitting.ipynb (https://github.com/KindXiaoming/pykan/blob/master/tutorials/Example_1_function_fitting.ipynb) gezeigt.
Mein Gesamteindruck: Es funktioniert, die Referenzimplementierung ist sehr langsam und braucht unbedingt eine GPU-Implementierung, und es fühlt sich nichtlinearer an als MLP + ReLU, bei geringerer Trainingsstabilität.
Es ist noch nicht garantiert, dass es gut skaliert, und man muss unbedingt sehen, ob sich MNIST mit diesem Ansatz lösen lässt. Ich werde es weiter verfolgen.
Hätte man große Ideen wie Transformer, LSTM oder ADAM nur mit Trainingsdaten aus 50 Zahlenpunkten auf der Kurve y=sin(x) getestet, hätte man diese Ideen möglicherweise fälschlicherweise verworfen.
Nur weil etwas auf der GPU läuft, ist es nicht automatisch schneller, insbesondere bei vielen Verzweigungen ist das nicht überraschend.
Leider lagen nicht alle relevanten Tensoren auf dem richtigen Device, sodass ich KAN.py und KANLayer.py anpassen musste. An einigen Formaten sieht man auch Spuren davon, dass es früher offenbar ein device-Argument gab.
In der klassischen Statistik gibt es ein von Kolmogorov-Arnold inspiriertes Modell namens GAM (https://en.wikipedia.org/wiki/Generalized_additive_model), das Hastie und Tibshirani als Erweiterung von GLM (https://en.wikipedia.org/wiki/Generalized_linear_model) entwickelt haben.
GLM verallgemeinert logistische Regression, lineare Regression und mehrere populäre Regressionsmodelle.
Auch neuronale GAMs mit gelernten Basisfunktionen wurden bereits vorgeschlagen, daher ist es etwas überraschend, dass diese Vorarbeiten im neuen Paper nicht erwähnt werden. Frühere Anwendungen legten den Schwerpunkt stärker auf Interpretierbarkeit.
Der Erfolg neuronaler Netze ist eng mit Skalierbarkeit verbunden. Nicht nur muss der Algorithmus selbst auf mehr Layer skalieren, er muss auch gut zur Hardware passen.
Neuronale Netze bestehen größtenteils aus Matrixmultiplikationen, und GPUs haben spezielle Beschleunigung für Matrixmultiplikationen. AlexNet hatte auch deshalb so große Wirkung, weil es zeigte, dass man neuronale Netze auf GPUs bringen, skalieren und beschleunigen kann.
Wie gut dieser Algorithmus skaliert, ist allein aus dem Paper nicht ersichtlich. Unklar ist sowohl, ob er algorithmisch auch mit vielen Layern gut trainierbar bleibt, als auch, ob er Hardwarebeschleunigung gut ausnutzen kann.
Insbesondere ist fraglich, ob eine Struktur, bei der jede Gewichtung ihre eigene Aktivierungsfunktion hat, schnelle Beschleunigung für Matrixmultiplikationen nutzen kann.
Im kleinen Maßstab ist es eine interessante Idee, die gut funktioniert und gute Eigenschaften hat, aber ob sie eine geeignete Architektur für ImageNet oder LLMs ist, weiß man noch nicht.
Schnelle Beschleunigung für Matrixmultiplikationen wurde anfangs in Hardware implementiert, weil sie für bestimmte Probleme wie Grafik nützlich war.
Wenn Aktivierungsfunktionen pro Gewichtung wirklich gut funktionieren, werden die Leute schnell herausfinden, wie man sie auf Hardware ausführt.
Es ist erfrischend, neue KI-Forschung zu sehen, die nicht dem üblichen Muster „Transformer auf diese oder jene Weise verändert und auf diesen oder jenen Benchmarks ein bisschen verbessert“ folgt.
Solche Papers mit inkrementellen Verbesserungen sind zwar auch wichtig, aber alle werden davon ein wenig müde, und anekdotische Hinweise sowie neuere Forschung legen nahe, dass wir uns fundamentalen Grenzen nähern, die dem Transformer selbst eigen sind; vielleicht braucht es also neue Alternativen (https://news.ycombinator.com/item?id=40179232).
Das Beste an dieser Arbeit ist, dass es kein Entweder-oder ist. Die vorgeschlagenen lernbaren Spline-Interpolations-Aktivierungsfunktionen lassen sich auch in bestehende tiefe neuronale Netze einbauen, um deren Ausdrucksstärke zu erhöhen.
Jetzt muss man nur noch testen, ob es in der Praxis besser funktioniert.
PR ist zu einer zu starken Kraft geworden; es gab sie früher auch schon, aber heute scheint ihr Einfluss noch größer zu sein.
Man kann dem entgegenwirken, indem man solche Beiträge upvotet und, wenn man selbst Gutachter ist, nicht nur auf neue State-of-the-Art-Ergebnisse achtet. Dieses Kriterium ist längst gamifiziert und führt uns offensichtlich in die falsche Richtung.
Aus heutiger Sicht waren die Inhalte des Buchs fast lächerlich grundlegend, aber als Motivation wurde der Darstellungssatz von Kolmogorov angeführt. Er besagt, dass ein geeignetes dreischichtiges Netzwerk mit passenden Aktivierungsfunktionen jede stetige Funktion von m nach n darstellen kann.
Vielleicht deshalb konzentrierte sich damals der Großteil der Forschung auf dreischichtige Netze, Sigmoid-Aktivierungen waren vorherrschend, und verschwindende Gradienten waren ein Hauptproblem.
Es dauerte 20 Jahre, bis AlexNet nach dem KI-Winter der 1990er die Forschung an neuronalen Netzen wiederbelebte.
Im Preprint gelten Eingabedimensionen von 100 bereits als „hoch“, und die meisten behandelten Probleme haben höchstens 5 Eingabedimensionen.
Das ist typisch für physikalisch inspirierte Machine-Learning-Setups, die ich gesehen habe.
Der nächste Schritt wäre, es auf MNIST zu zeigen, und selbst die 784 Dimensionen von MNIST sind nach heutigen Maßstäben sehr klein.
Bei den meisten dieser Probleme sind Entscheidungsbäume jedoch weiterhin konkurrenzfähig mit neuronalen Netzen oder sogar besser.
Interessant. Kolmogorov-Netze können unstetige Funktionen darstellen (https://arxiv.org/abs/2311.00049), aber ich fragte mich, wie praktikabel das in der Anwendung ist.
Dieses Repository scheint zumindest zu zeigen, dass es in gewissem Maße nützlich ist.
Im Paper steht ebenfalls: „Für unstetige beschränkte und unbeschränkte Funktionen ist noch keine praktische Konstruktion von g bekannt.“
Wenn man sich den arXiv-Link des OP ansieht (https://arxiv.org/abs/2404.19756), verwenden sie Splines.
Das ist weiterhin interessant und potenziell nützlich, aber ohne weitere Entdeckungen ist es für unstetige Funktionen nicht hilfreich. Falls ich falschliege, würde ich mich über einen Link freuen; das Thema interessiert mich sehr.
Vielleicht ist das eine vorschnelle Reaktion, aber ist eine Linearkombination von B-Splines nicht einfach ein weiterer B-Spline höherer Ordnung?
Ich frage mich, ob es am Ende nicht nur darum geht, eine Funktion mit höhergradigen B-Splines zu fitten.
Interessanterweise wurden bzw. entdeckte man diesen Ansatz und die Grundlagen des MLP vor etwa 66 Jahren fast zur gleichen Zeit
1957: https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Arnold_representation_theorem
1958: https://en.wikipedia.org/wiki/Multilayer_perceptron
Ein weiterer Vorteil ist, dass dieser Ansatz nur eine Art von Parametern hat, nämlich die Koeffizienten lokaler Aktivierungsfunktionen, während ein MLP drei Arten von Parametern hat: Gewichte, Biases und eine global identische Aktivierungsfunktion
Alle reden über Transformer, aber ich würde gern Diffusionsmodelle sehen, die diesen Ansatz verwenden
Zwischen den Gewichten einer linearen Summe und den Koeffizienten eines Splines scheint es auch keinen großen Unterschied zu geben
Es gibt U-Nets mit Self-Attention und Cross-Attention, Vision Transformer, Diffusion Transformer usw.
Man könnte es wohl mit Prägnanz, also aus Sicht von Ockhams Rasiermesser, begründen; ich frage mich, ob das gemeint ist oder ob es einen anderen Grund gibt
Es fühlt sich an, als hätte jemand Splines in Entscheidungsbäume hineingestopft
Auf Seite 2 des PDFs steht: „Die Knoten eines KAN wenden keine Nichtlinearität an, sondern summieren die eingehenden Signale einfach auf“