Dennislee:) commited on
Commit
b41fe25
·
1 Parent(s): a58c186

Deploy autoencoder-unsw (auto)

Browse files
Files changed (1) hide show
  1. app.py +43 -7
app.py CHANGED
@@ -1,15 +1,19 @@
1
  """
2
  Axiom Autoencoder UNSW-NB15 - 高維 log、行為壓縮與偵測(49 維)
3
  使用 Autoencoder 分析 UNSW-NB15 高維特徵。
 
4
  """
 
 
5
  import os
6
  import pickle
7
  import threading
8
  import time
 
9
  from typing import List, Optional
10
 
11
  import numpy as np
12
- from fastapi import FastAPI
13
  from fastapi.middleware.cors import CORSMiddleware
14
  from pydantic import BaseModel
15
 
@@ -89,6 +93,27 @@ def compute_score(features: List[float]) -> tuple[float, dict]:
89
  return _heuristic_score(features)
90
 
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  def _fetch_unsw(n_samples: int, rs: int) -> np.ndarray:
93
  try:
94
  from datasets import load_dataset
@@ -113,7 +138,7 @@ def _fetch_unsw(n_samples: int, rs: int) -> np.ndarray:
113
  return X[idx]
114
 
115
 
116
- def _run_training():
117
  global _model, _training
118
  with _training_lock:
119
  if _training:
@@ -124,8 +149,14 @@ def _run_training():
124
  import torch.nn as nn
125
  from sklearn.preprocessing import StandardScaler
126
  from huggingface_hub import HfApi, login
127
- rs = int(time.time()) % 10000
128
- X = _fetch_unsw(SKLEARN_N_SAMPLES, rs)
 
 
 
 
 
 
129
  scaler = StandardScaler()
130
  X_scaled = scaler.fit_transform(X)
131
 
@@ -200,11 +231,16 @@ def reload():
200
  return {"status": "ok", "model_loaded": _model is not None}
201
 
202
 
 
 
 
 
203
  @app.post("/train")
204
- def train():
205
- t = threading.Thread(target=_run_training, daemon=True)
 
206
  t.start()
207
- return {"status": "training_started", "dataset": "UNSW-NB15"}
208
 
209
 
210
  @app.get("/train/status")
 
1
  """
2
  Axiom Autoencoder UNSW-NB15 - 高維 log、行為壓縮與偵測(49 維)
3
  使用 Autoencoder 分析 UNSW-NB15 高維特徵。
4
+ 支援 POST /train {"csv_url": "..."} 從 Supabase 匯出資料訓練(5 維 pad 至 49)。
5
  """
6
+ import csv
7
+ import io
8
  import os
9
  import pickle
10
  import threading
11
  import time
12
+ import urllib.request
13
  from typing import List, Optional
14
 
15
  import numpy as np
16
+ from fastapi import Body, FastAPI
17
  from fastapi.middleware.cors import CORSMiddleware
18
  from pydantic import BaseModel
19
 
 
93
  return _heuristic_score(features)
94
 
95
 
96
+ def _load_csv_from_url(csv_url: str, feature_dim: int = 49) -> np.ndarray:
97
+ """下載 CSV,解析為 5 維,pad 至 feature_dim。"""
98
+ with urllib.request.urlopen(csv_url, timeout=60) as resp:
99
+ raw = resp.read().decode("utf-8")
100
+ rows = []
101
+ for r in csv.DictReader(io.StringIO(raw)):
102
+ risk = min(1.0, max(0.0, float(r.get("risk_score", 0) or 0) / 100.0))
103
+ sev = float(r.get("severity", 0.25) or 0.25)
104
+ layer = min(1.0, float(r.get("rule_layer", 1) or 1) / 5.0)
105
+ dev = (hash(r.get("device_id", "") or "") % 10000) / 10000.0
106
+ ag = (hash(r.get("agent_id", "") or "") % 10000) / 10000.0
107
+ rows.append([risk, sev, layer, dev, ag])
108
+ if not rows:
109
+ return np.empty((0, feature_dim))
110
+ X5 = np.array(rows, dtype=np.float64)
111
+ if X5.shape[1] < feature_dim:
112
+ pad = np.zeros((X5.shape[0], feature_dim - X5.shape[1]))
113
+ X5 = np.hstack([X5, pad])
114
+ return X5
115
+
116
+
117
  def _fetch_unsw(n_samples: int, rs: int) -> np.ndarray:
118
  try:
119
  from datasets import load_dataset
 
138
  return X[idx]
139
 
140
 
141
+ def _run_training(csv_url: Optional[str] = None):
142
  global _model, _training
143
  with _training_lock:
144
  if _training:
 
149
  import torch.nn as nn
150
  from sklearn.preprocessing import StandardScaler
151
  from huggingface_hub import HfApi, login
152
+ if csv_url:
153
+ X = _load_csv_from_url(csv_url)
154
+ if len(X) < 10:
155
+ rs = int(time.time()) % 10000
156
+ X = _fetch_unsw(SKLEARN_N_SAMPLES, rs)
157
+ else:
158
+ rs = int(time.time()) % 10000
159
+ X = _fetch_unsw(SKLEARN_N_SAMPLES, rs)
160
  scaler = StandardScaler()
161
  X_scaled = scaler.fit_transform(X)
162
 
 
231
  return {"status": "ok", "model_loaded": _model is not None}
232
 
233
 
234
+ class TrainRequest(BaseModel):
235
+ csv_url: Optional[str] = None
236
+
237
+
238
  @app.post("/train")
239
+ def train(req: TrainRequest | None = Body(None)):
240
+ csv_url = req.csv_url if req else None
241
+ t = threading.Thread(target=_run_training, args=(csv_url,), daemon=True)
242
  t.start()
243
+ return {"status": "training_started", "dataset": "csv" if csv_url else "UNSW-NB15"}
244
 
245
 
246
  @app.get("/train/status")