Update MLATE model selection and optimization app
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .gitignore +2 -0
- app.py +608 -39
- catboost_printability.cbm → models/cell response/Cell_Response_1D_CNN_model.pth +2 -2
- models/cell response/Cell_Response_AdaBoost.pkl +3 -0
- models/cell response/Cell_Response_Bagging.pkl +3 -0
- cell_line_encoder.joblib → models/cell response/Cell_Response_BernoulliNB.pkl +2 -2
- models/cell response/Cell_Response_CalibratedClassifierCV.pkl +3 -0
- models/cell response/Cell_Response_ComplementNB.pkl +3 -0
- scaler_printability.joblib → models/cell response/Cell_Response_DecisionTree.pkl +2 -2
- scaler_cell_response.joblib → models/cell response/Cell_Response_DummyClassifier.pkl +2 -2
- models/cell response/Cell_Response_ExtraTree.pkl +3 -0
- models/cell response/Cell_Response_ExtraTrees.pkl +3 -0
- catboost_cell_response.cbm → models/cell response/Cell_Response_FT_Transformer_model.pth +2 -2
- models/cell response/Cell_Response_GaussianNB.pkl +3 -0
- models/cell response/Cell_Response_GradientBoosting.pkl +3 -0
- models/cell response/Cell_Response_HistGradientBoosting.pkl +3 -0
- models/cell response/Cell_Response_KNeighbors.pkl +3 -0
- models/cell response/Cell_Response_LDA.pkl +3 -0
- models/cell response/Cell_Response_LabelPropagation.pkl +3 -0
- models/cell response/Cell_Response_LabelSpreading.pkl +3 -0
- models/cell response/Cell_Response_LightGBM.pkl +3 -0
- models/cell response/Cell_Response_LinearSVC.pkl +3 -0
- models/cell response/Cell_Response_LogisticRegression.pkl +3 -0
- models/cell response/Cell_Response_MLP.pkl +3 -0
- models/cell response/Cell_Response_MLP_model.pth +3 -0
- models/cell response/Cell_Response_MultinomialNB.pkl +3 -0
- models/cell response/Cell_Response_NODE_Lite_model.pth +3 -0
- models/cell response/Cell_Response_NuSVC.pkl +3 -0
- models/cell response/Cell_Response_PassiveAggressive.pkl +3 -0
- models/cell response/Cell_Response_Perceptron.pkl +3 -0
- models/cell response/Cell_Response_QDA.pkl +3 -0
- models/cell response/Cell_Response_RadiusNeighbors.pkl +3 -0
- models/cell response/Cell_Response_RandomForest.pkl +3 -0
- models/cell response/Cell_Response_ResNet_model.pth +3 -0
- models/cell response/Cell_Response_RidgeClassifier.pkl +3 -0
- models/cell response/Cell_Response_SGD.pkl +3 -0
- models/cell response/Cell_Response_TabICL_v2.joblib +3 -0
- models/cell response/Cell_Response_TabNet_Lite_model.pth +3 -0
- models/cell response/Cell_Response_TabPFN_2.6.joblib +3 -0
- models/cell response/Cell_Response_XGBoost.pkl +3 -0
- models/preprocessors/feature_cols.pkl +3 -0
- models/preprocessors/label_encoder_cell_response.pkl +3 -0
- models/preprocessors/label_encoder_printability.pkl +3 -0
- models/preprocessors/preprocessor.pkl +3 -0
- models/printability/Printability_1D_CNN_model.pth +3 -0
- models/printability/Printability_AdaBoost.pkl +3 -0
- models/printability/Printability_Bagging.pkl +3 -0
- models/printability/Printability_BernoulliNB.pkl +3 -0
- models/printability/Printability_CalibratedClassifierCV.pkl +3 -0
- models/printability/Printability_ComplementNB.pkl +3 -0
.gitignore
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
| 2 |
+
.venv-test/
|
app.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
| 1 |
import os
|
|
|
|
| 2 |
import streamlit as st
|
| 3 |
import pandas as pd
|
| 4 |
import joblib
|
| 5 |
import optuna
|
| 6 |
import numpy as np
|
| 7 |
-
from catboost import CatBoostClassifier
|
| 8 |
|
| 9 |
from google import genai
|
| 10 |
from google.genai import types
|
|
@@ -33,12 +33,197 @@ def safe_number_input(label, **kwargs):
|
|
| 33 |
|
| 34 |
st.number_input = safe_number_input
|
| 35 |
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
|
| 43 |
def scaffold_quality_combined(printability, cell_response,
|
| 44 |
weight_printability=0.3, weight_cell_response=0.7):
|
|
@@ -79,28 +264,342 @@ PRINT_PARAM_NAMES = [
|
|
| 79 |
]
|
| 80 |
|
| 81 |
@st.cache_resource
|
| 82 |
-
def
|
| 83 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
@st.cache_resource
|
| 86 |
-
def
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
joblib.load(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
)
|
| 91 |
|
| 92 |
-
@st.
|
| 93 |
-
def
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
-
|
| 99 |
-
scaler_print, scaler_cell = load_scalers()
|
| 100 |
-
model_print, model_cell = load_models()
|
| 101 |
|
| 102 |
-
|
| 103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
|
| 105 |
if 'bio_rows' not in st.session_state:
|
| 106 |
st.session_state.bio_rows = [{
|
|
@@ -129,11 +628,60 @@ w_cell_pct = st.sidebar.slider("Cell Response Weight (%)", min_value=0, max_valu
|
|
| 129 |
# Printability is dynamically calculated and cannot be changed manually
|
| 130 |
w_print_pct = 100 - w_cell_pct
|
| 131 |
st.sidebar.number_input("Printability Weight (%)", value=w_print_pct, disabled=True, help="Auto-calculated to ensure sum is 100%")
|
|
|
|
|
|
|
| 132 |
|
| 133 |
# Convert back to 0.0 - 1.0 for the mathematical formula
|
| 134 |
w_cell = w_cell_pct / 100.0
|
| 135 |
w_print = w_print_pct / 100.0
|
| 136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
st.title("MLATE: Machine Learning Applications in Tissue Engineering")
|
| 138 |
st.markdown(
|
| 139 |
"<p style='font-size:1.2em; color:grey;'>"
|
|
@@ -162,9 +710,10 @@ for i, row in enumerate(st.session_state.bio_rows):
|
|
| 162 |
|
| 163 |
c1, c2, c3, c4, c5 = st.columns([2, 1, 1, 1, 0.3])
|
| 164 |
mat = c1.selectbox(
|
| 165 |
-
"", options,
|
| 166 |
index=options.index(row['mat']) if row['mat'] in options else 0,
|
| 167 |
-
key=f"bio_mat_{i}"
|
|
|
|
| 168 |
)
|
| 169 |
st.session_state.bio_rows[i]['mat'] = mat
|
| 170 |
|
|
@@ -299,6 +848,28 @@ st.markdown("---")
|
|
| 299 |
|
| 300 |
if st.button("Optimize WSSQ"):
|
| 301 |
with st.spinner("Running Optuna…"):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
def objective(trial):
|
| 303 |
bi_vals = {
|
| 304 |
r['mat']: trial.suggest_float(
|
|
@@ -325,19 +896,12 @@ if st.button("Optimize WSSQ"):
|
|
| 325 |
|
| 326 |
feat = {**bi_vals, **pp_vals}
|
| 327 |
feat["Cell Density (cells/mL)"] = cd
|
| 328 |
-
feat
|
| 329 |
-
encoder.transform(pd.DataFrame({"Cell Line":[cell_line]}))
|
| 330 |
-
.iloc[0].to_dict()
|
| 331 |
-
)
|
| 332 |
|
| 333 |
-
X = pd.DataFrame([feat])
|
| 334 |
-
Xp = X.reindex(columns=feature_order_print, fill_value=0.0)
|
| 335 |
-
Xc = X.reindex(columns=feature_order_cell, fill_value=0.0)
|
| 336 |
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
exp_p = float(np.dot(p_proba, model_print.classes_.astype(float)))
|
| 340 |
-
exp_c = float(np.dot(c_proba, model_cell .classes_.astype(float)))
|
| 341 |
|
| 342 |
np.random.seed(42)
|
| 343 |
# Use dynamic weights from the sidebar sliders
|
|
@@ -361,7 +925,7 @@ if st.button("Optimize WSSQ"):
|
|
| 361 |
sampler=sampler,
|
| 362 |
pruner=optuna.pruners.MedianPruner()
|
| 363 |
)
|
| 364 |
-
study.optimize(objective, n_trials=
|
| 365 |
|
| 366 |
# Store results in session state to persist after rerun
|
| 367 |
st.session_state.best_params = study.best_trial.params
|
|
@@ -384,7 +948,12 @@ if 'best_params' in st.session_state:
|
|
| 384 |
)
|
| 385 |
|
| 386 |
if st.button("Generate Fabrication Procedure"):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 387 |
with st.spinner("Generating rigorous fabrication procedure…"):
|
|
|
|
| 388 |
|
| 389 |
formatted_params = "\n".join([
|
| 390 |
f"- {k.replace('bio__', 'Biomaterial: ').replace('pp__', 'Print Setting: ')}: {v:.2f}"
|
|
@@ -422,7 +991,7 @@ if 'best_params' in st.session_state:
|
|
| 422 |
final_prompt += f"\n**Additional User Constraints & Inquiries (Integrate these into the protocol):**\n{user_inquiry}"
|
| 423 |
|
| 424 |
resp = client.models.generate_content(
|
| 425 |
-
model=
|
| 426 |
contents=final_prompt,
|
| 427 |
config=types.GenerateContentConfig(
|
| 428 |
system_instruction=(
|
|
@@ -440,4 +1009,4 @@ if 'best_params' in st.session_state:
|
|
| 440 |
)
|
| 441 |
|
| 442 |
st.markdown("## Fabrication Procedure")
|
| 443 |
-
st.markdown(resp.text)
|
|
|
|
| 1 |
import os
|
| 2 |
+
from pathlib import Path
|
| 3 |
import streamlit as st
|
| 4 |
import pandas as pd
|
| 5 |
import joblib
|
| 6 |
import optuna
|
| 7 |
import numpy as np
|
|
|
|
| 8 |
|
| 9 |
from google import genai
|
| 10 |
from google.genai import types
|
|
|
|
| 33 |
|
| 34 |
st.number_input = safe_number_input
|
| 35 |
|
| 36 |
+
APP_DIR = Path(__file__).resolve().parent
|
| 37 |
+
MODEL_ROOT = APP_DIR / "models"
|
| 38 |
+
PREPROCESSOR_DIR = MODEL_ROOT / "preprocessors"
|
| 39 |
+
|
| 40 |
+
MODEL_TASKS = {
|
| 41 |
+
"printability": {
|
| 42 |
+
"folder": MODEL_ROOT / "printability",
|
| 43 |
+
"prefix": "Printability_",
|
| 44 |
+
"label_encoder": "label_encoder_printability.pkl",
|
| 45 |
+
},
|
| 46 |
+
"cell_response": {
|
| 47 |
+
"folder": MODEL_ROOT / "cell response",
|
| 48 |
+
"prefix": "Cell_Response_",
|
| 49 |
+
"label_encoder": "label_encoder_cell_response.pkl",
|
| 50 |
+
},
|
| 51 |
+
}
|
| 52 |
+
|
| 53 |
+
DL_MODEL_CONFIGS = {
|
| 54 |
+
("printability", "ResNet"): {"n_layers": 6, "hidden_dim": 302, "dropout": 0.190106, "activation_func": "relu"},
|
| 55 |
+
("printability", "MLP"): {"n_layers": 3, "hidden_dim": 367, "dropout": 0.169472, "activation_func": "tanh"},
|
| 56 |
+
("printability", "1D_CNN"): {"n_layers": 6, "hidden_dim": 287, "dropout": 0.233072, "activation_func": "relu"},
|
| 57 |
+
("printability", "FT_Transformer"): {"n_layers": 3, "hidden_dim": 437, "dropout": 0.324095, "activation_func": "GELU"},
|
| 58 |
+
("printability", "TabNet_Lite"): {"n_layers": 4, "hidden_dim": 283, "dropout": 0.309445, "activation_func": "relu"},
|
| 59 |
+
("printability", "NODE_Lite"): {"n_layers": 5, "hidden_dim": 289, "dropout": 0.145481, "activation_func": "SELU"},
|
| 60 |
+
("cell_response", "ResNet"): {"n_layers": 4, "hidden_dim": 269, "dropout": 0.229224, "activation_func": "tanh"},
|
| 61 |
+
("cell_response", "MLP"): {"n_layers": 5, "hidden_dim": 238, "dropout": 0.256294, "activation_func": "ELU"},
|
| 62 |
+
("cell_response", "1D_CNN"): {"n_layers": 6, "hidden_dim": 134, "dropout": 0.158794, "activation_func": "SiLU"},
|
| 63 |
+
("cell_response", "FT_Transformer"): {"n_layers": 5, "hidden_dim": 395, "dropout": 0.185155, "activation_func": "SiLU"},
|
| 64 |
+
("cell_response", "TabNet_Lite"): {"n_layers": 5, "hidden_dim": 342, "dropout": 0.103486, "activation_func": "SiLU"},
|
| 65 |
+
("cell_response", "NODE_Lite"): {"n_layers": 2, "hidden_dim": 127, "dropout": 0.328308, "activation_func": "SiLU"},
|
| 66 |
+
}
|
| 67 |
+
|
| 68 |
+
MODEL_RANKINGS = {
|
| 69 |
+
"printability": [
|
| 70 |
+
"HistGradientBoosting", "TabPFN 2.6", "Bagging", "GradientBoosting", "TabICL v2",
|
| 71 |
+
"XGBoost", "LightGBM", "KNeighbors", "LabelPropagation", "ExtraTrees", "MLP",
|
| 72 |
+
"LabelSpreading", "TabNet Lite", "MLP DL", "ResNet", "1D CNN", "DecisionTree",
|
| 73 |
+
"NODE Lite", "LinearSVC", "LDA", "PassiveAggressive", "CalibratedClassifierCV",
|
| 74 |
+
"LogisticRegression", "RidgeClassifier", "FT Transformer", "Perceptron",
|
| 75 |
+
"MultinomialNB", "RadiusNeighbors", "ComplementNB", "NuSVC", "AdaBoost",
|
| 76 |
+
"SGD", "BernoulliNB", "GaussianNB", "QDA", "RandomForest", "ExtraTreeClassifier",
|
| 77 |
+
"DummyClassifier",
|
| 78 |
+
],
|
| 79 |
+
"cell_response": [
|
| 80 |
+
"HistGradientBoosting", "TabICL v2", "TabPFN 2.6", "XGBoost", "Bagging",
|
| 81 |
+
"KNeighbors", "LabelPropagation", "LabelSpreading", "LightGBM", "FT Transformer",
|
| 82 |
+
"CalibratedClassifierCV", "ResNet", "NODE Lite", "1D CNN", "MLP DL", "LDA",
|
| 83 |
+
"NuSVC", "MultinomialNB", "LogisticRegression", "LinearSVC", "Perceptron",
|
| 84 |
+
"QDA", "RidgeClassifier", "ExtraTrees", "ExtraTreeClassifier", "AdaBoost",
|
| 85 |
+
"DecisionTree", "RandomForest", "GradientBoosting", "SGD", "MLP",
|
| 86 |
+
"PassiveAggressive", "ComplementNB", "TabNet Lite", "BernoulliNB",
|
| 87 |
+
"RadiusNeighbors", "DummyClassifier", "GaussianNB",
|
| 88 |
+
],
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
PERFORMANCE_GUIDE = {
|
| 92 |
+
"printability": """
|
| 93 |
+
| Rank | Model | Framework | Accuracy | F1 | AUC | MCC |
|
| 94 |
+
|---:|---|---|---:|---:|---:|---:|
|
| 95 |
+
| 1 | HistGradientBoosting | Machine Learning | 0.80 | 0.80 | 0.94 | 0.69 |
|
| 96 |
+
| 2 | TabPFN 2.6 | Deep Learning / Transformer | 0.80 | 0.80 | 0.94 | 0.69 |
|
| 97 |
+
| 3 | Bagging | Machine Learning | 0.79 | 0.79 | 0.93 | 0.67 |
|
| 98 |
+
| 4 | GradientBoosting | Machine Learning | 0.79 | 0.79 | 0.93 | 0.66 |
|
| 99 |
+
| 5 | TabICL v2 | Deep Learning / Transformer | 0.79 | 0.79 | 0.94 | 0.68 |
|
| 100 |
+
| 6 | XGBoost | Machine Learning | 0.78 | 0.78 | 0.93 | 0.66 |
|
| 101 |
+
| 7 | LightGBM | Machine Learning | 0.77 | 0.77 | 0.93 | 0.64 |
|
| 102 |
+
| 8 | KNeighbors | Machine Learning | 0.77 | 0.77 | 0.90 | 0.64 |
|
| 103 |
+
| 9 | LabelPropagation | Machine Learning | 0.77 | 0.77 | 0.82 | 0.64 |
|
| 104 |
+
| 10 | ExtraTrees | Machine Learning | 0.77 | 0.77 | 0.92 | 0.63 |
|
| 105 |
+
""",
|
| 106 |
+
"cell_response": """
|
| 107 |
+
| Rank | Model | Framework | Accuracy | F1 | AUC | MCC |
|
| 108 |
+
|---:|---|---|---:|---:|---:|---:|
|
| 109 |
+
| 1 | HistGradientBoosting | Machine Learning | 0.81 | 0.81 | 0.96 | 0.67 |
|
| 110 |
+
| 2 | TabICL v2 | Deep Learning / Transformer | 0.79 | 0.79 | 0.97 | 0.65 |
|
| 111 |
+
| 3 | TabPFN 2.6 | Deep Learning / Transformer | 0.78 | 0.78 | 0.96 | 0.63 |
|
| 112 |
+
| 4 | XGBoost | Machine Learning | 0.79 | 0.77 | 0.96 | 0.65 |
|
| 113 |
+
| 5 | Bagging | Machine Learning | 0.77 | 0.77 | 0.95 | 0.62 |
|
| 114 |
+
| 6 | KNeighbors | Machine Learning | 0.77 | 0.77 | 0.93 | 0.61 |
|
| 115 |
+
| 7 | LabelPropagation | Machine Learning | 0.77 | 0.77 | 0.93 | 0.61 |
|
| 116 |
+
| 8 | LabelSpreading | Machine Learning | 0.78 | 0.76 | 0.93 | 0.61 |
|
| 117 |
+
| 9 | LightGBM | Machine Learning | 0.78 | 0.76 | 0.96 | 0.64 |
|
| 118 |
+
| 10 | FT Transformer | Deep Learning / Transformer | 0.76 | 0.76 | 0.94 | 0.61 |
|
| 119 |
+
""",
|
| 120 |
+
}
|
| 121 |
+
|
| 122 |
+
PERFORMANCE_GUIDE_FULL = {
|
| 123 |
+
"printability": """
|
| 124 |
+
# Printability - Merged Performance Summary
|
| 125 |
+
|
| 126 |
+
This file contains the aggregated and benchmarked results of traditional Machine Learning (ML) and Deep Learning / Transformer architectures for predicting **Printability**, sorted hierarchically by **F1 Score** and **Accuracy**.
|
| 127 |
+
|
| 128 |
+
| Rank | Model | Framework | Accuracy | Precision | Recall | F1 | AUC | MCC | Kappa |
|
| 129 |
+
|---:|---|---|---:|---:|---:|---:|---:|---:|---:|
|
| 130 |
+
| 1 | HistGradientBoosting | Machine Learning | 0.80 | 0.80 | 0.80 | 0.80 | 0.94 | 0.69 | 0.69 |
|
| 131 |
+
| 2 | TabPFN 2.6 | Deep Learning / Transformer | 0.80 | 0.81 | 0.80 | 0.80 | 0.94 | 0.69 | 0.68 |
|
| 132 |
+
| 3 | Bagging | Machine Learning | 0.79 | 0.79 | 0.79 | 0.79 | 0.93 | 0.67 | 0.67 |
|
| 133 |
+
| 4 | GradientBoosting | Machine Learning | 0.79 | 0.79 | 0.79 | 0.79 | 0.93 | 0.66 | 0.66 |
|
| 134 |
+
| 5 | TabICL v2 | Deep Learning / Transformer | 0.79 | 0.81 | 0.79 | 0.79 | 0.94 | 0.68 | 0.67 |
|
| 135 |
+
| 6 | XGBoost | Machine Learning | 0.78 | 0.79 | 0.78 | 0.78 | 0.93 | 0.66 | 0.65 |
|
| 136 |
+
| 7 | LightGBM | Machine Learning | 0.77 | 0.78 | 0.77 | 0.77 | 0.93 | 0.64 | 0.64 |
|
| 137 |
+
| 8 | KNeighbors | Machine Learning | 0.77 | 0.78 | 0.77 | 0.77 | 0.90 | 0.64 | 0.64 |
|
| 138 |
+
| 9 | LabelPropagation | Machine Learning | 0.77 | 0.77 | 0.77 | 0.77 | 0.82 | 0.64 | 0.63 |
|
| 139 |
+
| 10 | ExtraTrees | Machine Learning | 0.77 | 0.77 | 0.77 | 0.77 | 0.92 | 0.63 | 0.63 |
|
| 140 |
+
| 11 | MLP | Machine Learning | 0.76 | 0.76 | 0.76 | 0.76 | 0.90 | 0.63 | 0.63 |
|
| 141 |
+
| 12 | LabelSpreading | Machine Learning | 0.76 | 0.76 | 0.76 | 0.76 | 0.90 | 0.62 | 0.62 |
|
| 142 |
+
| 13 | TabNet Lite | Deep Learning / Transformer | 0.74 | 0.74 | 0.74 | 0.74 | 0.91 | 0.59 | 0.59 |
|
| 143 |
+
| 14 | MLP (DL) | Deep Learning / Transformer | 0.73 | 0.73 | 0.73 | 0.73 | 0.91 | 0.58 | 0.58 |
|
| 144 |
+
| 15 | ResNet | Deep Learning / Transformer | 0.73 | 0.73 | 0.73 | 0.73 | 0.91 | 0.57 | 0.57 |
|
| 145 |
+
| 16 | 1D CNN | Deep Learning / Transformer | 0.71 | 0.73 | 0.71 | 0.72 | 0.89 | 0.56 | 0.56 |
|
| 146 |
+
| 17 | DecisionTree | Machine Learning | 0.71 | 0.72 | 0.71 | 0.71 | 0.89 | 0.54 | 0.54 |
|
| 147 |
+
| 18 | NODE Lite | Deep Learning / Transformer | 0.69 | 0.70 | 0.69 | 0.70 | 0.90 | 0.52 | 0.52 |
|
| 148 |
+
| 19 | LinearSVC | Machine Learning | 0.69 | 0.68 | 0.69 | 0.68 | 0.85 | 0.49 | 0.49 |
|
| 149 |
+
| 20 | LDA | Machine Learning | 0.68 | 0.68 | 0.68 | 0.68 | 0.84 | 0.49 | 0.48 |
|
| 150 |
+
| 21 | PassiveAggressive | Machine Learning | 0.69 | 0.68 | 0.69 | 0.67 | 0.85 | 0.48 | 0.48 |
|
| 151 |
+
| 22 | CalibratedClassifierCV | Machine Learning | 0.68 | 0.68 | 0.68 | 0.67 | 0.85 | 0.48 | 0.48 |
|
| 152 |
+
| 23 | LogisticRegression | Machine Learning | 0.68 | 0.67 | 0.68 | 0.67 | 0.85 | 0.47 | 0.47 |
|
| 153 |
+
| 24 | RidgeClassifier | Machine Learning | 0.68 | 0.67 | 0.68 | 0.66 | 0.84 | 0.46 | 0.46 |
|
| 154 |
+
| 25 | FT Transformer | Deep Learning / Transformer | 0.66 | 0.65 | 0.66 | 0.65 | 0.87 | 0.45 | 0.45 |
|
| 155 |
+
| 26 | Perceptron | Machine Learning | 0.67 | 0.68 | 0.67 | 0.64 | 0.84 | 0.45 | 0.42 |
|
| 156 |
+
| 27 | MultinomialNB | Machine Learning | 0.64 | 0.69 | 0.64 | 0.64 | 0.83 | 0.45 | 0.43 |
|
| 157 |
+
| 28 | RadiusNeighbors | Machine Learning | 0.66 | 0.70 | 0.66 | 0.63 | 0.87 | 0.43 | 0.39 |
|
| 158 |
+
| 29 | ComplementNB | Machine Learning | 0.63 | 0.67 | 0.63 | 0.63 | 0.82 | 0.44 | 0.43 |
|
| 159 |
+
| 30 | NuSVC | Machine Learning | 0.60 | 0.69 | 0.60 | 0.61 | 0.84 | 0.45 | 0.42 |
|
| 160 |
+
| 31 | AdaBoost | Machine Learning | 0.62 | 0.59 | 0.62 | 0.58 | 0.80 | 0.38 | 0.37 |
|
| 161 |
+
| 32 | SGD | Machine Learning | 0.63 | 0.59 | 0.63 | 0.57 | 0.82 | 0.36 | 0.35 |
|
| 162 |
+
| 33 | BernoulliNB | Machine Learning | 0.59 | 0.62 | 0.59 | 0.55 | 0.77 | 0.32 | 0.31 |
|
| 163 |
+
| 34 | GaussianNB | Machine Learning | 0.33 | 0.70 | 0.33 | 0.36 | 0.74 | 0.25 | 0.19 |
|
| 164 |
+
| 35 | QDA | Machine Learning | 0.52 | 0.27 | 0.52 | 0.35 | 0.80 | 0.00 | 0.00 |
|
| 165 |
+
| 36 | RandomForest | Machine Learning | 0.52 | 0.27 | 0.52 | 0.35 | 0.78 | 0.00 | 0.00 |
|
| 166 |
+
| 37 | ExtraTreeClassifier | Machine Learning | 0.52 | 0.27 | 0.52 | 0.35 | 0.50 | 0.00 | 0.00 |
|
| 167 |
+
| 38 | DummyClassifier | Machine Learning | 0.52 | 0.27 | 0.52 | 0.35 | 0.50 | 0.00 | 0.00 |
|
| 168 |
+
""",
|
| 169 |
+
"cell_response": """
|
| 170 |
+
# Cell Response - Merged Performance Summary
|
| 171 |
+
|
| 172 |
+
This file contains the aggregated and benchmarked results of traditional Machine Learning (ML) and Deep Learning / Transformer architectures for predicting **Cell Response**, sorted hierarchically by **F1 Score** and **Accuracy**.
|
| 173 |
+
|
| 174 |
+
| Rank | Model | Framework | Accuracy | Precision | Recall | F1 | AUC | MCC | Kappa |
|
| 175 |
+
|---:|---|---|---:|---:|---:|---:|---:|---:|---:|
|
| 176 |
+
| 1 | HistGradientBoosting | Machine Learning | 0.81 | 0.81 | 0.81 | 0.81 | 0.96 | 0.67 | 0.67 |
|
| 177 |
+
| 2 | TabICL v2 | Deep Learning / Transformer | 0.79 | 0.79 | 0.79 | 0.79 | 0.97 | 0.65 | 0.65 |
|
| 178 |
+
| 3 | TabPFN 2.6 | Deep Learning / Transformer | 0.78 | 0.78 | 0.78 | 0.78 | 0.96 | 0.63 | 0.63 |
|
| 179 |
+
| 4 | XGBoost | Machine Learning | 0.79 | 0.76 | 0.79 | 0.77 | 0.96 | 0.65 | 0.64 |
|
| 180 |
+
| 5 | Bagging | Machine Learning | 0.77 | 0.78 | 0.77 | 0.77 | 0.95 | 0.62 | 0.62 |
|
| 181 |
+
| 6 | KNeighbors | Machine Learning | 0.77 | 0.77 | 0.77 | 0.77 | 0.93 | 0.61 | 0.61 |
|
| 182 |
+
| 7 | LabelPropagation | Machine Learning | 0.77 | 0.77 | 0.77 | 0.77 | 0.93 | 0.61 | 0.61 |
|
| 183 |
+
| 8 | LabelSpreading | Machine Learning | 0.78 | 0.76 | 0.78 | 0.76 | 0.93 | 0.61 | 0.61 |
|
| 184 |
+
| 9 | LightGBM | Machine Learning | 0.78 | 0.79 | 0.78 | 0.76 | 0.96 | 0.64 | 0.63 |
|
| 185 |
+
| 10 | FT Transformer | Deep Learning / Transformer | 0.76 | 0.79 | 0.76 | 0.76 | 0.94 | 0.61 | 0.60 |
|
| 186 |
+
| 11 | CalibratedClassifierCV | Machine Learning | 0.76 | 0.76 | 0.76 | 0.75 | 0.94 | 0.59 | 0.59 |
|
| 187 |
+
| 12 | ResNet | Deep Learning / Transformer | 0.76 | 0.76 | 0.76 | 0.75 | 0.94 | 0.59 | 0.59 |
|
| 188 |
+
| 13 | NODE Lite | Deep Learning / Transformer | 0.76 | 0.75 | 0.76 | 0.75 | 0.95 | 0.59 | 0.59 |
|
| 189 |
+
| 14 | 1D CNN | Deep Learning / Transformer | 0.75 | 0.76 | 0.75 | 0.74 | 0.95 | 0.59 | 0.59 |
|
| 190 |
+
| 15 | MLP (DL) | Deep Learning / Transformer | 0.75 | 0.75 | 0.75 | 0.74 | 0.95 | 0.57 | 0.57 |
|
| 191 |
+
| 16 | LDA | Machine Learning | 0.75 | 0.72 | 0.75 | 0.73 | 0.94 | 0.55 | 0.55 |
|
| 192 |
+
| 17 | NuSVC | Machine Learning | 0.74 | 0.73 | 0.74 | 0.73 | 0.95 | 0.55 | 0.55 |
|
| 193 |
+
| 18 | MultinomialNB | Machine Learning | 0.74 | 0.72 | 0.74 | 0.73 | 0.95 | 0.55 | 0.55 |
|
| 194 |
+
| 19 | LogisticRegression | Machine Learning | 0.74 | 0.70 | 0.74 | 0.71 | 0.95 | 0.54 | 0.54 |
|
| 195 |
+
| 20 | LinearSVC | Machine Learning | 0.74 | 0.71 | 0.74 | 0.70 | 0.94 | 0.53 | 0.52 |
|
| 196 |
+
| 21 | Perceptron | Machine Learning | 0.74 | 0.68 | 0.74 | 0.70 | 0.94 | 0.53 | 0.52 |
|
| 197 |
+
| 22 | QDA | Machine Learning | 0.74 | 0.68 | 0.74 | 0.70 | 0.94 | 0.57 | 0.55 |
|
| 198 |
+
| 23 | RidgeClassifier | Machine Learning | 0.73 | 0.70 | 0.73 | 0.70 | 0.94 | 0.52 | 0.51 |
|
| 199 |
+
| 24 | ExtraTrees | Machine Learning | 0.74 | 0.71 | 0.74 | 0.68 | 0.95 | 0.55 | 0.52 |
|
| 200 |
+
| 25 | ExtraTreeClassifier | Machine Learning | 0.73 | 0.67 | 0.73 | 0.68 | 0.91 | 0.54 | 0.52 |
|
| 201 |
+
| 26 | AdaBoost | Machine Learning | 0.74 | 0.65 | 0.74 | 0.67 | 0.91 | 0.59 | 0.55 |
|
| 202 |
+
| 27 | DecisionTree | Machine Learning | 0.74 | 0.65 | 0.74 | 0.67 | 0.92 | 0.59 | 0.55 |
|
| 203 |
+
| 28 | RandomForest | Machine Learning | 0.74 | 0.65 | 0.74 | 0.67 | 0.92 | 0.59 | 0.55 |
|
| 204 |
+
| 29 | GradientBoosting | Machine Learning | 0.74 | 0.65 | 0.74 | 0.67 | 0.92 | 0.59 | 0.55 |
|
| 205 |
+
| 30 | SGD | Machine Learning | 0.71 | 0.65 | 0.71 | 0.66 | 0.92 | 0.49 | 0.47 |
|
| 206 |
+
| 31 | MLP | Machine Learning | 0.73 | 0.61 | 0.73 | 0.65 | 0.93 | 0.55 | 0.52 |
|
| 207 |
+
| 32 | PassiveAggressive | Machine Learning | 0.73 | 0.65 | 0.73 | 0.65 | 0.92 | 0.52 | 0.49 |
|
| 208 |
+
| 33 | ComplementNB | Machine Learning | 0.72 | 0.65 | 0.72 | 0.65 | 0.93 | 0.49 | 0.47 |
|
| 209 |
+
| 34 | TabNet Lite | Deep Learning / Transformer | 0.70 | 0.67 | 0.70 | 0.65 | 0.93 | 0.48 | 0.46 |
|
| 210 |
+
| 35 | BernoulliNB | Machine Learning | 0.71 | 0.60 | 0.71 | 0.63 | 0.93 | 0.48 | 0.45 |
|
| 211 |
+
| 36 | RadiusNeighbors | Machine Learning | 0.60 | 0.36 | 0.60 | 0.45 | 0.50 | 0.00 | 0.00 |
|
| 212 |
+
| 37 | DummyClassifier | Machine Learning | 0.60 | 0.36 | 0.60 | 0.45 | 0.50 | 0.00 | 0.00 |
|
| 213 |
+
| 38 | GaussianNB | Machine Learning | 0.28 | 0.69 | 0.28 | 0.34 | 0.84 | 0.18 | 0.14 |
|
| 214 |
+
""",
|
| 215 |
+
}
|
| 216 |
+
|
| 217 |
+
GEMINI_MODELS = [
|
| 218 |
+
"gemini-3.5-flash",
|
| 219 |
+
"gemini-3.1-flash-lite",
|
| 220 |
+
"gemini-3.1-pro-preview",
|
| 221 |
+
"gemini-3.1-flash-lite-preview",
|
| 222 |
+
"gemini-3-flash-preview",
|
| 223 |
+
"gemini-2.5-pro",
|
| 224 |
+
"gemini-2.5-flash",
|
| 225 |
+
"gemini-2.5-flash-lite",
|
| 226 |
+
]
|
| 227 |
|
| 228 |
def scaffold_quality_combined(printability, cell_response,
|
| 229 |
weight_printability=0.3, weight_cell_response=0.7):
|
|
|
|
| 264 |
]
|
| 265 |
|
| 266 |
@st.cache_resource
|
| 267 |
+
def load_prediction_preprocessors():
|
| 268 |
+
return {
|
| 269 |
+
"preprocessor": joblib.load(PREPROCESSOR_DIR / "preprocessor.pkl"),
|
| 270 |
+
"feature_cols": joblib.load(PREPROCESSOR_DIR / "feature_cols.pkl"),
|
| 271 |
+
"printability_encoder": joblib.load(PREPROCESSOR_DIR / MODEL_TASKS["printability"]["label_encoder"]),
|
| 272 |
+
"cell_response_encoder": joblib.load(PREPROCESSOR_DIR / MODEL_TASKS["cell_response"]["label_encoder"]),
|
| 273 |
+
}
|
| 274 |
+
|
| 275 |
+
def model_display_name(path, prefix):
|
| 276 |
+
name = path.stem.replace("_model", "")
|
| 277 |
+
if name.startswith(prefix):
|
| 278 |
+
name = name[len(prefix):]
|
| 279 |
+
return f"{name} ({path.suffix.lstrip('.')})"
|
| 280 |
+
|
| 281 |
+
def model_rank_key(display_name, task_key):
|
| 282 |
+
base_name = display_name.rsplit(" (", 1)[0]
|
| 283 |
+
rank_aliases = {
|
| 284 |
+
"1D_CNN": "1D CNN",
|
| 285 |
+
"FT_Transformer": "FT Transformer",
|
| 286 |
+
"NODE_Lite": "NODE Lite",
|
| 287 |
+
"TabNet_Lite": "TabNet Lite",
|
| 288 |
+
"TabPFN_2.6": "TabPFN 2.6",
|
| 289 |
+
"TabICL_v2": "TabICL v2",
|
| 290 |
+
"ExtraTree": "ExtraTreeClassifier",
|
| 291 |
+
}
|
| 292 |
+
rank_name = rank_aliases.get(base_name, base_name)
|
| 293 |
+
if base_name == "MLP" and display_name.endswith("(pth)"):
|
| 294 |
+
rank_name = "MLP DL"
|
| 295 |
+
ranking = MODEL_RANKINGS[task_key]
|
| 296 |
+
rank = ranking.index(rank_name) if rank_name in ranking else len(ranking)
|
| 297 |
+
return rank, base_name.lower(), display_name
|
| 298 |
+
|
| 299 |
+
def discover_model_options(task_key):
|
| 300 |
+
task = MODEL_TASKS[task_key]
|
| 301 |
+
files = []
|
| 302 |
+
for suffix in ("*.pkl", "*.joblib", "*.pth"):
|
| 303 |
+
files.extend(task["folder"].glob(suffix))
|
| 304 |
+
options = {model_display_name(path, task["prefix"]): str(path) for path in files}
|
| 305 |
+
return dict(sorted(options.items(), key=lambda item: model_rank_key(item[0], task_key)))
|
| 306 |
+
|
| 307 |
+
def parse_architecture(path, task_key):
|
| 308 |
+
stem = Path(path).stem.replace("_model", "")
|
| 309 |
+
prefix = MODEL_TASKS[task_key]["prefix"]
|
| 310 |
+
return stem[len(prefix):] if stem.startswith(prefix) else stem
|
| 311 |
+
|
| 312 |
+
def build_torch_model(architecture, input_dim, out_dim, cfg):
|
| 313 |
+
import torch
|
| 314 |
+
import torch.nn as nn
|
| 315 |
+
|
| 316 |
+
activation_funcs = {
|
| 317 |
+
"relu": nn.ReLU, "tanh": nn.Tanh, "GELU": nn.GELU,
|
| 318 |
+
"SELU": nn.SELU, "ELU": nn.ELU, "SiLU": nn.SiLU,
|
| 319 |
+
}
|
| 320 |
+
act = activation_funcs[cfg["activation_func"]]
|
| 321 |
+
|
| 322 |
+
class ResidualBlock(nn.Module):
|
| 323 |
+
def __init__(self):
|
| 324 |
+
super().__init__()
|
| 325 |
+
self.linear = nn.Linear(cfg["hidden_dim"], cfg["hidden_dim"])
|
| 326 |
+
self.bn = nn.BatchNorm1d(cfg["hidden_dim"])
|
| 327 |
+
self.act = act()
|
| 328 |
+
self.dropout = nn.Dropout(cfg["dropout"])
|
| 329 |
+
def forward(self, x):
|
| 330 |
+
return x + self.dropout(self.act(self.bn(self.linear(x))))
|
| 331 |
+
|
| 332 |
+
class TissueResNet(nn.Module):
|
| 333 |
+
def __init__(self):
|
| 334 |
+
super().__init__()
|
| 335 |
+
self.input_layer = nn.Sequential(
|
| 336 |
+
nn.Linear(input_dim, cfg["hidden_dim"]),
|
| 337 |
+
nn.BatchNorm1d(cfg["hidden_dim"]),
|
| 338 |
+
act(),
|
| 339 |
+
)
|
| 340 |
+
self.blocks = nn.ModuleList([ResidualBlock() for _ in range(cfg["n_layers"])])
|
| 341 |
+
self.output_layer = nn.Linear(cfg["hidden_dim"], out_dim)
|
| 342 |
+
def forward(self, x):
|
| 343 |
+
x = self.input_layer(x)
|
| 344 |
+
for block in self.blocks:
|
| 345 |
+
x = block(x)
|
| 346 |
+
return self.output_layer(x)
|
| 347 |
+
|
| 348 |
+
class StandardMLP(nn.Module):
|
| 349 |
+
def __init__(self):
|
| 350 |
+
super().__init__()
|
| 351 |
+
layers = []
|
| 352 |
+
in_dim = input_dim
|
| 353 |
+
for _ in range(cfg["n_layers"]):
|
| 354 |
+
layers.extend([
|
| 355 |
+
nn.Linear(in_dim, cfg["hidden_dim"]),
|
| 356 |
+
nn.BatchNorm1d(cfg["hidden_dim"]),
|
| 357 |
+
act(),
|
| 358 |
+
nn.Dropout(cfg["dropout"]),
|
| 359 |
+
])
|
| 360 |
+
in_dim = cfg["hidden_dim"]
|
| 361 |
+
layers.append(nn.Linear(cfg["hidden_dim"], out_dim))
|
| 362 |
+
self.network = nn.Sequential(*layers)
|
| 363 |
+
def forward(self, x):
|
| 364 |
+
return self.network(x)
|
| 365 |
+
|
| 366 |
+
class Tabular1DCNN(nn.Module):
|
| 367 |
+
def __init__(self):
|
| 368 |
+
super().__init__()
|
| 369 |
+
layers = []
|
| 370 |
+
in_channels = 1
|
| 371 |
+
for _ in range(cfg["n_layers"]):
|
| 372 |
+
layers.extend([
|
| 373 |
+
nn.Conv1d(in_channels, cfg["hidden_dim"], kernel_size=3, padding=1),
|
| 374 |
+
nn.BatchNorm1d(cfg["hidden_dim"]),
|
| 375 |
+
act(),
|
| 376 |
+
nn.Dropout(cfg["dropout"]),
|
| 377 |
+
])
|
| 378 |
+
in_channels = cfg["hidden_dim"]
|
| 379 |
+
self.conv_net = nn.Sequential(*layers)
|
| 380 |
+
self.pool = nn.AdaptiveAvgPool1d(1)
|
| 381 |
+
self.fc = nn.Linear(cfg["hidden_dim"], out_dim)
|
| 382 |
+
def forward(self, x):
|
| 383 |
+
x = self.conv_net(x.unsqueeze(1))
|
| 384 |
+
return self.fc(self.pool(x).squeeze(2))
|
| 385 |
+
|
| 386 |
+
class FTTransformer(nn.Module):
|
| 387 |
+
def __init__(self):
|
| 388 |
+
super().__init__()
|
| 389 |
+
self.d_token = max(4, (cfg["hidden_dim"] // 4) * 4)
|
| 390 |
+
self.feature_embeddings = nn.ModuleList([nn.Linear(1, self.d_token) for _ in range(input_dim)])
|
| 391 |
+
self.cls_token = nn.Parameter(torch.randn(1, 1, self.d_token))
|
| 392 |
+
encoder_layer = nn.TransformerEncoderLayer(
|
| 393 |
+
d_model=self.d_token, nhead=4, dropout=cfg["dropout"], batch_first=True
|
| 394 |
+
)
|
| 395 |
+
self.transformer = nn.TransformerEncoder(encoder_layer, num_layers=cfg["n_layers"])
|
| 396 |
+
self.fc = nn.Linear(self.d_token, out_dim)
|
| 397 |
+
def forward(self, x):
|
| 398 |
+
batch_size = x.size(0)
|
| 399 |
+
tokens = [self.feature_embeddings[i](x[:, i:i+1]).unsqueeze(1) for i in range(x.size(1))]
|
| 400 |
+
x_emb = torch.cat([self.cls_token.expand(batch_size, -1, -1)] + tokens, dim=1)
|
| 401 |
+
return self.fc(self.transformer(x_emb)[:, 0, :])
|
| 402 |
+
|
| 403 |
+
class TabNetLite(nn.Module):
|
| 404 |
+
def __init__(self):
|
| 405 |
+
super().__init__()
|
| 406 |
+
self.n_steps = max(1, cfg["n_layers"])
|
| 407 |
+
self.initial_bn = nn.BatchNorm1d(input_dim)
|
| 408 |
+
self.transformers = nn.ModuleList([
|
| 409 |
+
nn.Sequential(
|
| 410 |
+
nn.Linear(input_dim, cfg["hidden_dim"]),
|
| 411 |
+
nn.BatchNorm1d(cfg["hidden_dim"]),
|
| 412 |
+
act(),
|
| 413 |
+
nn.Dropout(cfg["dropout"]),
|
| 414 |
+
)
|
| 415 |
+
for _ in range(self.n_steps)
|
| 416 |
+
])
|
| 417 |
+
self.attentions = nn.ModuleList([
|
| 418 |
+
nn.Sequential(
|
| 419 |
+
nn.Linear(cfg["hidden_dim"], input_dim),
|
| 420 |
+
nn.BatchNorm1d(input_dim),
|
| 421 |
+
nn.Softmax(dim=-1),
|
| 422 |
+
)
|
| 423 |
+
for _ in range(self.n_steps)
|
| 424 |
+
])
|
| 425 |
+
self.fc_out = nn.Linear(cfg["hidden_dim"], out_dim)
|
| 426 |
+
def forward(self, x):
|
| 427 |
+
x = self.initial_bn(x)
|
| 428 |
+
out_agg, prior = 0, torch.ones_like(x)
|
| 429 |
+
feat_rep = self.transformers[0](x)
|
| 430 |
+
for step in range(self.n_steps):
|
| 431 |
+
mask = self.attentions[step](feat_rep) * prior
|
| 432 |
+
prior = prior * (1.0 - mask)
|
| 433 |
+
feat_rep = self.transformers[step](x * mask)
|
| 434 |
+
out_agg += feat_rep
|
| 435 |
+
return self.fc_out(out_agg)
|
| 436 |
+
|
| 437 |
+
class NeuralDecisionForest(nn.Module):
|
| 438 |
+
def __init__(self):
|
| 439 |
+
super().__init__()
|
| 440 |
+
self.n_trees = max(1, cfg["hidden_dim"] // 16)
|
| 441 |
+
self.depth = max(2, cfg["n_layers"] + 1)
|
| 442 |
+
self.n_leaves = 2 ** self.depth
|
| 443 |
+
self.trees = nn.ModuleList([
|
| 444 |
+
nn.Sequential(
|
| 445 |
+
nn.Linear(input_dim, self.n_leaves),
|
| 446 |
+
nn.Dropout(cfg["dropout"]),
|
| 447 |
+
nn.Softmax(dim=-1),
|
| 448 |
+
)
|
| 449 |
+
for _ in range(self.n_trees)
|
| 450 |
+
])
|
| 451 |
+
self.leaf_weights = nn.Parameter(torch.randn(self.n_trees, self.n_leaves, out_dim))
|
| 452 |
+
def forward(self, x):
|
| 453 |
+
out = 0
|
| 454 |
+
for i, tree in enumerate(self.trees):
|
| 455 |
+
out += torch.matmul(tree(x), self.leaf_weights[i])
|
| 456 |
+
return out / self.n_trees
|
| 457 |
+
|
| 458 |
+
builders = {
|
| 459 |
+
"ResNet": TissueResNet,
|
| 460 |
+
"MLP": StandardMLP,
|
| 461 |
+
"1D_CNN": Tabular1DCNN,
|
| 462 |
+
"FT_Transformer": FTTransformer,
|
| 463 |
+
"TabNet_Lite": TabNetLite,
|
| 464 |
+
"NODE_Lite": NeuralDecisionForest,
|
| 465 |
+
}
|
| 466 |
+
return builders[architecture]()
|
| 467 |
|
| 468 |
@st.cache_resource
|
| 469 |
+
def load_prediction_model(path, task_key, input_dim, out_dim):
|
| 470 |
+
path = Path(path)
|
| 471 |
+
if path.suffix in {".pkl", ".joblib"}:
|
| 472 |
+
return {"kind": "sklearn", "model": joblib.load(path)}
|
| 473 |
+
|
| 474 |
+
if path.suffix == ".pth":
|
| 475 |
+
import torch
|
| 476 |
+
architecture = parse_architecture(path, task_key)
|
| 477 |
+
cfg = DL_MODEL_CONFIGS.get((task_key, architecture))
|
| 478 |
+
if cfg is None:
|
| 479 |
+
raise ValueError(f"No architecture configuration found for {path.name}.")
|
| 480 |
+
model = build_torch_model(architecture, input_dim, out_dim, cfg)
|
| 481 |
+
state_dict = torch.load(path, map_location="cpu")
|
| 482 |
+
model.load_state_dict(state_dict)
|
| 483 |
+
model.eval()
|
| 484 |
+
return {"kind": "torch", "model": model}
|
| 485 |
+
|
| 486 |
+
raise ValueError(f"Unsupported model file: {path.name}")
|
| 487 |
+
|
| 488 |
+
def softmax(values):
|
| 489 |
+
values = np.asarray(values, dtype=float)
|
| 490 |
+
values = values - np.max(values)
|
| 491 |
+
exp_values = np.exp(values)
|
| 492 |
+
return exp_values / exp_values.sum()
|
| 493 |
+
|
| 494 |
+
def expected_class_value(model_bundle, x_raw, preprocessor, label_encoder):
|
| 495 |
+
x_model = preprocessor.transform(x_raw).astype(np.float32)
|
| 496 |
+
|
| 497 |
+
if model_bundle["kind"] == "torch":
|
| 498 |
+
import torch
|
| 499 |
+
with torch.no_grad():
|
| 500 |
+
logits = model_bundle["model"](torch.tensor(x_model, dtype=torch.float32)).numpy()[0]
|
| 501 |
+
probs = softmax(logits)
|
| 502 |
+
labels = label_encoder.classes_.astype(float)
|
| 503 |
+
return float(np.dot(probs, labels))
|
| 504 |
+
|
| 505 |
+
model = model_bundle["model"]
|
| 506 |
+
if hasattr(model, "predict_proba"):
|
| 507 |
+
probs = model.predict_proba(x_model)[0]
|
| 508 |
+
classes = np.asarray(model.classes_, dtype=int)
|
| 509 |
+
labels = label_encoder.inverse_transform(classes).astype(float)
|
| 510 |
+
return float(np.dot(probs, labels))
|
| 511 |
+
|
| 512 |
+
if hasattr(model, "decision_function"):
|
| 513 |
+
scores = np.asarray(model.decision_function(x_model)[0])
|
| 514 |
+
if scores.ndim == 0:
|
| 515 |
+
p_high = 1.0 / (1.0 + np.exp(-scores))
|
| 516 |
+
probs = np.array([1.0 - p_high, p_high])
|
| 517 |
+
else:
|
| 518 |
+
probs = softmax(scores)
|
| 519 |
+
classes = np.asarray(model.classes_, dtype=int)
|
| 520 |
+
labels = label_encoder.inverse_transform(classes).astype(float)
|
| 521 |
+
return float(np.dot(probs, labels))
|
| 522 |
+
|
| 523 |
+
pred = np.asarray(model.predict(x_model), dtype=int)
|
| 524 |
+
return float(label_encoder.inverse_transform(pred)[0])
|
| 525 |
+
|
| 526 |
+
prediction_assets = load_prediction_preprocessors()
|
| 527 |
+
preprocessor = prediction_assets["preprocessor"]
|
| 528 |
+
feature_cols = prediction_assets["feature_cols"]
|
| 529 |
+
label_encoder_print = prediction_assets["printability_encoder"]
|
| 530 |
+
label_encoder_cell = prediction_assets["cell_response_encoder"]
|
| 531 |
+
|
| 532 |
+
sample_for_shape = {col: 0.0 for col in feature_cols}
|
| 533 |
+
sample_for_shape["Cell Line"] = CELL_LINE_OPTIONS[0]
|
| 534 |
+
preprocessed_input_dim = preprocessor.transform(pd.DataFrame([sample_for_shape])[feature_cols]).shape[1]
|
| 535 |
+
|
| 536 |
+
@st.dialog("Optimization Trials")
|
| 537 |
+
def show_trial_guidance():
|
| 538 |
+
st.markdown(
|
| 539 |
+
"""
|
| 540 |
+
The trial count controls how many candidate scaffold settings Optuna tests before choosing the best WSSQ.
|
| 541 |
+
|
| 542 |
+
**Recommended range:** 100-1000 trials.
|
| 543 |
+
|
| 544 |
+
**Default:** 300 trials, which is a balanced choice for normal use.
|
| 545 |
+
|
| 546 |
+
**Runtime impact:** running time grows roughly in proportion to the number of trials. Use 50-100 for a quick test, 300 for a balanced run, and 500-1000 when you want a more thorough search and can wait longer.
|
| 547 |
+
"""
|
| 548 |
)
|
| 549 |
|
| 550 |
+
@st.dialog("Weighted Synergistic Scaffold Quality (WSSQ)")
|
| 551 |
+
def show_wssq_guidance():
|
| 552 |
+
st.markdown(
|
| 553 |
+
"""
|
| 554 |
+
WSSQ is the optimization score used in MLATE to combine **printability** and **cell response** into one scaffold-quality objective.
|
| 555 |
+
|
| 556 |
+
In the manuscript, WSSQ was introduced to handle two practical needs: acellular 3D-printed scaffolds, where cell response is not applicable in the same way, and bioprinted scaffolds, where biological response is central to scaffold quality. Cell response is weighted strongly because it reflects explicit biological outcomes and also indirectly captures scaffold physical and mechanical properties such as pore structure, interconnectivity, elasticity, and compressive behavior.
|
| 557 |
+
|
| 558 |
+
The app normalizes printability and cell response, then combines them using two components:
|
| 559 |
+
|
| 560 |
+
- **Weighted harmonic mean:** rewards balanced high values and penalizes weak performance in either target.
|
| 561 |
+
- **Weighted multiplicative component:** captures synergy between printability and cell response.
|
| 562 |
|
| 563 |
+
The final WSSQ is scaled from 0 to 100%. If printability is 0, WSSQ is 0. If cell response is at the minimum biological-response level, the score falls back to normalized printability. Otherwise, both targets contribute according to the sidebar weights.
|
|
|
|
|
|
|
| 564 |
|
| 565 |
+
Practically, a scaffold with excellent cell response but poor printability can score lower than a scaffold with slightly lower cell response but better balance, because WSSQ is designed to favor experimentally useful, well-balanced scaffold candidates.
|
| 566 |
+
"""
|
| 567 |
+
)
|
| 568 |
+
|
| 569 |
+
@st.dialog("Model Selection Guide", width="large")
|
| 570 |
+
def show_model_selection_guidance():
|
| 571 |
+
st.markdown(
|
| 572 |
+
"""
|
| 573 |
+
Models are sorted by the merged benchmark summaries you provided, using F1 score and accuracy as the main ranking criteria. The highest-ranked available model appears first in each dropdown.
|
| 574 |
+
|
| 575 |
+
Use the top-ranked models when you want the strongest benchmarked predictive performance. If a selected model fails to load because of local package-version incompatibility, choose the next ranked model in the same task until the environment is aligned with the model artifacts.
|
| 576 |
+
"""
|
| 577 |
+
)
|
| 578 |
+
tab_print, tab_cell = st.tabs(["Printability", "Cell Response"])
|
| 579 |
+
with tab_print:
|
| 580 |
+
st.markdown(PERFORMANCE_GUIDE["printability"])
|
| 581 |
+
with st.expander("Show more"):
|
| 582 |
+
st.markdown(PERFORMANCE_GUIDE_FULL["printability"])
|
| 583 |
+
with tab_cell:
|
| 584 |
+
st.markdown(PERFORMANCE_GUIDE["cell_response"])
|
| 585 |
+
with st.expander("Show more"):
|
| 586 |
+
st.markdown(PERFORMANCE_GUIDE_FULL["cell_response"])
|
| 587 |
+
|
| 588 |
+
@st.dialog("How to Get a Gemini API Key")
|
| 589 |
+
def show_gemini_api_key_guidance():
|
| 590 |
+
st.markdown(
|
| 591 |
+
"""
|
| 592 |
+
To generate a fabrication procedure, you need a Gemini API key from Google. Creating a key only takes a minute, and Google provides a free tier.
|
| 593 |
+
|
| 594 |
+
1. Open [Google AI Studio API Keys](https://aistudio.google.com/app/apikey) and sign in with your Google/Gmail account if prompted.
|
| 595 |
+
2. If this is your first visit, accept the terms of service and continue.
|
| 596 |
+
3. Click **Get API key** or **Create API key**.
|
| 597 |
+
4. Choose an existing Google Cloud project, or select **Create API key in new project**.
|
| 598 |
+
5. Copy the generated key, return to this app, and paste it into the **Gemini API Key** box.
|
| 599 |
+
|
| 600 |
+
**Important:** Treat your API key like a password. Do not share it publicly or paste it into files that will be uploaded online. This app uses your key only for the current protocol generation request and does not save it.
|
| 601 |
+
"""
|
| 602 |
+
)
|
| 603 |
|
| 604 |
if 'bio_rows' not in st.session_state:
|
| 605 |
st.session_state.bio_rows = [{
|
|
|
|
| 628 |
# Printability is dynamically calculated and cannot be changed manually
|
| 629 |
w_print_pct = 100 - w_cell_pct
|
| 630 |
st.sidebar.number_input("Printability Weight (%)", value=w_print_pct, disabled=True, help="Auto-calculated to ensure sum is 100%")
|
| 631 |
+
if st.sidebar.button("What is WSSQ?", use_container_width=True):
|
| 632 |
+
show_wssq_guidance()
|
| 633 |
|
| 634 |
# Convert back to 0.0 - 1.0 for the mathematical formula
|
| 635 |
w_cell = w_cell_pct / 100.0
|
| 636 |
w_print = w_print_pct / 100.0
|
| 637 |
|
| 638 |
+
print_model_options = discover_model_options("printability")
|
| 639 |
+
cell_model_options = discover_model_options("cell_response")
|
| 640 |
+
|
| 641 |
+
if not print_model_options or not cell_model_options:
|
| 642 |
+
st.error("No selectable prediction models were found in the models folder.")
|
| 643 |
+
st.stop()
|
| 644 |
+
|
| 645 |
+
selected_print_model_name = st.sidebar.selectbox(
|
| 646 |
+
"Printability Model",
|
| 647 |
+
list(print_model_options.keys()),
|
| 648 |
+
key="printability_model_select",
|
| 649 |
+
)
|
| 650 |
+
selected_cell_model_name = st.sidebar.selectbox(
|
| 651 |
+
"Cell Response Model",
|
| 652 |
+
list(cell_model_options.keys()),
|
| 653 |
+
key="cell_response_model_select",
|
| 654 |
+
)
|
| 655 |
+
if st.sidebar.button("Model Selection Guide", use_container_width=True):
|
| 656 |
+
show_model_selection_guidance()
|
| 657 |
+
|
| 658 |
+
n_trials = st.sidebar.number_input(
|
| 659 |
+
"Optimization Trials",
|
| 660 |
+
min_value=10,
|
| 661 |
+
max_value=10000,
|
| 662 |
+
value=300,
|
| 663 |
+
step=50,
|
| 664 |
+
help="Number of Optuna trials used when you click Optimize WSSQ.",
|
| 665 |
+
)
|
| 666 |
+
if st.sidebar.button("Trial Count Help", use_container_width=True):
|
| 667 |
+
show_trial_guidance()
|
| 668 |
+
|
| 669 |
+
gemini_key = st.sidebar.text_input(
|
| 670 |
+
"Gemini API Key",
|
| 671 |
+
value=os.getenv("GEMINI_API_KEY", ""),
|
| 672 |
+
type="password",
|
| 673 |
+
help="Used only when generating the LLM-based fabrication procedure.",
|
| 674 |
+
)
|
| 675 |
+
if st.sidebar.button("How to Get API Key", use_container_width=True):
|
| 676 |
+
show_gemini_api_key_guidance()
|
| 677 |
+
|
| 678 |
+
gemini_model = st.sidebar.selectbox(
|
| 679 |
+
"Gemini Model",
|
| 680 |
+
GEMINI_MODELS,
|
| 681 |
+
index=0,
|
| 682 |
+
key="gemini_model_select",
|
| 683 |
+
)
|
| 684 |
+
|
| 685 |
st.title("MLATE: Machine Learning Applications in Tissue Engineering")
|
| 686 |
st.markdown(
|
| 687 |
"<p style='font-size:1.2em; color:grey;'>"
|
|
|
|
| 710 |
|
| 711 |
c1, c2, c3, c4, c5 = st.columns([2, 1, 1, 1, 0.3])
|
| 712 |
mat = c1.selectbox(
|
| 713 |
+
"Biomaterial", options,
|
| 714 |
index=options.index(row['mat']) if row['mat'] in options else 0,
|
| 715 |
+
key=f"bio_mat_{i}",
|
| 716 |
+
label_visibility="collapsed",
|
| 717 |
)
|
| 718 |
st.session_state.bio_rows[i]['mat'] = mat
|
| 719 |
|
|
|
|
| 848 |
|
| 849 |
if st.button("Optimize WSSQ"):
|
| 850 |
with st.spinner("Running Optuna…"):
|
| 851 |
+
try:
|
| 852 |
+
model_print = load_prediction_model(
|
| 853 |
+
print_model_options[selected_print_model_name],
|
| 854 |
+
"printability",
|
| 855 |
+
preprocessed_input_dim,
|
| 856 |
+
len(label_encoder_print.classes_),
|
| 857 |
+
)
|
| 858 |
+
model_cell = load_prediction_model(
|
| 859 |
+
cell_model_options[selected_cell_model_name],
|
| 860 |
+
"cell_response",
|
| 861 |
+
preprocessed_input_dim,
|
| 862 |
+
len(label_encoder_cell.classes_),
|
| 863 |
+
)
|
| 864 |
+
except Exception as exc:
|
| 865 |
+
st.error(
|
| 866 |
+
"Could not load the selected prediction model. This model will only work when the "
|
| 867 |
+
"running environment matches the saved artifact dependencies. For HistGradientBoosting, "
|
| 868 |
+
"use numpy>=2.0 in the Python environment that runs Streamlit.\n\n"
|
| 869 |
+
f"Details:\n{exc}"
|
| 870 |
+
)
|
| 871 |
+
st.stop()
|
| 872 |
+
|
| 873 |
def objective(trial):
|
| 874 |
bi_vals = {
|
| 875 |
r['mat']: trial.suggest_float(
|
|
|
|
| 896 |
|
| 897 |
feat = {**bi_vals, **pp_vals}
|
| 898 |
feat["Cell Density (cells/mL)"] = cd
|
| 899 |
+
feat["Cell Line"] = cell_line
|
|
|
|
|
|
|
|
|
|
| 900 |
|
| 901 |
+
X = pd.DataFrame([feat]).reindex(columns=feature_cols, fill_value=0.0)
|
|
|
|
|
|
|
| 902 |
|
| 903 |
+
exp_p = expected_class_value(model_print, X, preprocessor, label_encoder_print)
|
| 904 |
+
exp_c = expected_class_value(model_cell, X, preprocessor, label_encoder_cell)
|
|
|
|
|
|
|
| 905 |
|
| 906 |
np.random.seed(42)
|
| 907 |
# Use dynamic weights from the sidebar sliders
|
|
|
|
| 925 |
sampler=sampler,
|
| 926 |
pruner=optuna.pruners.MedianPruner()
|
| 927 |
)
|
| 928 |
+
study.optimize(objective, n_trials=int(n_trials))
|
| 929 |
|
| 930 |
# Store results in session state to persist after rerun
|
| 931 |
st.session_state.best_params = study.best_trial.params
|
|
|
|
| 948 |
)
|
| 949 |
|
| 950 |
if st.button("Generate Fabrication Procedure"):
|
| 951 |
+
if not gemini_key:
|
| 952 |
+
st.error("Please enter your Gemini API key in the sidebar before generating a fabrication procedure.")
|
| 953 |
+
st.stop()
|
| 954 |
+
|
| 955 |
with st.spinner("Generating rigorous fabrication procedure…"):
|
| 956 |
+
client = genai.Client(api_key=gemini_key)
|
| 957 |
|
| 958 |
formatted_params = "\n".join([
|
| 959 |
f"- {k.replace('bio__', 'Biomaterial: ').replace('pp__', 'Print Setting: ')}: {v:.2f}"
|
|
|
|
| 991 |
final_prompt += f"\n**Additional User Constraints & Inquiries (Integrate these into the protocol):**\n{user_inquiry}"
|
| 992 |
|
| 993 |
resp = client.models.generate_content(
|
| 994 |
+
model=gemini_model,
|
| 995 |
contents=final_prompt,
|
| 996 |
config=types.GenerateContentConfig(
|
| 997 |
system_instruction=(
|
|
|
|
| 1009 |
)
|
| 1010 |
|
| 1011 |
st.markdown("## Fabrication Procedure")
|
| 1012 |
+
st.markdown(resp.text)
|
catboost_printability.cbm → models/cell response/Cell_Response_1D_CNN_model.pth
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f70717cc4444f97c2e20465a4c8b9f845bdc2daf9c202940f93eead164cff4b0
|
| 3 |
+
size 1113045
|
models/cell response/Cell_Response_AdaBoost.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b48ae05ebd1292beb4fa80c174e604dcc59ec1d110ef6b10e58e52e014af34eb
|
| 3 |
+
size 209772
|
models/cell response/Cell_Response_Bagging.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a675e99d706e3a0d067f763561e07d47070784c176ee8d62aef57dc6fcce1b2b
|
| 3 |
+
size 1589916
|
cell_line_encoder.joblib → models/cell response/Cell_Response_BernoulliNB.pkl
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d255aa6a97b9eb85ba154f09059fef319931e3a68ef5f05cac63d9b96cde8304
|
| 3 |
+
size 11919
|
models/cell response/Cell_Response_CalibratedClassifierCV.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:34ef9c42687fa42a0f81b24823e4325e4b1ee8422422317492400ae6d07336ed
|
| 3 |
+
size 10412
|
models/cell response/Cell_Response_ComplementNB.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c4fc2165c356f1c0c1cfdcf9ad01dad9a552cef4706b359f49d9ccc70d4402b4
|
| 3 |
+
size 13071
|
scaler_printability.joblib → models/cell response/Cell_Response_DecisionTree.pkl
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:22469b5cc3c669706f3bd5b96379f8d26fecf478f7867f2df2cada910c1beb87
|
| 3 |
+
size 1649
|
scaler_cell_response.joblib → models/cell response/Cell_Response_DummyClassifier.pkl
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:5c2d13a951982709550ec71eebb9e0585ed02165280b8e08587b8229ca683094
|
| 3 |
+
size 639
|
models/cell response/Cell_Response_ExtraTree.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ecf6cfe975b9bae1fd67796f9754f24837f7691e99cb976bf38f3a4db9b56592
|
| 3 |
+
size 2705
|
models/cell response/Cell_Response_ExtraTrees.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:9a7989a7733d5013777e20972c8d233f1719d93b23bd33c490a36e49a1dbd7a1
|
| 3 |
+
size 793841
|
catboost_cell_response.cbm → models/cell response/Cell_Response_FT_Transformer_model.pth
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e9f9c7750f1594daaf0c36f722814b030b23bd5a12b899e2b4d912954f3761c9
|
| 3 |
+
size 45076412
|
models/cell response/Cell_Response_GaussianNB.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:835125ad7ffce8a24e8a89ac6af4e94108e69e262301e40f2aac9e0d0c872d48
|
| 3 |
+
size 11935
|
models/cell response/Cell_Response_GradientBoosting.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:06c095734b4c2ab779f369987cd8fce7dc0ae0fed22413a0879d0aa021f9f933
|
| 3 |
+
size 481962
|
models/cell response/Cell_Response_HistGradientBoosting.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d53b8bdb8a5137461c4be6f5bb7b9c60e8c3ad9376c1fda18a8edd52a7dc7c57
|
| 3 |
+
size 1010734
|
models/cell response/Cell_Response_KNeighbors.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:60c934e5877f0524bf1d13683e3ae339182a212b71f0b2017233d0ebcc4bb876
|
| 3 |
+
size 3548502
|
models/cell response/Cell_Response_LDA.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:596c41b26b585f7eb520520eec27589a990e7f0c8a6d7623423cb8d872b2eef4
|
| 3 |
+
size 9443
|
models/cell response/Cell_Response_LabelPropagation.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:136a5ca830e55a3fae9b097afc121b276294a43822f2c50c78ca755c0fbab98a
|
| 3 |
+
size 2347800
|
models/cell response/Cell_Response_LabelSpreading.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:248ea1f34e286c939f3d81b7e0a983db48b7ee88f3c08bede2729f2650143892
|
| 3 |
+
size 1223023
|
models/cell response/Cell_Response_LightGBM.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:fe1a7ac9c25508dcf5639cf64d3286e1b9f752debf16bd1875b44b5091cc0491
|
| 3 |
+
size 1552684
|
models/cell response/Cell_Response_LinearSVC.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:4dbdfc34b36b5385c39dd31bb5fdde824616bc1357661ced6704b34d802d11db
|
| 3 |
+
size 37964
|
models/cell response/Cell_Response_LogisticRegression.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e609d345c492bb68e9c9fbda8ef9b0acb73b8beebd212d515b7c23be01502f35
|
| 3 |
+
size 6447
|
models/cell response/Cell_Response_MLP.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a17c1d1e68a25074f87f836ff8726943b146ca62be9f683b6cfc487332792a9f
|
| 3 |
+
size 1244052
|
models/cell response/Cell_Response_MLP_model.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:51d34e040f5681704b3119c04b9b08881cb72b1e6c9799c39b99e7158016d4bf
|
| 3 |
+
size 1079652
|
models/cell response/Cell_Response_MultinomialNB.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:c770fa8292e9027fd90cd81196c746e294143dc0c6a2256185d640ac6a740264
|
| 3 |
+
size 11903
|
models/cell response/Cell_Response_NODE_Lite_model.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:dfea4e05557355a92e031f2329be19b5e90f19f913a30d6a5a3f33f0c879f073
|
| 3 |
+
size 38724
|
models/cell response/Cell_Response_NuSVC.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:17fe9887f6e6b3406b79b83dc20fbb9e04049de61d360c3c7c5c5492f509a233
|
| 3 |
+
size 932687
|
models/cell response/Cell_Response_PassiveAggressive.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b8113b6af5e28e93e3ce83f0a85ecac45f4dde7d543c002377493786734e47f5
|
| 3 |
+
size 22764
|
models/cell response/Cell_Response_Perceptron.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d1c0ce5c5425f9974624eeb2821dd6981a945b4d7dbd1521175ce4d2445aa14a
|
| 3 |
+
size 22748
|
models/cell response/Cell_Response_QDA.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d3d0300d01053acde77c9f0c79aa5ae385349b9f5e6666609a78a3d463f4b415
|
| 3 |
+
size 367160
|
models/cell response/Cell_Response_RadiusNeighbors.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:1bfda1acdc5fb36f1b40dc04c955c652fccc5a66f32027534dcd69e4c6635341
|
| 3 |
+
size 3479055
|
models/cell response/Cell_Response_RandomForest.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:2f3053956b46b8d0c74a52b6ac0f13aeb8ac74b56b7c2c0dd5bb872256ce883a
|
| 3 |
+
size 332673
|
models/cell response/Cell_Response_ResNet_model.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:944e1b741ee964877bab40fd94e54b9be1164677c99d4132516fad76f2a2a30f
|
| 3 |
+
size 1352549
|
models/cell response/Cell_Response_RidgeClassifier.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:37db18fde6d0e4cc43d048d12457cf16c505b81fe2e4f8e88a8a3fdb35704f12
|
| 3 |
+
size 21148
|
models/cell response/Cell_Response_SGD.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:15d2ee2711131ff81259d756689f3b2c4eed4d4aa612df08d8dfca8dfb6aa908
|
| 3 |
+
size 3987
|
models/cell response/Cell_Response_TabICL_v2.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:34f5f68afdd324c18901a6aec64662fa3049992b46f0bfafd0c4e7f33a0ecb43
|
| 3 |
+
size 3595929
|
models/cell response/Cell_Response_TabNet_Lite_model.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:a5390d355028d8c9dc10810517e8622ae24a6ec568a706b01ab63cf2d71da7e5
|
| 3 |
+
size 1973188
|
models/cell response/Cell_Response_TabPFN_2.6.joblib
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e94ae36afa55bf2d92253ab3a41fe75967e741a40c20af4cfc4f0d5be1be69e4
|
| 3 |
+
size 1212783
|
models/cell response/Cell_Response_XGBoost.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:483ecf0b6d7e3cf90ad1e31859ad5d7de77c67379c5574df79d9da823a5e96c3
|
| 3 |
+
size 1735817
|
models/preprocessors/feature_cols.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:f3a045e40d698347d8b260e980d4271c50bbe5c7dd0e14363f5d3ec734b17e8a
|
| 3 |
+
size 2841
|
models/preprocessors/label_encoder_cell_response.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:8dee86699c0433019442cd223b7bbe83c27dc5097d3942aa128c5b1eec17da59
|
| 3 |
+
size 367
|
models/preprocessors/label_encoder_printability.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ee6eddf5091c4429a1ad40759cb7cc49ff5a3acb4450f529359c058eefc0771c
|
| 3 |
+
size 359
|
models/preprocessors/preprocessor.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:d9d91db4db191c3eb411f99a5f82a12f1f044c85f4a0e7096010b1cf70a27a02
|
| 3 |
+
size 38481
|
models/printability/Printability_1D_CNN_model.pth
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:b96f399e3e548ce7f0b815f2092ede680ecbdbe96617b81f2335b0d548b0632c
|
| 3 |
+
size 5000675
|
models/printability/Printability_AdaBoost.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:6283ac39e40e3234c153a7241367781316c31c1aefa2e0501edcc17679a40efb
|
| 3 |
+
size 168308
|
models/printability/Printability_Bagging.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:58a1b12b467887c97da2d278778bce5504d203d1746b492feaa6ed0bd3c845e4
|
| 3 |
+
size 11463188
|
models/printability/Printability_BernoulliNB.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:518379522054a43fc6fe7140901e6944728b50833069a57a3ce32a1f7a3b36ab
|
| 3 |
+
size 9687
|
models/printability/Printability_CalibratedClassifierCV.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:229166fe376a8809f5618f56d85b08212c8be0d4d8047db22aeaeaec3905beeb
|
| 3 |
+
size 41268
|
models/printability/Printability_ComplementNB.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ca825ba4811afa56f0bc8e7a71230897ae16a5e562fb1cdf582d94875b69f334
|
| 3 |
+
size 10839
|