ProCreations commited on
Commit
949a9db
·
verified ·
1 Parent(s): 3b2aa47

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +2102 -19
index.html CHANGED
@@ -1,19 +1,2102 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>🧠 AI Learning Lab</title>
7
+ <style>
8
+ * {
9
+ box-sizing: border-box;
10
+ margin: 0;
11
+ padding: 0;
12
+ }
13
+
14
+ body {
15
+ font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
16
+ background: linear-gradient(135deg, #111827 0%, #1f2937 50%, #111827 100%);
17
+ color: white;
18
+ min-height: 100vh;
19
+ padding: 1rem;
20
+ }
21
+
22
+ .container {
23
+ max-width: 1200px;
24
+ margin: 0 auto;
25
+ }
26
+
27
+ /* Main Category Menu */
28
+ .main-menu {
29
+ min-height: 100vh;
30
+ display: flex;
31
+ flex-direction: column;
32
+ align-items: center;
33
+ justify-content: center;
34
+ text-align: center;
35
+ }
36
+
37
+ .main-header {
38
+ margin-bottom: 3rem;
39
+ }
40
+
41
+ .main-title {
42
+ font-size: 4rem;
43
+ font-weight: bold;
44
+ margin-bottom: 1rem;
45
+ background: linear-gradient(135deg, #06b6d4, #8b5cf6, #f59e0b);
46
+ -webkit-background-clip: text;
47
+ -webkit-text-fill-color: transparent;
48
+ background-clip: text;
49
+ }
50
+
51
+ .main-subtitle {
52
+ font-size: 1.5rem;
53
+ color: #d1d5db;
54
+ max-width: 800px;
55
+ }
56
+
57
+ .category-grid {
58
+ display: grid;
59
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
60
+ gap: 2rem;
61
+ width: 100%;
62
+ max-width: 1000px;
63
+ }
64
+
65
+ .category-card {
66
+ background: #1f2937;
67
+ border: 3px solid #374151;
68
+ border-radius: 1.5rem;
69
+ padding: 2.5rem;
70
+ cursor: pointer;
71
+ transition: all 0.4s ease;
72
+ position: relative;
73
+ overflow: hidden;
74
+ }
75
+
76
+ .category-card:hover {
77
+ transform: translateY(-8px);
78
+ box-shadow: 0 25px 50px rgba(6, 182, 212, 0.2);
79
+ }
80
+
81
+ .category-card.fundamentals { border-color: #06b6d4; }
82
+ .category-card.fundamentals:hover { box-shadow: 0 25px 50px rgba(6, 182, 212, 0.3); }
83
+
84
+ .category-card.extras { border-color: #8b5cf6; }
85
+ .category-card.extras:hover { box-shadow: 0 25px 50px rgba(139, 92, 246, 0.3); }
86
+
87
+ .category-card.baby { border-color: #f59e0b; }
88
+ .category-card.baby:hover { box-shadow: 0 25px 50px rgba(245, 158, 11, 0.3); }
89
+
90
+ .category-card.developer { border-color: #ef4444; }
91
+ .category-card.developer:hover { box-shadow: 0 25px 50px rgba(239, 68, 68, 0.3); }
92
+
93
+ .category-icon {
94
+ font-size: 4rem;
95
+ margin-bottom: 1.5rem;
96
+ }
97
+
98
+ .category-title {
99
+ font-size: 2rem;
100
+ font-weight: bold;
101
+ margin-bottom: 1rem;
102
+ }
103
+
104
+ .category-description {
105
+ color: #d1d5db;
106
+ line-height: 1.6;
107
+ margin-bottom: 1rem;
108
+ }
109
+
110
+ .category-count {
111
+ font-size: 0.875rem;
112
+ color: #9ca3af;
113
+ font-weight: 600;
114
+ }
115
+
116
+ /* Task Selection Menu */
117
+ .task-selection {
118
+ display: none;
119
+ min-height: 100vh;
120
+ padding: 2rem 0;
121
+ }
122
+
123
+ .task-header {
124
+ text-align: center;
125
+ margin-bottom: 3rem;
126
+ position: relative;
127
+ }
128
+
129
+ .task-back-btn {
130
+ position: absolute;
131
+ left: 0;
132
+ top: 50%;
133
+ transform: translateY(-50%);
134
+ background: #374151;
135
+ border: none;
136
+ color: white;
137
+ padding: 0.75rem 1.5rem;
138
+ border-radius: 0.5rem;
139
+ cursor: pointer;
140
+ transition: background 0.3s;
141
+ }
142
+
143
+ .task-back-btn:hover {
144
+ background: #4b5563;
145
+ }
146
+
147
+ .task-title {
148
+ font-size: 2.5rem;
149
+ font-weight: bold;
150
+ margin-bottom: 0.5rem;
151
+ }
152
+
153
+ .task-subtitle {
154
+ font-size: 1.125rem;
155
+ color: #d1d5db;
156
+ }
157
+
158
+ .task-grid {
159
+ display: grid;
160
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
161
+ gap: 1.5rem;
162
+ width: 100%;
163
+ }
164
+
165
+ .task-card {
166
+ background: #1f2937;
167
+ border: 2px solid #374151;
168
+ border-radius: 1rem;
169
+ padding: 2rem;
170
+ cursor: pointer;
171
+ transition: all 0.3s ease;
172
+ position: relative;
173
+ overflow: hidden;
174
+ }
175
+
176
+ .task-card:hover {
177
+ border-color: #06b6d4;
178
+ transform: translateY(-4px);
179
+ box-shadow: 0 20px 40px rgba(6, 182, 212, 0.15);
180
+ }
181
+
182
+ .task-icon {
183
+ font-size: 3rem;
184
+ margin-bottom: 1rem;
185
+ }
186
+
187
+ .task-name {
188
+ font-size: 1.5rem;
189
+ font-weight: bold;
190
+ margin-bottom: 0.5rem;
191
+ color: white;
192
+ }
193
+
194
+ .task-difficulty {
195
+ display: inline-block;
196
+ padding: 0.25rem 0.75rem;
197
+ border-radius: 1rem;
198
+ font-size: 0.75rem;
199
+ font-weight: 600;
200
+ margin-bottom: 1rem;
201
+ }
202
+
203
+ .difficulty-easy { background: #065f46; color: #10b981; }
204
+ .difficulty-medium { background: #92400e; color: #f59e0b; }
205
+ .difficulty-hard { background: #7c2d12; color: #ef4444; }
206
+
207
+ .task-description {
208
+ color: #d1d5db;
209
+ line-height: 1.6;
210
+ margin-bottom: 1rem;
211
+ }
212
+
213
+ .task-specs {
214
+ font-size: 0.875rem;
215
+ color: #9ca3af;
216
+ }
217
+
218
+ /* Developer Mode */
219
+ .developer-form {
220
+ background: #1f2937;
221
+ border: 2px solid #374151;
222
+ border-radius: 1rem;
223
+ padding: 2rem;
224
+ margin-bottom: 2rem;
225
+ }
226
+
227
+ .form-group {
228
+ margin-bottom: 1.5rem;
229
+ }
230
+
231
+ .form-label {
232
+ display: block;
233
+ margin-bottom: 0.5rem;
234
+ font-weight: 600;
235
+ color: white;
236
+ }
237
+
238
+ .form-input, .form-select, .form-textarea {
239
+ width: 100%;
240
+ padding: 0.75rem;
241
+ border: 1px solid #4b5563;
242
+ border-radius: 0.5rem;
243
+ background: #111827;
244
+ color: white;
245
+ font-size: 0.875rem;
246
+ }
247
+
248
+ .form-textarea {
249
+ min-height: 100px;
250
+ resize: vertical;
251
+ }
252
+
253
+ .param-counter {
254
+ color: #f59e0b;
255
+ font-size: 0.875rem;
256
+ margin-top: 0.25rem;
257
+ }
258
+
259
+ .param-counter.over-limit {
260
+ color: #ef4444;
261
+ }
262
+
263
+ /* Training Interface */
264
+ .training-interface {
265
+ display: none;
266
+ }
267
+
268
+ .header {
269
+ text-align: center;
270
+ margin-bottom: 2rem;
271
+ }
272
+
273
+ .header-title {
274
+ display: flex;
275
+ align-items: center;
276
+ justify-content: center;
277
+ gap: 0.75rem;
278
+ margin-bottom: 1rem;
279
+ }
280
+
281
+ .back-btn {
282
+ position: absolute;
283
+ left: 0;
284
+ background: #374151;
285
+ border: none;
286
+ color: white;
287
+ padding: 0.5rem 1rem;
288
+ border-radius: 0.5rem;
289
+ cursor: pointer;
290
+ transition: background 0.3s;
291
+ }
292
+
293
+ .back-btn:hover {
294
+ background: #4b5563;
295
+ }
296
+
297
+ .brain-icon {
298
+ width: 2rem;
299
+ height: 2rem;
300
+ color: #06b6d4;
301
+ }
302
+
303
+ .title {
304
+ font-size: 1.875rem;
305
+ font-weight: bold;
306
+ color: white;
307
+ }
308
+
309
+ .subtitle {
310
+ color: #d1d5db;
311
+ max-width: 32rem;
312
+ margin: 0 auto;
313
+ }
314
+
315
+ .control-panel {
316
+ background: #1f2937;
317
+ border: 1px solid #374151;
318
+ border-radius: 0.5rem;
319
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
320
+ padding: 1.5rem;
321
+ margin-bottom: 1.5rem;
322
+ text-align: center;
323
+ }
324
+
325
+ .controls {
326
+ display: flex;
327
+ flex-wrap: wrap;
328
+ align-items: center;
329
+ justify-content: center;
330
+ gap: 1rem;
331
+ }
332
+
333
+ .btn {
334
+ display: flex;
335
+ align-items: center;
336
+ gap: 0.5rem;
337
+ padding: 0.75rem 1.5rem;
338
+ border-radius: 0.5rem;
339
+ font-weight: 600;
340
+ border: none;
341
+ cursor: pointer;
342
+ transition: all 0.3s ease;
343
+ color: white;
344
+ }
345
+
346
+ .btn-start {
347
+ background: #059669;
348
+ box-shadow: 0 10px 15px -3px rgba(5, 150, 105, 0.25);
349
+ }
350
+
351
+ .btn-start:hover { background: #047857; }
352
+
353
+ .btn-pause {
354
+ background: #dc2626;
355
+ box-shadow: 0 10px 15px -3px rgba(220, 38, 38, 0.25);
356
+ }
357
+
358
+ .btn-pause:hover { background: #b91c1c; }
359
+
360
+ .btn-reset {
361
+ background: #4b5563;
362
+ box-shadow: 0 10px 15px -3px rgba(75, 85, 99, 0.25);
363
+ }
364
+
365
+ .btn-reset:hover { background: #374151; }
366
+
367
+ .stats-grid {
368
+ display: grid;
369
+ grid-template-columns: repeat(2, 1fr);
370
+ gap: 1rem;
371
+ margin-bottom: 1.5rem;
372
+ }
373
+
374
+ @media (min-width: 768px) {
375
+ .stats-grid {
376
+ grid-template-columns: repeat(4, 1fr);
377
+ }
378
+ }
379
+
380
+ .stat-card {
381
+ background: #1f2937;
382
+ border: 1px solid #374151;
383
+ border-radius: 0.5rem;
384
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
385
+ padding: 1rem;
386
+ text-align: center;
387
+ }
388
+
389
+ .stat-value {
390
+ font-size: 1.5rem;
391
+ font-weight: bold;
392
+ margin-bottom: 0.25rem;
393
+ }
394
+
395
+ .stat-value.cyan { color: #06b6d4; }
396
+ .stat-value.purple { color: #a855f7; }
397
+ .stat-value.green { color: #10b981; }
398
+ .stat-value.orange { color: #f59e0b; }
399
+
400
+ .stat-label {
401
+ font-size: 0.875rem;
402
+ color: #9ca3af;
403
+ }
404
+
405
+ .main-grid {
406
+ display: grid;
407
+ gap: 1.5rem;
408
+ margin-bottom: 1.5rem;
409
+ }
410
+
411
+ @media (min-width: 768px) {
412
+ .main-grid {
413
+ grid-template-columns: repeat(2, 1fr);
414
+ }
415
+ }
416
+
417
+ .card {
418
+ background: #1f2937;
419
+ border: 1px solid #374151;
420
+ border-radius: 0.5rem;
421
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
422
+ padding: 1.5rem;
423
+ }
424
+
425
+ .card-title {
426
+ font-size: 1.125rem;
427
+ font-weight: 600;
428
+ margin-bottom: 1rem;
429
+ color: white;
430
+ display: flex;
431
+ align-items: center;
432
+ gap: 0.5rem;
433
+ }
434
+
435
+ .network-canvas {
436
+ width: 100%;
437
+ height: auto;
438
+ border: 1px solid #4b5563;
439
+ border-radius: 0.5rem;
440
+ background: #111827;
441
+ }
442
+
443
+ .network-labels {
444
+ margin-top: 1rem;
445
+ font-size: 0.875rem;
446
+ color: #9ca3af;
447
+ display: flex;
448
+ justify-content: space-between;
449
+ }
450
+
451
+ .chart-container {
452
+ height: 16rem;
453
+ background: #111827;
454
+ border: 1px solid #4b5563;
455
+ border-radius: 0.5rem;
456
+ position: relative;
457
+ overflow: hidden;
458
+ }
459
+
460
+ .chart-info {
461
+ position: absolute;
462
+ bottom: 0.5rem;
463
+ left: 0.5rem;
464
+ font-size: 0.75rem;
465
+ color: #9ca3af;
466
+ background: #1f2937;
467
+ padding: 0.25rem 0.5rem;
468
+ border-radius: 0.25rem;
469
+ }
470
+
471
+ .task-grid-output {
472
+ display: grid;
473
+ grid-template-columns: repeat(2, 1fr);
474
+ gap: 1rem;
475
+ margin-top: 1.5rem;
476
+ }
477
+
478
+ @media (min-width: 768px) {
479
+ .task-grid-output {
480
+ grid-template-columns: repeat(4, 1fr);
481
+ }
482
+ }
483
+
484
+ .output-card {
485
+ padding: 1rem;
486
+ border-radius: 0.5rem;
487
+ border: 2px solid;
488
+ transition: all 0.3s ease;
489
+ text-align: center;
490
+ }
491
+
492
+ .output-card.current {
493
+ border-color: #06b6d4;
494
+ background: rgba(6, 182, 212, 0.1);
495
+ box-shadow: 0 10px 15px -3px rgba(6, 182, 212, 0.2);
496
+ }
497
+
498
+ .output-card.correct {
499
+ border-color: #10b981;
500
+ background: rgba(16, 185, 129, 0.1);
501
+ }
502
+
503
+ .output-card.wrong {
504
+ border-color: #ef4444;
505
+ background: rgba(239, 68, 68, 0.1);
506
+ }
507
+
508
+ .output-io {
509
+ font-size: 1.125rem;
510
+ font-family: monospace;
511
+ font-weight: bold;
512
+ color: white;
513
+ margin-bottom: 0.25rem;
514
+ }
515
+
516
+ .output-raw {
517
+ font-size: 0.875rem;
518
+ color: #9ca3af;
519
+ margin-bottom: 0.25rem;
520
+ }
521
+
522
+ .output-predicted {
523
+ font-size: 0.875rem;
524
+ font-weight: 600;
525
+ color: white;
526
+ margin-bottom: 0.25rem;
527
+ }
528
+
529
+ .output-status {
530
+ font-size: 0.75rem;
531
+ }
532
+
533
+ .output-status.correct { color: #10b981; }
534
+ .output-status.wrong { color: #ef4444; }
535
+
536
+ .info-section {
537
+ background: linear-gradient(135deg, #06b6d4 0%, #8b5cf6 100%);
538
+ border-radius: 0.5rem;
539
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
540
+ padding: 1.5rem;
541
+ color: white;
542
+ }
543
+
544
+ .info-title {
545
+ font-size: 1.125rem;
546
+ font-weight: 600;
547
+ margin-bottom: 1rem;
548
+ }
549
+
550
+ .info-grid {
551
+ display: grid;
552
+ gap: 1rem;
553
+ font-size: 0.875rem;
554
+ }
555
+
556
+ @media (min-width: 768px) {
557
+ .info-grid {
558
+ grid-template-columns: repeat(3, 1fr);
559
+ }
560
+ }
561
+
562
+ .icon {
563
+ width: 1.25rem;
564
+ height: 1.25rem;
565
+ fill: currentColor;
566
+ }
567
+
568
+ .icon-stroke {
569
+ fill: none;
570
+ stroke: currentColor;
571
+ stroke-width: 2;
572
+ }
573
+
574
+ .data-viz {
575
+ width: 100%;
576
+ height: 300px;
577
+ border: 1px solid #4b5563;
578
+ border-radius: 0.5rem;
579
+ background: #111827;
580
+ margin-top: 1rem;
581
+ }
582
+
583
+ /* Baby Mode Styles */
584
+ .baby-viz {
585
+ background: linear-gradient(135deg, #fef3c7, #fde68a);
586
+ border-radius: 1rem;
587
+ padding: 2rem;
588
+ color: #92400e;
589
+ margin-top: 1rem;
590
+ text-align: center;
591
+ }
592
+
593
+ .baby-neuron {
594
+ display: inline-block;
595
+ width: 60px;
596
+ height: 60px;
597
+ border-radius: 50%;
598
+ margin: 0.5rem;
599
+ line-height: 60px;
600
+ font-weight: bold;
601
+ font-size: 1.2rem;
602
+ animation: bounce 2s infinite;
603
+ }
604
+
605
+ @keyframes bounce {
606
+ 0%, 20%, 50%, 80%, 100% { transform: translateY(0); }
607
+ 40% { transform: translateY(-10px); }
608
+ 60% { transform: translateY(-5px); }
609
+ }
610
+
611
+ .baby-connection {
612
+ stroke: #f59e0b;
613
+ stroke-width: 3;
614
+ animation: pulse 1.5s infinite;
615
+ }
616
+
617
+ @keyframes pulse {
618
+ 0% { opacity: 0.5; }
619
+ 50% { opacity: 1; }
620
+ 100% { opacity: 0.5; }
621
+ }
622
+ </style>
623
+ </head>
624
+ <body>
625
+ <div class="container">
626
+ <!-- Main Category Menu -->
627
+ <div id="mainMenu" class="main-menu">
628
+ <div class="main-header">
629
+ <h1 class="main-title">🧠 AI Learning Lab</h1>
630
+ <p class="main-subtitle">Explore different ways to learn about artificial intelligence - from basics to advanced!</p>
631
+ </div>
632
+
633
+ <div class="category-grid">
634
+ <div class="category-card fundamentals" onclick="showCategory('fundamentals')">
635
+ <div class="category-icon">🎯</div>
636
+ <h3 class="category-title">Fundamentals</h3>
637
+ <p class="category-description">Master the core concepts of neural networks with classic problems like logic gates and pattern recognition.</p>
638
+ <div class="category-count">6 Interactive Tasks</div>
639
+ </div>
640
+
641
+ <div class="category-card extras" onclick="showCategory('extras')">
642
+ <div class="category-icon">🚀</div>
643
+ <h3 class="category-title">Extras</h3>
644
+ <p class="category-description">Explore advanced techniques like autoencoders, GANs, and reinforcement learning in action.</p>
645
+ <div class="category-count">4 Advanced Techniques</div>
646
+ </div>
647
+
648
+ <div class="category-card baby" onclick="showCategory('baby')">
649
+ <div class="category-icon">🎈</div>
650
+ <h3 class="category-title">Baby Mode</h3>
651
+ <p class="category-description">Fun, colorful, and super simple explanations perfect for beginners of any age!</p>
652
+ <div class="category-count">5 Fun Activities</div>
653
+ </div>
654
+
655
+ <div class="category-card developer" onclick="showCategory('developer')">
656
+ <div class="category-icon">⚙️</div>
657
+ <h3 class="category-title">Developer</h3>
658
+ <p class="category-description">Create your own datasets and experiments. Full control over network architecture and training.</p>
659
+ <div class="category-count">Custom Everything</div>
660
+ </div>
661
+ </div>
662
+ </div>
663
+
664
+ <!-- Task Selection Menus -->
665
+ <div id="taskSelection" class="task-selection">
666
+ <div class="task-header">
667
+ <button class="task-back-btn" onclick="goBackToMain()">← Back to Categories</button>
668
+ <h2 id="categoryTitle" class="task-title">Fundamentals</h2>
669
+ <p id="categorySubtitle" class="task-subtitle">Master neural network basics</p>
670
+ </div>
671
+ <div id="taskGrid" class="task-grid">
672
+ <!-- Tasks will be populated by JavaScript -->
673
+ </div>
674
+ </div>
675
+
676
+ <!-- Developer Mode -->
677
+ <div id="developerMode" class="task-selection">
678
+ <div class="task-header">
679
+ <button class="task-back-btn" onclick="goBackToMain()">← Back to Categories</button>
680
+ <h2 class="task-title">Developer Mode</h2>
681
+ <p class="task-subtitle">Create custom AI experiments</p>
682
+ </div>
683
+
684
+ <div class="developer-form">
685
+ <div class="form-group">
686
+ <label class="form-label">Task Name</label>
687
+ <input type="text" id="devTaskName" class="form-input" placeholder="My Custom Task" value="Custom Task">
688
+ </div>
689
+
690
+ <div class="form-group">
691
+ <label class="form-label">Network Architecture (comma-separated)</label>
692
+ <input type="text" id="devArchitecture" class="form-input" placeholder="2,8,4,1" value="2,8,4,1">
693
+ <div id="paramCount" class="param-counter">Parameters: 0 / 5000</div>
694
+ </div>
695
+
696
+ <div class="form-group">
697
+ <label class="form-label">Learning Rate</label>
698
+ <input type="number" id="devLearningRate" class="form-input" step="0.01" min="0.01" max="1" value="0.2">
699
+ </div>
700
+
701
+ <div class="form-group">
702
+ <label class="form-label">Training Data (JSON format: [{"input": [x,y], "target": [z], "label": "text"}])</label>
703
+ <textarea id="devData" class="form-textarea" placeholder='[{"input": [0,0], "target": [0], "label": "0,0 → 0"}]'>[{"input": [0,0], "target": [0], "label": "0,0 → 0"},{"input": [0,1], "target": [1], "label": "0,1 → 1"},{"input": [1,0], "target": [1], "label": "1,0 → 1"},{"input": [1,1], "target": [0], "label": "1,1 → 0"}]</textarea>
704
+ </div>
705
+
706
+ <button id="createCustomTask" class="btn btn-start" onclick="createCustomTask()">
707
+ <svg class="icon" fill="currentColor" viewBox="0 0 24 24">
708
+ <path d="M12 5v14m-7-7h14"/>
709
+ </svg>
710
+ Create & Train
711
+ </button>
712
+ </div>
713
+ </div>
714
+
715
+ <!-- Training Interface -->
716
+ <div id="trainingInterface" class="training-interface">
717
+ <div class="header">
718
+ <div class="header-title" style="position: relative;">
719
+ <button id="backBtn" class="back-btn">← Back</button>
720
+ <svg class="brain-icon" fill="currentColor" viewBox="0 0 24 24">
721
+ <path d="M12 2C8.5 2 6 4.5 6 8c0 1.5.5 3 1.5 4C6.5 13 6 14.5 6 16c0 3.5 2.5 6 6 6s6-2.5 6-6c0-1.5-.5-3-1.5-4 1-1 1.5-2.5 1.5-4 0-3.5-2.5-6-6-6z"/>
722
+ </svg>
723
+ <h1 id="taskTitle" class="title">AI Task Trainer</h1>
724
+ </div>
725
+ <p id="taskSubtitle" class="subtitle">Watch the neural network learn in real-time</p>
726
+ </div>
727
+
728
+ <div class="control-panel">
729
+ <div class="controls">
730
+ <button id="trainBtn" class="btn btn-start">
731
+ <svg class="icon" fill="currentColor" viewBox="0 0 24 24">
732
+ <path d="M8 5v14l11-7z"/>
733
+ </svg>
734
+ Start Training
735
+ </button>
736
+ <button id="resetBtn" class="btn btn-reset">
737
+ <svg class="icon icon-stroke" viewBox="0 0 24 24">
738
+ <polyline points="1 4 1 10 7 10"></polyline>
739
+ <path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path>
740
+ </svg>
741
+ Reset
742
+ </button>
743
+ </div>
744
+ </div>
745
+
746
+ <div class="stats-grid">
747
+ <div class="stat-card">
748
+ <div id="epochValue" class="stat-value cyan">0</div>
749
+ <div class="stat-label">Epochs</div>
750
+ </div>
751
+ <div class="stat-card">
752
+ <div id="lossValue" class="stat-value purple">1.000000</div>
753
+ <div class="stat-label">Avg Loss</div>
754
+ </div>
755
+ <div class="stat-card">
756
+ <div id="accuracyValue" class="stat-value green">0.0%</div>
757
+ <div class="stat-label">Accuracy</div>
758
+ </div>
759
+ <div class="stat-card">
760
+ <div id="currentValue" class="stat-value orange">-</div>
761
+ <div class="stat-label">Current</div>
762
+ </div>
763
+ </div>
764
+
765
+ <div class="main-grid">
766
+ <div class="card">
767
+ <h3 class="card-title">
768
+ <svg class="icon icon-stroke" viewBox="0 0 24 24">
769
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
770
+ <circle cx="12" cy="12" r="3"></circle>
771
+ </svg>
772
+ Network Architecture
773
+ </h3>
774
+ <canvas id="networkCanvas" class="network-canvas" width="400" height="300"></canvas>
775
+ <div id="networkLabels" class="network-labels">
776
+ <span>Input</span>
777
+ <span>Hidden</span>
778
+ <span>Output</span>
779
+ </div>
780
+ <div id="babyViz" class="baby-viz" style="display: none;">
781
+ <h4>🧠 AI Brain Thinking!</h4>
782
+ <div id="babyNeurons"></div>
783
+ <p>Watch the colorful neurons light up as the AI learns!</p>
784
+ </div>
785
+ </div>
786
+
787
+ <div class="card">
788
+ <h3 class="card-title">
789
+ <svg class="icon icon-stroke" viewBox="0 0 24 24">
790
+ <polyline points="23 18 13.5 8.5 8.5 13.5 1 6"></polyline>
791
+ <polyline points="17 18 23 18 23 12"></polyline>
792
+ </svg>
793
+ <span id="vizTitle">Training Progress</span>
794
+ </h3>
795
+ <div id="chartContainer" class="chart-container">
796
+ <svg id="lossChart" width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
797
+ <defs>
798
+ <linearGradient id="lossGradient" x1="0%" y1="0%" x2="0%" y2="100%">
799
+ <stop offset="0%" stop-color="#06b6d4" stop-opacity="0.8"/>
800
+ <stop offset="100%" stop-color="#06b6d4" stop-opacity="0.2"/>
801
+ </linearGradient>
802
+ </defs>
803
+ <polyline id="lossLine" fill="none" stroke="#06b6d4" stroke-width="0.5" points=""/>
804
+ <polygon id="lossArea" fill="url(#lossGradient)" points=""/>
805
+ </svg>
806
+ <canvas id="dataViz" class="data-viz" style="display: none;"></canvas>
807
+ <div class="chart-info">
808
+ Loss: <span id="currentLoss">1.000000</span>
809
+ </div>
810
+ </div>
811
+ </div>
812
+ </div>
813
+
814
+ <div class="card">
815
+ <h3 class="card-title">
816
+ <svg class="icon" fill="currentColor" viewBox="0 0 24 24">
817
+ <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon>
818
+ </svg>
819
+ <span id="outputTitle">Task Output</span>
820
+ </h3>
821
+ <div class="task-grid-output" id="taskOutput"></div>
822
+ </div>
823
+
824
+ <div class="info-section">
825
+ <h3 class="info-title">How it works</h3>
826
+ <div class="info-grid" id="infoContent"></div>
827
+ </div>
828
+ </div>
829
+ </div>
830
+
831
+ <script>
832
+ // Task categories
833
+ const CATEGORIES = {
834
+ fundamentals: {
835
+ title: 'Fundamentals',
836
+ subtitle: 'Master neural network basics with classic problems',
837
+ tasks: {
838
+ and: {
839
+ title: 'AND Gate Learning',
840
+ subtitle: 'Learning the AND logic gate - output 1 only when both inputs are 1',
841
+ architecture: [2, 4, 1],
842
+ learningRate: 0.3,
843
+ isRegression: false,
844
+ data: [
845
+ { input: [0, 0], target: [0], label: "0,0 → 0" },
846
+ { input: [0, 1], target: [0], label: "0,1 → 0" },
847
+ { input: [1, 0], target: [0], label: "1,0 → 0" },
848
+ { input: [1, 1], target: [1], label: "1,1 → 1" }
849
+ ],
850
+ info: [
851
+ "The Problem: AND gate outputs 1 only when both inputs are 1. This is linearly separable and easier to learn.",
852
+ "The Network: Simple 2→4→1 architecture with ReLU activation. The simplicity matches the problem complexity.",
853
+ "The Training: Shows how even simple networks can learn basic logic. Notice the clear decision boundary."
854
+ ]
855
+ },
856
+ or: {
857
+ title: 'OR Gate Learning',
858
+ subtitle: 'Learning the OR logic gate - output 1 when at least one input is 1',
859
+ architecture: [2, 4, 1],
860
+ learningRate: 0.3,
861
+ isRegression: false,
862
+ data: [
863
+ { input: [0, 0], target: [0], label: "0,0 → 0" },
864
+ { input: [0, 1], target: [1], label: "0,1 → 1" },
865
+ { input: [1, 0], target: [1], label: "1,0 → 1" },
866
+ { input: [1, 1], target: [1], label: "1,1 → 1" }
867
+ ],
868
+ info: [
869
+ "The Problem: OR gate outputs 1 when at least one input is 1. Also linearly separable and learns quickly.",
870
+ "The Network: Same 2→4→1 architecture as AND gate. Different data, same network - shows versatility.",
871
+ "The Training: Demonstrates how network weights adapt to different logic patterns with identical architecture."
872
+ ]
873
+ },
874
+ xor: {
875
+ title: 'XOR Gate Learning',
876
+ subtitle: 'Learning the XOR logic gate - the classic non-linear problem requiring hidden layers',
877
+ architecture: [2, 12, 8, 1],
878
+ learningRate: 0.3,
879
+ isRegression: false,
880
+ data: [
881
+ { input: [0, 0], target: [0], label: "0,0 → 0" },
882
+ { input: [0, 1], target: [1], label: "0,1 → 1" },
883
+ { input: [1, 0], target: [1], label: "1,0 → 1" },
884
+ { input: [1, 1], target: [0], label: "1,1 → 0" }
885
+ ],
886
+ info: [
887
+ "The Problem: XOR outputs 1 when inputs differ. Not linearly separable - requires multiple layers to solve.",
888
+ "The Network: Deeper 2→12→8→1 architecture needed. Hidden layers create complex decision boundaries.",
889
+ "The Training: Shows why deep learning exists - some problems need multiple layers to represent solutions."
890
+ ]
891
+ },
892
+ classification: {
893
+ title: '2D Classification',
894
+ subtitle: 'Learning to separate red and blue points in 2D space',
895
+ architecture: [2, 8, 6, 1],
896
+ learningRate: 0.2,
897
+ isRegression: false,
898
+ data: generateClassificationData(),
899
+ info: [
900
+ "The Problem: Classify points as red (0) or blue (1) based on their 2D coordinates. Real-world classification example.",
901
+ "The Network: 2→8→6→1 architecture learns non-linear decision boundaries to separate the classes.",
902
+ "The Training: Visualizes how networks create decision boundaries. Each neuron contributes to the final classification."
903
+ ],
904
+ hasVisualization: true
905
+ },
906
+ sine: {
907
+ title: 'Sine Wave Approximation',
908
+ subtitle: 'Learning to approximate the sine function - regression with neural networks',
909
+ architecture: [1, 12, 8, 1],
910
+ learningRate: 0.1,
911
+ isRegression: true,
912
+ data: generateSineData(),
913
+ info: [
914
+ "The Problem: Learn to approximate sin(x) function. Shows how networks can learn continuous functions.",
915
+ "The Network: 1→12→8→1 architecture with single input/output. ReLU layers approximate smooth curves.",
916
+ "The Training: Demonstrates function approximation capabilities. Watch the network learn the wave pattern."
917
+ ],
918
+ hasVisualization: true
919
+ },
920
+ spiral: {
921
+ title: 'Spiral Classification',
922
+ subtitle: 'Learning to classify points in a complex spiral pattern - a challenging non-linear problem',
923
+ architecture: [2, 16, 12, 8, 1],
924
+ learningRate: 0.15,
925
+ isRegression: false,
926
+ data: generateSpiralData(),
927
+ info: [
928
+ "The Problem: Classify points in two interleaved spirals. Very complex non-linear decision boundary needed.",
929
+ "The Network: Deep 2→16→12→8→1 architecture required for this challenging pattern recognition task.",
930
+ "The Training: Shows the limits of what neural networks can learn. Complex patterns need deeper networks."
931
+ ],
932
+ hasVisualization: true
933
+ }
934
+ }
935
+ },
936
+ extras: {
937
+ title: 'Extra Techniques',
938
+ subtitle: 'Explore advanced AI methods and architectures',
939
+ tasks: {
940
+ autoencoder: {
941
+ title: 'Autoencoder',
942
+ subtitle: 'Learn to compress and reconstruct simple patterns - unsupervised learning in action',
943
+ architecture: [4, 2, 4],
944
+ learningRate: 0.3,
945
+ isRegression: true,
946
+ data: generateAutoencoderData(),
947
+ info: [
948
+ "The Problem: Compress 4D patterns into 2D and reconstruct them perfectly. Learn efficient data representations.",
949
+ "The Network: 4→2→4 hourglass forces compression. Middle layer captures essential features.",
950
+ "The Training: Watch the network learn to encode and decode simple binary patterns."
951
+ ]
952
+ },
953
+ rnn: {
954
+ title: 'Simple RNN',
955
+ subtitle: 'Sequential pattern learning - predicting alternating patterns',
956
+ architecture: [1, 6, 1],
957
+ learningRate: 0.4,
958
+ isRegression: false,
959
+ data: generateSequenceData(),
960
+ info: [
961
+ "The Problem: Learn simple alternating pattern (0→1→0→1). Foundation of sequence modeling.",
962
+ "The Network: 1→6→1 learns temporal dependencies. Simplified version of recurrent networks.",
963
+ "The Training: Shows how networks can learn to predict what comes next in sequences."
964
+ ]
965
+ },
966
+ gan_discriminator: {
967
+ title: 'GAN Discriminator',
968
+ subtitle: 'Learning to distinguish real vs fake data - half of a generative adversarial network',
969
+ architecture: [2, 6, 1],
970
+ learningRate: 0.3,
971
+ isRegression: false,
972
+ data: generateGANData(),
973
+ info: [
974
+ "The Problem: Distinguish between real data (top-right) and fake data (bottom-left). Core of GANs.",
975
+ "The Network: 2→6→1 discriminator learns clear spatial boundaries between data types.",
976
+ "The Training: In real GANs, this would compete with a generator in an adversarial game."
977
+ ],
978
+ hasVisualization: true
979
+ },
980
+ transfer: {
981
+ title: 'Transfer Learning',
982
+ subtitle: 'Using pre-trained features for new tasks - efficient learning with prior knowledge',
983
+ architecture: [2, 8, 4, 1],
984
+ learningRate: 0.3,
985
+ isRegression: false,
986
+ data: generateTransferData(),
987
+ info: [
988
+ "The Problem: Solve a new task using features learned from a previous similar task.",
989
+ "The Network: 2→8→4→1 where first layers are pre-trained and frozen. Only final layer learns.",
990
+ "The Training: Demonstrates how prior knowledge accelerates learning on related problems."
991
+ ]
992
+ }
993
+ }
994
+ },
995
+ baby: {
996
+ title: 'Baby Mode',
997
+ subtitle: 'Fun and simple AI learning for everyone!',
998
+ tasks: {
999
+ pet_classifier: {
1000
+ title: '🐱🐶 Pet Classifier',
1001
+ subtitle: 'Teach the AI to tell cats from dogs using simple features!',
1002
+ architecture: [2, 4, 1],
1003
+ learningRate: 0.3,
1004
+ isRegression: false,
1005
+ isBabyMode: true,
1006
+ data: [
1007
+ { input: [0.1, 0.9], target: [0], label: "🐱 Small ears, long tail = Cat" },
1008
+ { input: [0.2, 0.8], target: [0], label: "🐱 Small ears, long tail = Cat" },
1009
+ { input: [0.8, 0.2], target: [1], label: "🐶 Big ears, short tail = Dog" },
1010
+ { input: [0.9, 0.1], target: [1], label: "🐶 Big ears, short tail = Dog" }
1011
+ ],
1012
+ info: [
1013
+ "The Problem: Help the AI learn the difference between cats and dogs by looking at ear size and tail length!",
1014
+ "The Network: Simple brain with just a few neurons that learn to recognize pet features.",
1015
+ "The Fun: Watch the colorful neurons get excited when they see the right patterns!"
1016
+ ]
1017
+ },
1018
+ color_mixer: {
1019
+ title: '🎨 Color Mixer',
1020
+ subtitle: 'Teach the AI to mix colors and create beautiful combinations!',
1021
+ architecture: [2, 6, 3],
1022
+ learningRate: 0.2,
1023
+ isRegression: true,
1024
+ isBabyMode: true,
1025
+ data: [
1026
+ { input: [1, 0], target: [1, 0, 0], label: "🔴 Red input = Red output" },
1027
+ { input: [0, 1], target: [0, 0, 1], label: "🔵 Blue input = Blue output" },
1028
+ { input: [1, 1], target: [0.5, 0, 0.5], label: "🟣 Red + Blue = Purple" },
1029
+ { input: [0.5, 0.5], target: [0.25, 0, 0.75], label: "🟣 Mix = Light Purple" }
1030
+ ],
1031
+ info: [
1032
+ "The Problem: Teach the AI how to mix colors like a real artist!",
1033
+ "The Network: A creative brain that learns color combinations and mixing rules.",
1034
+ "The Magic: Watch as the AI learns to create new colors by combining others!"
1035
+ ]
1036
+ },
1037
+ number_guesser: {
1038
+ title: '🔢 Number Guesser',
1039
+ subtitle: 'The AI learns to guess if numbers are big or small!',
1040
+ architecture: [1, 4, 1],
1041
+ learningRate: 0.4,
1042
+ isRegression: false,
1043
+ isBabyMode: true,
1044
+ data: [
1045
+ { input: [0.1], target: [0], label: "0.1 = Small number 📉" },
1046
+ { input: [0.2], target: [0], label: "0.2 = Small number 📉" },
1047
+ { input: [0.8], target: [1], label: "0.8 = Big number 📈" },
1048
+ { input: [0.9], target: [1], label: "0.9 = Big number 📈" }
1049
+ ],
1050
+ info: [
1051
+ "The Problem: Help the AI learn which numbers are big and which are small!",
1052
+ "The Network: A simple counting brain that learns about number sizes.",
1053
+ "The Learning: Watch the AI get better at recognizing big and small numbers!"
1054
+ ]
1055
+ },
1056
+ weather_predictor: {
1057
+ title: '🌦️ Weather Predictor',
1058
+ subtitle: 'Teach the AI to predict sunny or rainy weather!',
1059
+ architecture: [2, 6, 1],
1060
+ learningRate: 0.25,
1061
+ isRegression: false,
1062
+ isBabyMode: true,
1063
+ data: [
1064
+ { input: [0.9, 0.1], target: [1], label: "☀️ Hot + Dry = Sunny" },
1065
+ { input: [0.8, 0.2], target: [1], label: "☀️ Warm + Dry = Sunny" },
1066
+ { input: [0.2, 0.9], target: [0], label: "🌧️ Cool + Humid = Rainy" },
1067
+ { input: [0.1, 0.8], target: [0], label: "🌧️ Cold + Humid = Rainy" }
1068
+ ],
1069
+ info: [
1070
+ "The Problem: Help the AI become a weather forecaster by learning temperature and humidity patterns!",
1071
+ "The Network: A weather brain that learns to predict rain or shine!",
1072
+ "The Prediction: Watch as the AI learns to be a smart weather assistant!"
1073
+ ]
1074
+ },
1075
+ emoji_matcher: {
1076
+ title: '😊 Emoji Matcher',
1077
+ subtitle: 'The AI learns to match happy and sad feelings!',
1078
+ architecture: [2, 5, 1],
1079
+ learningRate: 0.3,
1080
+ isRegression: false,
1081
+ isBabyMode: true,
1082
+ data: [
1083
+ { input: [0.9, 0.9], target: [1], label: "😊 High energy + Good mood = Happy" },
1084
+ { input: [0.8, 0.8], target: [1], label: "😊 Good energy + Good mood = Happy" },
1085
+ { input: [0.2, 0.2], target: [0], label: "😢 Low energy + Bad mood = Sad" },
1086
+ { input: [0.1, 0.3], target: [0], label: "😢 No energy + Bad mood = Sad" }
1087
+ ],
1088
+ info: [
1089
+ "The Problem: Teach the AI to understand emotions by looking at energy and mood levels!",
1090
+ "The Network: An emotional brain that learns about feelings and happiness!",
1091
+ "The Feelings: Watch the AI learn to recognize when someone is happy or sad!"
1092
+ ]
1093
+ }
1094
+ }
1095
+ }
1096
+ };
1097
+
1098
+ // Data generation functions
1099
+ function generateClassificationData() {
1100
+ const data = [];
1101
+ for (let i = 0; i < 8; i++) {
1102
+ data.push({
1103
+ input: [Math.random() * 0.4 + 0.1, Math.random() * 0.4 + 0.5],
1104
+ target: [0],
1105
+ label: "Red cluster"
1106
+ });
1107
+ data.push({
1108
+ input: [Math.random() * 0.4 + 0.5, Math.random() * 0.4 + 0.1],
1109
+ target: [1],
1110
+ label: "Blue cluster"
1111
+ });
1112
+ }
1113
+ return data;
1114
+ }
1115
+
1116
+ function generateSineData() {
1117
+ const data = [];
1118
+ for (let i = 0; i < 20; i++) {
1119
+ const x = (i / 19) * 2 * Math.PI;
1120
+ data.push({
1121
+ input: [x / (2 * Math.PI)],
1122
+ target: [(Math.sin(x) + 1) / 2],
1123
+ label: `${(x/(2*Math.PI)).toFixed(2)} → ${((Math.sin(x)+1)/2).toFixed(2)}`
1124
+ });
1125
+ }
1126
+ return data;
1127
+ }
1128
+
1129
+ function generateSpiralData() {
1130
+ const data = [];
1131
+ const n = 50;
1132
+ for (let i = 0; i < n; i++) {
1133
+ const r = i / n * 3;
1134
+ const t = 1.75 * i / n * 2 * Math.PI;
1135
+
1136
+ data.push({
1137
+ input: [
1138
+ (r * Math.cos(t) + 1) / 2,
1139
+ (r * Math.sin(t) + 1) / 2
1140
+ ],
1141
+ target: [0],
1142
+ label: "Spiral 1"
1143
+ });
1144
+
1145
+ data.push({
1146
+ input: [
1147
+ (r * Math.cos(t + Math.PI) + 1) / 2,
1148
+ (r * Math.sin(t + Math.PI) + 1) / 2
1149
+ ],
1150
+ target: [1],
1151
+ label: "Spiral 2"
1152
+ });
1153
+ }
1154
+ return data;
1155
+ }
1156
+
1157
+ function generateAutoencoderData() {
1158
+ const data = [];
1159
+ // Create simple, learnable patterns instead of random data
1160
+ const patterns = [
1161
+ [1, 0, 0, 0], // One-hot patterns are easier to reconstruct
1162
+ [0, 1, 0, 0],
1163
+ [0, 0, 1, 0],
1164
+ [0, 0, 0, 1],
1165
+ [1, 1, 0, 0], // Simple combinations
1166
+ [0, 0, 1, 1],
1167
+ [1, 0, 1, 0],
1168
+ [0, 1, 0, 1]
1169
+ ];
1170
+
1171
+ patterns.forEach((pattern, i) => {
1172
+ data.push({
1173
+ input: pattern,
1174
+ target: pattern, // Autoencoder reconstructs input
1175
+ label: `Pattern ${i+1}`
1176
+ });
1177
+ });
1178
+
1179
+ return data;
1180
+ }
1181
+
1182
+ function generateSequenceData() {
1183
+ const data = [];
1184
+ // Much simpler pattern: just alternating 0 and 1
1185
+ const sequence = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1];
1186
+
1187
+ for (let i = 0; i < sequence.length - 1; i++) {
1188
+ data.push({
1189
+ input: [sequence[i]],
1190
+ target: [sequence[i + 1]], // Predict next in sequence
1191
+ label: `${sequence[i]} → ${sequence[i + 1]}`
1192
+ });
1193
+ }
1194
+ return data;
1195
+ }
1196
+
1197
+ function generateGANData() {
1198
+ const data = [];
1199
+ // Real data: clear pattern - points in top-right quadrant
1200
+ for (let i = 0; i < 8; i++) {
1201
+ data.push({
1202
+ input: [
1203
+ 0.7 + Math.random() * 0.3, // 0.7-1.0 range
1204
+ 0.7 + Math.random() * 0.3 // 0.7-1.0 range
1205
+ ],
1206
+ target: [1], // Real
1207
+ label: "Real: top-right"
1208
+ });
1209
+ }
1210
+ // Fake data: clearly different - points in bottom-left quadrant
1211
+ for (let i = 0; i < 8; i++) {
1212
+ data.push({
1213
+ input: [
1214
+ Math.random() * 0.3, // 0.0-0.3 range
1215
+ Math.random() * 0.3 // 0.0-0.3 range
1216
+ ],
1217
+ target: [0], // Fake
1218
+ label: "Fake: bottom-left"
1219
+ });
1220
+ }
1221
+ return data;
1222
+ }
1223
+
1224
+ function generateTransferData() {
1225
+ const data = [];
1226
+ // Similar to XOR but slightly different
1227
+ data.push(
1228
+ { input: [0, 0], target: [1], label: "0,0 → 1 (NOT XOR)" },
1229
+ { input: [0, 1], target: [0], label: "0,1 → 0 (NOT XOR)" },
1230
+ { input: [1, 0], target: [0], label: "1,0 → 0 (NOT XOR)" },
1231
+ { input: [1, 1], target: [1], label: "1,1 → 1 (NOT XOR)" }
1232
+ );
1233
+ return data;
1234
+ }
1235
+
1236
+ // Neural Network class
1237
+ class NeuralNetwork {
1238
+ constructor(layers, learningRate = 0.3) {
1239
+ this.layers = layers;
1240
+ this.weights = [];
1241
+ this.biases = [];
1242
+ this.activations = [];
1243
+ this.zValues = [];
1244
+ this.learningRate = learningRate;
1245
+ this.momentum = 0.8;
1246
+ this.prevWeightUpdates = [];
1247
+ this.prevBiasUpdates = [];
1248
+
1249
+ this.initializeWeights();
1250
+ }
1251
+
1252
+ initializeWeights() {
1253
+ for (let i = 0; i < this.layers.length - 1; i++) {
1254
+ const fanIn = this.layers[i];
1255
+ const fanOut = this.layers[i + 1];
1256
+ const limit = Math.sqrt(2 / fanIn) * 1.5;
1257
+
1258
+ this.weights[i] = Array(fanOut).fill().map(() =>
1259
+ Array(fanIn).fill().map(() => (Math.random() * 2 - 1) * limit)
1260
+ );
1261
+
1262
+ this.biases[i] = Array(fanOut).fill().map(() => (Math.random() * 2 - 1) * 0.3);
1263
+
1264
+ this.prevWeightUpdates[i] = Array(fanOut).fill().map(() => Array(fanIn).fill(0));
1265
+ this.prevBiasUpdates[i] = Array(fanOut).fill(0);
1266
+ }
1267
+ }
1268
+
1269
+ getParameterCount() {
1270
+ let count = 0;
1271
+ for (let i = 0; i < this.layers.length - 1; i++) {
1272
+ count += this.layers[i] * this.layers[i + 1]; // weights
1273
+ count += this.layers[i + 1]; // biases
1274
+ }
1275
+ return count;
1276
+ }
1277
+
1278
+ relu(x) {
1279
+ return Math.max(0, x);
1280
+ }
1281
+
1282
+ reluDerivative(x) {
1283
+ return x > 0 ? 1 : 0;
1284
+ }
1285
+
1286
+ sigmoid(x) {
1287
+ return x > 20 ? 1 : x < -20 ? 0 : 1 / (1 + Math.exp(-x));
1288
+ }
1289
+
1290
+ sigmoidDerivative(x) {
1291
+ return x * (1 - x);
1292
+ }
1293
+
1294
+ activate(x, layer) {
1295
+ return layer === this.layers.length - 1 ? this.sigmoid(x) : this.relu(x);
1296
+ }
1297
+
1298
+ activateDerivative(x, layer) {
1299
+ return layer === this.layers.length - 1 ? this.sigmoidDerivative(x) : this.reluDerivative(x);
1300
+ }
1301
+
1302
+ forward(input) {
1303
+ this.activations = [input];
1304
+ this.zValues = [];
1305
+
1306
+ for (let i = 0; i < this.weights.length; i++) {
1307
+ const layer = [];
1308
+ const zLayer = [];
1309
+ for (let j = 0; j < this.weights[i].length; j++) {
1310
+ let sum = this.biases[i][j];
1311
+ for (let k = 0; k < this.weights[i][j].length; k++) {
1312
+ sum += this.weights[i][j][k] * this.activations[i][k];
1313
+ }
1314
+ zLayer.push(sum);
1315
+ layer.push(this.activate(sum, i + 1));
1316
+ }
1317
+ this.zValues.push(zLayer);
1318
+ this.activations.push(layer);
1319
+ }
1320
+
1321
+ return this.activations[this.activations.length - 1];
1322
+ }
1323
+
1324
+ trainBatch(data) {
1325
+ let totalLoss = 0;
1326
+
1327
+ const accWeightGrads = this.weights.map(layer =>
1328
+ layer.map(neuron => neuron.map(() => 0))
1329
+ );
1330
+ const accBiasGrads = this.biases.map(layer => layer.map(() => 0));
1331
+
1332
+ for (const sample of data) {
1333
+ const output = this.forward(sample.input);
1334
+ const loss = sample.target.reduce((sum, t, i) =>
1335
+ sum + Math.pow(t - output[i], 2), 0) / sample.target.length;
1336
+ totalLoss += loss;
1337
+
1338
+ const errors = [];
1339
+ const outputLayer = this.activations[this.activations.length - 1];
1340
+
1341
+ errors[this.weights.length - 1] = outputLayer.map((o, i) =>
1342
+ (sample.target[i] - o) * this.sigmoidDerivative(o)
1343
+ );
1344
+
1345
+ for (let i = this.weights.length - 2; i >= 0; i--) {
1346
+ errors[i] = [];
1347
+ for (let j = 0; j < this.layers[i + 1]; j++) {
1348
+ let error = 0;
1349
+ for (let k = 0; k < this.layers[i + 2]; k++) {
1350
+ error += errors[i + 1][k] * this.weights[i + 1][k][j];
1351
+ }
1352
+ const derivative = this.activateDerivative(this.zValues[i][j], i + 1);
1353
+ errors[i][j] = error * derivative;
1354
+ }
1355
+ }
1356
+
1357
+ for (let i = 0; i < this.weights.length; i++) {
1358
+ for (let j = 0; j < this.weights[i].length; j++) {
1359
+ for (let k = 0; k < this.weights[i][j].length; k++) {
1360
+ accWeightGrads[i][j][k] += errors[i][j] * this.activations[i][k];
1361
+ }
1362
+ accBiasGrads[i][j] += errors[i][j];
1363
+ }
1364
+ }
1365
+ }
1366
+
1367
+ const weightChanges = [];
1368
+ for (let i = 0; i < this.weights.length; i++) {
1369
+ weightChanges[i] = [];
1370
+ for (let j = 0; j < this.weights[i].length; j++) {
1371
+ weightChanges[i][j] = [];
1372
+ for (let k = 0; k < this.weights[i][j].length; k++) {
1373
+ const avgGradient = accWeightGrads[i][j][k] / data.length;
1374
+ const update = this.learningRate * avgGradient + this.momentum * this.prevWeightUpdates[i][j][k];
1375
+
1376
+ this.weights[i][j][k] += update;
1377
+ this.prevWeightUpdates[i][j][k] = update;
1378
+ weightChanges[i][j][k] = Math.abs(avgGradient);
1379
+ }
1380
+
1381
+ const avgBiasGradient = accBiasGrads[i][j] / data.length;
1382
+ const biasUpdate = this.learningRate * avgBiasGradient + this.momentum * this.prevBiasUpdates[i][j];
1383
+ this.biases[i][j] += biasUpdate;
1384
+ this.prevBiasUpdates[i][j] = biasUpdate;
1385
+ }
1386
+ }
1387
+
1388
+ const avgLoss = totalLoss / data.length;
1389
+ return { loss: avgLoss, weightChanges };
1390
+ }
1391
+ }
1392
+
1393
+ // Global state
1394
+ let currentCategory = null;
1395
+ let currentTask = null;
1396
+ let network = null;
1397
+ let isTraining = false;
1398
+ let epoch = 0;
1399
+ let currentLoss = 1.0;
1400
+ let lossHistory = [];
1401
+ let currentSample = 0;
1402
+ let activations = [];
1403
+ let predictions = [];
1404
+ let weightChanges = [];
1405
+ let avgLoss = 1.0;
1406
+ let accuracy = 0;
1407
+ let animationTime = 0;
1408
+ let trainInterval = null;
1409
+ let animationId = null;
1410
+
1411
+ // DOM elements
1412
+ const mainMenu = document.getElementById('mainMenu');
1413
+ const taskSelection = document.getElementById('taskSelection');
1414
+ const developerMode = document.getElementById('developerMode');
1415
+ const trainingInterface = document.getElementById('trainingInterface');
1416
+ const categoryTitle = document.getElementById('categoryTitle');
1417
+ const categorySubtitle = document.getElementById('categorySubtitle');
1418
+ const taskGrid = document.getElementById('taskGrid');
1419
+ const backBtn = document.getElementById('backBtn');
1420
+ const taskTitle = document.getElementById('taskTitle');
1421
+ const taskSubtitle = document.getElementById('taskSubtitle');
1422
+ const trainBtn = document.getElementById('trainBtn');
1423
+ const resetBtn = document.getElementById('resetBtn');
1424
+ const epochValue = document.getElementById('epochValue');
1425
+ const lossValue = document.getElementById('lossValue');
1426
+ const accuracyValue = document.getElementById('accuracyValue');
1427
+ const currentValue = document.getElementById('currentValue');
1428
+ const networkCanvas = document.getElementById('networkCanvas');
1429
+ const networkLabels = document.getElementById('networkLabels');
1430
+ const lossChart = document.getElementById('lossChart');
1431
+ const lossLine = document.getElementById('lossLine');
1432
+ const lossArea = document.getElementById('lossArea');
1433
+ const currentLossSpan = document.getElementById('currentLoss');
1434
+ const taskOutput = document.getElementById('taskOutput');
1435
+ const outputTitle = document.getElementById('outputTitle');
1436
+ const infoContent = document.getElementById('infoContent');
1437
+ const dataViz = document.getElementById('dataViz');
1438
+ const chartContainer = document.getElementById('chartContainer');
1439
+ const vizTitle = document.getElementById('vizTitle');
1440
+ const babyViz = document.getElementById('babyViz');
1441
+
1442
+ // Developer mode elements
1443
+ const devTaskName = document.getElementById('devTaskName');
1444
+ const devArchitecture = document.getElementById('devArchitecture');
1445
+ const devLearningRate = document.getElementById('devLearningRate');
1446
+ const devData = document.getElementById('devData');
1447
+ const paramCount = document.getElementById('paramCount');
1448
+
1449
+ // Category navigation
1450
+ function showCategory(categoryId) {
1451
+ window.scrollTo(0, 0);
1452
+ currentCategory = categoryId;
1453
+
1454
+ if (categoryId === 'developer') {
1455
+ mainMenu.style.display = 'none';
1456
+ developerMode.style.display = 'block';
1457
+ updateParameterCount();
1458
+ return;
1459
+ }
1460
+
1461
+ const category = CATEGORIES[categoryId];
1462
+ categoryTitle.textContent = category.title;
1463
+ categorySubtitle.textContent = category.subtitle;
1464
+
1465
+ // Populate task grid
1466
+ taskGrid.innerHTML = '';
1467
+ Object.entries(category.tasks).forEach(([taskId, task]) => {
1468
+ const difficulty = task.architecture.length <= 3 ? 'easy' :
1469
+ task.architecture.length <= 4 ? 'medium' : 'hard';
1470
+
1471
+ const card = document.createElement('div');
1472
+ card.className = 'task-card';
1473
+ card.onclick = () => selectTask(taskId);
1474
+ card.innerHTML = `
1475
+ <div class="task-icon">${getTaskIcon(taskId)}</div>
1476
+ <h3 class="task-name">${task.title}</h3>
1477
+ <span class="task-difficulty difficulty-${difficulty}">${difficulty.charAt(0).toUpperCase() + difficulty.slice(1)}</span>
1478
+ <p class="task-description">${task.subtitle}</p>
1479
+ <div class="task-specs">Network: ${task.architecture.join('→')} | ${task.isRegression ? 'Regression' : 'Classification'}</div>
1480
+ `;
1481
+ taskGrid.appendChild(card);
1482
+ });
1483
+
1484
+ mainMenu.style.display = 'none';
1485
+ taskSelection.style.display = 'block';
1486
+ }
1487
+
1488
+ function getTaskIcon(taskId) {
1489
+ const icons = {
1490
+ and: '🔗', or: '➕', xor: '⚡', classification: '🎯',
1491
+ sine: '📈', spiral: '🌀', autoencoder: '🔄', rnn: '🔗',
1492
+ gan_discriminator: '🎭', transfer: '📤', pet_classifier: '🐱🐶',
1493
+ color_mixer: '🎨', number_guesser: '🔢', weather_predictor: '🌦️',
1494
+ emoji_matcher: '😊'
1495
+ };
1496
+ return icons[taskId] || '🧠';
1497
+ }
1498
+
1499
+ function goBackToMain() {
1500
+ window.scrollTo(0, 0);
1501
+ mainMenu.style.display = 'block';
1502
+ taskSelection.style.display = 'none';
1503
+ developerMode.style.display = 'none';
1504
+ trainingInterface.style.display = 'none';
1505
+ currentCategory = null;
1506
+ }
1507
+
1508
+ // Developer mode functions
1509
+ function updateParameterCount() {
1510
+ try {
1511
+ const arch = devArchitecture.value.split(',').map(n => parseInt(n.trim()));
1512
+ let params = 0;
1513
+ for (let i = 0; i < arch.length - 1; i++) {
1514
+ params += arch[i] * arch[i + 1] + arch[i + 1]; // weights + biases
1515
+ }
1516
+ paramCount.textContent = `Parameters: ${params} / 5000`;
1517
+ paramCount.className = params > 5000 ? 'param-counter over-limit' : 'param-counter';
1518
+
1519
+ const createBtn = document.getElementById('createCustomTask');
1520
+ createBtn.disabled = params > 5000;
1521
+ } catch (e) {
1522
+ paramCount.textContent = 'Parameters: Invalid architecture';
1523
+ paramCount.className = 'param-counter over-limit';
1524
+ }
1525
+ }
1526
+
1527
+ function createCustomTask() {
1528
+ window.scrollTo(0, 0);
1529
+ try {
1530
+ const architecture = devArchitecture.value.split(',').map(n => parseInt(n.trim()));
1531
+ const learningRate = parseFloat(devLearningRate.value);
1532
+ const data = JSON.parse(devData.value);
1533
+
1534
+ // Validate
1535
+ if (architecture.some(n => isNaN(n) || n < 1)) {
1536
+ alert('Invalid architecture. Use positive integers separated by commas.');
1537
+ return;
1538
+ }
1539
+
1540
+ const params = architecture.reduce((sum, layer, i) =>
1541
+ i === 0 ? 0 : sum + architecture[i-1] * layer + layer, 0);
1542
+
1543
+ if (params > 5000) {
1544
+ alert('Too many parameters! Keep it under 5000 to prevent crashes.');
1545
+ return;
1546
+ }
1547
+
1548
+ if (!Array.isArray(data) || data.length === 0) {
1549
+ alert('Invalid data format. Use JSON array with input, target, and label fields.');
1550
+ return;
1551
+ }
1552
+
1553
+ // Create custom task
1554
+ currentTask = {
1555
+ title: devTaskName.value,
1556
+ subtitle: 'Custom developer task',
1557
+ architecture: architecture,
1558
+ learningRate: learningRate,
1559
+ isRegression: false, // Default to classification
1560
+ data: data,
1561
+ info: [
1562
+ `Custom Problem: ${devTaskName.value} with ${data.length} training samples.`,
1563
+ `Custom Network: ${architecture.join('→')} architecture with ${params} parameters.`,
1564
+ `Custom Training: Learning rate ${learningRate}, batch training with momentum.`
1565
+ ]
1566
+ };
1567
+
1568
+ network = new NeuralNetwork(currentTask.architecture, currentTask.learningRate);
1569
+
1570
+ // Update UI
1571
+ taskTitle.textContent = currentTask.title;
1572
+ taskSubtitle.textContent = currentTask.subtitle;
1573
+ outputTitle.textContent = 'Custom Output';
1574
+
1575
+ // Update network labels
1576
+ const layers = currentTask.architecture;
1577
+ let labelText = `Input (${layers[0]})`;
1578
+ if (layers.length > 2) {
1579
+ const hiddenSizes = layers.slice(1, -1).join('+');
1580
+ labelText += `||Hidden (${hiddenSizes})`;
1581
+ }
1582
+ labelText += `||Output (${layers[layers.length-1]})`;
1583
+ networkLabels.innerHTML = labelText.split('||').map(l => `<span>${l}</span>`).join('');
1584
+
1585
+ // Show training interface
1586
+ developerMode.style.display = 'none';
1587
+ trainingInterface.style.display = 'block';
1588
+
1589
+ // Initialize
1590
+ initializeTaskOutput();
1591
+ updateInfoSection();
1592
+ reset();
1593
+ startAnimation();
1594
+
1595
+ } catch (e) {
1596
+ alert('Error creating task: ' + e.message);
1597
+ }
1598
+ }
1599
+
1600
+ // Task selection
1601
+ function selectTask(taskId) {
1602
+ window.scrollTo(0, 0);
1603
+ currentTask = CATEGORIES[currentCategory].tasks[taskId];
1604
+ network = new NeuralNetwork(currentTask.architecture, currentTask.learningRate);
1605
+
1606
+ // Update UI
1607
+ taskTitle.textContent = currentTask.title;
1608
+ taskSubtitle.textContent = currentTask.subtitle;
1609
+ outputTitle.textContent = currentTask.title.split(' ')[0] + ' Results';
1610
+
1611
+ // Update network labels
1612
+ const layers = currentTask.architecture;
1613
+ let labelText = `Input (${layers[0]})`;
1614
+ if (layers.length > 2) {
1615
+ const hiddenSizes = layers.slice(1, -1).join('+');
1616
+ labelText += `||Hidden (${hiddenSizes})`;
1617
+ }
1618
+ labelText += `||Output (${layers[layers.length-1]})`;
1619
+ networkLabels.innerHTML = labelText.split('||').map(l => `<span>${l}</span>`).join('');
1620
+
1621
+ // Setup visualization
1622
+ if (currentTask.hasVisualization) {
1623
+ document.getElementById('lossChart').style.display = 'none';
1624
+ dataViz.style.display = 'block';
1625
+ vizTitle.textContent = 'Data Visualization';
1626
+ } else {
1627
+ document.getElementById('lossChart').style.display = 'block';
1628
+ dataViz.style.display = 'none';
1629
+ vizTitle.textContent = 'Training Progress';
1630
+ }
1631
+
1632
+ // Baby mode setup
1633
+ if (currentTask.isBabyMode) {
1634
+ networkCanvas.style.display = 'none';
1635
+ babyViz.style.display = 'block';
1636
+ setupBabyVisualization();
1637
+ } else {
1638
+ networkCanvas.style.display = 'block';
1639
+ babyViz.style.display = 'none';
1640
+ }
1641
+
1642
+ // Show interface
1643
+ taskSelection.style.display = 'none';
1644
+ trainingInterface.style.display = 'block';
1645
+
1646
+ // Initialize
1647
+ initializeTaskOutput();
1648
+ updateInfoSection();
1649
+ reset();
1650
+ startAnimation();
1651
+ }
1652
+
1653
+ // Baby mode visualization
1654
+ function setupBabyVisualization() {
1655
+ const babyNeurons = document.getElementById('babyNeurons');
1656
+ babyNeurons.innerHTML = '';
1657
+
1658
+ const layers = network.layers;
1659
+ layers.forEach((layerSize, layerIndex) => {
1660
+ for (let i = 0; i < Math.min(layerSize, 6); i++) { // Limit display
1661
+ const neuron = document.createElement('div');
1662
+ neuron.className = 'baby-neuron';
1663
+ neuron.id = `baby-neuron-${layerIndex}-${i}`;
1664
+ neuron.style.backgroundColor = `hsl(${layerIndex * 60 + 200}, 70%, 70%)`;
1665
+ neuron.textContent = '😴';
1666
+ babyNeurons.appendChild(neuron);
1667
+ }
1668
+ if (layerIndex < layers.length - 1) {
1669
+ const arrow = document.createElement('span');
1670
+ arrow.textContent = ' → ';
1671
+ arrow.style.fontSize = '2rem';
1672
+ babyNeurons.appendChild(arrow);
1673
+ }
1674
+ });
1675
+ }
1676
+
1677
+ function updateBabyVisualization() {
1678
+ if (!currentTask || !currentTask.isBabyMode || activations.length === 0) return;
1679
+
1680
+ const layers = network.layers;
1681
+ layers.forEach((layerSize, layerIndex) => {
1682
+ for (let i = 0; i < Math.min(layerSize, 6); i++) {
1683
+ const neuron = document.getElementById(`baby-neuron-${layerIndex}-${i}`);
1684
+ if (neuron && activations[layerIndex]) {
1685
+ const activation = activations[layerIndex][i] || 0;
1686
+ if (activation > 0.5) {
1687
+ neuron.textContent = '🤩';
1688
+ neuron.style.backgroundColor = `hsl(${layerIndex * 60 + 200}, 90%, 80%)`;
1689
+ } else if (activation > 0.2) {
1690
+ neuron.textContent = '😊';
1691
+ neuron.style.backgroundColor = `hsl(${layerIndex * 60 + 200}, 70%, 70%)`;
1692
+ } else {
1693
+ neuron.textContent = '😴';
1694
+ neuron.style.backgroundColor = `hsl(${layerIndex * 60 + 200}, 50%, 60%)`;
1695
+ }
1696
+ }
1697
+ }
1698
+ });
1699
+ }
1700
+
1701
+ // Back to task selection
1702
+ function goBack() {
1703
+ window.scrollTo(0, 0);
1704
+ isTraining = false;
1705
+ clearInterval(trainInterval);
1706
+ trainingInterface.style.display = 'none';
1707
+
1708
+ if (currentCategory) {
1709
+ taskSelection.style.display = 'block';
1710
+ } else {
1711
+ mainMenu.style.display = 'block';
1712
+ }
1713
+
1714
+ currentTask = null;
1715
+ }
1716
+
1717
+ // Initialize task output
1718
+ function initializeTaskOutput() {
1719
+ taskOutput.innerHTML = '';
1720
+ currentTask.data.forEach((data, index) => {
1721
+ const card = document.createElement('div');
1722
+ card.className = 'output-card';
1723
+ card.id = `output-card-${index}`;
1724
+ card.innerHTML = `
1725
+ <div class="output-io">${data.label}</div>
1726
+ <div class="output-raw">Raw: <span id="raw-${index}">0.000</span></div>
1727
+ <div class="output-predicted">Predicted: <span id="pred-${index}">-</span></div>
1728
+ <div class="output-status" id="status-${index}">✗ Wrong</div>
1729
+ `;
1730
+ taskOutput.appendChild(card);
1731
+ });
1732
+ }
1733
+
1734
+ // Update info section
1735
+ function updateInfoSection() {
1736
+ infoContent.innerHTML = currentTask.info.map(info => `<div>${info}</div>`).join('');
1737
+ }
1738
+
1739
+ // Draw network
1740
+ function drawNetwork() {
1741
+ const canvas = networkCanvas;
1742
+ const ctx = canvas.getContext('2d');
1743
+ const width = canvas.width;
1744
+ const height = canvas.height;
1745
+
1746
+ ctx.clearRect(0, 0, width, height);
1747
+
1748
+ if (activations.length === 0) return;
1749
+
1750
+ const layers = network.layers;
1751
+ const layerSpacing = width / (layers.length + 1);
1752
+ const nodeRadius = Math.min(15, width / 30);
1753
+
1754
+ // Draw connections
1755
+ for (let i = 0; i < layers.length - 1; i++) {
1756
+ for (let j = 0; j < layers[i]; j++) {
1757
+ for (let k = 0; k < layers[i + 1]; k++) {
1758
+ const x1 = layerSpacing * (i + 1);
1759
+ const y1 = (height / (layers[i] + 1)) * (j + 1);
1760
+ const x2 = layerSpacing * (i + 2);
1761
+ const y2 = (height / (layers[i + 1] + 1)) * (k + 1);
1762
+
1763
+ const weight = network.weights[i][k][j];
1764
+ const intensity = Math.min(Math.abs(weight) * 1.2, 0.7);
1765
+
1766
+ const baseColor = weight > 0 ?
1767
+ `rgba(34, 197, 94, ${intensity * 0.5})` :
1768
+ `rgba(239, 68, 68, ${intensity * 0.5})`;
1769
+
1770
+ ctx.strokeStyle = baseColor;
1771
+ ctx.lineWidth = Math.max(1, intensity * 1.5);
1772
+ ctx.beginPath();
1773
+ ctx.moveTo(x1, y1);
1774
+ ctx.lineTo(x2, y2);
1775
+ ctx.stroke();
1776
+
1777
+ // Subtle gradient flow
1778
+ if (isTraining && Math.abs(weight) > 0.3) {
1779
+ const flowProgress = ((animationTime * 0.5) % 120) / 120;
1780
+ const flowX = x1 + (x2 - x1) * flowProgress;
1781
+ const flowY = y1 + (y2 - y1) * flowProgress;
1782
+
1783
+ const flowIntensity = intensity * 0.3;
1784
+ ctx.fillStyle = weight > 0 ?
1785
+ `rgba(34, 197, 94, ${flowIntensity})` :
1786
+ `rgba(239, 68, 68, ${flowIntensity})`;
1787
+ ctx.beginPath();
1788
+ ctx.arc(flowX, flowY, 2, 0, 2 * Math.PI);
1789
+ ctx.fill();
1790
+ }
1791
+ }
1792
+ }
1793
+ }
1794
+
1795
+ // Draw nodes
1796
+ layers.forEach((layerSize, layerIndex) => {
1797
+ for (let nodeIndex = 0; nodeIndex < layerSize; nodeIndex++) {
1798
+ const x = layerSpacing * (layerIndex + 1);
1799
+ const y = (height / (layerSize + 1)) * (nodeIndex + 1);
1800
+
1801
+ const activation = activations[layerIndex] ? activations[layerIndex][nodeIndex] : 0;
1802
+
1803
+ const hue = layerIndex === 0 ? 200 : layerIndex === layers.length - 1 ? 280 : 160;
1804
+ const saturation = 50;
1805
+ let lightness = 35 + activation * 25;
1806
+
1807
+ if (isTraining && activation > 0.8) {
1808
+ const pulse = Math.sin(animationTime * 0.05) * 0.1;
1809
+ lightness += pulse * 10;
1810
+ }
1811
+
1812
+ ctx.fillStyle = `hsl(${hue}, ${saturation}%, ${lightness}%)`;
1813
+ ctx.beginPath();
1814
+ ctx.arc(x, y, nodeRadius, 0, 2 * Math.PI);
1815
+ ctx.fill();
1816
+
1817
+ ctx.strokeStyle = '#64748b';
1818
+ ctx.lineWidth = 1.5;
1819
+ ctx.stroke();
1820
+
1821
+ ctx.fillStyle = '#ffffff';
1822
+ ctx.font = `${Math.max(10, nodeRadius / 1.6)}px monospace`;
1823
+ ctx.textAlign = 'center';
1824
+ ctx.textBaseline = 'middle';
1825
+ ctx.shadowColor = 'rgba(0, 0, 0, 0.9)';
1826
+ ctx.shadowBlur = 2;
1827
+ ctx.fillText(activation.toFixed(2), x, y);
1828
+ ctx.shadowBlur = 0;
1829
+ }
1830
+ });
1831
+ }
1832
+
1833
+ // Draw data visualization
1834
+ function drawDataVisualization() {
1835
+ if (!currentTask.hasVisualization) return;
1836
+
1837
+ const canvas = dataViz;
1838
+ const ctx = canvas.getContext('2d');
1839
+ const width = canvas.width;
1840
+ const height = canvas.height;
1841
+
1842
+ ctx.clearRect(0, 0, width, height);
1843
+
1844
+ if (currentTask.title.includes('Classification') || currentTask.title.includes('Spiral') || currentTask.title.includes('GAN')) {
1845
+ // Draw classification data
1846
+ currentTask.data.forEach((point, i) => {
1847
+ const x = point.input[0] * width;
1848
+ const y = height - point.input[1] * height;
1849
+ const prediction = predictions[i];
1850
+
1851
+ // True color
1852
+ ctx.fillStyle = point.target[0] > 0.5 ? '#3b82f6' : '#ef4444';
1853
+ ctx.beginPath();
1854
+ ctx.arc(x, y, 6, 0, 2 * Math.PI);
1855
+ ctx.fill();
1856
+
1857
+ // Prediction border
1858
+ if (prediction) {
1859
+ ctx.strokeStyle = prediction.predicted > 0.5 ? '#3b82f6' : '#ef4444';
1860
+ ctx.lineWidth = prediction.correct ? 3 : 1;
1861
+ ctx.stroke();
1862
+ }
1863
+ });
1864
+
1865
+ // For GAN discriminator, draw decision boundary area
1866
+ if (currentTask.title.includes('GAN')) {
1867
+ ctx.fillStyle = 'rgba(59, 130, 246, 0.1)'; // Light blue for "real" area
1868
+ ctx.fillRect(width * 0.6, 0, width * 0.4, height * 0.4);
1869
+ ctx.fillStyle = 'rgba(239, 68, 68, 0.1)'; // Light red for "fake" area
1870
+ ctx.fillRect(0, height * 0.6, width * 0.4, height * 0.4);
1871
+ }
1872
+ } else if (currentTask.title.includes('Sine')) {
1873
+ // Draw true sine wave
1874
+ ctx.strokeStyle = '#64748b';
1875
+ ctx.lineWidth = 2;
1876
+ ctx.beginPath();
1877
+ for (let x = 0; x < width; x++) {
1878
+ const t = (x / width) * 2 * Math.PI;
1879
+ const y = height - ((Math.sin(t) + 1) / 2) * height;
1880
+ if (x === 0) ctx.moveTo(x, y);
1881
+ else ctx.lineTo(x, y);
1882
+ }
1883
+ ctx.stroke();
1884
+
1885
+ // Draw predictions
1886
+ predictions.forEach((pred, i) => {
1887
+ const x = (currentTask.data[i].input[0]) * width;
1888
+ const y = height - pred.output * height;
1889
+
1890
+ ctx.fillStyle = pred.correct ? '#10b981' : '#ef4444';
1891
+ ctx.beginPath();
1892
+ ctx.arc(x, y, 4, 0, 2 * Math.PI);
1893
+ ctx.fill();
1894
+ });
1895
+ }
1896
+ }
1897
+
1898
+ // Update loss chart
1899
+ function updateLossChart() {
1900
+ if (lossHistory.length < 2) return;
1901
+
1902
+ const points = lossHistory.map((loss, i) => {
1903
+ const x = (i / (lossHistory.length - 1)) * 100;
1904
+ const y = 100 - (Math.min(loss, 1) * 90);
1905
+ return `${x},${y}`;
1906
+ }).join(' ');
1907
+
1908
+ lossLine.setAttribute('points', points);
1909
+ lossArea.setAttribute('points', points + ' 100,100 0,100');
1910
+ }
1911
+
1912
+ // Training step
1913
+ function trainStep() {
1914
+ const result = network.trainBatch(currentTask.data);
1915
+
1916
+ const sample = currentTask.data[currentSample];
1917
+ const output = network.forward(sample.input);
1918
+
1919
+ currentLoss = result.loss;
1920
+ activations = [...network.activations];
1921
+ weightChanges = result.weightChanges;
1922
+
1923
+ lossHistory.push(result.loss);
1924
+ if (lossHistory.length > 100) lossHistory.shift();
1925
+
1926
+ const newPredictions = currentTask.data.map(data => {
1927
+ const output = network.forward(data.input);
1928
+ const rawOutput = output[0];
1929
+
1930
+ let predicted, correct;
1931
+ if (currentTask.isRegression) {
1932
+ // For regression, use different tolerances based on task type
1933
+ predicted = rawOutput.toFixed(2);
1934
+ let tolerance = 0.1; // Default tolerance
1935
+
1936
+ // Autoencoder needs more lenient accuracy since it's reconstructing multi-dimensional data
1937
+ if (currentTask.title.includes('Autoencoder')) {
1938
+ tolerance = 0.2;
1939
+ // For autoencoder, check if ALL outputs are within tolerance
1940
+ const allOutputs = network.forward(data.input);
1941
+ let totalError = 0;
1942
+ for (let j = 0; j < data.target.length; j++) {
1943
+ totalError += Math.abs(allOutputs[j] - data.target[j]);
1944
+ }
1945
+ const avgError = totalError / data.target.length;
1946
+ correct = avgError < tolerance;
1947
+ } else {
1948
+ correct = Math.abs(rawOutput - data.target[0]) < tolerance;
1949
+ }
1950
+ } else {
1951
+ // For classification, use threshold
1952
+ predicted = rawOutput >= 0.5 ? 1 : 0;
1953
+ const target = data.target[0];
1954
+ correct = predicted === target;
1955
+ }
1956
+
1957
+ return {
1958
+ ...data,
1959
+ output: rawOutput,
1960
+ predicted: predicted,
1961
+ correct: correct
1962
+ };
1963
+ });
1964
+ predictions = newPredictions;
1965
+
1966
+ const correct = newPredictions.filter(p => p.correct).length;
1967
+ accuracy = correct / newPredictions.length;
1968
+
1969
+ const totalLoss = newPredictions.reduce((sum, p) =>
1970
+ sum + Math.pow(p.target[0] - p.output, 2), 0) / newPredictions.length;
1971
+ avgLoss = totalLoss;
1972
+
1973
+ currentSample = (currentSample + 1) % currentTask.data.length;
1974
+ epoch++;
1975
+
1976
+ updateUI();
1977
+ }
1978
+
1979
+ // Update UI
1980
+ function updateUI() {
1981
+ epochValue.textContent = epoch.toLocaleString();
1982
+ lossValue.textContent = avgLoss.toFixed(6);
1983
+ accuracyValue.textContent = (accuracy * 100).toFixed(1) + '%';
1984
+ currentValue.textContent = currentTask.data[currentSample].label;
1985
+ currentLossSpan.textContent = currentLoss.toFixed(6);
1986
+
1987
+ updateLossChart();
1988
+ drawNetwork();
1989
+ if (currentTask.hasVisualization) {
1990
+ drawDataVisualization();
1991
+ }
1992
+ if (currentTask.isBabyMode) {
1993
+ updateBabyVisualization();
1994
+ }
1995
+
1996
+ // Update output cards
1997
+ predictions.forEach((pred, index) => {
1998
+ const card = document.getElementById(`output-card-${index}`);
1999
+ const raw = document.getElementById(`raw-${index}`);
2000
+ const predSpan = document.getElementById(`pred-${index}`);
2001
+ const status = document.getElementById(`status-${index}`);
2002
+
2003
+ if (raw && predSpan && status && card) {
2004
+ raw.textContent = pred.output.toFixed(3);
2005
+ predSpan.textContent = pred.predicted;
2006
+ status.textContent = pred.correct ? '✓ Correct' : '✗ Wrong';
2007
+ status.className = `output-status ${pred.correct ? 'correct' : 'wrong'}`;
2008
+
2009
+ card.className = `output-card ${currentSample === index ? 'current' : pred.correct ? 'correct' : 'wrong'}`;
2010
+ }
2011
+ });
2012
+ }
2013
+
2014
+ // Animation loop
2015
+ function animate() {
2016
+ animationTime += isTraining ? 1 : 0.2;
2017
+ if (currentTask) {
2018
+ drawNetwork();
2019
+ if (currentTask.hasVisualization) {
2020
+ drawDataVisualization();
2021
+ }
2022
+ if (currentTask.isBabyMode) {
2023
+ updateBabyVisualization();
2024
+ }
2025
+ }
2026
+ animationId = requestAnimationFrame(animate);
2027
+ }
2028
+
2029
+ // Start animation
2030
+ function startAnimation() {
2031
+ if (animationId) cancelAnimationFrame(animationId);
2032
+ animate();
2033
+ }
2034
+
2035
+ // Reset function
2036
+ function reset() {
2037
+ if (!currentTask) return;
2038
+
2039
+ isTraining = false;
2040
+ clearInterval(trainInterval);
2041
+
2042
+ network = new NeuralNetwork(currentTask.architecture, currentTask.learningRate);
2043
+ epoch = 0;
2044
+ currentLoss = 1.0;
2045
+ lossHistory = [];
2046
+ currentSample = 0;
2047
+ activations = [];
2048
+ predictions = [];
2049
+ weightChanges = [];
2050
+ avgLoss = 1.0;
2051
+ accuracy = 0;
2052
+ animationTime = 0;
2053
+
2054
+ trainBtn.innerHTML = `
2055
+ <svg class="icon" fill="currentColor" viewBox="0 0 24 24">
2056
+ <path d="M8 5v14l11-7z"/>
2057
+ </svg>
2058
+ Start Training
2059
+ `;
2060
+ trainBtn.className = 'btn btn-start';
2061
+
2062
+ updateUI();
2063
+ }
2064
+
2065
+ // Event listeners
2066
+ trainBtn.addEventListener('click', () => {
2067
+ isTraining = !isTraining;
2068
+
2069
+ if (isTraining) {
2070
+ trainBtn.innerHTML = `
2071
+ <svg class="icon" fill="currentColor" viewBox="0 0 24 24">
2072
+ <path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/>
2073
+ </svg>
2074
+ Pause Training
2075
+ `;
2076
+ trainBtn.className = 'btn btn-pause';
2077
+
2078
+ trainInterval = setInterval(trainStep, 100);
2079
+ } else {
2080
+ trainBtn.innerHTML = `
2081
+ <svg class="icon" fill="currentColor" viewBox="0 0 24 24">
2082
+ <path d="M8 5v14l11-7z"/>
2083
+ </svg>
2084
+ Start Training
2085
+ `;
2086
+ trainBtn.className = 'btn btn-start';
2087
+
2088
+ clearInterval(trainInterval);
2089
+ }
2090
+ });
2091
+
2092
+ resetBtn.addEventListener('click', reset);
2093
+ backBtn.addEventListener('click', goBack);
2094
+
2095
+ // Developer mode event listeners
2096
+ devArchitecture.addEventListener('input', updateParameterCount);
2097
+
2098
+ // Initialize
2099
+ startAnimation();
2100
+ </script>
2101
+ </body>
2102
+ </html>