Ich schätze, ich bin auf einer Mission, einer Mission, die Ehrfurcht, die die Menschen in Bezug auf KI zu empfinden scheinen, zu mildern.
Da ich mich mit Optik beschäftige, schreibe ich eine Menge Code, alle möglichen Arten von Code, und natürlich bin ich daran interessiert, so wenig Zeit wie möglich damit zu verbringen.
Bevor ich die Zernike-Darstellung mit der OpenGL-Pipeline zu meiner eigenen Plattform hinzufügte, bat ich ChatGPT, eine für mich zu schreiben. Das war vor 18 Monaten.
Unnötig zu sagen, dass ich das Ergebnis unbrauchbar fand. Warum? Wie schon bei meinem vorherigen Beitrag sah der Code aus der Ferne gut aus, aber in den nicht so tiefen Details war er unbrauchbar. Lassen Sie mich Ihnen zeigen, was ich meine.
Berechnung von Zernike-Polynomen
Bei der Berechnung von Zernike-Polynomen müssen Sie das radiale Polynom (das den Abstand zum Mittelpunkt für eine durch x und y gegebene Koordinate als Parameter hat) und entweder Sinus oder Kosinus des Winkels berechnen. Ich möchte Sie, die Sie nicht mit der KI Jagernaut konkurrieren können, fragen: Wenn Sie bereits den Abstand (die Hypotenuse eines Dreiecks) anhand der Koordinaten x und y berechnet haben, wie gehen Sie dann vor, um Sinus und Kosinus des Winkels zu berechnen?
Ich denke, 100% von euch, die bis hierher gelesen haben, tun das, indem sie x und y durch die Hypotenuse teilen. Was bedeutet die neueste und beste KI tun? Es nimmt die Koordinaten und berechnet den Winkel mit Hilfe des inversen Tangens und, wie Sie vielleicht schon erraten haben, verwendet es den Winkel, um Sinus und Kosinus zu berechnen.
All diese Energie für was?
Das war das Ergebnis, das ich vor 18 Monaten gesehen habe, und 300 GWh (allein für die GPUs, dann noch Kühlung, Vernetzung) oder 90 Tage Reinforcement Learning später haben wir genau das gleiche Ergebnis.
Hier ist kaum ein Fünkchen Intelligenz vorhanden. Es handelt sich lediglich um eine rein textliche Übersetzung von Lehrbuchmaterial in eine andere Form von Text.
Ich habe versucht, die Aufmerksamkeit auf die logarithmische Rendite der KI-Leistung im Vergleich zur Rechenleistung zu lenken. Angesichts dessen würde ich jederzeit den logarithmischen Wert nehmen, denn ich sehe keine Verbesserung.
Natürlich habe ich dem ehrfürchtigen DeepSeek die gleiche Frage gestellt, und tatsächlich (ich mache nur Spaß) war das Ergebnis noch schlechter. Nicht viel, denn es ist schwierig, schlechteren Code als diesen zu produzieren.
Wenn Sie selbst testen wollen, hier ist meine Aufforderung:
Können Sie einen OpenGL-Shader schreiben, der eine 2D-Dichtekarte auf der Grundlage eines Vektors von Zernike-Koeffizienten erzeugt? Das Ergebnis ist unten dargestellt.
uniform vec2 resolution; // Screen resolution
uniform float zernikeCoeffs[15]; // Array of Zernike coefficients (adjust size as needed)
uniform float scale; // Scaling factor for the density map
// Convert cartesian (x,y) to polar (rho, theta)
vec2 cartesianToPolar(vec2 xy) {
float rho = length(xy);
float theta = atan(xy.y, xy.x);
return vec2(rho, theta);
}
// Zernike radial polynomial function
float radialPoly(int n, int m, float rho) {
float result = 0.0;
m = abs(m);
if ((n - m) % 2 != 0) return 0.0;
for (int k = 0; k <= (n - m) / 2; k++) {
float coef = 1.0;
// Calculate binomial coefficient
for (int i = 1; i <= k; i++) {
coef *= float(n - 2 * k + i) / float(i);
}
for (int i = 1; i <= (n - m) / 2 - k; i++) {
coef *= float(m + i) / float(i);
}
result += pow(-1.0, float(k)) * coef * pow(rho, float(n - 2 * k));
}
return result;
}
// Zernike polynomial evaluation
float zernike(int index, vec2 polar) {
float rho = polar.x;
float theta = polar.y;
// Zernike polynomial ordering (n,m): (0,0), (1,-1), (1,1), (2,-2), (2,0), etc.
int n, m;
if (index == 0) { n = 0; m = 0; } // Z0,0
else if (index == 1) { n = 1; m = -1; } // Z1,-1
else if (index == 2) { n = 1; m = 1; } // Z1,1
else if (index == 3) { n = 2; m = -2; } // Z2,-2
else if (index == 4) { n = 2; m = 0; } // Z2,0
else if (index == 5) { n = 2; m = 2; } // Z2,2
else if (index == 6) { n = 3; m = -3; } // Z3,-3
else if (index == 7) { n = 3; m = -1; } // Z3,-1
else if (index == 8) { n = 3; m = 1; } // Z3,1
else if (index == 9) { n = 3; m = 3; } // Z3,3
else return 0.0;
if (rho > 1.0) return 0.0; // Zernike defined only within unit disk
float radial = radialPoly(n, m, rho);
if (m < 0) return radial * sin(float(-m) * theta);
else return radial * cos(float(m) * theta);
}
void main() {
// Normalize coordinates to [-1, 1] range centered at (0,0)
vec2 uv = (gl_FragCoord.xy - resolution.xy * 0.5) / (resolution.y * 0.5);
vec2 polar = cartesianToPolar(uv);
// Calculate wavefront aberration by summing Zernike terms
float density = 0.0;
for (int i = 0; i < 15; i++) {
density += zernikeCoeffs[i] * zernike(i, polar);
}
// Scale and convert to visible range
density *= scale;
float value = (density + 1.0) * 0.5; // Map [-1,1] to [0,1]
value = clamp(value, 0.0, 1.0);
// Output as grayscale density map
FragColor = vec4(vec3(value), 1.0);
}
Kommentar verfassen