Jethro85
commited on
Commit
·
0cc3b61
1
Parent(s):
cc77288
commit
Browse files- app/analytics.log.jsonl +176 -0
- app/routes.py +91 -2
- app/routes.py.ori.py +174 -0
- app/static/js/main.js +77 -5
- app/static/js/main.js.ori.js +858 -0
- requirements.txt +3 -2
app/analytics.log.jsonl
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{"t": 1757896550669, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.1}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.692087Z", "visitor_id": "f3e6f6a9f79745459616fd8d78431373", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 2 |
+
{"t": 1757896550698, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.2}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.709017Z", "visitor_id": "ff06e7aa323c4238be02195abce39706", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 3 |
+
{"t": 1757896550711, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.4}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.718500Z", "visitor_id": "c11c827c2a8c4a31a61d5be7660c9258", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 4 |
+
{"t": 1757896550732, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.6}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.737093Z", "visitor_id": "d2cc4e03bbc740da92b876c4df817fe7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 5 |
+
{"t": 1757896550741, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.7}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.745718Z", "visitor_id": "7834b751f6cb41cf985c419dc3e2d4b0", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 6 |
+
{"t": 1757896550749, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.8}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.755407Z", "visitor_id": "48491caedc2749caae454d65dff0f182", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 7 |
+
{"t": 1757896550757, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.9}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.761808Z", "visitor_id": "d88d65abea7c4ef6b0446f705ebfc2e3", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 8 |
+
{"t": 1757896550765, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.770138Z", "visitor_id": "73c237066e054371b65ceadfb8375d30", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 9 |
+
{"t": 1757896550774, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.1}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.780031Z", "visitor_id": "3f949c7a120f4b3ea77e032115ae86de", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 10 |
+
{"t": 1757896550782, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.3}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.789420Z", "visitor_id": "9ec816c6e94a4af4b8730717bdafab64", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 11 |
+
{"t": 1757896550790, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.4}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.797387Z", "visitor_id": "18a04d355d9a450eb677c32c745c3ceb", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 12 |
+
{"t": 1757896550799, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.5}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.808952Z", "visitor_id": "5241caae96a84b35884d25470df1ecbb", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 13 |
+
{"t": 1757896550807, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.6}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.812067Z", "visitor_id": "9f9fb0e5e48e4055ab1bb8bbfab61954", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 14 |
+
{"t": 1757896550815, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.7}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.818987Z", "visitor_id": "c1d6e2723dfb4883a030c45d5730d2a3", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 15 |
+
{"t": 1757896550824, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.8}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.830391Z", "visitor_id": "55253363029344ed9d6733bc7f2eaa86", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 16 |
+
{"t": 1757896550832, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.9}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.839021Z", "visitor_id": "ff7de07312884c848e260d34ba9d90f2", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 17 |
+
{"t": 1757896550849, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.853188Z", "visitor_id": "67b7410f81794bcd9f47be8d2598da6f", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 18 |
+
{"t": 1757896550865, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.1}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.874940Z", "visitor_id": "42d85a017a2e46b9ad9d5e95117cfb46", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 19 |
+
{"t": 1757896550890, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.2}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:50.895626Z", "visitor_id": "9e3ec5f3241e4012b228764c36de0264", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 20 |
+
{"t": 1757896555513, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "view_switch", "path": "/", "payload": {"view": "iterations"}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:55.527675Z", "visitor_id": "6a4d9afc83cd468c88f434d7310afbdf", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 21 |
+
{"t": 1757896555512, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "view-iterations"}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:55.526142Z", "visitor_id": "7b4b51c694ec4ea7a05c32ada87419be", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 22 |
+
{"t": 1757896558515, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "train-button"}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:58.527999Z", "visitor_id": "1eb6c3a5b7904d3e83f357fcb4d1e93d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 23 |
+
{"t": 1757896558527, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "train_toggle", "path": "/", "payload": {"clipping_norm": 3.2, "noise_multiplier": 1, "batch_size": 64, "learning_rate": 0.01, "epochs": 30, "dataset": "mnist", "model_architecture": "simple-mlp"}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:35:58.553873Z", "visitor_id": "cfe546d462254b3cb6fae4661360e556", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 24 |
+
{"t": 1757896828901, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "train-button"}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:40:28.913399Z", "visitor_id": "3ff68b57429b4e24bed029f2034889eb", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 25 |
+
{"t": 1757896828906, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "train_toggle", "path": "/", "payload": {"clipping_norm": 3.2, "noise_multiplier": 1, "batch_size": 64, "learning_rate": 0.01, "epochs": 30, "dataset": "mnist", "model_architecture": "simple-mlp"}, "user": {}, "vid": "1fa3e1f42c7043caa8ac3e9aac6494a6", "server_time": "2025-09-15T00:40:28.913973Z", "visitor_id": "5923f70d5d784793a182c0338715007f", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 26 |
+
{"t": 1757897467767, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "Playground"}, "user": {}, "vid": "6d640dbcfb074755a6dfa5f8a2e6d119", "server_time": "2025-09-15T00:51:07.773461Z", "visitor_id": "0f5a942f62954f2695c4baa605221e88", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 27 |
+
{"t": 1757897469319, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "Learning Hub"}, "user": {}, "vid": "9c6a6667c6ca44d086e01cb8706a8d99", "server_time": "2025-09-15T00:51:09.324924Z", "visitor_id": "f48c716e57a943f1a013aca5569199f4", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 28 |
+
{"t": 1757897474655, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/learning", "payload": {"name": "Playground"}, "user": {}, "vid": "63ed95f0c59c4043ac06f69948e76d12", "server_time": "2025-09-15T00:51:14.663494Z", "visitor_id": "fbbe53dafd7042ea8ebeafcba751bdd7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/learning", "dnt": false, "gpc": false}
|
| 29 |
+
{"t": 1757897483444, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.1}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.459996Z", "visitor_id": "87c99188fc9549c4a8f591e953d043eb", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 30 |
+
{"t": 1757897483597, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.2}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.605244Z", "visitor_id": "d415632f6d77404db05c31a88f8ce3b7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 31 |
+
{"t": 1757897483611, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.5}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.621548Z", "visitor_id": "d1335bd7f2994e8495eb2250a5e1fbd4", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 32 |
+
{"t": 1757897483621, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.6}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.629173Z", "visitor_id": "850c9a901a2b47f59689430c4793fae5", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 33 |
+
{"t": 1757897483629, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.8}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.635694Z", "visitor_id": "2e29c042276849bbaa8cabbc7196304c", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 34 |
+
{"t": 1757897483637, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.9}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.640779Z", "visitor_id": "25fa7b5eb6e6473aa5bec0f022e89a6b", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 35 |
+
{"t": 1757897483644, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.1}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.661324Z", "visitor_id": "8ff99bcd13f44184952854d11ca2efb3", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 36 |
+
{"t": 1757897483655, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.2}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.663030Z", "visitor_id": "98377b8b4de94d97ad0afcc4720b0ae7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 37 |
+
{"t": 1757897483663, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.3}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.667057Z", "visitor_id": "81b3c748a43341d580103ffcad94b43f", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 38 |
+
{"t": 1757897483677, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.4}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.685411Z", "visitor_id": "265a14fb8b68487dbed7ffc112e9e61a", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 39 |
+
{"t": 1757897483694, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.5}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:23.700092Z", "visitor_id": "60a2645bb3ba441e8dcd58d332392a14", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 40 |
+
{"t": 1757897484485, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 1.1}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.501144Z", "visitor_id": "cf617cb5105e42e1b7d3a2d8996c0b7d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 41 |
+
{"t": 1757897484610, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 1.2}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.626235Z", "visitor_id": "fdf534888baf4d33b9e3e34458506f2b", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 42 |
+
{"t": 1757897484635, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 1.6}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.652732Z", "visitor_id": "bdfccd5b93d847af8c79471e669076b4", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 43 |
+
{"t": 1757897484642, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 1.8}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.655315Z", "visitor_id": "68c42f3f83734cb5985d44e45c58e721", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 44 |
+
{"t": 1757897484660, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 2.2}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.675675Z", "visitor_id": "d9806eec39c94dd0aae9a432ac7333b5", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 45 |
+
{"t": 1757897484668, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 2.5}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.676956Z", "visitor_id": "f356a897cf4b40199f62a988c822cbf8", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 46 |
+
{"t": 1757897484685, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 2.9}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.697068Z", "visitor_id": "f5d27897ea9248e59ea5be776139c03d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 47 |
+
{"t": 1757897484693, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 3}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.698166Z", "visitor_id": "d3b717ed932442e396210f1703bc9659", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 48 |
+
{"t": 1757897484701, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 3.1}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.709838Z", "visitor_id": "237a9ace7c674bb3a6ed0de2a5ba06b4", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 49 |
+
{"t": 1757897484710, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 3.2}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.716517Z", "visitor_id": "a6d5b78c054544e9bf672920a72acdb7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 50 |
+
{"t": 1757897484718, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 3.3}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.733357Z", "visitor_id": "246ef048daf84f728d10906c0cedbec5", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 51 |
+
{"t": 1757897484768, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "noise-multiplier", "value": 3.4}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:24.783719Z", "visitor_id": "c4e6cb454b6a45ad9e30d7bbc732f849", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 52 |
+
{"t": 1757897485570, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "batch-size", "value": 80}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:25.591496Z", "visitor_id": "1dd7844327cf4215b5f934490ced3b84", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 53 |
+
{"t": 1757897485577, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "batch-size", "value": 96}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:25.597433Z", "visitor_id": "10d40d87b92949f8a9388cf776bca1d7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 54 |
+
{"t": 1757897485594, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "batch-size", "value": 128}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:25.613189Z", "visitor_id": "e9428647d0764385a3f6cc1517c42037", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 55 |
+
{"t": 1757897485586, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "batch-size", "value": 112}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:25.611344Z", "visitor_id": "29fe75dbffdc43cf9461dcbf568bbbca", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 56 |
+
{"t": 1757897485602, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "batch-size", "value": 144}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:25.615935Z", "visitor_id": "ed26b18bc53b49c9a31ca0689885d9b1", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 57 |
+
{"t": 1757897485620, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "batch-size", "value": 160}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:25.629426Z", "visitor_id": "a78ace51f6c6455792796c82762d3cf1", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 58 |
+
{"t": 1757897485637, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "batch-size", "value": 176}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:25.650657Z", "visitor_id": "8c445ce7ff5544429cbd72f178e27c09", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 59 |
+
{"t": 1757897486421, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.011}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.443318Z", "visitor_id": "ef5f99895d884f49bdaa3b59b53b5bd3", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 60 |
+
{"t": 1757897486427, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.012}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.451555Z", "visitor_id": "1597ca93d0b64d4bad5f44e476dc2c0b", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 61 |
+
{"t": 1757897486436, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.015}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.456376Z", "visitor_id": "0608fa933a24427baef019b7321a146e", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 62 |
+
{"t": 1757897486444, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.017}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.460776Z", "visitor_id": "49586a5a9cad4104a32aa69be4b8d482", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 63 |
+
{"t": 1757897486459, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.022}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.468454Z", "visitor_id": "7ecd0942c5d14198aadc24a82a65ffcf", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 64 |
+
{"t": 1757897486469, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.029}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.475157Z", "visitor_id": "95f07731110e467786014f645f4f94b8", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 65 |
+
{"t": 1757897486475, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.034}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.487651Z", "visitor_id": "6aa45d8d8b56465dbc1c495995816607", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 66 |
+
{"t": 1757897486484, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.037}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.489939Z", "visitor_id": "2b03d794e4d249eb8ccd4cd1e5244f29", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 67 |
+
{"t": 1757897486492, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.041}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.498677Z", "visitor_id": "3f3e4f34a25e4a3cbaad5ed4c7a82761", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 68 |
+
{"t": 1757897486501, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.044}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.506453Z", "visitor_id": "e61b501a24b943f0b1bc887182167317", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 69 |
+
{"t": 1757897486513, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.047}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.532807Z", "visitor_id": "dc57761bb64a43ca861702f50a81ac42", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 70 |
+
{"t": 1757897486516, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.048}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.533758Z", "visitor_id": "c7f192e163e7450d8bc501b6ea5f92d8", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 71 |
+
{"t": 1757897486523, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.05}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.539862Z", "visitor_id": "39e9f5d3530d45f2ba6240832d101f09", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 72 |
+
{"t": 1757897486531, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.051}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.541161Z", "visitor_id": "77a654e9780a4f2095a7f42bf7008c9c", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 73 |
+
{"t": 1757897486548, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.053}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.556647Z", "visitor_id": "8c0899e0ccca4a239b5ff099c7c41398", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 74 |
+
{"t": 1757897486546, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.052}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.555569Z", "visitor_id": "a112c34e23914be68903e5b0b68f619c", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 75 |
+
{"t": 1757897486563, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.054}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.569871Z", "visitor_id": "74a8607d1478401e9b33d8cb7104beea", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 76 |
+
{"t": 1757897486588, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.055}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.593982Z", "visitor_id": "509d9bba31774d6dbe9a7c2d89fb2457", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 77 |
+
{"t": 1757897486916, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.054}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.933900Z", "visitor_id": "5de24af176334e54b2f6e9f67248be65", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 78 |
+
{"t": 1757897486950, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.053}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.964258Z", "visitor_id": "d0f837a6a72145048a99fab532bcea56", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 79 |
+
{"t": 1757897486965, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.052}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.978163Z", "visitor_id": "0e934692d3ad45bf8b2fbaadfa55285d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 80 |
+
{"t": 1757897486989, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.05}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.999552Z", "visitor_id": "994021e73df54a9bae476a43ac2eb2c5", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 81 |
+
{"t": 1757897486981, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.051}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:26.997699Z", "visitor_id": "06762380b0cf4b3381210f515efe3f79", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 82 |
+
{"t": 1757897487006, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.049}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.018860Z", "visitor_id": "2b6b4e0512474cb2b49e80c520c46029", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 83 |
+
{"t": 1757897487014, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.048}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.020676Z", "visitor_id": "417780dd27d041e3818dd48f7ae5b031", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 84 |
+
{"t": 1757897487031, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.047}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.039205Z", "visitor_id": "fafff609e624472abe3718acbbb72c0d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 85 |
+
{"t": 1757897487039, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.046}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.044456Z", "visitor_id": "3e0b66801c3b42c587bd6f2261fcd258", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 86 |
+
{"t": 1757897487047, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.045}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.060515Z", "visitor_id": "9c153de13c304805818094592c7699ac", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 87 |
+
{"t": 1757897487056, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.044}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.062686Z", "visitor_id": "17a4b51844ba422da58dcc51cdd7753e", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 88 |
+
{"t": 1757897487064, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.043}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.069442Z", "visitor_id": "8a7f4eb7e5e44327b52902dd820d1b2e", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 89 |
+
{"t": 1757897487072, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.042}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.078208Z", "visitor_id": "4e23b446a3974c5b9b29b5cb845054e6", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 90 |
+
{"t": 1757897487081, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.041}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.086514Z", "visitor_id": "10063ab74fec4498b71c1d890ae19706", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 91 |
+
{"t": 1757897487089, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.039}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.093600Z", "visitor_id": "da1f2b2797194bda913e2dbb5e1a9612", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 92 |
+
{"t": 1757897487097, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.038}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.102394Z", "visitor_id": "468b85768b6c4f3b8e266c99767e3d5c", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 93 |
+
{"t": 1757897487106, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.036}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.111168Z", "visitor_id": "e93445d009304960bf1e16a7baf6b1e8", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 94 |
+
{"t": 1757897487114, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.035}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.122427Z", "visitor_id": "d0e0b676a58649a0aa6628e352483378", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 95 |
+
{"t": 1757897487122, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.032}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.127444Z", "visitor_id": "55394b5811064df4a624a72e88d2c7b1", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 96 |
+
{"t": 1757897487131, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.031}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.138348Z", "visitor_id": "ca092ee4fda041b78191457d9e1f0bfd", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 97 |
+
{"t": 1757897487139, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.03}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.143600Z", "visitor_id": "c6031926a6a540adb4718a77b8d66424", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 98 |
+
{"t": 1757897487147, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.029}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.162508Z", "visitor_id": "03c9f6dec7e545abb22348289fa34647", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 99 |
+
{"t": 1757897487156, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.028}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.163267Z", "visitor_id": "0c77d0a7bc224982bc4bdb8c04edff24", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 100 |
+
{"t": 1757897487164, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.027}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.168758Z", "visitor_id": "29bab3f6845e43638c8dd75c23820619", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 101 |
+
{"t": 1757897487171, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.026}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.175856Z", "visitor_id": "4f7f2754bdf04f539b3ec74393106efa", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 102 |
+
{"t": 1757897487181, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.025}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.184688Z", "visitor_id": "3a6834ac8670471da8917275851e2e91", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 103 |
+
{"t": 1757897487189, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.024}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.192230Z", "visitor_id": "7bd11b461c80417aba11eccc9a9e7593", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 104 |
+
{"t": 1757897487197, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.023}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.203530Z", "visitor_id": "c3882f011cd24624ad773cfdd5dea567", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 105 |
+
{"t": 1757897487214, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "learning-rate", "value": 0.022}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:27.218771Z", "visitor_id": "eb8e11001f1e463693aecad3eda7a8bd", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 106 |
+
{"t": 1757897488866, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 29}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:28.881757Z", "visitor_id": "736c4b7ca1b245f5b270d7c0254c953b", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 107 |
+
{"t": 1757897488884, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 28}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:28.903953Z", "visitor_id": "770030ef26eb484d8403fdfc93ca3c82", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 108 |
+
{"t": 1757897488890, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 27}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:28.911838Z", "visitor_id": "66395ae4e2fc4b16958d01ad61923205", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 109 |
+
{"t": 1757897488902, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 26}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:28.921253Z", "visitor_id": "36087b80a61842879031d3d2f2f27ffd", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 110 |
+
{"t": 1757897488915, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 25}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:28.923990Z", "visitor_id": "1a4b3ad68f9c473b80c7bae12fd7ac94", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 111 |
+
{"t": 1757897488940, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 24}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:28.953571Z", "visitor_id": "fb4e6f8753d044ee8bcf10188f929ba9", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 112 |
+
{"t": 1757897490741, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 25}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.755615Z", "visitor_id": "f975889892aa46ffa1bcb1c92e946bb5", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 113 |
+
{"t": 1757897490765, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 26}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.780780Z", "visitor_id": "ba5e1352c4ed4144a1da1339b8a04bd5", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 114 |
+
{"t": 1757897490773, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 27}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.786421Z", "visitor_id": "90a811602f0944ce9eaca685dd3c0f68", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 115 |
+
{"t": 1757897490784, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 28}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.806213Z", "visitor_id": "94094b92d05d4ecb85847101d037412c", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 116 |
+
{"t": 1757897490790, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 30}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.813080Z", "visitor_id": "58405d3f6c4047bebefcf6a8b2918f02", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 117 |
+
{"t": 1757897490798, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 31}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.815575Z", "visitor_id": "f1e8fbfbbd904ce2a06bd9090477a340", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 118 |
+
{"t": 1757897490807, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 32}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.818823Z", "visitor_id": "8dcceb6b31394478982c0ff5cc7b2808", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 119 |
+
{"t": 1757897490822, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 33}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.830624Z", "visitor_id": "707f7802d5a24ac5b239b9d63e6d6604", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 120 |
+
{"t": 1757897490839, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 34}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.847754Z", "visitor_id": "4ba5c745c0014a80a17a41a30d0e97f1", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 121 |
+
{"t": 1757897490856, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 35}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:30.864325Z", "visitor_id": "eb8e9a33f51d43f79b043f9b6d44ff56", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 122 |
+
{"t": 1757897491565, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 34}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.587631Z", "visitor_id": "88cb47a6272a47d68bb00e6078a01598", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 123 |
+
{"t": 1757897491573, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 33}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.596642Z", "visitor_id": "aa549143f16d4602b82641761dca4829", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 124 |
+
{"t": 1757897491583, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 32}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.607395Z", "visitor_id": "1dce8336bd844b23b6c2f463cc1b500c", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 125 |
+
{"t": 1757897491590, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 31}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.608258Z", "visitor_id": "f4561ccf9c584db48a15c43a59ec0c80", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 126 |
+
{"t": 1757897491600, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 30}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.610816Z", "visitor_id": "f044f05918e74a18849999eb96ca18e7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 127 |
+
{"t": 1757897491605, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 29}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.613141Z", "visitor_id": "33e2fa746f30469ea05c10718e655412", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 128 |
+
{"t": 1757897491614, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 27}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.619893Z", "visitor_id": "044574a3a8d4499eac61f9c98ab41e31", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 129 |
+
{"t": 1757897491623, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 25}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.629444Z", "visitor_id": "8fcc75e5568c4beb8730d6e0a086f03b", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 130 |
+
{"t": 1757897491632, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 23}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.638401Z", "visitor_id": "590783e013bd4ee8b76c46dc45dbb2d1", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 131 |
+
{"t": 1757897491639, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 22}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.647125Z", "visitor_id": "891f8bca177249018e960f6c08076e0b", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 132 |
+
{"t": 1757897491647, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 21}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.656126Z", "visitor_id": "5be26b3df4b54d5291849c81424e1a19", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 133 |
+
{"t": 1757897491656, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 20}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.661848Z", "visitor_id": "2c7883b14a6e433986dc04783445a1c3", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 134 |
+
{"t": 1757897491664, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 19}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.672260Z", "visitor_id": "53620d667d7d45808212f8b399884652", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 135 |
+
{"t": 1757897491672, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 18}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.679509Z", "visitor_id": "e1a3b284b94c4446ac39917982a31cbf", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 136 |
+
{"t": 1757897491690, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "epochs", "value": 17}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:31.702250Z", "visitor_id": "6874e4a15c0349b1b4de7a811e15c7e2", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 137 |
+
{"t": 1757897494763, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.4}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.776883Z", "visitor_id": "7a9711f853d340b4b81484ed29efb3c7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 138 |
+
{"t": 1757897494781, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.5}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.787762Z", "visitor_id": "f54f8d7ded964f90b509e8993658793a", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 139 |
+
{"t": 1757897494797, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.6}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.804320Z", "visitor_id": "bc3acfa7b56145c785302776fcd34762", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 140 |
+
{"t": 1757897494806, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.7}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.813977Z", "visitor_id": "95ad96734b694c40b1e4e320f6fd0607", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 141 |
+
{"t": 1757897494814, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.8}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.828936Z", "visitor_id": "4479169f3aa24640b99a9a3d82da6b75", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 142 |
+
{"t": 1757897494822, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.834494Z", "visitor_id": "53a06ac4a7da4d57b9dee56d495f4082", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 143 |
+
{"t": 1757897494829, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.1}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.835776Z", "visitor_id": "29d1f95281b04b079e182f6139e2955d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 144 |
+
{"t": 1757897494835, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.3}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.839903Z", "visitor_id": "d9e1a9492a204d2fa231f0effe385289", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 145 |
+
{"t": 1757897494843, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.4}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.846244Z", "visitor_id": "fbc4bb32b1c34cef9518240db9d3d7a2", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 146 |
+
{"t": 1757897494851, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.5}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.859535Z", "visitor_id": "7abba36059ec4a3296fa62e22ddb54af", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 147 |
+
{"t": 1757897494860, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.7}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.863677Z", "visitor_id": "13f1d34ab0ce41c4812835e1b2f79118", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 148 |
+
{"t": 1757897494877, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.8}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.882968Z", "visitor_id": "8c0556e11966451b90f3ef91ec5169ca", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 149 |
+
{"t": 1757897494893, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.9}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:34.903921Z", "visitor_id": "503a3485cd4a4a75835590b69706485a", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 150 |
+
{"t": 1757897495883, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.8}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.898662Z", "visitor_id": "de983ff645464b2ab0c3f0585ce55ea3", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 151 |
+
{"t": 1757897495897, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.7}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.906532Z", "visitor_id": "857dd5f661bb4d82bff96b81096bf25b", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 152 |
+
{"t": 1757897495907, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.6}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.915614Z", "visitor_id": "a4e176353ff9436490df688df19d3fe0", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 153 |
+
{"t": 1757897495916, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3.2}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.921782Z", "visitor_id": "df13ecc130274abab433c7a68d575987", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 154 |
+
{"t": 1757897495927, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 3}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.939066Z", "visitor_id": "f0e7f4edcc3d4907b402c48f4c32adb2", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 155 |
+
{"t": 1757897495935, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.7}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.945562Z", "visitor_id": "1ab5b28b54d84c35bfc5a1f75f90722d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 156 |
+
{"t": 1757897495943, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.5}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.949826Z", "visitor_id": "549b25876b754dd7821f311a87db9b6e", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 157 |
+
{"t": 1757897495960, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2.1}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.965465Z", "visitor_id": "b26e1b393fdb4ac7ada399d95ed64db8", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 158 |
+
{"t": 1757897495968, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 2}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.980671Z", "visitor_id": "7fe84822397d4ee9a465715554d60000", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 159 |
+
{"t": 1757897495976, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.8}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.981884Z", "visitor_id": "fa80bc0267c04b398bbc69762b49f644", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 160 |
+
{"t": 1757897495985, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.7}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.990460Z", "visitor_id": "5b024679d79e44f69d8eedb8327830bd", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 161 |
+
{"t": 1757897495993, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.6}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:35.996878Z", "visitor_id": "bf7dbec3b8274f69bc3f4491ffba4451", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 162 |
+
{"t": 1757897496010, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.5}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:36.017650Z", "visitor_id": "09c6cb794926434da285c2dc575bc2c9", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 163 |
+
{"t": 1757897496018, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.4}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:36.024760Z", "visitor_id": "ffdb572a99d84cc0b2ae853c22a78fd4", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 164 |
+
{"t": 1757897496043, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "param_change", "path": "/", "payload": {"param": "clipping-norm", "value": 1.3}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:36.049381Z", "visitor_id": "72d5cb50d7814968839c17946111111e", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 165 |
+
{"t": 1757897499668, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "🎯 Use Optimal Parameters"}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:39.680427Z", "visitor_id": "7664523ed7454322a4452317893083e9", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 166 |
+
{"t": 1757897500888, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "train-button"}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:40.905384Z", "visitor_id": "5f9fb54f91bb4b66aa9249645dce6bf0", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 167 |
+
{"t": 1757897500901, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "train_toggle", "path": "/", "payload": {"clipping_norm": 2, "noise_multiplier": 1, "batch_size": 256, "learning_rate": 0.05, "epochs": 30, "dataset": "mnist", "model_architecture": "simple-mlp"}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T00:51:40.913294Z", "visitor_id": "c90d0ece4122408aa78d67b4f9da310d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 168 |
+
{"t": 1757898030209, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "Gradient Clipping"}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T01:00:30.216813Z", "visitor_id": "d7f120bc90d84203814c2203288defd5", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 169 |
+
{"t": 1757898030210, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "tab_click", "path": "/", "payload": {"tab": "gradients"}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T01:00:30.217736Z", "visitor_id": "054c4c0afc8e48299a805968c31002f4", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 170 |
+
{"t": 1757898032198, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "Training Metrics"}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T01:00:32.203375Z", "visitor_id": "569c0418588640de86e374413bb697cd", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 171 |
+
{"t": 1757898032198, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "tab_click", "path": "/", "payload": {"tab": "training"}, "user": {}, "vid": "1fe54807080a44ae81596ee6ff1d510b", "server_time": "2025-09-15T01:00:32.203965Z", "visitor_id": "65662bb6d56e4393b14859512f91216d", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 172 |
+
{"t": 1757898321497, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "Playground"}, "user": {}, "vid": "1828b6fa963043a7945eab9868123e34", "server_time": "2025-09-15T01:05:21.520119Z", "visitor_id": "1da5c151c2554ffdae941a6eea2511c7", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 173 |
+
{"t": 1757898322837, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "Learning Hub"}, "user": {}, "vid": "3d614feabfc740859707a5f0970721f9", "server_time": "2025-09-15T01:05:22.842755Z", "visitor_id": "5408a90918914b49b36c46dc239e3524", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 174 |
+
{"t": 1757898352049, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/learning", "payload": {"name": "Playground"}, "user": {}, "vid": "24e47deb0173460e8dd8a821f219efe9", "server_time": "2025-09-15T01:05:52.056017Z", "visitor_id": "a8e5594073f248f099de4e5497ddb0b4", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/learning", "dnt": false, "gpc": false}
|
| 175 |
+
{"t": 1757898431382, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/", "payload": {"name": "Learning Hub"}, "user": {}, "vid": "e052efa6573a46f1bb059f505ada8544", "server_time": "2025-09-15T01:07:11.407601Z", "visitor_id": "6ae2cb63be1840929100920b940ae332", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/", "dnt": false, "gpc": false}
|
| 176 |
+
{"t": 1757898439032, "sessionId": "e6fbeada-329d-41e3-aa40-155e0da60edb", "eventType": "ui_click", "path": "/learning", "payload": {"name": "Playground"}, "user": {}, "vid": "287ddc28a4b24227a2076b5d34a49e6b", "server_time": "2025-09-15T01:07:19.037150Z", "visitor_id": "299e5e6dcaed47a990fc7c795739b3c3", "client_ip_truncated": "127.0.0.0", "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36", "referer": "http://127.0.0.1:5000/learning", "dnt": false, "gpc": false}
|
app/routes.py
CHANGED
|
@@ -1,4 +1,8 @@
|
|
| 1 |
-
from
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
from app.training.mock_trainer import MockTrainer
|
| 3 |
from app.training.privacy_calculator import PrivacyCalculator
|
| 4 |
from flask_cors import cross_origin
|
|
@@ -171,4 +175,89 @@ def trainer_status():
|
|
| 171 |
'real_trainer_available': REAL_TRAINER_AVAILABLE,
|
| 172 |
'current_trainer': 'real' if REAL_TRAINER_AVAILABLE else 'mock',
|
| 173 |
'dataset': 'MNIST' if REAL_TRAINER_AVAILABLE else 'synthetic'
|
| 174 |
-
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from datetime import datetime
|
| 2 |
+
import ipaddress
|
| 3 |
+
import uuid
|
| 4 |
+
import json
|
| 5 |
+
from flask import Blueprint, render_template, jsonify, request, current_app, make_response
|
| 6 |
from app.training.mock_trainer import MockTrainer
|
| 7 |
from app.training.privacy_calculator import PrivacyCalculator
|
| 8 |
from flask_cors import cross_origin
|
|
|
|
| 175 |
'real_trainer_available': REAL_TRAINER_AVAILABLE,
|
| 176 |
'current_trainer': 'real' if REAL_TRAINER_AVAILABLE else 'mock',
|
| 177 |
'dataset': 'MNIST' if REAL_TRAINER_AVAILABLE else 'synthetic'
|
| 178 |
+
})
|
| 179 |
+
|
| 180 |
+
|
| 181 |
+
# ===== Analytics & Identity Endpoints =====
|
| 182 |
+
COOKIE_NAME = "vid"
|
| 183 |
+
|
| 184 |
+
def _client_ip():
|
| 185 |
+
try:
|
| 186 |
+
xff = (request.headers.get("X-Forwarded-For") or "").split(",")[0].strip()
|
| 187 |
+
ip = xff or (request.remote_addr or "")
|
| 188 |
+
if not ip:
|
| 189 |
+
return ""
|
| 190 |
+
ip_obj = ipaddress.ip_address(ip)
|
| 191 |
+
if ip_obj.version == 4:
|
| 192 |
+
return ".".join(ip.split(".")[:3]) + ".0"
|
| 193 |
+
# IPv6 truncate to /48-ish
|
| 194 |
+
hextets = ip.split(":")
|
| 195 |
+
return ":".join((hextets + ["0"] * 8)[:3]) + "::"
|
| 196 |
+
except Exception:
|
| 197 |
+
return ""
|
| 198 |
+
|
| 199 |
+
def _ensure_vid_cookie(resp=None):
|
| 200 |
+
vid = request.cookies.get(COOKIE_NAME)
|
| 201 |
+
if not vid:
|
| 202 |
+
vid = uuid.uuid4().hex
|
| 203 |
+
if resp is None:
|
| 204 |
+
resp = make_response(jsonify({"vid": vid}))
|
| 205 |
+
resp.set_cookie(
|
| 206 |
+
key=COOKIE_NAME,
|
| 207 |
+
value=vid,
|
| 208 |
+
max_age=60*60*24*365*2,
|
| 209 |
+
httponly=True,
|
| 210 |
+
secure=True,
|
| 211 |
+
samesite="Lax",
|
| 212 |
+
path="/"
|
| 213 |
+
)
|
| 214 |
+
return vid, resp
|
| 215 |
+
return vid, resp
|
| 216 |
+
|
| 217 |
+
@main.route("/api/whoami", methods=["GET"])
|
| 218 |
+
@cross_origin()
|
| 219 |
+
def whoami():
|
| 220 |
+
ua = request.headers.get("User-Agent", "")[:200]
|
| 221 |
+
dnt = request.headers.get("DNT") == "1"
|
| 222 |
+
gpc = request.headers.get("Sec-GPC") == "1"
|
| 223 |
+
vid, resp = _ensure_vid_cookie()
|
| 224 |
+
payload = {"vid": vid, "user_agent": ua, "dnt": dnt, "gpc": gpc}
|
| 225 |
+
return jsonify(payload)
|
| 226 |
+
|
| 227 |
+
@main.route('/api/track', methods=['POST', 'OPTIONS'])
|
| 228 |
+
@cross_origin()
|
| 229 |
+
def track_event():
|
| 230 |
+
if request.method == 'OPTIONS':
|
| 231 |
+
return jsonify({'status': 'ok'})
|
| 232 |
+
try:
|
| 233 |
+
evt = request.get_json(force=True, silent=True) or {}
|
| 234 |
+
|
| 235 |
+
dnt = request.headers.get("DNT") == "1"
|
| 236 |
+
gpc = request.headers.get("Sec-GPC") == "1"
|
| 237 |
+
ua = request.headers.get("User-Agent", "")[:200]
|
| 238 |
+
ref = request.headers.get("Referer", "")[:200]
|
| 239 |
+
vid, resp = _ensure_vid_cookie()
|
| 240 |
+
|
| 241 |
+
# Allow only specific user fields if provided
|
| 242 |
+
user = evt.get("user") if isinstance(evt.get("user"), dict) else {}
|
| 243 |
+
allowed_user = {k: user[k] for k in ["id", "role", "org", "plan"] if k in user and isinstance(user[k], (str, int))}
|
| 244 |
+
|
| 245 |
+
evt.update({
|
| 246 |
+
"server_time": datetime.utcnow().isoformat() + "Z",
|
| 247 |
+
"visitor_id": vid,
|
| 248 |
+
"client_ip_truncated": _client_ip(),
|
| 249 |
+
"user_agent": ua,
|
| 250 |
+
"referer": ref,
|
| 251 |
+
"dnt": dnt,
|
| 252 |
+
"gpc": gpc,
|
| 253 |
+
"user": allowed_user
|
| 254 |
+
})
|
| 255 |
+
|
| 256 |
+
logfile = os.path.join(current_app.root_path, 'analytics.log.jsonl')
|
| 257 |
+
with open(logfile, 'a', encoding='utf-8') as f:
|
| 258 |
+
f.write(json.dumps(evt, ensure_ascii=False) + '\n')
|
| 259 |
+
|
| 260 |
+
return jsonify({'ok': True})
|
| 261 |
+
except Exception as e:
|
| 262 |
+
return jsonify({'ok': False, 'error': str(e)}), 400
|
| 263 |
+
# ===== End Analytics =====
|
app/routes.py.ori.py
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from flask import Blueprint, render_template, jsonify, request, current_app
|
| 2 |
+
from app.training.mock_trainer import MockTrainer
|
| 3 |
+
from app.training.privacy_calculator import PrivacyCalculator
|
| 4 |
+
from flask_cors import cross_origin
|
| 5 |
+
import os
|
| 6 |
+
|
| 7 |
+
# Try to import RealTrainer, fallback to MockTrainer if dependencies aren't available
|
| 8 |
+
try:
|
| 9 |
+
from app.training.simplified_real_trainer import SimplifiedRealTrainer as RealTrainer
|
| 10 |
+
REAL_TRAINER_AVAILABLE = True
|
| 11 |
+
print("Simplified real trainer available - will use MNIST dataset")
|
| 12 |
+
except ImportError as e:
|
| 13 |
+
print(f"Real trainer not available ({e}) - trying simplified version")
|
| 14 |
+
try:
|
| 15 |
+
from app.training.real_trainer import RealTrainer
|
| 16 |
+
REAL_TRAINER_AVAILABLE = True
|
| 17 |
+
print("Full real trainer available - will use MNIST dataset")
|
| 18 |
+
except ImportError as e2:
|
| 19 |
+
print(f"No real trainer available ({e2}) - using mock trainer")
|
| 20 |
+
REAL_TRAINER_AVAILABLE = False
|
| 21 |
+
|
| 22 |
+
main = Blueprint('main', __name__)
|
| 23 |
+
mock_trainer = MockTrainer()
|
| 24 |
+
privacy_calculator = PrivacyCalculator()
|
| 25 |
+
|
| 26 |
+
# We'll create trainers dynamically based on dataset selection
|
| 27 |
+
real_trainers = {} # Cache trainers by dataset to avoid reloading
|
| 28 |
+
|
| 29 |
+
def get_or_create_trainer(dataset, model_architecture='simple-mlp'):
|
| 30 |
+
"""Get or create a trainer for the specified dataset and architecture."""
|
| 31 |
+
if not REAL_TRAINER_AVAILABLE:
|
| 32 |
+
return None
|
| 33 |
+
|
| 34 |
+
# Create a unique key for dataset + architecture combination
|
| 35 |
+
trainer_key = f"{dataset}_{model_architecture}"
|
| 36 |
+
|
| 37 |
+
if trainer_key not in real_trainers:
|
| 38 |
+
try:
|
| 39 |
+
print(f"Creating new trainer for dataset: {dataset}, architecture: {model_architecture}")
|
| 40 |
+
real_trainers[trainer_key] = RealTrainer(dataset=dataset, model_architecture=model_architecture)
|
| 41 |
+
print(f"Trainer for {dataset} with {model_architecture} initialized successfully")
|
| 42 |
+
except Exception as e:
|
| 43 |
+
print(f"Failed to initialize trainer for {dataset} with {model_architecture}: {e}")
|
| 44 |
+
return None
|
| 45 |
+
|
| 46 |
+
return real_trainers[trainer_key]
|
| 47 |
+
|
| 48 |
+
@main.route('/')
|
| 49 |
+
def index():
|
| 50 |
+
return render_template('index.html')
|
| 51 |
+
|
| 52 |
+
@main.route('/learning')
|
| 53 |
+
def learning():
|
| 54 |
+
return render_template('learning.html')
|
| 55 |
+
|
| 56 |
+
@main.route('/api/train', methods=['POST', 'OPTIONS'])
|
| 57 |
+
@cross_origin()
|
| 58 |
+
def train():
|
| 59 |
+
if request.method == 'OPTIONS':
|
| 60 |
+
return jsonify({'status': 'ok'})
|
| 61 |
+
|
| 62 |
+
try:
|
| 63 |
+
data = request.json
|
| 64 |
+
if not data:
|
| 65 |
+
return jsonify({'error': 'No data provided'}), 400
|
| 66 |
+
|
| 67 |
+
params = {
|
| 68 |
+
'clipping_norm': float(data.get('clipping_norm', 1.0)),
|
| 69 |
+
'noise_multiplier': float(data.get('noise_multiplier', 1.0)),
|
| 70 |
+
'batch_size': int(data.get('batch_size', 64)),
|
| 71 |
+
'learning_rate': float(data.get('learning_rate', 0.01)),
|
| 72 |
+
'epochs': int(data.get('epochs', 5))
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
# Get dataset and model architecture selection
|
| 76 |
+
dataset = data.get('dataset', 'mnist')
|
| 77 |
+
model_architecture = data.get('model_architecture', 'simple-mlp')
|
| 78 |
+
|
| 79 |
+
# Check if user wants to force mock training
|
| 80 |
+
use_mock = data.get('use_mock', False)
|
| 81 |
+
|
| 82 |
+
# Use real trainer if available and not forced to use mock
|
| 83 |
+
if REAL_TRAINER_AVAILABLE and not use_mock:
|
| 84 |
+
real_trainer = get_or_create_trainer(dataset, model_architecture)
|
| 85 |
+
if real_trainer:
|
| 86 |
+
print(f"Using real trainer with {dataset.upper()} dataset and {model_architecture} architecture")
|
| 87 |
+
results = real_trainer.train(params)
|
| 88 |
+
results['trainer_type'] = 'real'
|
| 89 |
+
results['dataset'] = dataset.upper()
|
| 90 |
+
results['model_architecture'] = model_architecture
|
| 91 |
+
else:
|
| 92 |
+
print("Failed to create real trainer, falling back to mock trainer")
|
| 93 |
+
results = mock_trainer.train(params)
|
| 94 |
+
results['trainer_type'] = 'mock'
|
| 95 |
+
results['dataset'] = 'synthetic'
|
| 96 |
+
results['model_architecture'] = 'mock'
|
| 97 |
+
else:
|
| 98 |
+
print("Using mock trainer with synthetic data")
|
| 99 |
+
results = mock_trainer.train(params)
|
| 100 |
+
results['trainer_type'] = 'mock'
|
| 101 |
+
results['dataset'] = 'synthetic'
|
| 102 |
+
results['model_architecture'] = 'mock'
|
| 103 |
+
|
| 104 |
+
# Add gradient information for visualization (if not already included)
|
| 105 |
+
if 'gradient_info' not in results:
|
| 106 |
+
if REAL_TRAINER_AVAILABLE and not use_mock:
|
| 107 |
+
current_trainer = get_or_create_trainer(dataset, model_architecture)
|
| 108 |
+
if current_trainer:
|
| 109 |
+
trainer = current_trainer
|
| 110 |
+
else:
|
| 111 |
+
trainer = mock_trainer
|
| 112 |
+
else:
|
| 113 |
+
trainer = mock_trainer
|
| 114 |
+
|
| 115 |
+
results['gradient_info'] = {
|
| 116 |
+
'before_clipping': trainer.generate_gradient_norms(params['clipping_norm']),
|
| 117 |
+
'after_clipping': trainer.generate_clipped_gradients(params['clipping_norm'])
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
return jsonify(results)
|
| 121 |
+
except (TypeError, ValueError) as e:
|
| 122 |
+
return jsonify({'error': f'Invalid parameter values: {str(e)}'}), 400
|
| 123 |
+
except Exception as e:
|
| 124 |
+
print(f"Training error: {str(e)}")
|
| 125 |
+
# Fallback to mock trainer on any error
|
| 126 |
+
try:
|
| 127 |
+
print("Falling back to mock trainer due to error")
|
| 128 |
+
results = mock_trainer.train(params)
|
| 129 |
+
results['trainer_type'] = 'mock'
|
| 130 |
+
results['dataset'] = 'synthetic'
|
| 131 |
+
results['fallback_reason'] = str(e)
|
| 132 |
+
return jsonify(results)
|
| 133 |
+
except Exception as fallback_error:
|
| 134 |
+
return jsonify({'error': f'Server error: {str(fallback_error)}'}), 500
|
| 135 |
+
|
| 136 |
+
@main.route('/api/privacy-budget', methods=['POST', 'OPTIONS'])
|
| 137 |
+
@cross_origin()
|
| 138 |
+
def calculate_privacy_budget():
|
| 139 |
+
if request.method == 'OPTIONS':
|
| 140 |
+
return jsonify({'status': 'ok'})
|
| 141 |
+
|
| 142 |
+
try:
|
| 143 |
+
data = request.json
|
| 144 |
+
if not data:
|
| 145 |
+
return jsonify({'error': 'No data provided'}), 400
|
| 146 |
+
|
| 147 |
+
params = {
|
| 148 |
+
'clipping_norm': float(data.get('clipping_norm', 1.0)),
|
| 149 |
+
'noise_multiplier': float(data.get('noise_multiplier', 1.0)),
|
| 150 |
+
'batch_size': int(data.get('batch_size', 64)),
|
| 151 |
+
'epochs': int(data.get('epochs', 5))
|
| 152 |
+
}
|
| 153 |
+
|
| 154 |
+
# Use real trainer's privacy calculation if available, otherwise use privacy calculator
|
| 155 |
+
if REAL_TRAINER_AVAILABLE and real_trainer:
|
| 156 |
+
epsilon = real_trainer._calculate_privacy_budget(params)
|
| 157 |
+
else:
|
| 158 |
+
epsilon = privacy_calculator.calculate_epsilon(params)
|
| 159 |
+
|
| 160 |
+
return jsonify({'epsilon': epsilon})
|
| 161 |
+
except (TypeError, ValueError) as e:
|
| 162 |
+
return jsonify({'error': f'Invalid parameter values: {str(e)}'}), 400
|
| 163 |
+
except Exception as e:
|
| 164 |
+
return jsonify({'error': f'Server error: {str(e)}'}), 500
|
| 165 |
+
|
| 166 |
+
@main.route('/api/trainer-status', methods=['GET'])
|
| 167 |
+
@cross_origin()
|
| 168 |
+
def trainer_status():
|
| 169 |
+
"""Endpoint to check which trainer is being used."""
|
| 170 |
+
return jsonify({
|
| 171 |
+
'real_trainer_available': REAL_TRAINER_AVAILABLE,
|
| 172 |
+
'current_trainer': 'real' if REAL_TRAINER_AVAILABLE else 'mock',
|
| 173 |
+
'dataset': 'MNIST' if REAL_TRAINER_AVAILABLE else 'synthetic'
|
| 174 |
+
})
|
app/static/js/main.js
CHANGED
|
@@ -1,3 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
class DPSGDExplorer {
|
| 2 |
constructor() {
|
| 3 |
this.trainingChart = null;
|
|
@@ -20,7 +82,9 @@ class DPSGDExplorer {
|
|
| 20 |
// Add event listeners
|
| 21 |
document.getElementById('train-button')?.addEventListener('click', () => this.toggleTraining());
|
| 22 |
|
| 23 |
-
|
|
|
|
|
|
|
| 24 |
document.getElementById('view-epochs')?.addEventListener('click', () => this.switchView('epochs'));
|
| 25 |
document.getElementById('view-iterations')?.addEventListener('click', () => this.switchView('iterations'));
|
| 26 |
}
|
|
@@ -45,7 +109,9 @@ class DPSGDExplorer {
|
|
| 45 |
// Update privacy budget
|
| 46 |
this.updatePrivacyBudget();
|
| 47 |
|
| 48 |
-
|
|
|
|
|
|
|
| 49 |
if (id === 'clipping-norm') {
|
| 50 |
this.updateGradientVisualization(value);
|
| 51 |
}
|
|
@@ -100,7 +166,9 @@ class DPSGDExplorer {
|
|
| 100 |
initializeTabs() {
|
| 101 |
const tabs = document.querySelectorAll('.tab');
|
| 102 |
tabs.forEach(tab => {
|
| 103 |
-
|
|
|
|
|
|
|
| 104 |
const tabsContainer = tab.closest('.tabs');
|
| 105 |
tabsContainer.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
| 106 |
tab.classList.add('active');
|
|
@@ -374,7 +442,9 @@ class DPSGDExplorer {
|
|
| 374 |
budgetValue.textContent = data.epsilon.toFixed(2);
|
| 375 |
budgetFill.style.width = `${Math.min(data.epsilon / 10 * 100, 100)}%`;
|
| 376 |
|
| 377 |
-
|
|
|
|
|
|
|
| 378 |
budgetFill.classList.remove('low', 'medium', 'high');
|
| 379 |
if (data.epsilon <= 1) {
|
| 380 |
budgetFill.classList.add('low');
|
|
@@ -484,7 +554,9 @@ class DPSGDExplorer {
|
|
| 484 |
switchView(view) {
|
| 485 |
this.currentView = view;
|
| 486 |
|
| 487 |
-
|
|
|
|
|
|
|
| 488 |
document.querySelectorAll('.view-toggle').forEach(btn => {
|
| 489 |
btn.classList.remove('active');
|
| 490 |
});
|
|
|
|
| 1 |
+
|
| 2 |
+
// ======= Analytics & Identity Bootstrap =======
|
| 3 |
+
const ANALYTICS_ENDPOINT = '/api/track';
|
| 4 |
+
const COOKIE_NAME = 'vid';
|
| 5 |
+
|
| 6 |
+
// Generate a stable session id (per browser)
|
| 7 |
+
const sessionId = (() => {
|
| 8 |
+
const key = 'dpsgd_session_id';
|
| 9 |
+
let id = localStorage.getItem(key);
|
| 10 |
+
if (!id) { id = (crypto.randomUUID?.() || (String(Date.now()) + Math.random().toString(16).slice(2))); localStorage.setItem(key, id); }
|
| 11 |
+
return id;
|
| 12 |
+
})();
|
| 13 |
+
|
| 14 |
+
// Minimal user context (non-PII by default). Call identify({ id, role, org, plan }) if you have a login.
|
| 15 |
+
let userContext = { vid: null, id: null, role: null, org: null, plan: null };
|
| 16 |
+
|
| 17 |
+
async function initIdentity() {
|
| 18 |
+
try {
|
| 19 |
+
const r = await fetch('/api/whoami', { credentials: 'same-origin' });
|
| 20 |
+
const info = await r.json();
|
| 21 |
+
if (info && info.vid) userContext.vid = info.vid;
|
| 22 |
+
} catch {}
|
| 23 |
+
}
|
| 24 |
+
initIdentity();
|
| 25 |
+
|
| 26 |
+
function identify(user) {
|
| 27 |
+
userContext = { ...userContext, ...{
|
| 28 |
+
id: user?.id ?? null,
|
| 29 |
+
role: user?.role ?? null,
|
| 30 |
+
org: user?.org ?? null,
|
| 31 |
+
plan: user?.plan ?? null,
|
| 32 |
+
}};
|
| 33 |
+
track('identify', { user: { id: userContext.id, role: userContext.role, org: userContext.org, plan: userContext.plan } });
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
// Fire-and-forget tracker
|
| 37 |
+
function track(eventType, payload = {}) {
|
| 38 |
+
const body = {
|
| 39 |
+
t: Date.now(),
|
| 40 |
+
sessionId,
|
| 41 |
+
eventType,
|
| 42 |
+
path: location.pathname,
|
| 43 |
+
payload,
|
| 44 |
+
user: { id: userContext.id, role: userContext.role, org: userContext.org, plan: userContext.plan },
|
| 45 |
+
vid: userContext.vid
|
| 46 |
+
};
|
| 47 |
+
const data = new Blob([JSON.stringify(body)], { type: 'application/json' });
|
| 48 |
+
if (!(navigator.sendBeacon && navigator.sendBeacon(ANALYTICS_ENDPOINT, data))) {
|
| 49 |
+
fetch(ANALYTICS_ENDPOINT, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body), credentials: 'same-origin' }).catch(()=>{});
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
// Global click listener (optional; captures generic UI clicks)
|
| 54 |
+
document.addEventListener('click', (e) => {
|
| 55 |
+
const target = e.target?.closest?.('[data-track], button, a, .nav-link, .tab');
|
| 56 |
+
if (!target) return;
|
| 57 |
+
const name = target.getAttribute('data-track') || target.id || target.textContent?.trim()?.slice(0, 60);
|
| 58 |
+
if (!name) return;
|
| 59 |
+
track('ui_click', { name });
|
| 60 |
+
}, { capture: true });
|
| 61 |
+
// ======= End Analytics Bootstrap =======
|
| 62 |
+
|
| 63 |
class DPSGDExplorer {
|
| 64 |
constructor() {
|
| 65 |
this.trainingChart = null;
|
|
|
|
| 82 |
// Add event listeners
|
| 83 |
document.getElementById('train-button')?.addEventListener('click', () => this.toggleTraining());
|
| 84 |
|
| 85 |
+
|
| 86 |
+
document.getElementById('train-button')?.addEventListener('click', () => { try { track('train_toggle', (this.getParameters?.()||{})); } catch (e) {} });
|
| 87 |
+
// Add view toggle listeners
|
| 88 |
document.getElementById('view-epochs')?.addEventListener('click', () => this.switchView('epochs'));
|
| 89 |
document.getElementById('view-iterations')?.addEventListener('click', () => this.switchView('iterations'));
|
| 90 |
}
|
|
|
|
| 109 |
// Update privacy budget
|
| 110 |
this.updatePrivacyBudget();
|
| 111 |
|
| 112 |
+
|
| 113 |
+
try { track('param_change', { param: id, value }); } catch (e) {};
|
| 114 |
+
// Update gradient visualization when clipping norm changes
|
| 115 |
if (id === 'clipping-norm') {
|
| 116 |
this.updateGradientVisualization(value);
|
| 117 |
}
|
|
|
|
| 166 |
initializeTabs() {
|
| 167 |
const tabs = document.querySelectorAll('.tab');
|
| 168 |
tabs.forEach(tab => {
|
| 169 |
+
|
| 170 |
+
tab.addEventListener('click', () => { try { track('tab_click', { tab: tab.dataset?.tab || tab.id || 'unknown' }); } catch (e) {} });
|
| 171 |
+
tab.addEventListener('click', () => {
|
| 172 |
const tabsContainer = tab.closest('.tabs');
|
| 173 |
tabsContainer.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
| 174 |
tab.classList.add('active');
|
|
|
|
| 442 |
budgetValue.textContent = data.epsilon.toFixed(2);
|
| 443 |
budgetFill.style.width = `${Math.min(data.epsilon / 10 * 100, 100)}%`;
|
| 444 |
|
| 445 |
+
|
| 446 |
+
try { track('privacy_budget_update', { epsilon: data.epsilon }); } catch (e) {};
|
| 447 |
+
// Update class for coloring
|
| 448 |
budgetFill.classList.remove('low', 'medium', 'high');
|
| 449 |
if (data.epsilon <= 1) {
|
| 450 |
budgetFill.classList.add('low');
|
|
|
|
| 554 |
switchView(view) {
|
| 555 |
this.currentView = view;
|
| 556 |
|
| 557 |
+
|
| 558 |
+
try { track('view_switch', { view }); } catch (e) {};
|
| 559 |
+
// Update button states
|
| 560 |
document.querySelectorAll('.view-toggle').forEach(btn => {
|
| 561 |
btn.classList.remove('active');
|
| 562 |
});
|
app/static/js/main.js.ori.js
ADDED
|
@@ -0,0 +1,858 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
class DPSGDExplorer {
|
| 2 |
+
constructor() {
|
| 3 |
+
this.trainingChart = null;
|
| 4 |
+
this.privacyChart = null;
|
| 5 |
+
this.gradientChart = null;
|
| 6 |
+
this.isTraining = false;
|
| 7 |
+
this.currentView = 'epochs'; // 'epochs' or 'iterations'
|
| 8 |
+
this.epochsData = [];
|
| 9 |
+
this.iterationsData = [];
|
| 10 |
+
this.initializeUI();
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
initializeUI() {
|
| 14 |
+
// Initialize parameter controls
|
| 15 |
+
this.initializeSliders();
|
| 16 |
+
this.initializePresets();
|
| 17 |
+
this.initializeTabs();
|
| 18 |
+
this.initializeCharts();
|
| 19 |
+
|
| 20 |
+
// Add event listeners
|
| 21 |
+
document.getElementById('train-button')?.addEventListener('click', () => this.toggleTraining());
|
| 22 |
+
|
| 23 |
+
// Add view toggle listeners
|
| 24 |
+
document.getElementById('view-epochs')?.addEventListener('click', () => this.switchView('epochs'));
|
| 25 |
+
document.getElementById('view-iterations')?.addEventListener('click', () => this.switchView('iterations'));
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
initializeSliders() {
|
| 29 |
+
// Parameter sliders
|
| 30 |
+
const sliders = {
|
| 31 |
+
'clipping-norm': document.getElementById('clipping-norm'),
|
| 32 |
+
'noise-multiplier': document.getElementById('noise-multiplier'),
|
| 33 |
+
'batch-size': document.getElementById('batch-size'),
|
| 34 |
+
'learning-rate': document.getElementById('learning-rate'),
|
| 35 |
+
'epochs': document.getElementById('epochs')
|
| 36 |
+
};
|
| 37 |
+
|
| 38 |
+
// Add event listeners to sliders
|
| 39 |
+
for (const [id, slider] of Object.entries(sliders)) {
|
| 40 |
+
if (slider) {
|
| 41 |
+
slider.addEventListener('input', (e) => {
|
| 42 |
+
const value = parseFloat(e.target.value);
|
| 43 |
+
document.getElementById(`${id}-value`).textContent = value.toFixed(1);
|
| 44 |
+
|
| 45 |
+
// Update privacy budget
|
| 46 |
+
this.updatePrivacyBudget();
|
| 47 |
+
|
| 48 |
+
// Update gradient visualization when clipping norm changes
|
| 49 |
+
if (id === 'clipping-norm') {
|
| 50 |
+
this.updateGradientVisualization(value);
|
| 51 |
+
}
|
| 52 |
+
});
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
// Add event listener for the visual clipping norm slider
|
| 57 |
+
const visualSlider = document.getElementById('clipping-norm-visual');
|
| 58 |
+
if (visualSlider) {
|
| 59 |
+
visualSlider.addEventListener('input', (e) => {
|
| 60 |
+
const value = parseFloat(e.target.value);
|
| 61 |
+
document.getElementById('clipping-norm-visual-value').textContent = value.toFixed(1);
|
| 62 |
+
this.updateGradientVisualization(value);
|
| 63 |
+
});
|
| 64 |
+
}
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
initializePresets() {
|
| 68 |
+
const presets = {
|
| 69 |
+
'high-privacy': {
|
| 70 |
+
clippingNorm: 1.0,
|
| 71 |
+
noiseMultiplier: 1.5,
|
| 72 |
+
batchSize: 256,
|
| 73 |
+
learningRate: 0.005,
|
| 74 |
+
epochs: 30
|
| 75 |
+
},
|
| 76 |
+
'balanced': {
|
| 77 |
+
clippingNorm: 1.0,
|
| 78 |
+
noiseMultiplier: 1.0,
|
| 79 |
+
batchSize: 128,
|
| 80 |
+
learningRate: 0.01,
|
| 81 |
+
epochs: 30
|
| 82 |
+
},
|
| 83 |
+
'high-utility': {
|
| 84 |
+
clippingNorm: 1.5,
|
| 85 |
+
noiseMultiplier: 0.5,
|
| 86 |
+
batchSize: 64,
|
| 87 |
+
learningRate: 0.02,
|
| 88 |
+
epochs: 30
|
| 89 |
+
}
|
| 90 |
+
};
|
| 91 |
+
|
| 92 |
+
// Add event listeners to preset buttons
|
| 93 |
+
for (const [preset, values] of Object.entries(presets)) {
|
| 94 |
+
document.getElementById(`preset-${preset}`)?.addEventListener('click', () => {
|
| 95 |
+
this.applyPreset(values);
|
| 96 |
+
});
|
| 97 |
+
}
|
| 98 |
+
}
|
| 99 |
+
|
| 100 |
+
initializeTabs() {
|
| 101 |
+
const tabs = document.querySelectorAll('.tab');
|
| 102 |
+
tabs.forEach(tab => {
|
| 103 |
+
tab.addEventListener('click', () => {
|
| 104 |
+
const tabsContainer = tab.closest('.tabs');
|
| 105 |
+
tabsContainer.querySelectorAll('.tab').forEach(t => t.classList.remove('active'));
|
| 106 |
+
tab.classList.add('active');
|
| 107 |
+
|
| 108 |
+
const tabName = tab.getAttribute('data-tab');
|
| 109 |
+
const panel = tab.closest('.panel');
|
| 110 |
+
panel.querySelectorAll('.tab-content').forEach(content => {
|
| 111 |
+
content.classList.remove('active');
|
| 112 |
+
});
|
| 113 |
+
panel.querySelector(`#${tabName}-tab`)?.classList.add('active');
|
| 114 |
+
});
|
| 115 |
+
});
|
| 116 |
+
}
|
| 117 |
+
|
| 118 |
+
initializeCharts() {
|
| 119 |
+
const trainingCtx = document.getElementById('training-chart')?.getContext('2d');
|
| 120 |
+
const privacyCtx = document.getElementById('privacy-chart')?.getContext('2d');
|
| 121 |
+
const gradientCtx = document.getElementById('gradient-chart')?.getContext('2d');
|
| 122 |
+
|
| 123 |
+
if (trainingCtx) {
|
| 124 |
+
this.trainingChart = new Chart(trainingCtx, {
|
| 125 |
+
type: 'line',
|
| 126 |
+
data: {
|
| 127 |
+
labels: [],
|
| 128 |
+
datasets: [
|
| 129 |
+
{
|
| 130 |
+
label: 'Accuracy',
|
| 131 |
+
borderColor: '#4caf50',
|
| 132 |
+
backgroundColor: 'rgba(76, 175, 80, 0.1)',
|
| 133 |
+
data: [],
|
| 134 |
+
yAxisID: 'y',
|
| 135 |
+
borderWidth: 3,
|
| 136 |
+
pointRadius: 4,
|
| 137 |
+
pointHoverRadius: 6,
|
| 138 |
+
tension: 0.1
|
| 139 |
+
},
|
| 140 |
+
{
|
| 141 |
+
label: 'Loss',
|
| 142 |
+
borderColor: '#f44336',
|
| 143 |
+
backgroundColor: 'rgba(244, 67, 54, 0.1)',
|
| 144 |
+
data: [],
|
| 145 |
+
yAxisID: 'y1',
|
| 146 |
+
borderWidth: 3,
|
| 147 |
+
pointRadius: 4,
|
| 148 |
+
pointHoverRadius: 6,
|
| 149 |
+
tension: 0.1,
|
| 150 |
+
borderDash: [5, 5] // Dashed line to differentiate from accuracy
|
| 151 |
+
}
|
| 152 |
+
]
|
| 153 |
+
},
|
| 154 |
+
options: {
|
| 155 |
+
responsive: true,
|
| 156 |
+
maintainAspectRatio: false,
|
| 157 |
+
interaction: {
|
| 158 |
+
mode: 'index',
|
| 159 |
+
intersect: false,
|
| 160 |
+
},
|
| 161 |
+
plugins: {
|
| 162 |
+
legend: {
|
| 163 |
+
display: true,
|
| 164 |
+
position: 'top',
|
| 165 |
+
labels: {
|
| 166 |
+
usePointStyle: true,
|
| 167 |
+
padding: 20,
|
| 168 |
+
font: {
|
| 169 |
+
size: 12,
|
| 170 |
+
weight: 'bold'
|
| 171 |
+
}
|
| 172 |
+
}
|
| 173 |
+
},
|
| 174 |
+
tooltip: {
|
| 175 |
+
mode: 'index',
|
| 176 |
+
intersect: false,
|
| 177 |
+
backgroundColor: 'rgba(0, 0, 0, 0.8)',
|
| 178 |
+
titleColor: '#fff',
|
| 179 |
+
bodyColor: '#fff',
|
| 180 |
+
borderColor: '#ddd',
|
| 181 |
+
borderWidth: 1
|
| 182 |
+
}
|
| 183 |
+
},
|
| 184 |
+
scales: {
|
| 185 |
+
y: {
|
| 186 |
+
type: 'linear',
|
| 187 |
+
display: true,
|
| 188 |
+
position: 'left',
|
| 189 |
+
title: {
|
| 190 |
+
display: true,
|
| 191 |
+
text: 'Accuracy (%)',
|
| 192 |
+
color: '#4caf50',
|
| 193 |
+
font: {
|
| 194 |
+
size: 14,
|
| 195 |
+
weight: 'bold'
|
| 196 |
+
}
|
| 197 |
+
},
|
| 198 |
+
min: 0,
|
| 199 |
+
max: 100,
|
| 200 |
+
ticks: {
|
| 201 |
+
color: '#4caf50',
|
| 202 |
+
font: {
|
| 203 |
+
weight: 'bold'
|
| 204 |
+
},
|
| 205 |
+
callback: function(value) {
|
| 206 |
+
return value + '%';
|
| 207 |
+
}
|
| 208 |
+
},
|
| 209 |
+
grid: {
|
| 210 |
+
color: 'rgba(76, 175, 80, 0.2)'
|
| 211 |
+
}
|
| 212 |
+
},
|
| 213 |
+
y1: {
|
| 214 |
+
type: 'linear',
|
| 215 |
+
display: true,
|
| 216 |
+
position: 'right',
|
| 217 |
+
title: {
|
| 218 |
+
display: true,
|
| 219 |
+
text: 'Loss',
|
| 220 |
+
color: '#f44336',
|
| 221 |
+
font: {
|
| 222 |
+
size: 14,
|
| 223 |
+
weight: 'bold'
|
| 224 |
+
}
|
| 225 |
+
},
|
| 226 |
+
min: 0,
|
| 227 |
+
max: 3, // More reasonable max for loss
|
| 228 |
+
ticks: {
|
| 229 |
+
color: '#f44336',
|
| 230 |
+
font: {
|
| 231 |
+
weight: 'bold'
|
| 232 |
+
},
|
| 233 |
+
callback: function(value) {
|
| 234 |
+
return value.toFixed(1);
|
| 235 |
+
}
|
| 236 |
+
},
|
| 237 |
+
grid: {
|
| 238 |
+
drawOnChartArea: false, // Don't overlay grid lines
|
| 239 |
+
color: 'rgba(244, 67, 54, 0.2)'
|
| 240 |
+
},
|
| 241 |
+
},
|
| 242 |
+
x: {
|
| 243 |
+
title: {
|
| 244 |
+
display: true,
|
| 245 |
+
text: 'Training Progress',
|
| 246 |
+
font: {
|
| 247 |
+
size: 12,
|
| 248 |
+
weight: 'bold'
|
| 249 |
+
}
|
| 250 |
+
},
|
| 251 |
+
ticks: {
|
| 252 |
+
font: {
|
| 253 |
+
size: 11
|
| 254 |
+
}
|
| 255 |
+
}
|
| 256 |
+
}
|
| 257 |
+
}
|
| 258 |
+
}
|
| 259 |
+
});
|
| 260 |
+
}
|
| 261 |
+
|
| 262 |
+
if (privacyCtx) {
|
| 263 |
+
this.privacyChart = new Chart(privacyCtx, {
|
| 264 |
+
type: 'line',
|
| 265 |
+
data: {
|
| 266 |
+
labels: [],
|
| 267 |
+
datasets: [{
|
| 268 |
+
label: 'Privacy Budget (ε)',
|
| 269 |
+
borderColor: '#3f51b5',
|
| 270 |
+
data: []
|
| 271 |
+
}]
|
| 272 |
+
},
|
| 273 |
+
options: {
|
| 274 |
+
responsive: true,
|
| 275 |
+
maintainAspectRatio: false,
|
| 276 |
+
scales: {
|
| 277 |
+
y: {
|
| 278 |
+
beginAtZero: true,
|
| 279 |
+
title: {
|
| 280 |
+
display: true,
|
| 281 |
+
text: 'Privacy Budget (ε)'
|
| 282 |
+
}
|
| 283 |
+
}
|
| 284 |
+
}
|
| 285 |
+
}
|
| 286 |
+
});
|
| 287 |
+
}
|
| 288 |
+
|
| 289 |
+
if (gradientCtx) {
|
| 290 |
+
this.gradientChart = new Chart(gradientCtx, {
|
| 291 |
+
type: 'scatter',
|
| 292 |
+
data: {
|
| 293 |
+
datasets: [
|
| 294 |
+
{
|
| 295 |
+
label: 'Before Clipping',
|
| 296 |
+
borderColor: '#2196f3',
|
| 297 |
+
backgroundColor: 'rgba(33, 150, 243, 0.1)',
|
| 298 |
+
data: [],
|
| 299 |
+
showLine: true
|
| 300 |
+
},
|
| 301 |
+
{
|
| 302 |
+
label: 'After Clipping',
|
| 303 |
+
borderColor: '#f44336',
|
| 304 |
+
backgroundColor: 'rgba(244, 67, 54, 0.1)',
|
| 305 |
+
data: [],
|
| 306 |
+
showLine: true
|
| 307 |
+
}
|
| 308 |
+
]
|
| 309 |
+
},
|
| 310 |
+
options: {
|
| 311 |
+
responsive: true,
|
| 312 |
+
maintainAspectRatio: false,
|
| 313 |
+
scales: {
|
| 314 |
+
x: {
|
| 315 |
+
type: 'linear',
|
| 316 |
+
position: 'bottom',
|
| 317 |
+
title: {
|
| 318 |
+
display: true,
|
| 319 |
+
text: 'Gradient Norm'
|
| 320 |
+
},
|
| 321 |
+
min: 0
|
| 322 |
+
},
|
| 323 |
+
y: {
|
| 324 |
+
type: 'linear',
|
| 325 |
+
position: 'left',
|
| 326 |
+
title: {
|
| 327 |
+
display: true,
|
| 328 |
+
text: 'Density'
|
| 329 |
+
},
|
| 330 |
+
min: 0
|
| 331 |
+
}
|
| 332 |
+
},
|
| 333 |
+
plugins: {
|
| 334 |
+
annotation: {
|
| 335 |
+
annotations: {
|
| 336 |
+
line1: {
|
| 337 |
+
type: 'line',
|
| 338 |
+
xMin: 1,
|
| 339 |
+
xMax: 1,
|
| 340 |
+
borderColor: '#f44336',
|
| 341 |
+
borderWidth: 2,
|
| 342 |
+
borderDash: [5, 5],
|
| 343 |
+
label: {
|
| 344 |
+
content: 'Clipping Threshold',
|
| 345 |
+
display: true,
|
| 346 |
+
position: 'top'
|
| 347 |
+
}
|
| 348 |
+
}
|
| 349 |
+
}
|
| 350 |
+
}
|
| 351 |
+
}
|
| 352 |
+
}
|
| 353 |
+
});
|
| 354 |
+
}
|
| 355 |
+
}
|
| 356 |
+
|
| 357 |
+
async updatePrivacyBudget() {
|
| 358 |
+
const params = this.getParameters();
|
| 359 |
+
try {
|
| 360 |
+
const response = await fetch('/api/privacy-budget', {
|
| 361 |
+
method: 'POST',
|
| 362 |
+
headers: {
|
| 363 |
+
'Content-Type': 'application/json',
|
| 364 |
+
},
|
| 365 |
+
body: JSON.stringify(params)
|
| 366 |
+
});
|
| 367 |
+
const data = await response.json();
|
| 368 |
+
|
| 369 |
+
// Update UI
|
| 370 |
+
const budgetValue = document.getElementById('budget-value');
|
| 371 |
+
const budgetFill = document.getElementById('budget-fill');
|
| 372 |
+
|
| 373 |
+
if (budgetValue && budgetFill) {
|
| 374 |
+
budgetValue.textContent = data.epsilon.toFixed(2);
|
| 375 |
+
budgetFill.style.width = `${Math.min(data.epsilon / 10 * 100, 100)}%`;
|
| 376 |
+
|
| 377 |
+
// Update class for coloring
|
| 378 |
+
budgetFill.classList.remove('low', 'medium', 'high');
|
| 379 |
+
if (data.epsilon <= 1) {
|
| 380 |
+
budgetFill.classList.add('low');
|
| 381 |
+
} else if (data.epsilon <= 5) {
|
| 382 |
+
budgetFill.classList.add('medium');
|
| 383 |
+
} else {
|
| 384 |
+
budgetFill.classList.add('high');
|
| 385 |
+
}
|
| 386 |
+
}
|
| 387 |
+
} catch (error) {
|
| 388 |
+
console.error('Error calculating privacy budget:', error);
|
| 389 |
+
}
|
| 390 |
+
}
|
| 391 |
+
|
| 392 |
+
async toggleTraining() {
|
| 393 |
+
if (this.isTraining) {
|
| 394 |
+
this.stopTraining();
|
| 395 |
+
} else {
|
| 396 |
+
await this.startTraining();
|
| 397 |
+
}
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
async startTraining() {
|
| 401 |
+
const trainButton = document.getElementById('train-button');
|
| 402 |
+
const trainingStatus = document.getElementById('training-status');
|
| 403 |
+
|
| 404 |
+
if (!trainButton || this.isTraining) return;
|
| 405 |
+
|
| 406 |
+
this.isTraining = true;
|
| 407 |
+
trainButton.textContent = 'Stop Training';
|
| 408 |
+
trainButton.classList.add('running');
|
| 409 |
+
trainingStatus.style.display = 'flex';
|
| 410 |
+
|
| 411 |
+
// Reset charts
|
| 412 |
+
this.resetCharts();
|
| 413 |
+
|
| 414 |
+
try {
|
| 415 |
+
console.log('Starting training with parameters:', this.getParameters()); // Debug log
|
| 416 |
+
|
| 417 |
+
const response = await fetch('/api/train', {
|
| 418 |
+
method: 'POST',
|
| 419 |
+
headers: {
|
| 420 |
+
'Content-Type': 'application/json',
|
| 421 |
+
},
|
| 422 |
+
body: JSON.stringify(this.getParameters())
|
| 423 |
+
});
|
| 424 |
+
|
| 425 |
+
const data = await response.json();
|
| 426 |
+
|
| 427 |
+
if (!response.ok) {
|
| 428 |
+
throw new Error(data.error || 'Unknown error occurred');
|
| 429 |
+
}
|
| 430 |
+
|
| 431 |
+
console.log('Received training data:', data); // Debug log
|
| 432 |
+
|
| 433 |
+
// Update charts and results
|
| 434 |
+
this.updateCharts(data);
|
| 435 |
+
this.updateResults(data);
|
| 436 |
+
} catch (error) {
|
| 437 |
+
console.error('Training error:', error);
|
| 438 |
+
// Show error message to user
|
| 439 |
+
const errorMessage = document.createElement('div');
|
| 440 |
+
errorMessage.className = 'error-message';
|
| 441 |
+
errorMessage.textContent = error.message || 'An error occurred during training';
|
| 442 |
+
document.querySelector('.lab-main').insertBefore(errorMessage, document.querySelector('.lab-main').firstChild);
|
| 443 |
+
|
| 444 |
+
// Remove error message after 5 seconds
|
| 445 |
+
setTimeout(() => {
|
| 446 |
+
errorMessage.remove();
|
| 447 |
+
}, 5000);
|
| 448 |
+
} finally {
|
| 449 |
+
this.stopTraining();
|
| 450 |
+
}
|
| 451 |
+
}
|
| 452 |
+
|
| 453 |
+
stopTraining() {
|
| 454 |
+
this.isTraining = false;
|
| 455 |
+
const trainButton = document.getElementById('train-button');
|
| 456 |
+
if (trainButton) {
|
| 457 |
+
trainButton.textContent = 'Run Training';
|
| 458 |
+
trainButton.classList.remove('running');
|
| 459 |
+
}
|
| 460 |
+
document.getElementById('training-status').style.display = 'none';
|
| 461 |
+
}
|
| 462 |
+
|
| 463 |
+
resetCharts() {
|
| 464 |
+
if (this.trainingChart) {
|
| 465 |
+
this.trainingChart.data.labels = [];
|
| 466 |
+
this.trainingChart.data.datasets[0].data = [];
|
| 467 |
+
this.trainingChart.data.datasets[1].data = [];
|
| 468 |
+
this.trainingChart.update();
|
| 469 |
+
}
|
| 470 |
+
|
| 471 |
+
if (this.privacyChart) {
|
| 472 |
+
this.privacyChart.data.labels = [];
|
| 473 |
+
this.privacyChart.data.datasets[0].data = [];
|
| 474 |
+
this.privacyChart.update();
|
| 475 |
+
}
|
| 476 |
+
|
| 477 |
+
if (this.gradientChart) {
|
| 478 |
+
this.gradientChart.data.datasets[0].data = [];
|
| 479 |
+
this.gradientChart.data.datasets[1].data = [];
|
| 480 |
+
this.gradientChart.update();
|
| 481 |
+
}
|
| 482 |
+
}
|
| 483 |
+
|
| 484 |
+
switchView(view) {
|
| 485 |
+
this.currentView = view;
|
| 486 |
+
|
| 487 |
+
// Update button states
|
| 488 |
+
document.querySelectorAll('.view-toggle').forEach(btn => {
|
| 489 |
+
btn.classList.remove('active');
|
| 490 |
+
});
|
| 491 |
+
document.getElementById(`view-${view}`).classList.add('active');
|
| 492 |
+
|
| 493 |
+
// Update chart with current data
|
| 494 |
+
if (view === 'epochs' && this.epochsData.length > 0) {
|
| 495 |
+
this.updateChartsWithData(this.epochsData, 'epochs');
|
| 496 |
+
} else if (view === 'iterations' && this.iterationsData.length > 0) {
|
| 497 |
+
this.updateChartsWithData(this.iterationsData, 'iterations');
|
| 498 |
+
}
|
| 499 |
+
}
|
| 500 |
+
|
| 501 |
+
updateCharts(data) {
|
| 502 |
+
if (!this.trainingChart || !data) return;
|
| 503 |
+
|
| 504 |
+
console.log('Updating charts with data:', data); // Debug log
|
| 505 |
+
|
| 506 |
+
// Store data for view switching
|
| 507 |
+
if (data.epochs_data) {
|
| 508 |
+
this.epochsData = data.epochs_data;
|
| 509 |
+
}
|
| 510 |
+
if (data.iterations_data) {
|
| 511 |
+
this.iterationsData = data.iterations_data;
|
| 512 |
+
}
|
| 513 |
+
|
| 514 |
+
// Use current view to determine which data to display
|
| 515 |
+
if (this.currentView === 'epochs' && this.epochsData.length > 0) {
|
| 516 |
+
this.updateChartsWithData(this.epochsData, 'epochs');
|
| 517 |
+
} else if (this.currentView === 'iterations' && this.iterationsData.length > 0) {
|
| 518 |
+
this.updateChartsWithData(this.iterationsData, 'iterations');
|
| 519 |
+
} else if (this.epochsData.length > 0) {
|
| 520 |
+
// Fallback to epochs if iterations not available
|
| 521 |
+
this.updateChartsWithData(this.epochsData, 'epochs');
|
| 522 |
+
}
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
updateChartsWithData(chartData, dataType) {
|
| 526 |
+
if (!this.trainingChart || !chartData) return;
|
| 527 |
+
|
| 528 |
+
// Update training metrics chart
|
| 529 |
+
const labels = chartData.map(d =>
|
| 530 |
+
dataType === 'epochs' ? `Epoch ${d.epoch}` : `Iter ${d.iteration}`
|
| 531 |
+
);
|
| 532 |
+
const accuracies = chartData.map(d => d.accuracy);
|
| 533 |
+
const losses = chartData.map(d => d.loss);
|
| 534 |
+
|
| 535 |
+
console.log(`${dataType} - Accuracies:`, accuracies);
|
| 536 |
+
console.log(`${dataType} - Losses:`, losses);
|
| 537 |
+
|
| 538 |
+
this.trainingChart.data.labels = labels;
|
| 539 |
+
this.trainingChart.data.datasets[0].data = accuracies;
|
| 540 |
+
this.trainingChart.data.datasets[1].data = losses;
|
| 541 |
+
|
| 542 |
+
// Auto-adjust loss scale based on actual data
|
| 543 |
+
const maxLoss = Math.max(...losses);
|
| 544 |
+
const minLoss = Math.min(...losses);
|
| 545 |
+
this.trainingChart.options.scales.y1.max = Math.max(maxLoss * 1.1, 3);
|
| 546 |
+
this.trainingChart.options.scales.y1.min = Math.max(0, minLoss * 0.9);
|
| 547 |
+
|
| 548 |
+
// Update chart info
|
| 549 |
+
const chartInfo = document.getElementById('chart-info');
|
| 550 |
+
if (chartInfo) {
|
| 551 |
+
chartInfo.textContent = `Showing ${chartData.length} data points (${dataType})`;
|
| 552 |
+
}
|
| 553 |
+
|
| 554 |
+
this.trainingChart.update();
|
| 555 |
+
|
| 556 |
+
// Update current epoch display
|
| 557 |
+
const currentEpoch = document.getElementById('current-epoch');
|
| 558 |
+
const totalEpochs = document.getElementById('total-epochs');
|
| 559 |
+
if (currentEpoch && totalEpochs && dataType === 'epochs') {
|
| 560 |
+
currentEpoch.textContent = chartData.length;
|
| 561 |
+
totalEpochs.textContent = this.getParameters().epochs;
|
| 562 |
+
}
|
| 563 |
+
|
| 564 |
+
// Update privacy budget chart (only for epochs view)
|
| 565 |
+
if (this.privacyChart && dataType === 'epochs') {
|
| 566 |
+
const privacyBudgets = chartData.map((_, i) =>
|
| 567 |
+
this.calculateEpochPrivacy(i + 1)
|
| 568 |
+
);
|
| 569 |
+
this.privacyChart.data.labels = labels;
|
| 570 |
+
this.privacyChart.data.datasets[0].data = privacyBudgets;
|
| 571 |
+
this.privacyChart.update();
|
| 572 |
+
}
|
| 573 |
+
|
| 574 |
+
// Update gradient visualization
|
| 575 |
+
if (this.gradientChart) {
|
| 576 |
+
const clippingNorm = this.getParameters().clipping_norm;
|
| 577 |
+
|
| 578 |
+
// Generate gradient data if not provided in chartData
|
| 579 |
+
let gradientData;
|
| 580 |
+
if (chartData[chartData.length - 1]?.gradient_info) {
|
| 581 |
+
gradientData = chartData[chartData.length - 1].gradient_info;
|
| 582 |
+
} else {
|
| 583 |
+
// Generate synthetic gradient data
|
| 584 |
+
const beforeClipping = [];
|
| 585 |
+
const afterClipping = [];
|
| 586 |
+
|
| 587 |
+
// Generate log-normal distributed gradients
|
| 588 |
+
const mu = Math.log(clippingNorm) - 0.5;
|
| 589 |
+
const sigma = 0.8;
|
| 590 |
+
|
| 591 |
+
for (let i = 0; i < 100; i++) {
|
| 592 |
+
const u1 = Math.random();
|
| 593 |
+
const u2 = Math.random();
|
| 594 |
+
const z = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2);
|
| 595 |
+
const norm = Math.exp(mu + sigma * z);
|
| 596 |
+
|
| 597 |
+
const density = Math.exp(-(Math.pow(Math.log(norm) - mu, 2) / (2 * sigma * sigma))) /
|
| 598 |
+
(norm * sigma * Math.sqrt(2 * Math.PI));
|
| 599 |
+
const y = 0.2 + 0.8 * (density / 0.8) + 0.1 * (Math.random() - 0.5);
|
| 600 |
+
|
| 601 |
+
beforeClipping.push({ x: norm, y: y });
|
| 602 |
+
afterClipping.push({ x: Math.min(norm, clippingNorm), y: y });
|
| 603 |
+
}
|
| 604 |
+
|
| 605 |
+
gradientData = {
|
| 606 |
+
before_clipping: beforeClipping.sort((a, b) => a.x - b.x),
|
| 607 |
+
after_clipping: afterClipping.sort((a, b) => a.x - b.x)
|
| 608 |
+
};
|
| 609 |
+
}
|
| 610 |
+
|
| 611 |
+
// Update gradient chart
|
| 612 |
+
this.gradientChart.data.datasets[0].data = gradientData.before_clipping;
|
| 613 |
+
this.gradientChart.data.datasets[1].data = gradientData.after_clipping;
|
| 614 |
+
|
| 615 |
+
// Update clipping threshold line
|
| 616 |
+
this.gradientChart.options.plugins.annotation.annotations.line1 = {
|
| 617 |
+
type: 'line',
|
| 618 |
+
xMin: clippingNorm,
|
| 619 |
+
xMax: clippingNorm,
|
| 620 |
+
borderColor: '#f44336',
|
| 621 |
+
borderWidth: 2,
|
| 622 |
+
borderDash: [5, 5],
|
| 623 |
+
label: {
|
| 624 |
+
content: `Clipping Threshold (C=${clippingNorm.toFixed(1)})`,
|
| 625 |
+
display: true,
|
| 626 |
+
position: 'top'
|
| 627 |
+
}
|
| 628 |
+
};
|
| 629 |
+
|
| 630 |
+
// Update x-axis scale based on clipping norm
|
| 631 |
+
this.gradientChart.options.scales.x.max = Math.max(clippingNorm * 2.5, 5);
|
| 632 |
+
|
| 633 |
+
this.gradientChart.update('active');
|
| 634 |
+
}
|
| 635 |
+
}
|
| 636 |
+
|
| 637 |
+
updateResults(data) {
|
| 638 |
+
// Hide no-results message and show results content
|
| 639 |
+
document.getElementById('no-results').style.display = 'none';
|
| 640 |
+
document.getElementById('results-content').style.display = 'block';
|
| 641 |
+
|
| 642 |
+
// Update metrics
|
| 643 |
+
document.getElementById('accuracy-value').textContent =
|
| 644 |
+
data.final_metrics.accuracy.toFixed(1) + '%';
|
| 645 |
+
document.getElementById('loss-value').textContent =
|
| 646 |
+
data.final_metrics.loss.toFixed(3);
|
| 647 |
+
document.getElementById('training-time-value').textContent =
|
| 648 |
+
data.final_metrics.training_time.toFixed(1) + 's';
|
| 649 |
+
|
| 650 |
+
// Update privacy budget display (make it dynamic)
|
| 651 |
+
const privacyBudgetElement = document.getElementById('privacy-budget-value');
|
| 652 |
+
if (privacyBudgetElement) {
|
| 653 |
+
privacyBudgetElement.textContent = `ε=${data.privacy_budget.toFixed(1)}`;
|
| 654 |
+
}
|
| 655 |
+
|
| 656 |
+
// Update privacy-utility trade-off explanation dynamically
|
| 657 |
+
const tradeoffElement = document.getElementById('tradeoff-explanation');
|
| 658 |
+
if (tradeoffElement) {
|
| 659 |
+
const accuracy = data.final_metrics.accuracy.toFixed(1);
|
| 660 |
+
const epsilon = data.privacy_budget.toFixed(1);
|
| 661 |
+
|
| 662 |
+
// Generate realistic trade-off assessment
|
| 663 |
+
let tradeoffAssessment;
|
| 664 |
+
if (data.final_metrics.accuracy >= 85) {
|
| 665 |
+
tradeoffAssessment = "This is an excellent trade-off for most applications.";
|
| 666 |
+
} else if (data.final_metrics.accuracy >= 75) {
|
| 667 |
+
tradeoffAssessment = "This is a good trade-off for most applications.";
|
| 668 |
+
} else if (data.final_metrics.accuracy >= 65) {
|
| 669 |
+
tradeoffAssessment = "This trade-off may be acceptable for privacy-critical applications.";
|
| 670 |
+
} else if (data.final_metrics.accuracy >= 50) {
|
| 671 |
+
tradeoffAssessment = "Low utility - consider reducing noise or increasing clipping norm.";
|
| 672 |
+
} else {
|
| 673 |
+
tradeoffAssessment = "Very poor utility - privacy parameters need significant adjustment.";
|
| 674 |
+
}
|
| 675 |
+
|
| 676 |
+
tradeoffElement.textContent =
|
| 677 |
+
`This model achieved ${accuracy}% accuracy with a privacy budget of ε=${epsilon}. ${tradeoffAssessment}`;
|
| 678 |
+
}
|
| 679 |
+
|
| 680 |
+
// Update recommendations
|
| 681 |
+
const recommendationList = document.querySelector('.recommendation-list');
|
| 682 |
+
recommendationList.innerHTML = '';
|
| 683 |
+
data.recommendations.forEach(rec => {
|
| 684 |
+
const item = document.createElement('li');
|
| 685 |
+
item.className = 'recommendation-item';
|
| 686 |
+
item.innerHTML = `
|
| 687 |
+
<span class="recommendation-icon">${rec.icon}</span>
|
| 688 |
+
<span>${rec.text}</span>
|
| 689 |
+
`;
|
| 690 |
+
recommendationList.appendChild(item);
|
| 691 |
+
});
|
| 692 |
+
}
|
| 693 |
+
|
| 694 |
+
getParameters() {
|
| 695 |
+
return {
|
| 696 |
+
clipping_norm: parseFloat(document.getElementById('clipping-norm').value),
|
| 697 |
+
noise_multiplier: parseFloat(document.getElementById('noise-multiplier').value),
|
| 698 |
+
batch_size: parseInt(document.getElementById('batch-size').value),
|
| 699 |
+
learning_rate: parseFloat(document.getElementById('learning-rate').value),
|
| 700 |
+
epochs: parseInt(document.getElementById('epochs').value),
|
| 701 |
+
dataset: document.getElementById('dataset-select').value,
|
| 702 |
+
model_architecture: document.getElementById('model-select').value
|
| 703 |
+
};
|
| 704 |
+
}
|
| 705 |
+
|
| 706 |
+
applyPreset(values) {
|
| 707 |
+
document.getElementById('clipping-norm').value = values.clippingNorm;
|
| 708 |
+
document.getElementById('noise-multiplier').value = values.noiseMultiplier;
|
| 709 |
+
document.getElementById('batch-size').value = values.batchSize;
|
| 710 |
+
document.getElementById('learning-rate').value = values.learningRate;
|
| 711 |
+
document.getElementById('epochs').value = values.epochs;
|
| 712 |
+
|
| 713 |
+
// Update displayed values
|
| 714 |
+
document.getElementById('clipping-norm-value').textContent = values.clippingNorm;
|
| 715 |
+
document.getElementById('noise-multiplier-value').textContent = values.noiseMultiplier;
|
| 716 |
+
document.getElementById('batch-size-value').textContent = values.batchSize;
|
| 717 |
+
document.getElementById('learning-rate-value').textContent = values.learningRate;
|
| 718 |
+
document.getElementById('epochs-value').textContent = values.epochs;
|
| 719 |
+
|
| 720 |
+
this.updatePrivacyBudget();
|
| 721 |
+
}
|
| 722 |
+
|
| 723 |
+
calculateEpochPrivacy(epoch) {
|
| 724 |
+
const params = this.getParameters();
|
| 725 |
+
|
| 726 |
+
// Get dataset size based on selection
|
| 727 |
+
let datasetSize;
|
| 728 |
+
switch(params.dataset) {
|
| 729 |
+
case 'cifar10':
|
| 730 |
+
datasetSize = 50000; // CIFAR-10 training set size
|
| 731 |
+
break;
|
| 732 |
+
case 'fashion-mnist':
|
| 733 |
+
datasetSize = 60000; // Fashion-MNIST training set size
|
| 734 |
+
break;
|
| 735 |
+
case 'mnist':
|
| 736 |
+
default:
|
| 737 |
+
datasetSize = 60000; // MNIST training set size
|
| 738 |
+
break;
|
| 739 |
+
}
|
| 740 |
+
|
| 741 |
+
const samplingRate = params.batch_size / datasetSize;
|
| 742 |
+
const steps = epoch * (1 / samplingRate);
|
| 743 |
+
const delta = 1e-5;
|
| 744 |
+
const c = Math.sqrt(2 * Math.log(1.25 / delta));
|
| 745 |
+
return Math.min((c * samplingRate * Math.sqrt(steps)) / params.noise_multiplier, 10);
|
| 746 |
+
}
|
| 747 |
+
|
| 748 |
+
updateGradientVisualization(clippingNorm) {
|
| 749 |
+
if (!this.gradientChart) return;
|
| 750 |
+
|
| 751 |
+
// Generate random gradient norms following a log-normal distribution
|
| 752 |
+
const numPoints = 100;
|
| 753 |
+
const beforeClipping = [];
|
| 754 |
+
const afterClipping = [];
|
| 755 |
+
|
| 756 |
+
// Parameters for log-normal distribution
|
| 757 |
+
const mu = Math.log(clippingNorm) - 0.5;
|
| 758 |
+
const sigma = 0.8;
|
| 759 |
+
|
| 760 |
+
// Generate gradient norms
|
| 761 |
+
for (let i = 0; i < numPoints; i++) {
|
| 762 |
+
// Generate log-normal distributed gradient norms
|
| 763 |
+
const u1 = Math.random();
|
| 764 |
+
const u2 = Math.random();
|
| 765 |
+
const z = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2);
|
| 766 |
+
const norm = Math.exp(mu + sigma * z);
|
| 767 |
+
|
| 768 |
+
// Calculate density using kernel density estimation
|
| 769 |
+
const density = Math.exp(-(Math.pow(Math.log(norm) - mu, 2) / (2 * sigma * sigma))) / (norm * sigma * Math.sqrt(2 * Math.PI));
|
| 770 |
+
|
| 771 |
+
// Normalize density and add some randomness
|
| 772 |
+
const y = 0.2 + 0.8 * (density / 0.8) + 0.1 * (Math.random() - 0.5);
|
| 773 |
+
|
| 774 |
+
beforeClipping.push({ x: norm, y: y });
|
| 775 |
+
afterClipping.push({ x: Math.min(norm, clippingNorm), y: y });
|
| 776 |
+
}
|
| 777 |
+
|
| 778 |
+
// Sort points by x-value for smoother lines
|
| 779 |
+
beforeClipping.sort((a, b) => a.x - b.x);
|
| 780 |
+
afterClipping.sort((a, b) => a.x - b.x);
|
| 781 |
+
|
| 782 |
+
// Update chart data
|
| 783 |
+
this.gradientChart.data.datasets[0].data = beforeClipping;
|
| 784 |
+
this.gradientChart.data.datasets[1].data = afterClipping;
|
| 785 |
+
|
| 786 |
+
// Update clipping threshold line
|
| 787 |
+
this.gradientChart.options.plugins.annotation.annotations.line1 = {
|
| 788 |
+
type: 'line',
|
| 789 |
+
xMin: clippingNorm,
|
| 790 |
+
xMax: clippingNorm,
|
| 791 |
+
borderColor: '#f44336',
|
| 792 |
+
borderWidth: 2,
|
| 793 |
+
borderDash: [5, 5],
|
| 794 |
+
label: {
|
| 795 |
+
content: `Clipping Threshold (C=${clippingNorm.toFixed(1)})`,
|
| 796 |
+
display: true,
|
| 797 |
+
position: 'top'
|
| 798 |
+
}
|
| 799 |
+
};
|
| 800 |
+
|
| 801 |
+
// Update x-axis scale based on clipping norm
|
| 802 |
+
this.gradientChart.options.scales.x.max = Math.max(clippingNorm * 2.5, 5);
|
| 803 |
+
|
| 804 |
+
// Update the chart with animation
|
| 805 |
+
this.gradientChart.update('active');
|
| 806 |
+
}
|
| 807 |
+
|
| 808 |
+
updateGradientVisualizationWithData(beforeClipping, afterClipping, clippingNorm) {
|
| 809 |
+
if (!this.gradientChart) return;
|
| 810 |
+
|
| 811 |
+
// Update chart data with real training data
|
| 812 |
+
this.gradientChart.data.datasets[0].data = beforeClipping;
|
| 813 |
+
this.gradientChart.data.datasets[1].data = afterClipping;
|
| 814 |
+
|
| 815 |
+
// Update clipping threshold line
|
| 816 |
+
this.gradientChart.options.plugins.annotation.annotations.line1 = {
|
| 817 |
+
type: 'line',
|
| 818 |
+
xMin: clippingNorm,
|
| 819 |
+
xMax: clippingNorm,
|
| 820 |
+
borderColor: '#f44336',
|
| 821 |
+
borderWidth: 2,
|
| 822 |
+
borderDash: [5, 5],
|
| 823 |
+
label: {
|
| 824 |
+
content: `Clipping Threshold (C=${clippingNorm.toFixed(1)})`,
|
| 825 |
+
display: true,
|
| 826 |
+
position: 'top'
|
| 827 |
+
}
|
| 828 |
+
};
|
| 829 |
+
|
| 830 |
+
// Update x-axis scale based on clipping norm
|
| 831 |
+
this.gradientChart.options.scales.x.max = Math.max(clippingNorm * 2.5, 5);
|
| 832 |
+
|
| 833 |
+
// Update the chart with animation
|
| 834 |
+
this.gradientChart.update('active');
|
| 835 |
+
}
|
| 836 |
+
}
|
| 837 |
+
|
| 838 |
+
// Initialize the application when the DOM is loaded
|
| 839 |
+
document.addEventListener('DOMContentLoaded', () => {
|
| 840 |
+
window.dpsgdExplorer = new DPSGDExplorer();
|
| 841 |
+
});
|
| 842 |
+
|
| 843 |
+
function setOptimalParameters() {
|
| 844 |
+
// Set optimal parameters based on actual MNIST DP-SGD training results
|
| 845 |
+
// These values achieve ~95% accuracy with reasonable privacy budget (ε≈15)
|
| 846 |
+
document.getElementById('clipping-norm').value = '2.0'; // Balanced clipping norm
|
| 847 |
+
document.getElementById('noise-multiplier').value = '1.0'; // Moderate noise for good privacy
|
| 848 |
+
document.getElementById('batch-size').value = '256'; // Large batches for DP-SGD stability
|
| 849 |
+
document.getElementById('learning-rate').value = '0.05'; // Balanced learning rate
|
| 850 |
+
document.getElementById('epochs').value = '30'; // Sufficient epochs for convergence
|
| 851 |
+
|
| 852 |
+
// Update displays
|
| 853 |
+
updateClippingNormDisplay();
|
| 854 |
+
updateNoiseMultiplierDisplay();
|
| 855 |
+
updateBatchSizeDisplay();
|
| 856 |
+
updateLearningRateDisplay();
|
| 857 |
+
updateEpochsDisplay();
|
| 858 |
+
}
|
requirements.txt
CHANGED
|
@@ -3,6 +3,7 @@ flask-cors==4.0.0
|
|
| 3 |
python-dotenv==1.0.0
|
| 4 |
gunicorn==21.2.0
|
| 5 |
numpy==1.24.3
|
| 6 |
-
tensorflow==2.13.1
|
|
|
|
| 7 |
tensorflow-privacy==0.8.11
|
| 8 |
-
scikit-learn==1.3.0
|
|
|
|
| 3 |
python-dotenv==1.0.0
|
| 4 |
gunicorn==21.2.0
|
| 5 |
numpy==1.24.3
|
| 6 |
+
tensorflow-macos==2.13.1
|
| 7 |
+
tensorflow-metal==1.0.0 # optional but speeds things up on M1/M2
|
| 8 |
tensorflow-privacy==0.8.11
|
| 9 |
+
scikit-learn==1.3.0
|