| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung |
| p:ki:fische3 [2025/11/04 10:05] – Ralf Kretzschmar | p:ki:fische3 [2026/04/20 16:32] (aktuell) – [5. Aber was bedeutet das nun für Sigrún?] Ralf Kretzschmar |
|---|
| In der nebenstehenden Abbildung siehst du mehrere Decision Boundaries. Jede Zeile zeigt dieselbe Decsion Boundary zweimal, einmal mit dem Training Set und einmal mit dem Validation Set. | In der nebenstehenden Abbildung siehst du mehrere Decision Boundaries. Jede Zeile zeigt dieselbe Decsion Boundary zweimal, einmal mit dem Training Set und einmal mit dem Validation Set. |
| * Oberste Zeile: Die lineare Decision Boundary vermag die Fischsorten nicht gut zu trennen. Der "Trainingsfehler" und der "Validationsfehler" sind beide hoch. | * Oberste Zeile: Die lineare Decision Boundary vermag die Fischsorten nicht gut zu trennen. Der "Trainingsfehler" und der "Validationsfehler" sind beide hoch. |
| * Unterste Zeile: Die Decision Boundary wurde stark von den einzelnen Trainingsfischen beeinflusst, d.h. die Trainingsfische wurden "auswendig gelernt". Daher ist der Trainingsfehler klein, jedoch der Validationsfehler gross. Vermutlich werden künftige Fische ähnlich schlecht wie die Validationsfische erkannt werden. | * Unterste Zeile: Die Decision Boundary wurde stark von den einzelnen Trainingsfischen beeinflusst, d. h., die Trainingsfische wurden "auswendig gelernt". Daher ist der Trainingsfehler klein, jedoch der Validationsfehler gross. Vermutlich werden künftige Fische ähnlich schlecht wie die Validationsfische erkannt werden. |
| * Mittlere Zeile: Die Decision Boundary hat den groben Zusammenhang zwischen Hering und Lodde recht gut erfasst. Die Trainings- und Validationsfehler sind ähnlich klein. Vermutlich werden künftige Fische ähnlich gut erkannt werden. | * Mittlere Zeile: Die Decision Boundary hat den groben Zusammenhang zwischen Hering und Lodde recht gut erfasst. Die Trainings- und Validationsfehler sind ähnlich klein. Vermutlich werden künftige Fische ähnlich gut erkannt werden. |
| |
| |
| ; Generalisierung und Overfitting | ; Generalisierung und Overfitting |
| : Sind Trainings- und Validationsfehler ungefähr gleich, so wird von einer hohen **Generalisierung** gesprochen. Ist der Validationsfehler deutlich grösser, so hat ein **Overfitting** der Training Data stattgefunden, d.h. die Trainingsfische wurden auswendig gelernt. | : Sind Trainings- und Validationsfehler ungefähr gleich, so wird von einer hohen **Generalisierung** gesprochen. Ist der Validationsfehler deutlich grösser, so hat ein **Overfitting** der Training Data stattgefunden, d. h., die Trainingsfische wurden auswendig gelernt. |
| |
| ⚠️ Das Ziel besteht darin, bei einer guten Generalisierung einen möglichst tiefen Fehler zu erhalten (und Overfitting zu vermeiden). | ⚠️ Das Ziel besteht darin, bei einer guten Generalisierung einen möglichst tiefen Fehler zu erhalten (und Overfitting zu vermeiden). |
| ===== - Künstliche Intelligenz – bitte übernehmen! ====== | ===== - Künstliche Intelligenz – bitte übernehmen! ====== |
| |
| 🤔 Eine Decision Boundary von Hand zu zeichnen und die falschen Fische von Auge zu zählen ist mühsam. | 🤔 Eine Decision Boundary von Hand zu zeichnen und die falschen Fische von Auge zu zählen, ist mühsam. |
| |
| 😎 Glücklicherweise kann das der Computer übernehmen. Das Stichwort hierfür heisst künstliche Intelligenz - das Programm soll selber lernen, welche Decision Boundary die beste ist. | 😎 Glücklicherweise kann das der Computer übernehmen. Das Stichwort hierfür heisst künstliche Intelligenz - das Programm soll selber lernen, welche Decision Boundary die beste ist. |
| <WRAP center round box > | <WRAP center round box > |
| == ✍ Auftrag == | == ✍ Auftrag == |
| 💡 Das nachfolgende Programm nutzt ein **neuronales Netz**, um Hering von Lodde zu trennen((Im Programm wurde das Neuronale-Netz-Framework [[https://www.tensorflow.org/js|TensorFlow.js]] verwendet)). Neuronale Netze werden zu den Verfahren der **künstlichen Intelligenz** gezählt. Das neuronale Netz "lernt" mithilfe des Training Sets in mehreren **Epochen** ("Lernrunden") eine immer bessere Decision Boundary zu zeichnen. Dieser Prozess wird als **Training** bezeichnet. Dabei wird die Güte der Decision Boudary regelmässig mit dem Validation Set überprüft. Dieser Prozess wird als **Validation** bezeichnet. | 💡 Das nachfolgende Programm nutzt ein **neuronales Netz**, um Hering von Lodde zu trennen((Im Programm wurde das Neuronale-Netz-Framework [[https://www.tensorflow.org/js|TensorFlow.js]] verwendet)). Neuronale Netze werden zu den Verfahren der **künstlichen Intelligenz** gezählt. Das neuronale Netz "lernt" mithilfe des Training Sets in mehreren **Epochen** ("Lernrunden") eine immer bessere Decision Boundary zu zeichnen. Dieser Prozess wird als **Training** bezeichnet. Dabei wird die Güte der Decision Boundary regelmässig mit dem Validation Set überprüft. Dieser Prozess wird als **Validation** bezeichnet. |
| |
| ⚠️ Die %-Angabe in den Grafiken bezeichnet den Anteil richtig erkannter Fische (zusätzlich wird in Klammern die Anzahl falsch erkannter Fische angegeben). Der ''mse'' Wert in der Console ist ein Fehlermass, das vom neuronalen Netz für das Training genutzt wird. Je kleiner der ''mse'', desto besser. | ⚠️ Die %-Angabe in den Grafiken bezeichnet den Anteil richtig erkannter Fische (zusätzlich wird in Klammern die Anzahl falsch erkannter Fische angegeben). Der ''mse''-Wert in der Console ist ein Fehlermass, das vom neuronalen Netz für das Training genutzt wird. Je kleiner der ''mse'', desto besser. |
| |
| 🚨 Training manuell stoppen: In die Grafik klicken und ''ESC'' drücken. | 🚨 Training manuell stoppen: In die Grafik klicken und ''ESC'' drücken. |
| - Starte das nachfolgende Programm mit ''▶Run''. Der erste Start kann etwas dauern. Wenn alles klappt, so "faltet" sich die Decision Boundary langsam in die Trainingsdaten hinein. Notiere dir am Ende den Anteil richtig erkannter Fische und den mse beides für Training und Validation. {{gem/plain?0=N4XyA#626808271a9b17be}} | - Starte das nachfolgende Programm mit ''▶Run''. Der erste Start kann etwas dauern. Wenn alles klappt, so "faltet" sich die Decision Boundary langsam in die Trainingsdaten hinein. Notiere dir am Ende den Anteil richtig erkannter Fische und den mse beides für Training und Validation. {{gem/plain?0=N4XyA#626808271a9b17be}} |
| - Starte das Programm erneut und notiere dir wiederum den Anteil richtig erkannter Fische und den mse bezüglich Training und Validation. {{gem/plain?0=N4XyA#c8dcd0136aafd540}} | - Starte das Programm erneut und notiere dir wiederum den Anteil richtig erkannter Fische und den mse bezüglich Training und Validation. {{gem/plain?0=N4XyA#c8dcd0136aafd540}} |
| - Vergleiche die Zahlen in den beiden obigen Textfeldern. Sind diese identisch oder unterschiedlich? Lies danach:\\ ++diese Erklärung.|\\ \\ Am Anfang jedes Trainings wird zuerst eine zufällige Decision Boundary erzeugt. Ausgehend von dieser "schlechten" Decision Boundary versucht das neuronale Netz immer bessere Decision Boundaries zu zeichnen. Aufgrund der zufälligen Wahl der Decision Boundary verläuft jedes Training anders und führt zu einem anderen Resultat.\\ \\ ++ | - Vergleiche die Zahlen in den beiden obigen Textfeldern. Sind diese identisch oder unterschiedlich? Lies danach:\\ ++diese Erklärung.|\\ \\ Am Anfang jedes Trainings wird zuerst eine zufällige Decision Boundary erzeugt. Ausgehend von dieser "schlechten" Decision Boundary versucht das neuronale Netz, immer bessere Decision Boundaries zu zeichnen. Aufgrund der zufälligen Wahl der Decision Boundary verläuft jedes Training anders und führt zu einem anderen Resultat.\\ \\ ++ |
| - Starte das Programm mehrfach. Dabei darfst du auch die folgenden Parameter am Anfang des Programmcodes ändern: | - Starte das Programm mehrfach. Dabei darfst du auch die folgenden Parameter am Anfang des Programmcodes ändern: |
| * ''LERNRATE'': Legt fest, wie stark sich die Decision Boundary pro Epoche ändern darf. Ist der Wert zu hoch, springt die Decision Boundary hin und her, ist der Wert zu tief, brauchst du viel Geduld… | * ''LERNRATE'': Legt fest, wie stark sich die Decision Boundary pro Epoche ändern darf. Ist der Wert zu hoch, springt die Decision Boundary hin und her. Ist der Wert zu tief, brauchst du viel Geduld … |
| * ''ANZAHL_HIDDEN_NEURONS'': Bestimmt die Komplexität der Decision Boundary. Ist der Wert zu hoch, kann Overfitting auftreten, ist die Zahl zu klein, können die Fische nicht gut getrennt werden. | * ''ANZAHL_HIDDEN_NEURONS'': Bestimmt die Komplexität der Decision Boundary. Ist der Wert zu hoch, kann Overfitting auftreten, ist die Zahl zu klein, können die Fische nicht gut getrennt werden. |
| * ''ANZAHL_EPOCHEN'': Legt die Anzahl der Epochen fest. Ist der Wert zu klein, so kann das neuronale Netz nicht genügend lernen. Ist der Wert zu hoch, brauchst du viel Geduld... | * ''ANZAHL_EPOCHEN'': Legt die Anzahl der Epochen fest. Ist der Wert zu klein, so kann das neuronale Netz nicht genügend lernen. Ist der Wert zu hoch, brauchst du viel Geduld … |
| * ''EPOCHEN_FUER_GRAFIK_UPDATE'': Legt fest, nach wie vielen Epochen die Grafik jeweils aktualisiert wird. | * ''EPOCHEN_FUER_GRAFIK_UPDATE'': Legt fest, nach wie vielen Epochen die Grafik jeweils aktualisiert wird. |
| - Halte deine Rekorde für die Anteile richtig erkannter Fische und den mse für Training und Validation fest. {{gem/plain?0=N4XyA#1ec2fc568fb48b2d}} | - Halte deine Rekorde für die Anteile richtig erkannter Fische und den mse für Training und Validation fest. {{gem/plain?0=N4XyA#1ec2fc568fb48b2d}} |
| ; 🕸️ Neuronale Netze: Beschreibung und Einsatzgebiete | ; 🕸️ Neuronale Netze: Beschreibung und Einsatzgebiete |
| : \\ **Neuronale Netze** sind einfache Nachbildungen des **menschlichen Gehirns** 🧠. Sie bestehen aus mehreren miteinander verbundenen **künstlichen Neuronen** (das sind einfache Nachbildungen von Gehirnzellen). Das Praktische an neuronalen Netzen ist, sie können auf einem Computer erstellt und genutzt werden. | : \\ **Neuronale Netze** sind einfache Nachbildungen des **menschlichen Gehirns** 🧠. Sie bestehen aus mehreren miteinander verbundenen **künstlichen Neuronen** (das sind einfache Nachbildungen von Gehirnzellen). Das Praktische an neuronalen Netzen ist, sie können auf einem Computer erstellt und genutzt werden. |
| : Neuronale Netze sind (noch?) nicht in der Lage, das menschliche Gehirn vollständig nachzuahmen. Sie eignen sich jedoch relativ gut dafür, Muster zu erkennen und werden daher in verschiedenen Feldern der Forschung und Industrie eingesetzt (z.B. Gesichtserkennung, Bildkorrektur, Sprachübersetzung, Chatbots, Diagnosen in der Medizin). | : Neuronale Netze sind (noch?) nicht in der Lage, das menschliche Gehirn vollständig nachzuahmen. Sie eignen sich jedoch relativ gut dafür, **Muster zu erkennen** und werden daher in verschiedenen Feldern der Forschung und Industrie eingesetzt (z.B. Gesichtserkennung, Bildkorrektur, Sprachübersetzung, Chatbots, Diagnosen in der Medizin). |
| |
| <WRAP clear/> | <WRAP clear/> |
| |
| ; 🕸️ Neuronale Netze: Daten und Training | ; 🕸️ Neuronale Netze: Daten und Training |
| :\\ Von jedem Fisch 🐟 kennen wir seine beiden Messwerte und die Klasse, zu welcher dieser gehört. Für Hering legen wir fest, dass das neuronale Netz die Zahl ''0'' ausgeben soll und für Lodde die Zahl ''1''. Diese beiden Zahlen werden als **Desired Output** (erwünschte Ausgabewerte) bezeichnet. | :\\ Von jedem Fisch 🐟 kennen wir seine beiden Messwerte und die Klasse, zu welcher dieser gehört. Für Hering legen wir fest, dass das neuronale Netz die Zahl ''0'' ausgeben soll, und für Lodde die Zahl ''1''. Diese beiden Zahlen werden als **Desired Output** (erwünschte Ausgabewerte) bezeichnet. |
| : Für das Training schnappen wir uns den ersten Trainingsfisch. Nehmen wir an, es sei ein Hering. Seine beiden Messwerte werden in das neuronale Netz eingegeben. Daraus berechnet das neuronale Netz einen Ausgabewert, der bei unserem neuronalen Netz zwischen 0 und 1 liegt. Sagen wir, das neuronale Netz gibt 0.3 aus. Aus der Differenz des Ausgangswerts 0.3 und dem Desired Output für Heringe 0 wird ein Fehler berechnet. Das wird für alle Fische im Training Set wiederholt. Wenn der Gesamtfehler am Ende "gross" ist, werden die Gewichte "stark" angepasst, wenn der Fehler "klein" ist, werden die Gewichte nur "leicht" angepasst. Jede solche Wiederholung wird als **Epoche** bezeichnet. | : Für das Training schnappen wir uns den ersten Trainingsfisch. Nehmen wir an, es sei ein Hering. Seine beiden Messwerte werden in das neuronale Netz eingegeben. Daraus berechnet das neuronale Netz einen Ausgabewert, der bei unserem neuronalen Netz zwischen 0 und 1 liegt. Sagen wir, das neuronale Netz gibt 0.3 aus. Aus der Differenz des Ausgangswerts 0.3 und dem Desired Output für Heringe 0 wird ein Fehler berechnet. Das wird für alle Fische im Training Set wiederholt. Wenn der Gesamtfehler am Ende "gross" ist, werden die Gewichte "stark" angepasst. Wenn der Fehler "klein" ist, werden die Gewichte nur "leicht" angepasst. Jede solche Wiederholung wird als **Epoche** bezeichnet. |
| |
| ; 🕸️ Neuronale Netze: Anwenden | ; 🕸️ Neuronale Netze: Anwenden |
| :\\ Ist das neuronale Netz fertig trainiert, werden die Gewichte nicht mehr geändert. Das neuronale Netz kann nun für die Fischklassifikation verwendet werden. Dazu wird ein unbekannter Fisch 🐠 genommen und seine Messwerte dem neuronalen Netz eingegeben. Das neuronale Netz produziert daraufhin eine Zahl zwischen 0 und 1. Angenommen die Ausgabe ist 0.7, was bedeutet das? Das Einfachste ist das Folgende. Wir legen fest, ein Ausgabewert < 0.5 wird als Hering erkannt und ein Ausgabewert ≥ 0.5 als Lodde. Somit wird der unbekannte Fisch als Lodde erkannt. Der Grenzwert (in unserem Beispiel 0.5) wird als **Threshold** bezeichnet. | :\\ Ist das neuronale Netz fertig trainiert, werden die Gewichte nicht mehr geändert. Das neuronale Netz kann nun für die Fischklassifikation verwendet werden. Dazu wird ein unbekannter Fisch 🐠 genommen und seine Messwertewerden demm neuronalen Netz eingegeben. Das neuronale Netz produziert daraufhin eine Zahl zwischen 0 und 1. Angenommen, die Ausgabe ist 0.7, was bedeutet das? Das Einfachste ist das Folgende. Wir wählen den **Grenzwert** 0.5. Ein Ausgabewert < 0.5 wird als Hering erkannt und ein Ausgabewert ≥ 0.5 als Lodde. Somit wird der unbekannte Fisch als Lodde erkannt. |
| |
| <WRAP center round box > | <WRAP center round box > |
| |
| == ✍ Auftrag == | == ✍ Auftrag == |
| - Ersetze im Text die ''🐟'' in den ''%%[🐟]%%'' durch folgende Wörter, welche du natürlich grammatikalisch an den Text anpasst:\\ ''Epoche'', ''Gehirn'', ''Gewicht'', ''Hering'', ''Hidden'', ''Input'', ''Lodde'', ''Muster'', ''Output'', ''Training Set'', ''Threshold''. \\ ⚠️ Jedes Wort wird nur einmal gebraucht, die ''['' '']'' sollten stehen gelassen werden, dann ist auch nach dem Ausfüllen klar, wo die Lücke war. | - Ersetze im Text die ''🐟'' in den ''%%[🐟]%%'' durch folgende Wörter, welche du natürlich grammatikalisch an den Text anpasst:\\ ''Epoche'', ''Gehirn'', ''Gewicht'', ''Hering'', ''Hidden'', ''Input'', ''Lodde'', ''Muster'', ''Output'', ''Training Set'', ''Grenzwert''. \\ ⚠️ Jedes Wort wird nur einmal gebraucht, die ''['' '']'' sollten stehen gelassen werden, dann ist auch nach dem Ausfüllen klar, wo die Lücke war. |
| {{gem/match?0=N4IgLgpgHmIFwgKIEsB2ACVECuAnA9qgIYA2EAzugHIRgBe6y5Y6EaE1RAxgBYBGyEgBNsqAObohFdAFsIqcrxLJe89AG1AvBuB8HYC6AGnQB3CCVXoi2AGat2M9AGF8MgA7ZIuVrmamSLUULoYvLudCwmuFIYANZEqKgAdOiIlEwsfBSEUt5B7pJEuGgaOrrodNhe0fJYiQA6qPUAIkSUAG6E6KJtELgmqFKQmDgExGTUtAwZ5Mj0LHQmyMV643iE8oZyPLg9HFrLNKs1nf22GHulByNJKeguBCJ0yD0sAILY5GJxYuQRg-NMqgwAAZjoEAIxJF4kMYAMQBPAghisAB-PEInqd0G8Pl8fs90NEyOxPKRKNklqUABRAhIAVgAlBZ3sFghkMEZkJFDBEohYSJRzpU4qgwIZSGM4tk1HDFAjjD1eaSKUL4mAEvV6jDUflKAAVXBENBoCQ8tTo3YlSTSLCHUhqGj0aTlKwAE+hyAkwSMLp4fiSzWIvGMnMCKM8ACsILyZUHkPZBWwMDCIL6ekyPjteFg1egAEItJ7bE5CAqWGymjDm9AAcQgHN4gy+EBcLWYoKtngAavhcJ9xMHIrIU9ttsqSF9g1Gejx8H6QPoQFZx994CBkPOQNtglAXKuEgAqWs8ZAHgCy7zV+41iX3AElUG4DwAJZBCIQHgDy7hcB91Wwgz49Ce+4ADL4G+B7XgetYcr+BpoAeiAuPgXAHiAAC+QA#eabdce03d12ad3bd}} | {{gem/match?0=N4IgLgpgHmIFwgKIEsB2ACVECuAnA9qgIYA2EAzugHIRgBe6y5Y6EaE1RAxgBYBGyEgBNsqAObohFdAFsIqcrxLJe89AG1AvBuB8HYC6AGnQB3CCVXoi2AGat2M9AGF8MgA7ZIuVrmamSLUULoYvLudCwmuFIYANZEqKgAdOiIlEwsfBSEUt5B7pJEuGgaOrrodNhe0fJYiQA6qPUAIkSUAG6E6KJtELgmqFKQmDgExGTUtAwZ5Mj0LHQmyMV643iE8oZyPLg9HFrLNKs1nf22GHulByNJKeguBCJ0yD0sAILY5GJxYuQRg-NMqgwAAZjoEAIxJF4kMYAMQBPAghisAB-PEInqd0G8Pl8fs90NEyOxPKRKNklqUABRAhIAVgAlBZ3sFghkMEZkJFDBEohYSJRzpU4qgwIZSGM4tk1HDFAjjD1eaSKUL4mAEvV6jDUflKAAVXBENBoCQ8tTo3YlSTSLCHUhqGj0aTlKwAE+hyAkwSMLp4fiSzWIvGMnMCKM8ACsILyZUHkPZBWwMDCIL6ekyPjteFg1egAEItJ7bE5CAqWGymjDm9AAcQgHN4gy+EBcLWYoKtngAavhcJ9xMHIrIU9ttsqSF9g1Gejx8H6QPoQFZx994CBkPOQNtglAXKuEgAqWs8ZAHgCy7zV+41iX3AElUG4DwAJZBCIQHgDy7hcB+rRboz49Ce+4ADL4G+B7Xr+dbAfqho3ogLj4FwB4gAAvkAA#eabdce03d12ad3bd}} |
| </WRAP> | </WRAP> |
| |
| | <WRAP center round box > |
| | == ✍ Auftrag "Black Box" == |
| | 💡 Das Wissen eines neuronalen Netzes ist in seinen Gewichten gespeichert. Die Gewichte sind jedoch für uns Menschen schwer zu verstehen. Daher werden neuronale Netze auch als "Black Box" bezeichnet. Hier machst du dir selbst ein Bild davon, warum das so ist. |
| | - Verschiebe als Erstes den vertikalen, grauen Strich in der Mitte mit der Maus, so dass du die Grafikausgabe inklusive der drei Buttons vollständig siehst (im Programmcode gibt es diesmal nichts zu ändern). |
| | - Die Abbildung des neuronalen Netzes ist hier etwas anders gezeichnet. Die schwarzen, kleinen Neuronen geben immer den Wert 1 weiter. Diese wurden bisher zur Vereinfachung weggelassen. Jede Linie stellt ein Gewicht dar. Das hier verwendete neuronale Netz mit drei Hidden-Neuronen hat 13 Gewichte. Deren Werte können mit den 13 Schiebereglern geändert werden. |
| | - Spiele mit den Reglern etwas herum. Über den Button ''🔄 Reset'' kommst du zur Anfangseinstellung zurück. Findest du heraus welcher Regler für was genau zuständig ist und wie durch das Zusammenspiel der Regler ein gutes Resultat erzielt werden kann? |
| | - Teste danach deine Einsichten, indem du auf den ''Random''-Button klickst. Dadurch werden die Gewichte zufällig eingestellt. Kannst du jetzt mit deinen Erkenntnissen durch gezieltes Verschieben der Regler wiederum ein gutes Resultat erzielen? |
| | - Noch herausfordernder ist dasselbe, wenn du auf den ''Zero''-Button klickst. Dadurch werden alle Gewichte auf ''0.0'' eingestellt. |
| | - Lies danach ++diese Erklärung.|\\ \\ Uns war es in vernünftiger Zeit nicht gelungen, eindeutig herauszufinden, welcher Regler was genau bewirkt und wie zielgerichtet mit allen Reglern zusammen ein gutes Resultat eingestellt werden kann.\\ \\ Wenn man bedenkt, dass dieses neuronale Netz 13 Gewichten hat und ein aktueller KI-Chatobt in der Grössenordnung von 1 Billionen Gewichte besitzt, ist aus unserer Sicht der Ausdruck "Black Box" für ein neuronales Netz passend.\\ \\ Faszinierend, dass es Algorithmen gibt, welche selbständig in diesem "Wirrwarr" nach guten Gewichten suchen können, oder?\\ \\ ++ |
| | - Markiere diesen Auftrag als erledigt. {{ gem/flag?label=Erledigt&icon=%E2%9C%8D#2a9cf89c7c8be05e}} |
| | {{exorciser/jspg?javascript=%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%2F%2F%20CONSTANTS%20AND%20GLOBAL%20VARIABLES%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%0Aconst%20MIN_WEIGHT%20%3D%20-5.0%3B%0Aconst%20MAX_WEIGHT%20%3D%205.0%3B%0Aconst%20SLIDER_STEP%20%3D%200.1%3B%0Aconst%20ANZAHL_HIDDEN_NEURONS%20%3D%203%3B%0A%0Aconst%20STATIC_INITIAL_WEIGHTS%20%3D%20%7B%0A%20%20w11%3A%20%5B1.9025458097457886%2C%20-1.6482696533203125%2C%204.451645374298096%5D%2C%0A%20%20w12%3A%20%5B-2.826908588409424%2C%20-2.5485761165618896%2C%202.1593072414398193%5D%2C%0A%20%20b1%3A%20%5B-0.3300899565219879%2C%202.8926424980163574%2C%20-1.6070349216461182%5D%2C%0A%20%20w2%3A%20%5B-4.269681930541992%2C%20-3.927882194519043%2C%20-4.3639044761657715%5D%2C%0A%20%20b2%3A%201.3493579626083374%2C%0A%7D%3B%0A%0Aconst%20DATA_RANGE%20%3D%2010%3B%0Aconst%20DATA_WINDOW_SIZE%20%3D%20200%3B%0Aconst%20DATA_SCALE%20%3D%20Math.round%28DATA_WINDOW_SIZE%20%2F%20DATA_RANGE%29%3B%0Aconst%20NUM_DATA_PIXEL%20%3D%2050%3B%0Aconst%20PIXEL_SIZE%20%3D%20Math.round%28DATA_WINDOW_SIZE%20%2F%20NUM_DATA_PIXEL%29%3B%0Aconst%20NN_PANEL_WIDTH%20%3D%20DATA_WINDOW_SIZE%3B%0A%0A%2F%2F%20training%20data%0Aconst%20trainInputArray%20%3D%20%5B%0A%20%20%5B2.5%2C%206.0%5D%2C%0A%20%20%5B3.5%2C%201.5%5D%2C%0A%20%20%5B3.5%2C%204.0%5D%2C%0A%20%20%5B4.0%2C%206.0%5D%2C%0A%20%20%5B4.0%2C%207.0%5D%2C%0A%20%20%5B4.5%2C%203.0%5D%2C%0A%20%20%5B5.0%2C%205.0%5D%2C%0A%20%20%5B5.5%2C%206.0%5D%2C%0A%20%20%5B6.5%2C%203.0%5D%2C%0A%20%20%5B7.0%2C%205.5%5D%2C%0A%20%20%5B7.5%2C%204.0%5D%2C%0A%20%20%5B8.5%2C%205.5%5D%2C%0A%20%20%5B1.5%2C%203.0%5D%2C%0A%20%20%5B1.5%2C%204.5%5D%2C%0A%20%20%5B1.5%2C%207.0%5D%2C%0A%20%20%5B2.0%2C%201.5%5D%2C%0A%20%20%5B3.0%2C%203.0%5D%2C%0A%20%20%5B3.0%2C%205.5%5D%2C%0A%20%20%5B3.0%2C%206.5%5D%2C%0A%20%20%5B4.0%2C%208.5%5D%2C%0A%20%20%5B4.5%2C%206.5%5D%2C%0A%20%20%5B6.5%2C%207.5%5D%2C%0A%20%20%5B8.0%2C%206.5%5D%2C%0A%20%20%5B8.0%2C%208.5%5D%2C%0A%5D%3B%0A%0Aconst%20trainOutputArray%20%3D%20%5B%0A%20%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%0A%5D%3B%0A%0Aconst%20trainInputMax%20%3D%20%5B9.0%2C%208.5%5D%3B%0Aconst%20trainInputMin%20%3D%20%5B1.5%2C%201.5%5D%3B%0A%0A%2F%2F%20validation%20data%0Aconst%20validInputArray%20%3D%20%5B%0A%20%20%5B2.5%2C%207.0%5D%2C%0A%20%20%5B3.5%2C%201.0%5D%2C%0A%20%20%5B3.5%2C%207.0%5D%2C%0A%20%20%5B4.0%2C%203.5%5D%2C%0A%20%20%5B4.5%2C%206.5%5D%2C%0A%20%20%5B4.5%2C%202.5%5D%2C%0A%20%20%5B4.5%2C%205.0%5D%2C%0A%20%20%5B6.0%2C%202.5%5D%2C%0A%20%20%5B6.0%2C%204.5%5D%2C%0A%20%20%5B6.5%2C%205.5%5D%2C%0A%20%20%5B7.5%2C%204.5%5D%2C%0A%20%20%5B8.5%2C%205.0%5D%2C%0A%20%20%5B1.5%2C%205.0%5D%2C%0A%20%20%5B1.5%2C%206.5%5D%2C%0A%20%20%5B2.0%2C%201.5%5D%2C%0A%20%20%5B2.5%2C%203.5%5D%2C%0A%20%20%5B2.5%2C%206.0%5D%2C%0A%20%20%5B3.5%2C%206.0%5D%2C%0A%20%20%5B4.0%2C%208.0%5D%2C%0A%20%20%5B4.0%2C%207.0%5D%2C%0A%20%20%5B5.5%2C%208.5%5D%2C%0A%20%20%5B6.5%2C%207.0%5D%2C%0A%20%20%5B7.5%2C%208.5%5D%2C%0A%20%20%5B8.5%2C%207.0%5D%2C%0A%5D%3B%0A%0Aconst%20validOutputArray%20%3D%20%5B%0A%20%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%200%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%201%2C%0A%5D%3B%0A%0A%2F%2F%20global%20variables%0Alet%20model%2C%0A%20%20trainInput%2C%0A%20%20trainOutput%2C%0A%20%20validInput%2C%0A%20%20validOutput%2C%0A%20%20testInput%2C%0A%20%20trainBuffer%2C%0A%20%20validBuffer%2C%0A%20%20decisionBuffer%2C%0A%20%20sliderArray%2C%0A%20%20sliderControls%3B%0A%0Alet%20metricsElement%3B%0Alet%20highlightedConnectionKey%20%3D%20null%3B%0Alet%20sliderPanelResizeObserver%20%3D%20null%3B%0A%0Aconst%20currentWeights%20%3D%20%7B%0A%20%20w11%3A%20%5B%5D%2C%0A%20%20w12%3A%20%5B%5D%2C%0A%20%20b1%3A%20%5B%5D%2C%0A%20%20w2%3A%20%5B%5D%2C%0A%20%20b2%3A%200%2C%0A%7D%3B%0A%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%2F%2F%20NEURAL%20NETWORK%20FUNCTIONS%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%0Afunction%20generateTensors%28%29%20%7B%0A%20%20let%20normalizedTrainInputArray%20%3D%20%5B%5D%3B%0A%20%20let%20normalizedValidInputArray%20%3D%20%5B%5D%3B%0A%20%20let%20normalizedTestInputArray%20%3D%20%5B%5D%3B%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20trainInputArray.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20normalizedTrainInputArray.push%28%5B%0A%20%20%20%20%20%20%28trainInputArray%5Bi%5D%5B0%5D%20-%20trainInputMin%5B0%5D%29%20%2F%0A%20%20%20%20%20%20%20%20%28trainInputMax%5B0%5D%20-%20trainInputMin%5B0%5D%29%2C%0A%20%20%20%20%20%20%28trainInputArray%5Bi%5D%5B1%5D%20-%20trainInputMin%5B1%5D%29%20%2F%0A%20%20%20%20%20%20%20%20%28trainInputMax%5B1%5D%20-%20trainInputMin%5B1%5D%29%2C%0A%20%20%20%20%5D%29%3B%0A%0A%20%20%20%20normalizedValidInputArray.push%28%5B%0A%20%20%20%20%20%20%28validInputArray%5Bi%5D%5B0%5D%20-%20trainInputMin%5B0%5D%29%20%2F%0A%20%20%20%20%20%20%20%20%28trainInputMax%5B0%5D%20-%20trainInputMin%5B0%5D%29%2C%0A%20%20%20%20%20%20%28validInputArray%5Bi%5D%5B1%5D%20-%20trainInputMin%5B1%5D%29%20%2F%0A%20%20%20%20%20%20%20%20%28trainInputMax%5B1%5D%20-%20trainInputMin%5B1%5D%29%2C%0A%20%20%20%20%5D%29%3B%0A%20%20%7D%0A%0A%20%20trainInput%20%3D%20tf.tensor2d%28normalizedTrainInputArray%2C%20%5B%0A%20%20%20%20normalizedTrainInputArray.length%2C%0A%20%20%20%202%2C%0A%20%20%5D%29%3B%0A%20%20trainOutput%20%3D%20tf.tensor2d%28trainOutputArray%2C%20%5BtrainOutputArray.length%2C%201%5D%29%3B%0A%0A%20%20validInput%20%3D%20tf.tensor2d%28normalizedValidInputArray%2C%20%5B%0A%20%20%20%20normalizedValidInputArray.length%2C%0A%20%20%20%202%2C%0A%20%20%5D%29%3B%0A%20%20validOutput%20%3D%20tf.tensor2d%28validOutputArray%2C%20%5BvalidOutputArray.length%2C%201%5D%29%3B%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20NUM_DATA_PIXEL%20%2B%201%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20for%20%28let%20j%20%3D%200%3B%20j%20%3C%20NUM_DATA_PIXEL%20%2B%201%3B%20j%2B%2B%29%20%7B%0A%20%20%20%20%20%20normalizedTestInputArray.push%28%5B%0A%20%20%20%20%20%20%20%20%28%28i%20%2F%20NUM_DATA_PIXEL%29%20%2a%20DATA_RANGE%20-%20trainInputMin%5B0%5D%29%20%2F%0A%20%20%20%20%20%20%20%20%20%20%28trainInputMax%5B0%5D%20-%20trainInputMin%5B0%5D%29%2C%0A%20%20%20%20%20%20%20%20%28%28j%20%2F%20NUM_DATA_PIXEL%29%20%2a%20DATA_RANGE%20-%20trainInputMin%5B1%5D%29%20%2F%0A%20%20%20%20%20%20%20%20%20%20%28trainInputMax%5B1%5D%20-%20trainInputMin%5B1%5D%29%2C%0A%20%20%20%20%20%20%5D%29%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%0A%20%20testInput%20%3D%20tf.tensor2d%28normalizedTestInputArray%2C%20%5B%0A%20%20%20%20normalizedTestInputArray.length%2C%0A%20%20%20%202%2C%0A%20%20%5D%29%3B%0A%7D%0A%0Afunction%20compileModel%28%29%20%7B%0A%20%20model%20%3D%20tf.sequential%28%7B%0A%20%20%20%20layers%3A%20%5B%0A%20%20%20%20%20%20tf.layers.dense%28%7B%0A%20%20%20%20%20%20%20%20name%3A%20%22HiddenLayer1%22%2C%0A%20%20%20%20%20%20%20%20inputShape%3A%20%5B2%5D%2C%0A%20%20%20%20%20%20%20%20units%3A%20ANZAHL_HIDDEN_NEURONS%2C%0A%20%20%20%20%20%20%20%20activation%3A%20%22tanh%22%2C%0A%20%20%20%20%20%20%7D%29%2C%0A%20%20%20%20%20%20tf.layers.dense%28%7B%0A%20%20%20%20%20%20%20%20name%3A%20%22OutputLayer%22%2C%0A%20%20%20%20%20%20%20%20units%3A%201%2C%0A%20%20%20%20%20%20%20%20activation%3A%20%22sigmoid%22%2C%0A%20%20%20%20%20%20%7D%29%2C%0A%20%20%20%20%5D%2C%0A%20%20%7D%29%3B%0A%7D%0A%0Afunction%20initializeStaticWeights%28%29%20%7B%0A%20%20setWeightsFromObject%28STATIC_INITIAL_WEIGHTS%29%3B%0A%7D%0A%0Afunction%20setWeightsFromObject%28weights%29%20%7B%0A%20%20currentWeights.w11.length%20%3D%200%3B%0A%20%20currentWeights.w12.length%20%3D%200%3B%0A%20%20currentWeights.b1.length%20%3D%200%3B%0A%20%20currentWeights.w2.length%20%3D%200%3B%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20weights.w11.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20currentWeights.w11.push%28weights.w11%5Bi%5D%29%3B%0A%20%20%7D%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20weights.w12.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20currentWeights.w12.push%28weights.w12%5Bi%5D%29%3B%0A%20%20%7D%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20weights.b1.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20currentWeights.b1.push%28weights.b1%5Bi%5D%29%3B%0A%20%20%7D%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20weights.w2.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20currentWeights.w2.push%28weights.w2%5Bi%5D%29%3B%0A%20%20%7D%0A%0A%20%20currentWeights.b2%20%3D%20weights.b2%3B%0A%7D%0A%0Afunction%20getWeightsAsSliderValues%28weights%29%20%7B%0A%20%20return%20%5B%0A%20%20%20%20...weights.b1%2C%0A%20%20%20%20...weights.w11%2C%0A%20%20%20%20...weights.w12%2C%0A%20%20%20%20weights.b2%2C%0A%20%20%20%20...weights.w2%2C%0A%20%20%5D%3B%0A%7D%0A%0Afunction%20applyValuesToSliders%28values%29%20%7B%0A%20%20if%20%28%21sliderControls%20%7C%7C%20sliderControls.length%20%21%3D%3D%20values.length%29%20%7B%0A%20%20%20%20return%3B%0A%20%20%7D%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20sliderControls.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20sliderControls%5Bi%5D.setValue%28values%5Bi%5D%29%3B%0A%20%20%7D%0A%0A%20%20applyCurrentWeightsToModel%28%29%3B%0A%20%20drawPrediction%28%29%3B%0A%7D%0A%0Afunction%20randomWeightValue%28%29%20%7B%0A%20%20const%20raw%20%3D%20Math.random%28%29%20%2a%20%28MAX_WEIGHT%20-%20MIN_WEIGHT%29%20%2B%20MIN_WEIGHT%3B%0A%20%20const%20stepped%20%3D%20Math.round%28raw%20%2F%20SLIDER_STEP%29%20%2a%20SLIDER_STEP%3B%0A%20%20return%20Number%28stepped.toFixed%281%29%29%3B%0A%7D%0A%0Afunction%20applyRandomWeights%28%29%20%7B%0A%20%20const%20randomWeights%20%3D%20%7B%0A%20%20%20%20b1%3A%20Array.from%28%7B%20length%3A%20ANZAHL_HIDDEN_NEURONS%20%7D%2C%20randomWeightValue%29%2C%0A%20%20%20%20w11%3A%20Array.from%28%7B%20length%3A%20ANZAHL_HIDDEN_NEURONS%20%7D%2C%20randomWeightValue%29%2C%0A%20%20%20%20w12%3A%20Array.from%28%7B%20length%3A%20ANZAHL_HIDDEN_NEURONS%20%7D%2C%20randomWeightValue%29%2C%0A%20%20%20%20b2%3A%20randomWeightValue%28%29%2C%0A%20%20%20%20w2%3A%20Array.from%28%7B%20length%3A%20ANZAHL_HIDDEN_NEURONS%20%7D%2C%20randomWeightValue%29%2C%0A%20%20%7D%3B%0A%0A%20%20applyValuesToSliders%28getWeightsAsSliderValues%28randomWeights%29%29%3B%0A%7D%0A%0Afunction%20applyZeroWeights%28%29%20%7B%0A%20%20applyValuesToSliders%28%5B%0A%20%20%20%200%2C%0A%20%20%20%200%2C%0A%20%20%20%200%2C%20%2F%2F%20b1%0A%20%20%20%200%2C%0A%20%20%20%200%2C%0A%20%20%20%200%2C%20%2F%2F%20w11%0A%20%20%20%200%2C%0A%20%20%20%200%2C%0A%20%20%20%200%2C%20%2F%2F%20w12%0A%20%20%20%200%2C%20%2F%2F%20b2%0A%20%20%20%200%2C%0A%20%20%20%200%2C%0A%20%20%20%200%2C%20%2F%2F%20w2%0A%20%20%5D%29%3B%0A%7D%0A%0Afunction%20applyPretrainedWeights%28%29%20%7B%0A%20%20applyValuesToSliders%28getWeightsAsSliderValues%28STATIC_INITIAL_WEIGHTS%29%29%3B%0A%7D%0A%0Afunction%20applyCurrentWeightsToModel%28%29%20%7B%0A%20%20const%20kernelHidden%20%3D%20tf.tensor2d%28%0A%20%20%20%20%5BcurrentWeights.w11%2C%20currentWeights.w12%5D%2C%0A%20%20%20%20%5B2%2C%20ANZAHL_HIDDEN_NEURONS%5D%2C%0A%20%20%29%3B%0A%20%20const%20biasHidden%20%3D%20tf.tensor1d%28currentWeights.b1%29%3B%0A%0A%20%20const%20kernelOut%20%3D%20tf.tensor2d%28%0A%20%20%20%20currentWeights.w2.map%28%28value%29%20%3D%3E%20%5Bvalue%5D%29%2C%0A%20%20%20%20%5BANZAHL_HIDDEN_NEURONS%2C%201%5D%2C%0A%20%20%29%3B%0A%20%20const%20biasOut%20%3D%20tf.tensor1d%28%5BcurrentWeights.b2%5D%29%3B%0A%0A%20%20model.layers%5B0%5D.setWeights%28%5BkernelHidden%2C%20biasHidden%5D%29%3B%0A%20%20model.layers%5B1%5D.setWeights%28%5BkernelOut%2C%20biasOut%5D%29%3B%0A%0A%20%20kernelHidden.dispose%28%29%3B%0A%20%20biasHidden.dispose%28%29%3B%0A%20%20kernelOut.dispose%28%29%3B%0A%20%20biasOut.dispose%28%29%3B%0A%7D%0A%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%2F%2F%20METRICS%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%0Afunction%20calculateMSE%28predictedOutput%2C%20trueOutput%29%20%7B%0A%20%20let%20mse%20%3D%200.0%3B%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20predictedOutput.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20mse%20%2B%3D%20%28predictedOutput%5Bi%5D%5B0%5D%20-%20trueOutput%5Bi%5D%29%20%2a%2a%202%3B%0A%20%20%7D%0A%20%20return%20mse%20%2F%20predictedOutput.length%3B%0A%7D%0A%0Afunction%20calculatePercentageCorrect%28predictedOutput%2C%20trueOutput%29%20%7B%0A%20%20let%20correct%20%3D%200%3B%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20predictedOutput.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20const%20prediction%20%3D%20predictedOutput%5Bi%5D%5B0%5D%3B%0A%20%20%20%20if%20%28%0A%20%20%20%20%20%20%28trueOutput%5Bi%5D%20%3D%3D%3D%201%20%26%26%20prediction%20%3E%3D%200.5%29%20%7C%7C%0A%20%20%20%20%20%20%28trueOutput%5Bi%5D%20%3D%3D%3D%200%20%26%26%20prediction%20%3C%200.5%29%0A%20%20%20%20%29%20%7B%0A%20%20%20%20%20%20correct%20%2B%3D%201%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20return%20%7B%0A%20%20%20%20accuracy%3A%20Math.round%28%28correct%20%2a%20100%29%20%2F%20predictedOutput.length%29%2C%0A%20%20%20%20wrong%3A%20predictedOutput.length%20-%20correct%2C%0A%20%20%7D%3B%0A%7D%0A%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%2F%2F%20VISUALISATION%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%0Afunction%20drawDataInBuffer%28inputData%2C%20outputData%2C%20buffer%29%20%7B%0A%20%20buffer.clear%28%29%3B%0A%20%20buffer.noFill%28%29%3B%0A%20%20buffer.strokeWeight%28PIXEL_SIZE%20%2F%202%29%3B%0A%20%20buffer.rect%280%2C%200%2C%20DATA_WINDOW_SIZE%2C%20DATA_WINDOW_SIZE%29%3B%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20inputData.length%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20if%20%28outputData%5Bi%5D%20%3D%3D%3D%201%29%20%7B%0A%20%20%20%20%20%20buffer.stroke%28%22darkgreen%22%29%3B%0A%20%20%20%20%20%20buffer.circle%28%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20inputData%5Bi%5D%5B0%5D%2C%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20%2810%20-%20inputData%5Bi%5D%5B1%5D%29%2C%0A%20%20%20%20%20%20%20%202%20%2a%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%29%3B%0A%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20buffer.stroke%28%22blue%22%29%3B%0A%20%20%20%20%20%20buffer.line%28%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20inputData%5Bi%5D%5B0%5D%20%2B%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20%2810%20-%20inputData%5Bi%5D%5B1%5D%29%20%2B%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20inputData%5Bi%5D%5B0%5D%20-%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20%2810%20-%20inputData%5Bi%5D%5B1%5D%29%20-%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%29%3B%0A%20%20%20%20%20%20buffer.line%28%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20inputData%5Bi%5D%5B0%5D%20%2B%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20%2810%20-%20inputData%5Bi%5D%5B1%5D%29%20-%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20inputData%5Bi%5D%5B0%5D%20-%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20%2810%20-%20inputData%5Bi%5D%5B1%5D%29%20%2B%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%29%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%7D%0A%0Afunction%20drawPrediction%28%29%20%7B%0A%20%20const%20%7B%20training%2C%20validation%2C%20prediction%20%7D%20%3D%20tf.tidy%28%28%29%20%3D%3E%20%7B%0A%20%20%20%20const%20trainingTensor%20%3D%20model.predict%28trainInput%29%3B%0A%20%20%20%20const%20validationTensor%20%3D%20model.predict%28validInput%29%3B%0A%20%20%20%20const%20predictionTensor%20%3D%20model.predict%28testInput%29%3B%0A%0A%20%20%20%20return%20%7B%0A%20%20%20%20%20%20training%3A%20trainingTensor.arraySync%28%29%2C%0A%20%20%20%20%20%20validation%3A%20validationTensor.arraySync%28%29%2C%0A%20%20%20%20%20%20prediction%3A%20predictionTensor.arraySync%28%29%2C%0A%20%20%20%20%7D%3B%0A%20%20%7D%29%3B%0A%0A%20%20const%20mseTrain%20%3D%20calculateMSE%28training%2C%20trainOutputArray%29%3B%0A%20%20const%20mseValid%20%3D%20calculateMSE%28validation%2C%20validOutputArray%29%3B%0A%20%20const%20trainCorrect%20%3D%20calculatePercentageCorrect%28training%2C%20trainOutputArray%29%3B%0A%20%20const%20validCorrect%20%3D%20calculatePercentageCorrect%28validation%2C%20validOutputArray%29%3B%0A%0A%20%20decisionBuffer.clear%28%29%3B%0A%20%20decisionBuffer.noStroke%28%29%3B%0A%0A%20%20let%20element%20%3D%200%3B%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20NUM_DATA_PIXEL%20%2B%201%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20for%20%28let%20j%20%3D%200%3B%20j%20%3C%20NUM_DATA_PIXEL%20%2B%201%3B%20j%2B%2B%29%20%7B%0A%20%20%20%20%20%20const%20out%20%3D%20prediction%5Belement%5D%5B0%5D%3B%0A%0A%20%20%20%20%20%20if%20%28out%20%3E%200.5%29%20%7B%0A%20%20%20%20%20%20%20%20decisionBuffer.fill%28%0A%20%20%20%20%20%20%20%20%20%20Math.round%28%281%20-%20out%29%20%2a%20100%20%2B%20200.5%29%2C%0A%20%20%20%20%20%20%20%20%20%20255%2C%0A%20%20%20%20%20%20%20%20%20%20Math.round%28%281%20-%20out%29%20%2a%20100%20%2B%20200.5%29%2C%0A%20%20%20%20%20%20%20%20%29%3B%0A%20%20%20%20%20%20%7D%20else%20%7B%0A%20%20%20%20%20%20%20%20decisionBuffer.fill%28%0A%20%20%20%20%20%20%20%20%20%20Math.round%28out%20%2a%20100%20%2B%20200.5%29%2C%0A%20%20%20%20%20%20%20%20%20%20Math.round%28out%20%2a%20100%20%2B%20200.5%29%2C%0A%20%20%20%20%20%20%20%20%20%20255%2C%0A%20%20%20%20%20%20%20%20%29%3B%0A%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20if%20%28%0A%20%20%20%20%20%20%20%20element%20%25%20%28NUM_DATA_PIXEL%20%2B%201%29%20%21%3D%3D%200%20%26%26%0A%20%20%20%20%20%20%20%20%28%28out%20%3E%200.5%20%26%26%20prediction%5Belement%20-%201%5D%5B0%5D%20%3C%3D%200.5%29%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%28out%20%3C%3D%200.5%20%26%26%20prediction%5Belement%20-%201%5D%5B0%5D%20%3E%200.5%29%29%0A%20%20%20%20%20%20%29%20%7B%0A%20%20%20%20%20%20%20%20decisionBuffer.fill%28%22red%22%29%3B%0A%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20if%20%28%0A%20%20%20%20%20%20%20%20element%20%3E%3D%20NUM_DATA_PIXEL%20%2B%201%20%26%26%0A%20%20%20%20%20%20%20%20%28%28out%20%3E%200.5%20%26%26%20prediction%5Belement%20-%20%28NUM_DATA_PIXEL%20%2B%201%29%5D%5B0%5D%20%3C%3D%200.5%29%20%7C%7C%0A%20%20%20%20%20%20%20%20%20%20%28out%20%3C%3D%200.5%20%26%26%20prediction%5Belement%20-%20%28NUM_DATA_PIXEL%20%2B%201%29%5D%5B0%5D%20%3E%200.5%29%29%0A%20%20%20%20%20%20%29%20%7B%0A%20%20%20%20%20%20%20%20decisionBuffer.fill%28%22red%22%29%3B%0A%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20decisionBuffer.rect%28%0A%20%20%20%20%20%20%20%20%28%28DATA_SCALE%20%2a%20i%29%20%2F%20NUM_DATA_PIXEL%29%20%2a%20DATA_RANGE%20-%20PIXEL_SIZE%20%2F%202%2C%0A%20%20%20%20%20%20%20%20DATA_SCALE%20%2a%20%2810%20-%20%28j%20%2F%20NUM_DATA_PIXEL%29%20%2a%20DATA_RANGE%29%20-%20PIXEL_SIZE%20%2F%202%2C%0A%20%20%20%20%20%20%20%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%20%20PIXEL_SIZE%2C%0A%20%20%20%20%20%20%29%3B%0A%0A%20%20%20%20%20%20element%20%2B%3D%201%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%0A%20%20clear%28%29%3B%0A%20%20image%28decisionBuffer%2C%200%2C%200%29%3B%0A%20%20image%28decisionBuffer%2C%20DATA_WINDOW_SIZE%2C%200%29%3B%0A%20%20image%28trainBuffer%2C%200%2C%200%29%3B%0A%20%20image%28validBuffer%2C%20DATA_WINDOW_SIZE%2C%200%29%3B%0A%20%20drawNetworkDiagram%28%29%3B%0A%0A%20%20%2F%2F%20Section%20titles%20%28horizontally%20centered%20at%20the%20top%20of%20each%20square%2Fpanel%29%0A%20%20noStroke%28%29%3B%0A%20%20fill%28%22black%22%29%3B%0A%20%20textSize%2813%29%3B%0A%20%20textAlign%28CENTER%2C%20TOP%29%3B%0A%20%20text%28%22Training%20Set%22%2C%20DATA_WINDOW_SIZE%20%2F%202%2C%206%29%3B%0A%20%20text%28%22Validation%20Set%22%2C%20DATA_WINDOW_SIZE%20%2B%20DATA_WINDOW_SIZE%20%2F%202%2C%206%29%3B%0A%20%20text%28%22Neuronales%20Netz%22%2C%202%20%2a%20DATA_WINDOW_SIZE%20%2B%20NN_PANEL_WIDTH%20%2F%202%2C%206%29%3B%0A%0A%20%20if%20%28metricsElement%29%20%7B%0A%20%20%20%20metricsElement.textContent%20%3D%0A%20%20%20%20%20%20%60MSE%20Training%3A%20%24%7BmseTrain.toFixed%284%29%7D%20%7C%20%60%20%2B%0A%20%20%20%20%20%20%60MSE%20Validation%3A%20%24%7BmseValid.toFixed%284%29%7D%20%7C%20%60%20%2B%0A%20%20%20%20%20%20%60Korrekt%20Training%3A%20%24%7BtrainCorrect.accuracy%7D%25%20%7C%20Korrekt%20Validation%3A%20%24%7BvalidCorrect.accuracy%7D%25%60%3B%0A%20%20%7D%0A%7D%0A%0Afunction%20drawNetworkDiagram%28%29%20%7B%0A%20%20const%20panelX%20%3D%202%20%2a%20DATA_WINDOW_SIZE%3B%0A%20%20const%20panelY%20%3D%200%3B%0A%20%20const%20panelH%20%3D%20DATA_WINDOW_SIZE%3B%0A%20%20const%20margin%20%3D%2016%3B%0A%0A%20%20const%20xInput%20%3D%20panelX%20%2B%20margin%20%2B%2014%3B%0A%20%20const%20xHidden%20%3D%20panelX%20%2B%20Math.round%28NN_PANEL_WIDTH%20%2a%200.48%29%3B%0A%20%20const%20xOutput%20%3D%20panelX%20%2B%20NN_PANEL_WIDTH%20-%20margin%20-%2014%3B%0A%20%20const%20xBiasHidden%20%3D%20xInput%3B%0A%20%20const%20xBiasOutput%20%3D%20panelX%20%2B%20Math.round%28NN_PANEL_WIDTH%20%2a%200.48%29%3B%0A%0A%20%20%2F%2F%20Input%20column%3A%20bias%20%2B%202%20input%20nodes%2C%20vertically%20centered%20in%20the%20panel.%0A%20%20const%20inputSpacing%20%3D%2055%3B%0A%20%20const%20biasHiddenY%20%3D%20panelY%20%2B%20panelH%20%2F%202%20-%20inputSpacing%3B%0A%20%20const%20inputY%20%3D%20%5BbiasHiddenY%20%2B%20inputSpacing%2C%20biasHiddenY%20%2B%202%20%2a%20inputSpacing%5D%3B%0A%0A%20%20%2F%2F%20Hidden%20column%3A%20bias%20%2B%203%20hidden%20nodes%2C%20vertically%20centered%20in%20the%20panel.%0A%20%20const%20hiddenSpacing%20%3D%2036%3B%0A%20%20const%20biasOutputY%20%3D%20panelY%20%2B%20panelH%20%2F%202%20-%201.5%20%2a%20hiddenSpacing%3B%0A%20%20const%20hiddenY%20%3D%20%5B%0A%20%20%20%20biasOutputY%20%2B%20hiddenSpacing%2C%0A%20%20%20%20biasOutputY%20%2B%202%20%2a%20hiddenSpacing%2C%0A%20%20%20%20biasOutputY%20%2B%203%20%2a%20hiddenSpacing%2C%0A%20%20%5D%3B%0A%0A%20%20const%20outputY%20%3D%20100%3B%0A%0A%20%20const%20drawConnection%20%3D%20%28x1%2C%20y1%2C%20x2%2C%20y2%2C%20key%29%20%3D%3E%20%7B%0A%20%20%20%20stroke%28key%20%3D%3D%3D%20highlightedConnectionKey%20%3F%20%22%23f59e0b%22%20%3A%20%22black%22%29%3B%0A%20%20%20%20strokeWeight%282%29%3B%0A%20%20%20%20line%28x1%2C%20y1%2C%20x2%2C%20y2%29%3B%0A%20%20%7D%3B%0A%0A%20%20const%20drawNode%20%3D%20%28%7B%20x%2C%20y%2C%20radius%2C%20filled%20%3D%20false%20%7D%29%20%3D%3E%20%7B%0A%20%20%20%20stroke%28%22black%22%29%3B%0A%20%20%20%20strokeWeight%281.5%29%3B%0A%20%20%20%20fill%28filled%20%3F%20%22black%22%20%3A%20%22white%22%29%3B%0A%20%20%20%20circle%28x%2C%20y%2C%20radius%20%2a%202%29%3B%0A%20%20%7D%3B%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20ANZAHL_HIDDEN_NEURONS%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20drawConnection%28xInput%2C%20inputY%5B0%5D%2C%20xHidden%2C%20hiddenY%5Bi%5D%2C%20%60w11-%24%7Bi%7D%60%29%3B%0A%20%20%20%20drawConnection%28xInput%2C%20inputY%5B1%5D%2C%20xHidden%2C%20hiddenY%5Bi%5D%2C%20%60w12-%24%7Bi%7D%60%29%3B%0A%20%20%20%20drawConnection%28xBiasHidden%2C%20biasHiddenY%2C%20xHidden%2C%20hiddenY%5Bi%5D%2C%20%60b1-%24%7Bi%7D%60%29%3B%0A%20%20%20%20drawConnection%28xHidden%2C%20hiddenY%5Bi%5D%2C%20xOutput%2C%20outputY%2C%20%60w2-%24%7Bi%7D%60%29%3B%0A%20%20%7D%0A%20%20drawConnection%28xBiasOutput%2C%20biasOutputY%2C%20xOutput%2C%20outputY%2C%20%22b2%22%29%3B%0A%0A%20%20drawNode%28%7B%20x%3A%20xInput%2C%20y%3A%20inputY%5B0%5D%2C%20radius%3A%2010%20%7D%29%3B%0A%20%20drawNode%28%7B%20x%3A%20xInput%2C%20y%3A%20inputY%5B1%5D%2C%20radius%3A%2010%20%7D%29%3B%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20ANZAHL_HIDDEN_NEURONS%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20drawNode%28%7B%20x%3A%20xHidden%2C%20y%3A%20hiddenY%5Bi%5D%2C%20radius%3A%2010%20%7D%29%3B%0A%20%20%7D%0A%0A%20%20drawNode%28%7B%20x%3A%20xOutput%2C%20y%3A%20outputY%2C%20radius%3A%2010%20%7D%29%3B%0A%20%20drawNode%28%7B%0A%20%20%20%20x%3A%20xBiasHidden%2C%0A%20%20%20%20y%3A%20biasHiddenY%2C%0A%20%20%20%20radius%3A%205%2C%0A%20%20%20%20filled%3A%20true%2C%0A%20%20%7D%29%3B%0A%20%20drawNode%28%7B%0A%20%20%20%20x%3A%20xBiasOutput%2C%0A%20%20%20%20y%3A%20biasOutputY%2C%0A%20%20%20%20radius%3A%205%2C%0A%20%20%20%20filled%3A%20true%2C%0A%20%20%7D%29%3B%0A%7D%0A%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%2F%2F%20SLIDER%20UI%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%0Afunction%20createSliderControl%28%7B%20value%2C%20onInput%2C%20connectionKey%20%7D%29%20%7B%0A%20%20const%20row%20%3D%20document.createElement%28%22div%22%29%3B%0A%20%20row.className%20%3D%20%22slider-row%22%3B%0A%0A%20%20const%20slider%20%3D%20document.createElement%28%22input%22%29%3B%0A%20%20slider.type%20%3D%20%22range%22%3B%0A%20%20slider.min%20%3D%20String%28MIN_WEIGHT%29%3B%0A%20%20slider.max%20%3D%20String%28MAX_WEIGHT%29%3B%0A%20%20slider.step%20%3D%20String%28SLIDER_STEP%29%3B%0A%20%20slider.value%20%3D%20String%28value%29%3B%0A%20%20slider.className%20%3D%20%22weight-slider%22%3B%0A%0A%20%20const%20valueEl%20%3D%20document.createElement%28%22span%22%29%3B%0A%20%20valueEl.className%20%3D%20%22slider-value%22%3B%0A%20%20valueEl.textContent%20%3D%20Number%28value%29.toFixed%281%29%3B%0A%0A%20%20let%20isHovered%20%3D%20false%3B%0A%20%20let%20isFocused%20%3D%20false%3B%0A%20%20let%20isDragging%20%3D%20false%3B%0A%0A%20%20const%20refreshConnectionHighlight%20%3D%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20const%20shouldHighlight%20%3D%20isHovered%20%7C%7C%20isDragging%3B%0A%0A%20%20%20%20slider.classList.toggle%28%22is-engaged%22%2C%20shouldHighlight%29%3B%0A%0A%20%20%20%20if%20%28shouldHighlight%29%20%7B%0A%20%20%20%20%20%20highlightedConnectionKey%20%3D%20connectionKey%3B%0A%20%20%20%20%7D%20else%20if%20%28highlightedConnectionKey%20%3D%3D%3D%20connectionKey%29%20%7B%0A%20%20%20%20%20%20highlightedConnectionKey%20%3D%20null%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20drawPrediction%28%29%3B%0A%20%20%7D%3B%0A%0A%20%20slider.addEventListener%28%22input%22%2C%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20const%20parsed%20%3D%20parseFloat%28slider.value%29%3B%0A%20%20%20%20valueEl.textContent%20%3D%20parsed.toFixed%281%29%3B%0A%20%20%20%20isDragging%20%3D%20true%3B%0A%20%20%20%20onInput%28parsed%29%3B%0A%20%20%20%20applyCurrentWeightsToModel%28%29%3B%0A%20%20%20%20refreshConnectionHighlight%28%29%3B%0A%20%20%7D%29%3B%0A%0A%20%20slider.addEventListener%28%22mouseenter%22%2C%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20isHovered%20%3D%20true%3B%0A%20%20%20%20refreshConnectionHighlight%28%29%3B%0A%20%20%7D%29%3B%0A%0A%20%20slider.addEventListener%28%22mouseleave%22%2C%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20isHovered%20%3D%20false%3B%0A%20%20%20%20refreshConnectionHighlight%28%29%3B%0A%20%20%7D%29%3B%0A%0A%20%20slider.addEventListener%28%22focus%22%2C%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20isFocused%20%3D%20true%3B%0A%20%20%20%20refreshConnectionHighlight%28%29%3B%0A%20%20%7D%29%3B%0A%0A%20%20slider.addEventListener%28%22blur%22%2C%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20isFocused%20%3D%20false%3B%0A%20%20%20%20isDragging%20%3D%20false%3B%0A%20%20%20%20refreshConnectionHighlight%28%29%3B%0A%20%20%7D%29%3B%0A%0A%20%20slider.addEventListener%28%22pointerdown%22%2C%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20isDragging%20%3D%20true%3B%0A%20%20%20%20refreshConnectionHighlight%28%29%3B%0A%20%20%7D%29%3B%0A%0A%20%20window.addEventListener%28%22pointerup%22%2C%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20if%20%28isDragging%29%20%7B%0A%20%20%20%20%20%20isDragging%20%3D%20false%3B%0A%20%20%20%20%20%20refreshConnectionHighlight%28%29%3B%0A%20%20%20%20%7D%0A%20%20%7D%29%3B%0A%0A%20%20row.appendChild%28slider%29%3B%0A%20%20row.appendChild%28valueEl%29%3B%0A%0A%20%20const%20setValue%20%3D%20%28nextValue%29%20%3D%3E%20%7B%0A%20%20%20%20const%20parsed%20%3D%20Number%28nextValue%29%3B%0A%20%20%20%20slider.value%20%3D%20String%28parsed%29%3B%0A%20%20%20%20valueEl.textContent%20%3D%20parsed.toFixed%281%29%3B%0A%20%20%20%20onInput%28parsed%29%3B%0A%20%20%7D%3B%0A%0A%20%20return%20%7B%20row%2C%20slider%2C%20valueEl%2C%20setValue%20%7D%3B%0A%7D%0A%0Afunction%20createWeightSliders%28%29%20%7B%0A%20%20sliderArray%20%3D%20%5B%5D%3B%0A%20%20sliderControls%20%3D%20%5B%5D%3B%0A%0A%20%20const%20canvasContainer%20%3D%20document.getElementById%28%22canvas-container%22%29%3B%0A%20%20const%20main%20%3D%20document.querySelector%28%22main%22%29%3B%0A%20%20const%20canvas%20%3D%20document.querySelector%28%22canvas%22%29%3B%0A%0A%20%20if%20%28%21main%29%20%7B%0A%20%20%20%20return%3B%0A%20%20%7D%0A%0A%20%20const%20existingPanel%20%3D%20document.getElementById%28%22slider-panel%22%29%3B%0A%20%20if%20%28existingPanel%29%20%7B%0A%20%20%20%20existingPanel.remove%28%29%3B%0A%20%20%7D%0A%0A%20%20const%20panel%20%3D%20document.createElement%28%22section%22%29%3B%0A%20%20panel.id%20%3D%20%22slider-panel%22%3B%0A%20%20panel.setAttribute%28%22aria-label%22%2C%20%22Gewichte%20und%20Biases%22%29%3B%0A%0A%20%20const%20syncSliderPanelWidth%20%3D%20%28%29%20%3D%3E%20%7B%0A%20%20%20%20const%20widthSource%20%3D%20canvas%20%21%3D%20null%20%3F%20canvas%20%3A%20canvasContainer%3B%0A%20%20%20%20let%20sourceWidth%20%3D%200%3B%0A%0A%20%20%20%20if%20%28%0A%20%20%20%20%20%20widthSource%20%21%3D%3D%20null%20%26%26%0A%20%20%20%20%20%20widthSource%20%21%3D%3D%20undefined%20%26%26%0A%20%20%20%20%20%20typeof%20widthSource.getBoundingClientRect%20%3D%3D%3D%20%22function%22%0A%20%20%20%20%29%20%7B%0A%20%20%20%20%20%20sourceWidth%20%3D%20widthSource.getBoundingClientRect%28%29.width%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if%20%28sourceWidth%20%3E%200%29%20%7B%0A%20%20%20%20%20%20const%20lockedWidth%20%3D%20%60%24%7BMath.round%28sourceWidth%29%7Dpx%60%3B%0A%20%20%20%20%20%20panel.style.width%20%3D%20lockedWidth%3B%0A%20%20%20%20%20%20panel.style.minWidth%20%3D%20lockedWidth%3B%0A%20%20%20%20%20%20panel.style.maxWidth%20%3D%20lockedWidth%3B%0A%20%20%20%20%7D%0A%20%20%7D%3B%0A%0A%20%20metricsElement%20%3D%20document.createElement%28%22p%22%29%3B%0A%20%20metricsElement.id%20%3D%20%22metrics-line%22%3B%0A%20%20panel.appendChild%28metricsElement%29%3B%0A%0A%20%20const%20grid%20%3D%20document.createElement%28%22div%22%29%3B%0A%20%20grid.className%20%3D%20%22slider-grid%22%3B%0A%0A%20%20const%20hiddenColumn%20%3D%20document.createElement%28%22div%22%29%3B%0A%20%20hiddenColumn.className%20%3D%20%22slider-column%20slider-column-hidden%22%3B%0A%0A%20%20const%20outputColumn%20%3D%20document.createElement%28%22div%22%29%3B%0A%20%20outputColumn.className%20%3D%20%22slider-column%20slider-column-output%22%3B%0A%0A%20%20const%20addControl%20%3D%20%28column%2C%20config%29%20%3D%3E%20%7B%0A%20%20%20%20const%20control%20%3D%20createSliderControl%28config%29%3B%0A%20%20%20%20column.appendChild%28control.row%29%3B%0A%20%20%20%20sliderArray.push%28control.slider%29%3B%0A%20%20%20%20sliderControls.push%28control%29%3B%0A%20%20%7D%3B%0A%0A%20%20const%20createIndexedSetter%20%3D%20function%20%28key%2C%20index%29%20%7B%0A%20%20%20%20return%20function%20%28v%29%20%7B%0A%20%20%20%20%20%20currentWeights%5Bkey%5D%5Bindex%5D%20%3D%20v%3B%0A%20%20%20%20%7D%3B%0A%20%20%7D%3B%0A%0A%20%20%2F%2F%20Column%201%3A%20connections%20to%20hidden%20layer%0A%20%20%2F%2F%20Start%20with%20bias%20sliders%20%28b1%29%2C%20then%20weights%20from%20x1%20%28w11%29%2C%20then%20from%20x2%20%28w12%29.%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20ANZAHL_HIDDEN_NEURONS%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20addControl%28hiddenColumn%2C%20%7B%0A%20%20%20%20%20%20value%3A%20currentWeights.b1%5Bi%5D%2C%0A%20%20%20%20%20%20connectionKey%3A%20%60b1-%24%7Bi%7D%60%2C%0A%20%20%20%20%20%20onInput%3A%20createIndexedSetter%28%22b1%22%2C%20i%29%2C%0A%20%20%20%20%7D%29%3B%0A%20%20%7D%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20ANZAHL_HIDDEN_NEURONS%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20addControl%28hiddenColumn%2C%20%7B%0A%20%20%20%20%20%20value%3A%20currentWeights.w11%5Bi%5D%2C%0A%20%20%20%20%20%20connectionKey%3A%20%60w11-%24%7Bi%7D%60%2C%0A%20%20%20%20%20%20onInput%3A%20createIndexedSetter%28%22w11%22%2C%20i%29%2C%0A%20%20%20%20%7D%29%3B%0A%20%20%7D%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20ANZAHL_HIDDEN_NEURONS%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20addControl%28hiddenColumn%2C%20%7B%0A%20%20%20%20%20%20value%3A%20currentWeights.w12%5Bi%5D%2C%0A%20%20%20%20%20%20connectionKey%3A%20%60w12-%24%7Bi%7D%60%2C%0A%20%20%20%20%20%20onInput%3A%20createIndexedSetter%28%22w12%22%2C%20i%29%2C%0A%20%20%20%20%7D%29%3B%0A%20%20%7D%0A%0A%20%20%2F%2F%20Column%202%3A%20connections%20to%20output%20layer%0A%20%20%2F%2F%20Start%20with%20bias%20slider%20%28b2%29%2C%20then%20weights%20from%20hidden%20neurons%20%28w2%29.%0A%20%20addControl%28outputColumn%2C%20%7B%0A%20%20%20%20value%3A%20currentWeights.b2%2C%0A%20%20%20%20connectionKey%3A%20%22b2%22%2C%0A%20%20%20%20onInput%3A%20function%20%28v%29%20%7B%0A%20%20%20%20%20%20currentWeights.b2%20%3D%20v%3B%0A%20%20%20%20%7D%2C%0A%20%20%7D%29%3B%0A%0A%20%20for%20%28let%20i%20%3D%200%3B%20i%20%3C%20ANZAHL_HIDDEN_NEURONS%3B%20i%2B%2B%29%20%7B%0A%20%20%20%20addControl%28outputColumn%2C%20%7B%0A%20%20%20%20%20%20value%3A%20currentWeights.w2%5Bi%5D%2C%0A%20%20%20%20%20%20connectionKey%3A%20%60w2-%24%7Bi%7D%60%2C%0A%20%20%20%20%20%20onInput%3A%20createIndexedSetter%28%22w2%22%2C%20i%29%2C%0A%20%20%20%20%7D%29%3B%0A%20%20%7D%0A%0A%20%20grid.appendChild%28hiddenColumn%29%3B%0A%20%20grid.appendChild%28outputColumn%29%3B%0A%0A%20%20panel.appendChild%28grid%29%3B%0A%0A%20%20const%20actions%20%3D%20document.createElement%28%22div%22%29%3B%0A%20%20actions.className%20%3D%20%22slider-actions%22%3B%0A%0A%20%20const%20randomButton%20%3D%20document.createElement%28%22button%22%29%3B%0A%20%20randomButton.type%20%3D%20%22button%22%3B%0A%20%20randomButton.className%20%3D%20%22weight-action-btn%22%3B%0A%20%20randomButton.textContent%20%3D%20%22Random%22%3B%0A%20%20randomButton.addEventListener%28%22click%22%2C%20applyRandomWeights%29%3B%0A%0A%20%20const%20zeroButton%20%3D%20document.createElement%28%22button%22%29%3B%0A%20%20zeroButton.type%20%3D%20%22button%22%3B%0A%20%20zeroButton.className%20%3D%20%22weight-action-btn%22%3B%0A%20%20zeroButton.textContent%20%3D%20%22Zero%22%3B%0A%20%20zeroButton.addEventListener%28%22click%22%2C%20applyZeroWeights%29%3B%0A%0A%20%20const%20pretrainedButton%20%3D%20document.createElement%28%22button%22%29%3B%0A%20%20pretrainedButton.type%20%3D%20%22button%22%3B%0A%20%20pretrainedButton.className%20%3D%20%22weight-action-btn%22%3B%0A%20%20pretrainedButton.textContent%20%3D%20%22Pretrained%22%3B%0A%20%20pretrainedButton.addEventListener%28%22click%22%2C%20applyPretrainedWeights%29%3B%0A%0A%20%20actions.appendChild%28randomButton%29%3B%0A%20%20actions.appendChild%28zeroButton%29%3B%0A%20%20actions.appendChild%28pretrainedButton%29%3B%0A%20%20panel.appendChild%28actions%29%3B%0A%0A%20%20if%20%28canvasContainer%29%20%7B%0A%20%20%20%20canvasContainer.appendChild%28panel%29%3B%0A%20%20%7D%20else%20if%20%28canvas%20%26%26%20canvas.parentElement%29%20%7B%0A%20%20%20%20canvas.parentElement.appendChild%28panel%29%3B%0A%20%20%7D%20else%20%7B%0A%20%20%20%20main.appendChild%28panel%29%3B%0A%20%20%7D%0A%0A%20%20syncSliderPanelWidth%28%29%3B%0A%0A%20%20if%20%28typeof%20ResizeObserver%20%21%3D%3D%20%22undefined%22%29%20%7B%0A%20%20%20%20if%20%28sliderPanelResizeObserver%29%20%7B%0A%20%20%20%20%20%20sliderPanelResizeObserver.disconnect%28%29%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20sliderPanelResizeObserver%20%3D%20new%20ResizeObserver%28syncSliderPanelWidth%29%3B%0A%20%20%20%20const%20widthSource%20%3D%20canvas%20%21%3D%20null%20%3F%20canvas%20%3A%20canvasContainer%3B%0A%0A%20%20%20%20if%20%28widthSource%29%20%7B%0A%20%20%20%20%20%20sliderPanelResizeObserver.observe%28widthSource%29%3B%0A%20%20%20%20%7D%0A%20%20%7D%0A%0A%20%20window.addEventListener%28%22resize%22%2C%20syncSliderPanelWidth%29%3B%0A%7D%0A%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%2F%2F%20MAIN%20PROGRAM%20%28p5.js%29%0A%2F%2F%20%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%2a%0A%0Afunction%20setup%28%29%20%7B%0A%20%20createCanvas%282%20%2a%20DATA_WINDOW_SIZE%20%2B%20NN_PANEL_WIDTH%2C%20DATA_WINDOW_SIZE%29%3B%0A%0A%20%20trainBuffer%20%3D%20createGraphics%28DATA_WINDOW_SIZE%2C%20DATA_WINDOW_SIZE%29%3B%0A%20%20validBuffer%20%3D%20createGraphics%28DATA_WINDOW_SIZE%2C%20DATA_WINDOW_SIZE%29%3B%0A%20%20decisionBuffer%20%3D%20createGraphics%28DATA_WINDOW_SIZE%2C%20DATA_WINDOW_SIZE%29%3B%0A%0A%20%20drawDataInBuffer%28trainInputArray%2C%20trainOutputArray%2C%20trainBuffer%29%3B%0A%20%20drawDataInBuffer%28validInputArray%2C%20validOutputArray%2C%20validBuffer%29%3B%0A%0A%20%20generateTensors%28%29%3B%0A%20%20compileModel%28%29%3B%0A%20%20initializeStaticWeights%28%29%3B%0A%20%20applyCurrentWeightsToModel%28%29%3B%0A%20%20createWeightSliders%28%29%3B%0A%20%20drawPrediction%28%29%3B%0A%7D%0A&css=html%20%7B%0A%20%20box-sizing%3A%20border-box%3B%0A%7D%0A%0Abody%2C%0Amain%2C%0Ah1%2C%0Ah2%2C%0Asection%2C%0Adiv%2C%0Acanvas%2C%0Ainput%2C%0Abutton%2C%0Aspan%2C%0Apre%20%7B%0A%20%20box-sizing%3A%20border-box%3B%0A%7D%0A%0Abody%20%7B%0A%20%20margin%3A%200%3B%0A%20%20font-family%3A%20Arial%2C%20Helvetica%2C%20sans-serif%3B%0A%20%20background%3A%20%23f7f8fb%3B%0A%20%20color%3A%20%231f2937%3B%0A%7D%0A%0Amain%20%7B%0A%20%20max-width%3A%20920px%3B%0A%20%20margin%3A%200%20auto%3B%0A%20%20padding%3A%201rem%201rem%202rem%3B%0A%7D%0A%0Ah1%2C%0Ah2%20%7B%0A%20%20margin%3A%200.4rem%200%200.8rem%3B%0A%7D%0A%0A%23canvas-container%20%7B%0A%20%20margin%3A%200.5rem%200%201rem%3B%0A%20%20width%3A%20600px%3B%0A%20%20border%3A%201px%20solid%20%23d1d5db%3B%0A%20%20background%3A%20%23fff%3B%0A%20%20overflow%3A%20hidden%3B%0A%7D%0A%0A%23slider-panel%20%7B%0A%20%20margin%3A%200%3B%0A%20%20width%3A%20auto%3B%0A%20%20padding%3A%200.3rem%200.75rem%200.75rem%3B%0A%20%20background%3A%20transparent%3B%0A%20%20max-width%3A%20100%25%3B%0A%20%20overflow%3A%20hidden%3B%0A%7D%0A%0A%23metrics-line%20%7B%0A%20%20margin%3A%200%200%201rem%3B%0A%20%20color%3A%20%23374151%3B%0A%20%20font-size%3A%200.8rem%3B%0A%7D%0A%0Acanvas%20%7B%0A%20%20display%3A%20block%3B%0A%7D%0A%0A.slider-grid%20%7B%0A%20%20display%3A%20grid%3B%0A%20%20grid-template-columns%3A%20repeat%282%2C%20minmax%280%2C%201fr%29%29%3B%0A%20%20gap%3A%200.75rem%3B%0A%7D%0A%0A.slider-column%20%7B%0A%20%20display%3A%20grid%3B%0A%20%20align-content%3A%20flex-start%3B%0A%20%20grid-auto-rows%3A%20max-content%3B%0A%20%20gap%3A%200.5rem%3B%0A%7D%0A%0A.slider-column-hidden%20.slider-row%3Anth-child%284%29%2C%0A.slider-column-hidden%20.slider-row%3Anth-child%287%29%20%7B%0A%20%20margin-top%3A%200.625rem%3B%0A%7D%0A%0A.slider-column-output%20%7B%0A%20%20gap%3A%201.125rem%3B%0A%7D%0A%0A.slider-row%20%7B%0A%20%20display%3A%20grid%3B%0A%20%20grid-template-columns%3A%20minmax%280%2C%201fr%29%2052px%3B%0A%20%20align-items%3A%20center%3B%0A%20%20gap%3A%200.5rem%3B%0A%7D%0A%0A.weight-slider%20%7B%0A%20%20-webkit-appearance%3A%20none%3B%0A%20%20-moz-appearance%3A%20none%3B%0A%20%20appearance%3A%20none%3B%0A%20%20width%3A%20100%25%3B%0A%20%20min-width%3A%200%3B%0A%20%20height%3A%206px%3B%0A%20%20border-radius%3A%20999px%3B%0A%20%20background%3A%20%236b7280%3B%0A%20%20outline%3A%20none%3B%0A%20%20cursor%3A%20pointer%3B%0A%7D%0A%0A.weight-slider%3A%3A-webkit-slider-runnable-track%20%7B%0A%20%20height%3A%206px%3B%0A%20%20border-radius%3A%20999px%3B%0A%20%20background%3A%20%236b7280%3B%0A%7D%0A%0A.weight-slider%3A%3A-webkit-slider-thumb%20%7B%0A%20%20-webkit-appearance%3A%20none%3B%0A%20%20-moz-appearance%3A%20none%3B%0A%20%20appearance%3A%20none%3B%0A%20%20width%3A%2014px%3B%0A%20%20height%3A%2014px%3B%0A%20%20margin-top%3A%20-4px%3B%0A%20%20border-radius%3A%2050%25%3B%0A%20%20border%3A%200%3B%0A%20%20background%3A%20%23111827%3B%0A%7D%0A%0A.weight-slider%3A%3A-moz-range-track%20%7B%0A%20%20height%3A%206px%3B%0A%20%20border%3A%200%3B%0A%20%20border-radius%3A%20999px%3B%0A%20%20background%3A%20%236b7280%3B%0A%7D%0A%0A.weight-slider%3A%3A-moz-range-thumb%20%7B%0A%20%20width%3A%2014px%3B%0A%20%20height%3A%2014px%3B%0A%20%20border%3A%200%3B%0A%20%20border-radius%3A%2050%25%3B%0A%20%20background%3A%20%23111827%3B%0A%7D%0A%0A.weight-slider%3Ahover%3A%3A-webkit-slider-runnable-track%2C%0A.weight-slider%3Afocus-visible%3A%3A-webkit-slider-runnable-track%2C%0A.weight-slider%3Aactive%3A%3A-webkit-slider-runnable-track%2C%0A.weight-slider.is-engaged%3A%3A-webkit-slider-runnable-track%20%7B%0A%20%20background%3A%20%23f59e0b%3B%0A%7D%0A%0A.weight-slider%3Ahover%3A%3A-webkit-slider-thumb%2C%0A.weight-slider%3Afocus-visible%3A%3A-webkit-slider-thumb%2C%0A.weight-slider%3Aactive%3A%3A-webkit-slider-thumb%2C%0A.weight-slider.is-engaged%3A%3A-webkit-slider-thumb%20%7B%0A%20%20background%3A%20%23f59e0b%3B%0A%7D%0A%0A.weight-slider%3Ahover%3A%3A-moz-range-track%2C%0A.weight-slider%3Afocus-visible%3A%3A-moz-range-track%2C%0A.weight-slider%3Aactive%3A%3A-moz-range-track%2C%0A.weight-slider.is-engaged%3A%3A-moz-range-track%20%7B%0A%20%20background%3A%20%23f59e0b%3B%0A%7D%0A%0A.weight-slider%3Ahover%3A%3A-moz-range-thumb%2C%0A.weight-slider%3Afocus-visible%3A%3A-moz-range-thumb%2C%0A.weight-slider%3Aactive%3A%3A-moz-range-thumb%2C%0A.weight-slider.is-engaged%3A%3A-moz-range-thumb%20%7B%0A%20%20background%3A%20%23f59e0b%3B%0A%7D%0A%0A.slider-value%20%7B%0A%20%20text-align%3A%20right%3B%0A%20%20font-family%3A%20ui-monospace%2C%20SFMono-Regular%2C%20Menlo%2C%20Consolas%2C%20monospace%3B%0A%20%20font-size%3A%200.9rem%3B%0A%20%20color%3A%20%23111827%3B%0A%7D%0A%0A.slider-actions%20%7B%0A%20%20margin-top%3A%20-2rem%3B%0A%20%20display%3A%20flex%3B%0A%20%20justify-content%3A%20flex-end%3B%0A%20%20gap%3A%200.5rem%3B%0A%20%20flex-wrap%3A%20wrap%3B%0A%7D%0A%0A.weight-action-btn%20%7B%0A%20%20border%3A%201px%20solid%20%239ca3af%3B%0A%20%20background%3A%20%23ffffff%3B%0A%20%20color%3A%20%23111827%3B%0A%20%20font-size%3A%200.85rem%3B%0A%20%20font-weight%3A%20600%3B%0A%20%20border-radius%3A%206px%3B%0A%20%20padding%3A%200.35rem%200.6rem%3B%0A%20%20cursor%3A%20pointer%3B%0A%7D%0A%0A.weight-action-btn%3Ahover%2C%0A.weight-action-btn%3Afocus-visible%20%7B%0A%20%20border-color%3A%20%23f59e0b%3B%0A%20%20color%3A%20%2392400e%3B%0A%20%20outline%3A%20none%3B%0A%7D%0A%0A%23console-output%20%7B%0A%20%20margin%3A%200%3B%0A%20%20max-height%3A%20280px%3B%0A%20%20overflow%3A%20auto%3B%0A%20%20background%3A%20%230f172a%3B%0A%20%20color%3A%20%23e2e8f0%3B%0A%20%20padding%3A%200.75rem%3B%0A%20%20border-radius%3A%208px%3B%0A%20%20font-size%3A%200.85rem%3B%0A%7D%0A&html=%3Cscript%20src%3D%22https%3A%2F%2Fapp.exorciser.ch%2Flib%2Fp5.js%22%3E%3C%2Fscript%3E%0A%3Cscript%20src%3D%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2F%40tensorflow%2Ftfjs%40latest%2Fdist%2Ftf.min.js%22%3E%3C%2Fscript%3E&autorun=on&height=750px#Gewichte}} |
| | </WRAP> |
| \\ | \\ |
| ===== - Aber was bedeutet das nun für Sigrún? ====== | ===== - Aber was bedeutet das nun für Sigrún? ====== |
| 😄 Sigrún freut sich zuerst darüber, dass es dir gelungen ist, einen so guten Fischsortierapparat zu bauen. Der Apparat liefert keine perfekten Resultate, aber der grösste Teil der Fische wird richtig sortiert. | 😄 Sigrún freut sich zuerst darüber, dass es dir gelungen ist, einen so guten Fischsortierapparat zu bauen. Der Apparat liefert keine perfekten Resultate, aber der grösste Teil der Fische wird richtig sortiert. |
| |
| 😭 Dann realisiert Sigrún jedoch, dass im Hering-Korb immer noch zu viele Lodde und im Lodde-Korb immer noch zu viele Heringe zu liegen kommen. Somit müsste sie alle Fische in beiden Körben von Hand nachkontrollieren! Der Fischsortierapparat ist trotz seiner "Intelligenz" für Sigrún immer noch nutzlos. | 😭 Dann realisiert Sigrún jedoch, dass im Hering-Korb immer noch zu viele Lodden und im Lodde-Korb immer noch zu viele Heringe zu liegen kommen. Somit müsste sie alle Fische in beiden Körben von Hand nachkontrollieren! Der Fischsortierapparat ist trotz seiner "Intelligenz" für Sigrún immer noch nutzlos. |
| |
| \\ | \\ |