Spaces:
Sleeping
Sleeping
Upload 3 files
Browse files- app.py +117 -0
- best_10fold_uncertainty_model.pt +3 -0
- requirements.txt +3 -0
app.py
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
|
| 3 |
+
|
| 4 |
+
import numpy as np
|
| 5 |
+
import torch
|
| 6 |
+
import torch.nn as nn
|
| 7 |
+
import gradio as gr
|
| 8 |
+
|
| 9 |
+
MODEL_PATH = "best_10fold_uncertainty_model.pt"
|
| 10 |
+
DEVICE = "cpu" # HF Spaces CPU'da çalıştırmak en stabil seçenek
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
# ===== Model mimarisi (checkpoint ile birebir) =====
|
| 14 |
+
class MLPRegressor(nn.Module):
|
| 15 |
+
def __init__(self, in_dim=5, out_dim=3):
|
| 16 |
+
super().__init__()
|
| 17 |
+
self.net = nn.Sequential(
|
| 18 |
+
nn.Linear(in_dim, 64),
|
| 19 |
+
nn.ReLU(),
|
| 20 |
+
nn.Dropout(0.1),
|
| 21 |
+
nn.Linear(64, 32),
|
| 22 |
+
nn.ReLU(),
|
| 23 |
+
nn.Dropout(0.1),
|
| 24 |
+
nn.Linear(32, out_dim),
|
| 25 |
+
)
|
| 26 |
+
|
| 27 |
+
def forward(self, x):
|
| 28 |
+
return self.net(x)
|
| 29 |
+
|
| 30 |
+
|
| 31 |
+
# ===== Checkpoint yükle =====
|
| 32 |
+
if not os.path.exists(MODEL_PATH):
|
| 33 |
+
raise FileNotFoundError(
|
| 34 |
+
f"Model dosyası bulunamadı: {MODEL_PATH}\n"
|
| 35 |
+
"Lütfen best_10fold_uncertainty_model.pt dosyasını app.py ile aynı klasöre koyun."
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
ckpt = torch.load(MODEL_PATH, map_location=DEVICE)
|
| 39 |
+
|
| 40 |
+
model = MLPRegressor().to(DEVICE)
|
| 41 |
+
model.load_state_dict(ckpt["model_state"])
|
| 42 |
+
model.eval()
|
| 43 |
+
|
| 44 |
+
x_mean = ckpt["x_mean"].cpu().numpy()
|
| 45 |
+
x_scale = ckpt["x_scale"].cpu().numpy()
|
| 46 |
+
y_mean = ckpt["y_mean"].cpu().numpy()
|
| 47 |
+
y_scale = ckpt["y_scale"].cpu().numpy()
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def predict(P, v, h, t, E, e_mode):
|
| 51 |
+
"""
|
| 52 |
+
Inputs: P, v, h, t, E
|
| 53 |
+
Outputs: bulk, Ms, Hc
|
| 54 |
+
e_mode:
|
| 55 |
+
- "Auto-calc E = P/(v*h*t)"
|
| 56 |
+
- "Manual E"
|
| 57 |
+
"""
|
| 58 |
+
# Basit validasyon
|
| 59 |
+
if v <= 0 or h <= 0 or t <= 0:
|
| 60 |
+
return "Hata: v, h, t > 0 olmalı.", None, None, None, None
|
| 61 |
+
|
| 62 |
+
if e_mode.startswith("Auto"):
|
| 63 |
+
E = P / (v * h * t)
|
| 64 |
+
|
| 65 |
+
if E <= 0:
|
| 66 |
+
return "Hata: E > 0 olmalı.", None, None, None, None
|
| 67 |
+
|
| 68 |
+
X = np.array([[P, v, h, t, E]], dtype=np.float32)
|
| 69 |
+
Xs = (X - x_mean) / x_scale
|
| 70 |
+
|
| 71 |
+
with torch.no_grad():
|
| 72 |
+
Xs_t = torch.tensor(Xs, dtype=torch.float32, device=DEVICE)
|
| 73 |
+
Ys = model(Xs_t).cpu().numpy()
|
| 74 |
+
|
| 75 |
+
Y = Ys * y_scale + y_mean
|
| 76 |
+
bulk, Ms, Hc = Y[0]
|
| 77 |
+
return "OK", float(E), float(bulk), float(Ms), float(Hc)
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
with gr.Blocks(title="LPBF ANN Simulator (5→3)") as demo:
|
| 81 |
+
gr.Markdown(
|
| 82 |
+
"# LPBF Fe-based ANN Simulator (5 inputs → 3 outputs)\n"
|
| 83 |
+
"**Inputs:** P, v, h, t, E → **Outputs:** Bulk density, Ms, Hc\n\n"
|
| 84 |
+
"- **Auto-calc E** seçerseniz fiziksel tutarlılık korunur: `E = P/(v·h·t)`\n"
|
| 85 |
+
"- **Manual E** seçerseniz E’yi elle girersiniz.\n"
|
| 86 |
+
)
|
| 87 |
+
|
| 88 |
+
with gr.Row():
|
| 89 |
+
with gr.Column():
|
| 90 |
+
P = gr.Number(value=70, label="Laser power P (W)")
|
| 91 |
+
v = gr.Number(value=900, label="Scan speed v (mm/s)")
|
| 92 |
+
h = gr.Dropdown(choices=[0.02, 0.03], value=0.02, label="Hatch spacing h (mm)")
|
| 93 |
+
t = gr.Number(value=0.05, label="Layer thickness t (mm)")
|
| 94 |
+
|
| 95 |
+
e_mode = gr.Radio(
|
| 96 |
+
choices=["Auto-calc E = P/(v*h*t)", "Manual E"],
|
| 97 |
+
value="Auto-calc E = P/(v*h*t)",
|
| 98 |
+
label="Energy density mode"
|
| 99 |
+
)
|
| 100 |
+
E = gr.Number(value=77.7778, label="Energy density E (J/mm³) (Manual modda kullanılır)")
|
| 101 |
+
|
| 102 |
+
btn = gr.Button("Predict")
|
| 103 |
+
|
| 104 |
+
with gr.Column():
|
| 105 |
+
status = gr.Textbox(label="Status")
|
| 106 |
+
E_used = gr.Number(label="E used (J/mm³)")
|
| 107 |
+
bulk_out = gr.Number(label="Predicted Bulk density (%)")
|
| 108 |
+
Ms_out = gr.Number(label="Predicted Ms (Am²/kg)")
|
| 109 |
+
Hc_out = gr.Number(label="Predicted Hc (kA/m)")
|
| 110 |
+
|
| 111 |
+
btn.click(
|
| 112 |
+
fn=predict,
|
| 113 |
+
inputs=[P, v, h, t, E, e_mode],
|
| 114 |
+
outputs=[status, E_used, bulk_out, Ms_out, Hc_out]
|
| 115 |
+
)
|
| 116 |
+
|
| 117 |
+
demo.launch()
|
best_10fold_uncertainty_model.pt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c7327ad73955c809d6a8fc7a7b8a834b54224da83e2b25214f0352caac47198b
|
| 3 |
+
size 14719
|
requirements.txt
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio==4.44.0
|
| 2 |
+
numpy
|
| 3 |
+
torch
|