- Ein Experiment zur Klassifikation handgeschriebener Ziffern aus MNIST erreicht mit GZIP-Komprimierung und k-Nearest Neighbors (k-NN) rund 78 % Genauigkeit und zeigt, dass sich Komprimierung als modellfreies Klassifikationswerkzeug nutzen lässt
- Die normalisierte Kompressionsdistanz (NCD) wird daraus berechnet, wie stark sich die Länge verändert, wenn zwei Bildbeispiele gemeinsam komprimiert werden, und als Ähnlichkeitsmaß zwischen Bildern verwendet
- Jedes Testbeispiel wird mit 100 Trainingsbeispielen verglichen; das Mehrheitslabel der k=5 nächsten Nachbarn wird zur Vorhersage
- Wegen der Rechenkosten wurde die Genauigkeit nicht auf dem gesamten Testset, sondern nur auf einem Teil der Testbilder gemessen; mit dem vollständigen Set könnte die Auswertung genauer werden
- Im veröffentlichten Beispiel bleibt ein Refactoring-Fehler bestehen: Obwohl ein Cache für Kompressionslängen angelegt wird, wird er in der eigentlichen NCD-Berechnung nicht verwendet; nötig wäre das Entfernen des Caches oder eine Anpassung von
compute_ncd
MNIST mit GZIP + k-NN klassifizieren
- Das Experiment klassifiziert den Datensatz handgeschriebener Ziffern MNIST mit der Kombination GZIP + k-NN
- Das kurze Codebeispiel verwendet die Länge von
gzip.compress(z.tobytes())als Kompressionslänge, berechnet daraus die NCD und wählt anschließend das häufigste Label unter den fünf nächsten Nachbarn - Ein ausführbares Beispiel gibt es im Jupyter Notebook
- Das Ziel ist nicht die bestmögliche Genauigkeit, sondern eine einfache Überprüfung der Idee, Komprimierung als modellfreies Klassifikationswerkzeug einzusetzen
- Der Code mit weniger als 10 Zeilen ist weniger der Kern des Experiments als vielmehr ein Code-Golf-Element zum Spaß
Ähnlichkeitsberechnung und Klassifikationsablauf
- Die NCD misst Ähnlichkeit, indem sie normiert, wie stark sich die Kosten der gemeinsamen Komprimierung zweier Datenpunkte von der getrennten Komprimierung unterscheiden
- Die Kompressionslängen werden in folgender Form berechnet
Cx1 = len(gzip.compress(x1.tobytes()))Cx2 = len(gzip.compress(x2.tobytes()))Cx1x2 = len(gzip.compress((x1 + x2).tobytes()))
- Die NCD-Formel hat die Form
(Cx1x2 - min(Cx1, Cx2)) / max(Cx1, Cx2) - Für die Klassifikation werden die Distanzen zwischen jedem Testbild und den Trainingsbildern berechnet, nach Nähe sortiert und anschließend die Labels der fünf nächsten per Mehrheitsentscheid ausgewertet
- Im Experiment wurden 100 Trainingsbeispiele als Vergleichsbasis verwendet, und wegen der Rechenkosten kam auch beim Testset nur ein Teil zum Einsatz
Verwandte Ideen und Hinweise zum Code
- Dieser Ansatz ist inspiriert vom Artikel text generation from data compression und dem Paper parameter free text classification
- Nach Veröffentlichung wurde außerdem der Beitrag MNIST by ZIP von Andreas Kirsch aus dem Jahr 2019 entdeckt, der einen ähnlichen Ansatz verwendet
- Der Beispielcode legt zwar einen Cache für Kompressionslängen der Trainingsbeispiele an, verwendet diese Werte in der eigentlichen Schleife aber nicht
- Sowohl die normale als auch die obfuskierte Version erzeugen
compressed_lengthsbzw.cls, nutzen die zwischengespeicherten Längen jedoch nicht in der NCD-Berechnung - Wenn der Cache entfernt und direkt
training_setverwendet wird odercompute_ncdso angepasst wird, dass die Cache-Werte genutzt werden, stimmen Absicht und Implementierung des Codes wieder überein
- Sowohl die normale als auch die obfuskierte Version erzeugen
1 Kommentare
Meinungen auf Hacker News
Als ich die Distanzfunktion im Code durch einfachere Maße ersetzt habe, zeigte sich: Die GZIP-Distanz hat bei der MNIST-Klassifikation eine niedrigere Genauigkeit und einen deutlich höheren Rechenaufwand.
Gzip-Distanz: ca. 3 Minuten, 78 % Genauigkeit / euklidische Distanz: ca. 0,5 Sekunden, 93 % / Jaccard-Distanz: ca. 0,7 Sekunden, 94 % / Dice-Dissimilarität: ca. 0,8 Sekunden, 94 %
Jaccard und Dice wurden nach Binarisierung der Bilder gemessen.
Ich bin mit dem GZIP-Algorithmus nicht besonders vertraut, aber dass die Ergebnisse so niedrig ausfallen, ist interessant; ich frage mich auch, ob ein bildzentrierter Kompressionsalgorithmus besser wäre.
Der Beitrag selbst ist kreativ, und Code sowie Erklärung waren gut, aber ich denke, die obigen Baselines geben dem gzip-Score mehr Kontext.
NMI skimage: ca. 30 Sekunden, 95 % Genauigkeit / NMI numba: ca. 0,6 Sekunden, 95 % Genauigkeit
Mit dem von ChatGPT gelieferten
numba-Code habe ich 2x2-Joint-Counts, Entropie und normalisierte gegenseitige Information berechnet.Persönlich interessiere ich mich für schnelles Training auf CIFAR10, und solche Ansätze scheinen auch in anderen Bereichen recht nützlich sein zu können.
https://github.com/benjamin-recht/mnist_1_pt_2/tree/main
Ich habe auch zstandard hinzugefügt; Zstd(level=3) war mit ca. 3,5 Sekunden und 88 % Genauigkeit deutlich schneller als gzip.
Wenn man bei der Berechnung von
Cx1x2stattx1+x2den Ausdruck(x1-x2)*2verwendet, steigt zstd auf 93 % Genauigkeit.Wenn man die beiden Arrays nicht addiert, sondern vertikal stapelt, bricht die Leistung völlig ein und fällt unter 20 %; interessant ist, dass diese Methode bei der String-Klassifikation offenbar gut funktioniert.
Im Vergleich zu anderen Verfahren liegt Linear SVC bei 92 %, SVC mit RBF-Kernel bei 96,4 %, SVC mit polynomialem Kernel bei 94,5 %, logistische Regression bei 89 % und Naive Bayes bei etwa 81 %.
Quelle: https://dmkothari.github.io/Machine-Learning-Projects/SVM_wi...
Wenn man sich Online-Beiträge ansieht, scheint allein mit K-NN ein deutlich besseres Ergebnis möglich zu sein; vielleicht hat der Autor es sich mit gzip unnötig schwer gemacht.
Ich beginne gern mit einfachen Modellen und erhöhe später die Komplexität, aber ich habe oft gehört: „logistische Regression geht nicht“, selbst bei Problemen, bei denen sie tatsächlich gut funktioniert hätte.
Wenn man fragt, welche Basisleistung sie bei MNIST erwarten würden, schätzen viele 20 bis 30 %.
Auch Leute aus dem Machine Learning unterschätzen oft, wie schnell bei stark steigender Modellkomplexität abnehmende Erträge einsetzen.
Wenn ein einfaches Modell keine gute Leistung bringt, war es in vielen Fällen auch schwierig, mit einem komplexeren Modell hervorragende Ergebnisse zu erzielen.
Schon das ursprüngliche Paper, das den MNIST-Datensatz eingeführt hat, erreichte etwa 98 % Genauigkeit, und heutige neuronale Netze kommen auf bis zu 99,87 %.
https://paperswithcode.com/sota/image-classification-on-mnis...
Kompression ist ursprünglich dazu da, das Problem schwieriger zu machen, und tatsächlich funktioniert sie weiterhin so.
Andere Modelle neigen dazu, irgendwo Rauschen hinzuzufügen; daher frage ich mich, wie es wäre, vor gzip Feature Engineering einzubauen.
Zum Beispiel könnte man zuerst Gaussian Blur und Faltungen anwenden und danach Deep Learning für die Feature-Auswahl nutzen.
Der Code mag elegant und kurz sein, aber 78 % Genauigkeit auf MNIST ist sehr schlecht.
Selbst ein Dummy-Modell mit TensorFlow erreicht leicht 90 % Genauigkeit, und das beste Modell liegt bei 99,87 %.
Benchmark: https://paperswithcode.com/sota/image-classification-on-mnis...
Interessant ist, dass man Kompression zur Klassifikation nutzen kann, ohne ein Modell zu trainieren.
Das wirft die Frage auf, ob sich auch andere, günstigere und verlustbehaftete informationstheoretische Maße verwenden lassen.
To Compress or Not to Compress- Self-Supervised Learning and Information Theory: A Review
[https://arxiv.org/abs/2304.09355\)" class="ud link">https://arxiv.org/abs/2304.09355\](https://arxiv.org/abs/2304.09355\)*
Interessant ist nicht, ob GZip die aktuelle Bestleistung erreicht, sondern dass es halbwegs klassifizieren kann.
Es ist ein bisschen so, als wäre nicht entscheidend, ob ein Bär Mozart perfekt wiedergibt, sondern dass er überhaupt Klavier spielen kann.
Trotzdem ist es achtmal besser als die Baseline und zeigt, dass Kompression Repräsentationen lernen kann.
Wenn man
compute_ncddurch die euklidische Distanz ersetzt, steigt die Testgenauigkeit um 15 Prozentpunkte und der Rechenaufwand sinkt deutlich.Man kann es etwa so ändern:
distances = [(np.sqrt(np.sum(np.square(x1-x))), label) for x, _, label in compressed_lengths]Als Buch über die tiefen Zusammenhänge zwischen Informationstheorie, Kompression und Lernalgorithmen fand ich MacKay am besten.
Für ordentlich ausgebildete Leute mag das Allgemeinwissen sein, aber aus der Perspektive von jemandem, der sich praxisorientiertes Machine Learning autodidaktisch beigebracht hat, war es ein intensiver „Aha!“-Moment zu sehen, wie dieses Thema bis in Bereiche wie Teilchenphysik und Kosmologie hineinreicht.
Ich lasse das hier stehen, in der Hoffnung, dass wenigstens eine Person zu derselben Erkenntnis kommt.
Ziemlich beeindruckend fand ich die Erkenntnis, dass die ursprüngliche Lempel-Ziv-Kompression, eine der Grundlagen von gzip, nicht einfach aus dem Versuch entstand, Dinge kleiner zu machen, sondern aus der Forschung zur „Komplexität endlicher Folgen“.
https://ieeexplore.ieee.org/document/1055501
Fairerweise muss man sagen: MNIST wird schon fast perfekt getrennt, wenn man es nur durch UMAP schickt.
Ich denke, heutzutage muss man sich bei MNIST schon ziemlich anstrengen, um schlechte Ergebnisse zu bekommen.
https://github.com/lmcinnes/umap_paper_notebooks/blob/master...
Es wäre wohl besser, diesen Datensatz endlich in den Ruhestand zu schicken; Datensätze wie QuickDraw ergeben deutlich mehr Sinn.
An sich ist das schwerlich eine große Leistung, aber es ist trotzdem interessant zu sehen, dass es funktioniert.
Wenn ich zu Hause bin, werde ich im Artikel ergänzen, dass MNIST vergleichsweise leicht zu lösen ist.
Trotzdem erreichen die meisten einfachen und vernünftigen Algorithmen 97 % Genauigkeit, daher hat es als Lehrmittel oder als Hello-World-Datensatz weiterhin Wert.
Selbst wenn man die Werkzeuge von Grund auf selbst baut, passt es vom Umfang her zu einer Hausaufgabe, und es ist eine nützliche Aufgabe, die jeder versteht, etwa „Ziffernerkennung auf Postsendungen“.
Wenn man Kompression versteht, ist auch dieser Ansatz eine sehr einfache Idee; man hätte ihn schon am ersten Tag der Veröffentlichung von MNIST schreiben können und wäre trotzdem auf 78 % Genauigkeit gekommen.
Das finde ich ziemlich erstaunlich.
Auch das Repository definiert UMAP nicht, aber wenn man ChatGPT glaubt, steht UMAP für Uniform Manifold Approximation and Projection, eine Technik zur Dimensionsreduktion und Visualisierung, die in Machine Learning und Datenanalyse verwendet wird.
Ich beschäftige mich mit diesem Gebiet nur hobbymäßig, aber stark komprimierte Daten haben doch, ähnlich wie verschlüsselte Daten, eine hohe Entropie, oder?
Wenn man in komprimierten Daten Muster findet, um die ursprüngliche Ziffer zu erkennen, müsste man diese Muster dann nicht für eine bessere Kompression nutzen können?
Die Idee ist: „7 7“ sollte sich besser komprimieren lassen als „7 3“, und auch bei Rasterbildern sollte sich „7 7“ besser komprimieren lassen als „7 3“.
Nichtkomprimierbarkeit ist ein Merkmal effizienter kryptografischer Operationen.
Siehe den Abschnitt zur Kompression im Artikel zur Kolmogorow-Komplexität: https://en.wikipedia.org/wiki/Kolmogorov_complexity#Compress...
Eines meiner Lieblingskonzepte bei Kompression ist das Schubfachprinzip: Für jeden Kompressionsalgorithmus gibt es zwangsläufig Ausgaben, die größer sind als die Eingaben.
Auch bei gut entworfenen verschlüsselten Payloads kann man versuchen, sie zu komprimieren, aber im Durchschnitt wird die Ausgabe größer als die Eingabe, wodurch Kompression nutzlos wird; deshalb nennt man sie „nicht komprimierbar“.
https://en.wikipedia.org/wiki/Pigeonhole_principle#Uses_and_...
Ich glaube, vor ein paar Jahren gab es einen Fall, in dem die Größe von MNIST-Bildern als „Meta-Feature“ verwendet wurde, aber ich kann ihn auf die Schnelle nicht finden.
Soweit ich mich erinnere, kam man allein mit diesem einen Feature, ohne die Bilder überhaupt anzusehen, ungefähr auf eine Genauigkeit von um die 90 %.
Die mit gzip komprimierte Größe? Wenn man nur betrachtet, wie dunkel ein MNIST-Bild ist, also den Anteil dunkler Pixel, kommt man auf etwa 20 % Genauigkeit – doppelt so gut wie Zufall, aber weit entfernt von 90 %.
Ich vermute, die Autoren des Papers haben einen Fehler gemacht, wodurch die Ergebnisse in den oberen Bereich des Benchmarks geschossen sind.
Seit diesem Vorfall hielt ich die Theorie für inkonsistent, aber 78 % Genauigkeit nur mit GZIP sind trotzdem beeindruckend.
Unabhängig davon, ob dieses Problem ein guter Anwendungsfall für Kompressionstricks ist: Wer damit experimentiert, sollte aufhören,
gzipzu verwenden, und stattdessenzlibnutzen.Wenn man in der ersten Zeile
gzip.compressdurchzlib.compressersetzt, bekommt man bei gleicher Klassifikationsleistung eine dreimal höhere Geschwindigkeit.