Spaces:
Running on Zero
Running on Zero
Commit ·
b19e8c7
1
Parent(s): 2e6a2a4
Fix BRCA training collapse, mobile layout and results history (#3)
Browse files- Fix mobile dashboard layout (9a10d98c1ae2d54e01852d5dd5f5a7cda0f8e577)
- Fix BRCA training collapse with lab-grid defaults (62a8628cbfa0da789c989c19608ee2c2f6bb536b)
- Add BRCA training diagnostics and lab grid results (d1ec2eed8c6cd02479da5b4234a056cb83761ab5)
- Keep the action bar visible without scrolling (bb42e347c5bc5557015683583eba1f7f6def7354)
- Scroll long result tables inside their own box (e413269a95818f6de610533927deab1f2d19ad52)
- Align Results tables and fix overlapping table headers (c5021fff6b8ddc17cd0286c07d68bc7db95e569c)
- Align the confusion matrix with the training history chart (adaf2dbccdb6e262631b7f94b561b5d2618fd8f4)
Co-authored-by: Faruk Yildirim <F4RUKYLDRM@users.noreply.huggingface.co>
- app.py +75 -43
- biolmnet/training.py +64 -19
- biolmnet/ui/styles.py +270 -8
- diagnostics/2026-10-16-brca-training-collapse/README.md +37 -0
- diagnostics/2026-10-16-brca-training-collapse/results/brca_weighted.txt +147 -0
- diagnostics/2026-10-16-brca-training-collapse/results/effective_fanin_init.txt +16 -0
- diagnostics/2026-10-16-brca-training-collapse/results/epochs_100.json +0 -0
- diagnostics/2026-10-16-brca-training-collapse/results/epochs_100.log +9 -0
- diagnostics/2026-10-16-brca-training-collapse/results/epochs_200.json +0 -0
- diagnostics/2026-10-16-brca-training-collapse/results/epochs_200.log +9 -0
- diagnostics/2026-10-16-brca-training-collapse/results/epochs_50.json +3105 -0
- diagnostics/2026-10-16-brca-training-collapse/results/epochs_50.log +9 -0
- diagnostics/2026-10-16-brca-training-collapse/results/paper_config_sgd.txt +4 -0
- diagnostics/2026-10-16-brca-training-collapse/results/seed_runs.txt +63 -0
- diagnostics/2026-10-16-brca-training-collapse/results/weight_decay_sweep.txt +7 -0
- diagnostics/2026-10-16-brca-training-collapse/scripts/diagnose.py +177 -0
- diagnostics/2026-10-16-brca-training-collapse/scripts/epochs.py +71 -0
- diagnostics/2026-10-16-brca-training-collapse/scripts/epochs_summary.py +95 -0
- diagnostics/2026-10-16-brca-training-collapse/scripts/seeds.py +44 -0
- diagnostics/2026-10-16-brca-training-collapse/scripts/sweep.py +27 -0
- diagnostics/2026-10-16-brca-training-collapse/upstream/BioLMNET.ipynb +947 -0
- diagnostics/2026-10-16-brca-training-collapse/upstream/BioLMNET_Weighted_Loss.ipynb +940 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/README.md +22 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_shard0.log +55 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_shard1.log +55 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_shard2.log +55 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_shard3.log +55 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_singlecell_seed42.jsonl +0 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_summary.txt +63 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_check_singlecell.jsonl +48 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_check_summary.txt +25 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_shard0.log +13 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_shard1.log +13 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_shard2.log +13 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_shard3.log +13 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/scripts/build_workspaces.py +30 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/scripts/grid.py +70 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/scripts/grid_summary.py +31 -0
- diagnostics/2026-10-30-lab-hyperparameter-grid/scripts/seed_check.py +62 -0
- tests/test_core.py +223 -1
app.py
CHANGED
|
@@ -34,6 +34,7 @@ from biolmnet.data import (
|
|
| 34 |
validate_and_align_omics,
|
| 35 |
)
|
| 36 |
from biolmnet.training import (
|
|
|
|
| 37 |
Hyperparameters,
|
| 38 |
ModelBundle,
|
| 39 |
pathway_importance,
|
|
@@ -44,8 +45,11 @@ from biolmnet.ui import components as ui
|
|
| 44 |
from biolmnet.ui.styles import CSS
|
| 45 |
|
| 46 |
|
|
|
|
|
|
|
|
|
|
| 47 |
GENEPT_OPTIONS = {
|
| 48 |
-
"Auto —
|
| 49 |
"Bulk · large-3 context": "embedding_original_large_3.parquet",
|
| 50 |
"Bulk · original ada-text context": "embedding_original_ada_text.parquet",
|
| 51 |
"Single-cell · cell type, tissue, drug & pathway": (
|
|
@@ -101,9 +105,8 @@ def _resolve_embedding_file(option: str, source_mode: str, example_dataset: str)
|
|
| 101 |
selected = GENEPT_OPTIONS[option]
|
| 102 |
if selected != "auto":
|
| 103 |
return selected
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
return "embedding_original_large_3.parquet"
|
| 107 |
|
| 108 |
|
| 109 |
def _graph_preview_html(mask_density: str, gene_nodes: str, pathway_units: str, genept_dim: str) -> str:
|
|
@@ -514,6 +517,14 @@ def _loss_plot(history: list[dict[str, float]]) -> go.Figure:
|
|
| 514 |
return figure
|
| 515 |
|
| 516 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 517 |
def estimate_training_duration(
|
| 518 |
workspace: PreparedWorkspace | None,
|
| 519 |
epochs: int,
|
|
@@ -651,8 +662,7 @@ def train_workspace(
|
|
| 651 |
importance = pathway_importance(bundle).head(100)
|
| 652 |
architecture_audit = _architecture_audit(bundle)
|
| 653 |
confusion_html = ui.blueprint_div(
|
| 654 |
-
|
| 655 |
-
+ ui.confusion_matrix_html(result.confusion.tolist(), bundle.label_names)
|
| 656 |
)
|
| 657 |
|
| 658 |
run_meta_update = {
|
|
@@ -949,6 +959,7 @@ def refresh_results(bundle: ModelBundle | None, run_meta: dict):
|
|
| 949 |
"Build the biological architecture, train a model, or run prediction to populate this page."
|
| 950 |
),
|
| 951 |
gr.update(visible=False),
|
|
|
|
| 952 |
)
|
| 953 |
|
| 954 |
macro_auc = run_meta.get("macro_auc")
|
|
@@ -965,7 +976,8 @@ def refresh_results(bundle: ModelBundle | None, run_meta: dict):
|
|
| 965 |
)
|
| 966 |
+ "</div>"
|
| 967 |
)
|
| 968 |
-
|
|
|
|
| 969 |
|
| 970 |
|
| 971 |
THEME = gr.themes.Base(primary_hue="gray", neutral_hue="gray")
|
|
@@ -986,18 +998,19 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 986 |
session_id_state = gr.State("")
|
| 987 |
intro_step_state = gr.State(0)
|
| 988 |
intro_dismissed_state = gr.BrowserState(False, storage_key="biolmnet_intro_dismissed")
|
|
|
|
| 989 |
|
| 990 |
with gr.Row(elem_classes=["app-shell"]):
|
| 991 |
with gr.Column(elem_classes=["rail-col"]):
|
| 992 |
with gr.Column(elem_classes=["rail"]):
|
| 993 |
-
gr.HTML(ui.brand_block_html())
|
| 994 |
rail_row_htmls = []
|
| 995 |
rail_row_buttons = []
|
| 996 |
with gr.Column(elem_classes=["rail-nav"]):
|
| 997 |
for index, label in enumerate(STAGE_LABELS):
|
| 998 |
with gr.Column(elem_classes=["rail-row-wrap"]):
|
| 999 |
row_html = gr.HTML(ui.rail_row_html(index + 1, label, "on" if index == 0 else "off", "Active" if index == 0 else "Locked"))
|
| 1000 |
-
row_button = gr.Button("", elem_classes=["rail-row-click"])
|
| 1001 |
rail_row_htmls.append(row_html)
|
| 1002 |
rail_row_buttons.append(row_button)
|
| 1003 |
with gr.Column(elem_classes=["rail-spacer", "rail-plate-wrap"]):
|
|
@@ -1011,7 +1024,7 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1011 |
intro_open_button = gr.Button("Introduction", size="sm", variant="secondary", elem_classes=["btn-ghost", "intro-open-btn"])
|
| 1012 |
|
| 1013 |
# ── Data & Priors ──────────────────────────────────────���─
|
| 1014 |
-
with gr.Column(visible=True) as data_page:
|
| 1015 |
with gr.Row(elem_classes=["pghd"]):
|
| 1016 |
gr.HTML(
|
| 1017 |
ui.title_block_html(
|
|
@@ -1028,7 +1041,7 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1028 |
source_mode = gr.Radio(
|
| 1029 |
["BioLM-NET examples", "GitHub folder", "Upload files"],
|
| 1030 |
value="BioLM-NET examples", show_label=False, container=False,
|
| 1031 |
-
elem_classes=["seg-radio"],
|
| 1032 |
)
|
| 1033 |
with gr.Row(elem_classes=["srow-row", "first"]):
|
| 1034 |
with gr.Column(scale=1, min_width=0):
|
|
@@ -1038,7 +1051,7 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1038 |
gr.HTML('<div class="field-label">Repository dataset</div>')
|
| 1039 |
example_dataset = gr.Dropdown(
|
| 1040 |
["BRCA", "COAD", "GBM", "scTrioseq2"], value="BRCA",
|
| 1041 |
-
show_label=False, container=False,
|
| 1042 |
)
|
| 1043 |
with gr.Column(visible=False) as github_group:
|
| 1044 |
github_folder = gr.Textbox(
|
|
@@ -1056,7 +1069,7 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1056 |
uploaded_dna_pathway = gr.File(label="DNA → pathway mapping", file_types=[".csv"], type="filepath", elem_classes=["file-slot"])
|
| 1057 |
|
| 1058 |
gr.HTML('<div class="mono sect sect-spaced">Resolved files</div>')
|
| 1059 |
-
resolved_files_table = gr.Dataframe(
|
| 1060 |
headers=["File", "Shape", "Rows matched", "Status"], interactive=False, wrap=False,
|
| 1061 |
value=pd.DataFrame(),
|
| 1062 |
)
|
|
@@ -1134,8 +1147,8 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1134 |
graph_preview = gr.HTML(_graph_preview_html("—", "—", "—", "—"))
|
| 1135 |
|
| 1136 |
with gr.Row(visible=False):
|
| 1137 |
-
architecture_table = gr.Dataframe(interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1138 |
-
enrichment_table = gr.Dataframe(interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1139 |
|
| 1140 |
with gr.Row(elem_classes=["actbar-row"]):
|
| 1141 |
data_actionbar_note = gr.HTML(f'<div class="actbar-note">{ui.esc("Choose a source, then build the biological architecture.")}</div>')
|
|
@@ -1144,12 +1157,13 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1144 |
"Re-validate inputs", size="sm", variant="secondary", elem_classes=["actbar-secondary-btn"]
|
| 1145 |
)
|
| 1146 |
prepare_button = gr.Button(
|
| 1147 |
-
"Build biological architecture", size="sm", variant="primary",
|
|
|
|
| 1148 |
)
|
| 1149 |
preparation_status = gr.HTML(visible=False)
|
| 1150 |
|
| 1151 |
# ── Train Model ──────────────────────────────────────────
|
| 1152 |
-
with gr.Column(visible=False) as train_page:
|
| 1153 |
with gr.Row(elem_classes=["pghd"]):
|
| 1154 |
gr.HTML(
|
| 1155 |
ui.title_block_html(
|
|
@@ -1165,22 +1179,22 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1165 |
with gr.Column(min_width=140):
|
| 1166 |
gr.HTML(ui.esc("Epochs"))
|
| 1167 |
with gr.Column():
|
| 1168 |
-
epochs = gr.Slider(5, 200, value=
|
| 1169 |
with gr.Row(elem_classes=["srow-row"]):
|
| 1170 |
with gr.Column(min_width=140):
|
| 1171 |
gr.HTML(ui.esc("Batch size"))
|
| 1172 |
with gr.Column():
|
| 1173 |
-
batch_size = gr.Dropdown([8, 16, 32, 64, 128], value=
|
| 1174 |
with gr.Row(elem_classes=["srow-row"]):
|
| 1175 |
with gr.Column(min_width=140):
|
| 1176 |
gr.HTML(ui.esc("Learning rate"))
|
| 1177 |
with gr.Column():
|
| 1178 |
-
learning_rate = gr.Number(value=
|
| 1179 |
with gr.Row(elem_classes=["srow-row"]):
|
| 1180 |
with gr.Column(min_width=140):
|
| 1181 |
gr.HTML(ui.esc("L2 weight decay"))
|
| 1182 |
with gr.Column():
|
| 1183 |
-
weight_decay = gr.Number(value=
|
| 1184 |
with gr.Row(elem_classes=["srow-row", "last"]):
|
| 1185 |
with gr.Column(min_width=140):
|
| 1186 |
gr.HTML(ui.esc("Dropout"))
|
|
@@ -1202,7 +1216,13 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1202 |
with gr.Column(min_width=140):
|
| 1203 |
gr.HTML(ui.esc("Validation fraction"))
|
| 1204 |
with gr.Column():
|
| 1205 |
-
validation_fraction = gr.Slider(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1206 |
with gr.Row(elem_classes=["srow-row"]):
|
| 1207 |
with gr.Column(min_width=140):
|
| 1208 |
gr.HTML(ui.esc("Optimizer"))
|
|
@@ -1221,11 +1241,16 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1221 |
gr.HTML('<div class="mono" style="margin-bottom:9px">Training result</div>')
|
| 1222 |
training_status = gr.HTML(_status("Prepare the architecture before training."))
|
| 1223 |
loss_plot = gr.Plot(label="Loss by epoch", show_label=False)
|
| 1224 |
-
gr.HTML('<div class="mono" style="margin:20px 0 9px">
|
| 1225 |
gr.HTML(
|
| 1226 |
"".join(
|
| 1227 |
[
|
| 1228 |
ui.kv_plain_row("First layer", "trainable W ⊙ M"),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1229 |
ui.kv_plain_row("PDI weights", "binary"),
|
| 1230 |
ui.kv_plain_row("PPI weights", "STRING norm."),
|
| 1231 |
ui.kv_plain_row("Attention", "GenePT query"),
|
|
@@ -1238,11 +1263,12 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1238 |
train_actionbar_note = gr.HTML('<div class="actbar-note">Set hyperparameters, then train.</div>')
|
| 1239 |
with gr.Row(elem_classes=["actbar-buttons"]):
|
| 1240 |
train_button = gr.Button(
|
| 1241 |
-
"Train BioLM-NET on ZeroGPU", size="sm", variant="primary",
|
|
|
|
| 1242 |
)
|
| 1243 |
|
| 1244 |
# ── Export Artifacts ───────────────────────���─────────────
|
| 1245 |
-
with gr.Column(visible=False) as export_page:
|
| 1246 |
with gr.Row(elem_classes=["pghd"]):
|
| 1247 |
gr.HTML(
|
| 1248 |
ui.title_block_html(
|
|
@@ -1270,7 +1296,7 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1270 |
gr.HTML('<div class="actbar-note">Bundle written to a temp file on export · not persisted between Space restarts</div>')
|
| 1271 |
|
| 1272 |
# ── Predict ──────────────────────────────────────────────
|
| 1273 |
-
with gr.Column(visible=False) as predict_page:
|
| 1274 |
with gr.Row(elem_classes=["pghd"]):
|
| 1275 |
gr.HTML(
|
| 1276 |
ui.title_block_html(
|
|
@@ -1326,7 +1352,7 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1326 |
with gr.Column(scale=6, min_width=0):
|
| 1327 |
gr.HTML('<div class="mono" style="margin-bottom:9px">Predictions · last successful run</div>')
|
| 1328 |
distribution_panel = gr.HTML(ui.empty_note_html("No predictions yet."))
|
| 1329 |
-
prediction_table = gr.Dataframe(interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1330 |
prediction_download = gr.File(label="Prediction CSV", interactive=False, elem_classes=["file-slot", "btn-block"])
|
| 1331 |
|
| 1332 |
with gr.Row(elem_classes=["actbar-row"]):
|
|
@@ -1334,12 +1360,12 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1334 |
with gr.Row(elem_classes=["actbar-buttons"]):
|
| 1335 |
predict_button = gr.Button(
|
| 1336 |
"Run inference", size="sm", variant="primary", interactive=False,
|
| 1337 |
-
elem_classes=["actbar-primary-btn"],
|
| 1338 |
)
|
| 1339 |
prediction_status = gr.HTML(visible=False)
|
| 1340 |
|
| 1341 |
# ── Results ──────────────────────────────────────────────
|
| 1342 |
-
with gr.Column(visible=False) as results_page:
|
| 1343 |
with gr.Row(elem_classes=["pghd"]):
|
| 1344 |
gr.HTML(
|
| 1345 |
ui.title_block_html(
|
|
@@ -1351,21 +1377,27 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1351 |
results_empty_note = gr.HTML(ui.empty_note_html("Build the biological architecture, train a model, or run prediction to populate this page."))
|
| 1352 |
with gr.Row(elem_classes=["results-stat-row"], visible=False) as results_stats_row:
|
| 1353 |
results_stats = gr.HTML("")
|
| 1354 |
-
|
| 1355 |
-
|
| 1356 |
-
|
| 1357 |
-
|
| 1358 |
-
|
| 1359 |
-
|
| 1360 |
-
|
| 1361 |
-
|
| 1362 |
-
|
| 1363 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1364 |
with gr.Column(visible=False) as results_tables_bottom:
|
| 1365 |
gr.HTML('<div class="mono sect sect-spaced">Validation predictions</div>')
|
| 1366 |
-
results_validation_table = gr.Dataframe(interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1367 |
gr.HTML('<div class="mono sect sect-spaced">Predictions and class probabilities</div>')
|
| 1368 |
-
results_prediction_table = gr.Dataframe(interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1369 |
with gr.Row(elem_classes=["actbar-row"]):
|
| 1370 |
gr.HTML(
|
| 1371 |
'<div class="actbar-note">Validate cohorts, preprocessing and performance before '
|
|
@@ -1642,7 +1674,7 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1642 |
).then(
|
| 1643 |
refresh_results,
|
| 1644 |
inputs=[model_state, run_meta_state],
|
| 1645 |
-
outputs=[results_stats, results_stats_row, results_empty_note, results_content],
|
| 1646 |
show_progress="hidden",
|
| 1647 |
).then(
|
| 1648 |
lambda df: gr.update(value=df), inputs=[validation_predictions_state], outputs=[results_validation_table],
|
|
@@ -1718,7 +1750,7 @@ with gr.Blocks(title="BioLM-NET Workbench", fill_width=True) as demo:
|
|
| 1718 |
show_progress="hidden",
|
| 1719 |
).then(
|
| 1720 |
refresh_results, inputs=[model_state, run_meta_state],
|
| 1721 |
-
outputs=[results_stats, results_stats_row, results_empty_note, results_content],
|
| 1722 |
show_progress="hidden",
|
| 1723 |
)
|
| 1724 |
|
|
|
|
| 34 |
validate_and_align_omics,
|
| 35 |
)
|
| 36 |
from biolmnet.training import (
|
| 37 |
+
DEFAULT_VALIDATION_FRACTION,
|
| 38 |
Hyperparameters,
|
| 39 |
ModelBundle,
|
| 40 |
pathway_importance,
|
|
|
|
| 45 |
from biolmnet.ui.styles import CSS
|
| 46 |
|
| 47 |
|
| 48 |
+
# Long result tables scroll inside a box of this height (px) instead of stretching the page.
|
| 49 |
+
TABLE_MAX_HEIGHT = 320
|
| 50 |
+
|
| 51 |
GENEPT_OPTIONS = {
|
| 52 |
+
"Auto — lab-recommended single-cell context": "auto",
|
| 53 |
"Bulk · large-3 context": "embedding_original_large_3.parquet",
|
| 54 |
"Bulk · original ada-text context": "embedding_original_ada_text.parquet",
|
| 55 |
"Single-cell · cell type, tissue, drug & pathway": (
|
|
|
|
| 105 |
selected = GENEPT_OPTIONS[option]
|
| 106 |
if selected != "auto":
|
| 107 |
return selected
|
| 108 |
+
# Bozdag Lab recommendation (J. Rifat, 2026-10-17) for every source.
|
| 109 |
+
return "embedding_associations_cell_type_tissue_drug_pathway_openai_large.parquet"
|
|
|
|
| 110 |
|
| 111 |
|
| 112 |
def _graph_preview_html(mask_density: str, gene_nodes: str, pathway_units: str, genept_dim: str) -> str:
|
|
|
|
| 517 |
return figure
|
| 518 |
|
| 519 |
|
| 520 |
+
def _validation_split_note(validation_fraction: float) -> str:
|
| 521 |
+
validation_percent = round(float(validation_fraction) * 100)
|
| 522 |
+
return (
|
| 523 |
+
f'<div class="field-hint">{validation_percent}% of samples are held out for validation '
|
| 524 |
+
f"(stratified by class). The remaining {100 - validation_percent}% are used for training.</div>"
|
| 525 |
+
)
|
| 526 |
+
|
| 527 |
+
|
| 528 |
def estimate_training_duration(
|
| 529 |
workspace: PreparedWorkspace | None,
|
| 530 |
epochs: int,
|
|
|
|
| 662 |
importance = pathway_importance(bundle).head(100)
|
| 663 |
architecture_audit = _architecture_audit(bundle)
|
| 664 |
confusion_html = ui.blueprint_div(
|
| 665 |
+
ui.confusion_matrix_html(result.confusion.tolist(), bundle.label_names)
|
|
|
|
| 666 |
)
|
| 667 |
|
| 668 |
run_meta_update = {
|
|
|
|
| 959 |
"Build the biological architecture, train a model, or run prediction to populate this page."
|
| 960 |
),
|
| 961 |
gr.update(visible=False),
|
| 962 |
+
None,
|
| 963 |
)
|
| 964 |
|
| 965 |
macro_auc = run_meta.get("macro_auc")
|
|
|
|
| 976 |
)
|
| 977 |
+ "</div>"
|
| 978 |
)
|
| 979 |
+
loss_figure = _loss_plot(bundle.history) if bundle.history else None
|
| 980 |
+
return stats, gr.update(visible=True), "", gr.update(visible=True), loss_figure
|
| 981 |
|
| 982 |
|
| 983 |
THEME = gr.themes.Base(primary_hue="gray", neutral_hue="gray")
|
|
|
|
| 998 |
session_id_state = gr.State("")
|
| 999 |
intro_step_state = gr.State(0)
|
| 1000 |
intro_dismissed_state = gr.BrowserState(False, storage_key="biolmnet_intro_dismissed")
|
| 1001 |
+
nav_ids = ["nav-data", "nav-train", "nav-export", "nav-predict", "nav-results"]
|
| 1002 |
|
| 1003 |
with gr.Row(elem_classes=["app-shell"]):
|
| 1004 |
with gr.Column(elem_classes=["rail-col"]):
|
| 1005 |
with gr.Column(elem_classes=["rail"]):
|
| 1006 |
+
gr.HTML(ui.brand_block_html(), elem_id="app-header")
|
| 1007 |
rail_row_htmls = []
|
| 1008 |
rail_row_buttons = []
|
| 1009 |
with gr.Column(elem_classes=["rail-nav"]):
|
| 1010 |
for index, label in enumerate(STAGE_LABELS):
|
| 1011 |
with gr.Column(elem_classes=["rail-row-wrap"]):
|
| 1012 |
row_html = gr.HTML(ui.rail_row_html(index + 1, label, "on" if index == 0 else "off", "Active" if index == 0 else "Locked"))
|
| 1013 |
+
row_button = gr.Button("", elem_id=nav_ids[index], elem_classes=["rail-row-click"])
|
| 1014 |
rail_row_htmls.append(row_html)
|
| 1015 |
rail_row_buttons.append(row_button)
|
| 1016 |
with gr.Column(elem_classes=["rail-spacer", "rail-plate-wrap"]):
|
|
|
|
| 1024 |
intro_open_button = gr.Button("Introduction", size="sm", variant="secondary", elem_classes=["btn-ghost", "intro-open-btn"])
|
| 1025 |
|
| 1026 |
# ── Data & Priors ──────────────────────────────────────���─
|
| 1027 |
+
with gr.Column(visible=True, elem_id="page-data", elem_classes=["workspace-page", "data-workspace-page"]) as data_page:
|
| 1028 |
with gr.Row(elem_classes=["pghd"]):
|
| 1029 |
gr.HTML(
|
| 1030 |
ui.title_block_html(
|
|
|
|
| 1041 |
source_mode = gr.Radio(
|
| 1042 |
["BioLM-NET examples", "GitHub folder", "Upload files"],
|
| 1043 |
value="BioLM-NET examples", show_label=False, container=False,
|
| 1044 |
+
elem_id="dataset-source", elem_classes=["seg-radio"],
|
| 1045 |
)
|
| 1046 |
with gr.Row(elem_classes=["srow-row", "first"]):
|
| 1047 |
with gr.Column(scale=1, min_width=0):
|
|
|
|
| 1051 |
gr.HTML('<div class="field-label">Repository dataset</div>')
|
| 1052 |
example_dataset = gr.Dropdown(
|
| 1053 |
["BRCA", "COAD", "GBM", "scTrioseq2"], value="BRCA",
|
| 1054 |
+
show_label=False, container=False, elem_id="dataset-select",
|
| 1055 |
)
|
| 1056 |
with gr.Column(visible=False) as github_group:
|
| 1057 |
github_folder = gr.Textbox(
|
|
|
|
| 1069 |
uploaded_dna_pathway = gr.File(label="DNA → pathway mapping", file_types=[".csv"], type="filepath", elem_classes=["file-slot"])
|
| 1070 |
|
| 1071 |
gr.HTML('<div class="mono sect sect-spaced">Resolved files</div>')
|
| 1072 |
+
resolved_files_table = gr.Dataframe(max_height=TABLE_MAX_HEIGHT,
|
| 1073 |
headers=["File", "Shape", "Rows matched", "Status"], interactive=False, wrap=False,
|
| 1074 |
value=pd.DataFrame(),
|
| 1075 |
)
|
|
|
|
| 1147 |
graph_preview = gr.HTML(_graph_preview_html("—", "—", "—", "—"))
|
| 1148 |
|
| 1149 |
with gr.Row(visible=False):
|
| 1150 |
+
architecture_table = gr.Dataframe(max_height=TABLE_MAX_HEIGHT, interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1151 |
+
enrichment_table = gr.Dataframe(max_height=TABLE_MAX_HEIGHT, interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1152 |
|
| 1153 |
with gr.Row(elem_classes=["actbar-row"]):
|
| 1154 |
data_actionbar_note = gr.HTML(f'<div class="actbar-note">{ui.esc("Choose a source, then build the biological architecture.")}</div>')
|
|
|
|
| 1157 |
"Re-validate inputs", size="sm", variant="secondary", elem_classes=["actbar-secondary-btn"]
|
| 1158 |
)
|
| 1159 |
prepare_button = gr.Button(
|
| 1160 |
+
"Build biological architecture", size="sm", variant="primary",
|
| 1161 |
+
elem_id="build-architecture-btn", elem_classes=["actbar-primary-btn"]
|
| 1162 |
)
|
| 1163 |
preparation_status = gr.HTML(visible=False)
|
| 1164 |
|
| 1165 |
# ── Train Model ──────────────────────────────────────────
|
| 1166 |
+
with gr.Column(visible=False, elem_id="page-train", elem_classes=["workspace-page"]) as train_page:
|
| 1167 |
with gr.Row(elem_classes=["pghd"]):
|
| 1168 |
gr.HTML(
|
| 1169 |
ui.title_block_html(
|
|
|
|
| 1179 |
with gr.Column(min_width=140):
|
| 1180 |
gr.HTML(ui.esc("Epochs"))
|
| 1181 |
with gr.Column():
|
| 1182 |
+
epochs = gr.Slider(5, 200, value=Hyperparameters.epochs, step=5, show_label=False, container=False)
|
| 1183 |
with gr.Row(elem_classes=["srow-row"]):
|
| 1184 |
with gr.Column(min_width=140):
|
| 1185 |
gr.HTML(ui.esc("Batch size"))
|
| 1186 |
with gr.Column():
|
| 1187 |
+
batch_size = gr.Dropdown([8, 16, 32, 64, 128], value=Hyperparameters.batch_size, show_label=False, container=False)
|
| 1188 |
with gr.Row(elem_classes=["srow-row"]):
|
| 1189 |
with gr.Column(min_width=140):
|
| 1190 |
gr.HTML(ui.esc("Learning rate"))
|
| 1191 |
with gr.Column():
|
| 1192 |
+
learning_rate = gr.Number(value=Hyperparameters.learning_rate, minimum=0.000001, show_label=False, container=False)
|
| 1193 |
with gr.Row(elem_classes=["srow-row"]):
|
| 1194 |
with gr.Column(min_width=140):
|
| 1195 |
gr.HTML(ui.esc("L2 weight decay"))
|
| 1196 |
with gr.Column():
|
| 1197 |
+
weight_decay = gr.Number(value=Hyperparameters.weight_decay, minimum=0, show_label=False, container=False)
|
| 1198 |
with gr.Row(elem_classes=["srow-row", "last"]):
|
| 1199 |
with gr.Column(min_width=140):
|
| 1200 |
gr.HTML(ui.esc("Dropout"))
|
|
|
|
| 1216 |
with gr.Column(min_width=140):
|
| 1217 |
gr.HTML(ui.esc("Validation fraction"))
|
| 1218 |
with gr.Column():
|
| 1219 |
+
validation_fraction = gr.Slider(
|
| 1220 |
+
0.1, 0.4, value=DEFAULT_VALIDATION_FRACTION, step=0.05, show_label=False, container=False
|
| 1221 |
+
)
|
| 1222 |
+
validation_split_note = gr.HTML(_validation_split_note(DEFAULT_VALIDATION_FRACTION))
|
| 1223 |
+
validation_fraction.change(
|
| 1224 |
+
_validation_split_note, inputs=[validation_fraction], outputs=[validation_split_note]
|
| 1225 |
+
)
|
| 1226 |
with gr.Row(elem_classes=["srow-row"]):
|
| 1227 |
with gr.Column(min_width=140):
|
| 1228 |
gr.HTML(ui.esc("Optimizer"))
|
|
|
|
| 1241 |
gr.HTML('<div class="mono" style="margin-bottom:9px">Training result</div>')
|
| 1242 |
training_status = gr.HTML(_status("Prepare the architecture before training."))
|
| 1243 |
loss_plot = gr.Plot(label="Loss by epoch", show_label=False)
|
| 1244 |
+
gr.HTML('<div class="mono" style="margin:20px 0 9px">Architecture defaults</div>')
|
| 1245 |
gr.HTML(
|
| 1246 |
"".join(
|
| 1247 |
[
|
| 1248 |
ui.kv_plain_row("First layer", "trainable W ⊙ M"),
|
| 1249 |
+
ui.kv_plain_row(
|
| 1250 |
+
"Activations",
|
| 1251 |
+
f"{Hyperparameters.biological_activation} / {Hyperparameters.projection_activation} / "
|
| 1252 |
+
f"{Hyperparameters.fusion_activation}",
|
| 1253 |
+
),
|
| 1254 |
ui.kv_plain_row("PDI weights", "binary"),
|
| 1255 |
ui.kv_plain_row("PPI weights", "STRING norm."),
|
| 1256 |
ui.kv_plain_row("Attention", "GenePT query"),
|
|
|
|
| 1263 |
train_actionbar_note = gr.HTML('<div class="actbar-note">Set hyperparameters, then train.</div>')
|
| 1264 |
with gr.Row(elem_classes=["actbar-buttons"]):
|
| 1265 |
train_button = gr.Button(
|
| 1266 |
+
"Train BioLM-NET on ZeroGPU", size="sm", variant="primary",
|
| 1267 |
+
elem_id="train-btn", elem_classes=["actbar-primary-btn"]
|
| 1268 |
)
|
| 1269 |
|
| 1270 |
# ── Export Artifacts ───────────────────────���─────────────
|
| 1271 |
+
with gr.Column(visible=False, elem_id="page-export", elem_classes=["workspace-page"]) as export_page:
|
| 1272 |
with gr.Row(elem_classes=["pghd"]):
|
| 1273 |
gr.HTML(
|
| 1274 |
ui.title_block_html(
|
|
|
|
| 1296 |
gr.HTML('<div class="actbar-note">Bundle written to a temp file on export · not persisted between Space restarts</div>')
|
| 1297 |
|
| 1298 |
# ── Predict ──────────────────────────────────────────────
|
| 1299 |
+
with gr.Column(visible=False, elem_id="page-predict", elem_classes=["workspace-page"]) as predict_page:
|
| 1300 |
with gr.Row(elem_classes=["pghd"]):
|
| 1301 |
gr.HTML(
|
| 1302 |
ui.title_block_html(
|
|
|
|
| 1352 |
with gr.Column(scale=6, min_width=0):
|
| 1353 |
gr.HTML('<div class="mono" style="margin-bottom:9px">Predictions · last successful run</div>')
|
| 1354 |
distribution_panel = gr.HTML(ui.empty_note_html("No predictions yet."))
|
| 1355 |
+
prediction_table = gr.Dataframe(max_height=TABLE_MAX_HEIGHT, interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1356 |
prediction_download = gr.File(label="Prediction CSV", interactive=False, elem_classes=["file-slot", "btn-block"])
|
| 1357 |
|
| 1358 |
with gr.Row(elem_classes=["actbar-row"]):
|
|
|
|
| 1360 |
with gr.Row(elem_classes=["actbar-buttons"]):
|
| 1361 |
predict_button = gr.Button(
|
| 1362 |
"Run inference", size="sm", variant="primary", interactive=False,
|
| 1363 |
+
elem_id="predict-btn", elem_classes=["actbar-primary-btn"],
|
| 1364 |
)
|
| 1365 |
prediction_status = gr.HTML(visible=False)
|
| 1366 |
|
| 1367 |
# ── Results ──────────────────────────────────────────────
|
| 1368 |
+
with gr.Column(visible=False, elem_id="page-results", elem_classes=["workspace-page"]) as results_page:
|
| 1369 |
with gr.Row(elem_classes=["pghd"]):
|
| 1370 |
gr.HTML(
|
| 1371 |
ui.title_block_html(
|
|
|
|
| 1377 |
results_empty_note = gr.HTML(ui.empty_note_html("Build the biological architecture, train a model, or run prediction to populate this page."))
|
| 1378 |
with gr.Row(elem_classes=["results-stat-row"], visible=False) as results_stats_row:
|
| 1379 |
results_stats = gr.HTML("")
|
| 1380 |
+
# Two rows so the side-by-side panels in each row start at the same height.
|
| 1381 |
+
with gr.Column(visible=False) as results_content:
|
| 1382 |
+
with gr.Row(elem_classes=["results-grid"], equal_height=False):
|
| 1383 |
+
with gr.Column(scale=6, min_width=0):
|
| 1384 |
+
gr.HTML('<div class="mono sect">Training history</div>')
|
| 1385 |
+
results_loss_plot = gr.Plot(show_label=False)
|
| 1386 |
+
with gr.Column(scale=6, min_width=0):
|
| 1387 |
+
gr.HTML('<div class="mono sect">Confusion matrix · validation split</div>')
|
| 1388 |
+
results_confusion = gr.HTML("")
|
| 1389 |
+
with gr.Row(elem_classes=["results-grid"], equal_height=False):
|
| 1390 |
+
with gr.Column(scale=6, min_width=0):
|
| 1391 |
+
gr.HTML('<div class="mono sect">Sparse architecture audit</div>')
|
| 1392 |
+
results_architecture_table = gr.Dataframe(max_height=TABLE_MAX_HEIGHT, interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1393 |
+
with gr.Column(scale=6, min_width=0):
|
| 1394 |
+
gr.HTML('<div class="mono sect">Pathway attention · top retained</div>')
|
| 1395 |
+
results_pathway_table = gr.Dataframe(max_height=TABLE_MAX_HEIGHT, interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1396 |
with gr.Column(visible=False) as results_tables_bottom:
|
| 1397 |
gr.HTML('<div class="mono sect sect-spaced">Validation predictions</div>')
|
| 1398 |
+
results_validation_table = gr.Dataframe(max_height=TABLE_MAX_HEIGHT, interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1399 |
gr.HTML('<div class="mono sect sect-spaced">Predictions and class probabilities</div>')
|
| 1400 |
+
results_prediction_table = gr.Dataframe(max_height=TABLE_MAX_HEIGHT, interactive=False, wrap=False, value=pd.DataFrame(), headers=[""], column_count=(1, "dynamic"))
|
| 1401 |
with gr.Row(elem_classes=["actbar-row"]):
|
| 1402 |
gr.HTML(
|
| 1403 |
'<div class="actbar-note">Validate cohorts, preprocessing and performance before '
|
|
|
|
| 1674 |
).then(
|
| 1675 |
refresh_results,
|
| 1676 |
inputs=[model_state, run_meta_state],
|
| 1677 |
+
outputs=[results_stats, results_stats_row, results_empty_note, results_content, results_loss_plot],
|
| 1678 |
show_progress="hidden",
|
| 1679 |
).then(
|
| 1680 |
lambda df: gr.update(value=df), inputs=[validation_predictions_state], outputs=[results_validation_table],
|
|
|
|
| 1750 |
show_progress="hidden",
|
| 1751 |
).then(
|
| 1752 |
refresh_results, inputs=[model_state, run_meta_state],
|
| 1753 |
+
outputs=[results_stats, results_stats_row, results_empty_note, results_content, results_loss_plot],
|
| 1754 |
show_progress="hidden",
|
| 1755 |
)
|
| 1756 |
|
biolmnet/training.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import copy
|
|
|
|
| 4 |
import random
|
| 5 |
from dataclasses import asdict, dataclass
|
| 6 |
from typing import Callable
|
|
@@ -25,21 +26,36 @@ from .model import BioLMNet
|
|
| 25 |
|
| 26 |
ProgressCallback = Callable[[float, str], None]
|
| 27 |
|
|
|
|
|
|
|
|
|
|
| 28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 29 |
@dataclass(frozen=True)
|
| 30 |
class Hyperparameters:
|
| 31 |
-
epochs: int =
|
| 32 |
-
batch_size: int =
|
| 33 |
-
learning_rate: float = 0.
|
| 34 |
weight_decay: float = 0.01
|
| 35 |
dropout: float = 0.3
|
| 36 |
projection_dim: int = 64
|
| 37 |
fusion_dim: int = 12
|
| 38 |
-
validation_fraction: float =
|
| 39 |
optimizer: str = "Adam"
|
| 40 |
class_weighting: bool = True
|
| 41 |
early_stopping_patience: int = 12
|
| 42 |
seed: int = 42
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
def validate(self) -> None:
|
| 45 |
if not 1 <= self.epochs <= 1000:
|
|
@@ -54,6 +70,11 @@ class Hyperparameters:
|
|
| 54 |
raise ValueError("Validation fraction must be between 0.05 and 0.5.")
|
| 55 |
if self.optimizer.lower() not in {"adam", "sgd"}:
|
| 56 |
raise ValueError("Optimizer must be Adam or SGD.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
|
| 59 |
@dataclass
|
|
@@ -86,6 +107,36 @@ def set_reproducible_seed(seed: int) -> None:
|
|
| 86 |
torch.cuda.manual_seed_all(seed)
|
| 87 |
|
| 88 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
def _fit_scaler(values: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
|
| 90 |
mean = values.mean(axis=0, dtype=np.float64).astype(np.float32)
|
| 91 |
scale = values.std(axis=0, dtype=np.float64).astype(np.float32)
|
|
@@ -121,6 +172,9 @@ def _make_model(
|
|
| 121 |
projection_dim=hyperparameters.projection_dim,
|
| 122 |
fusion_dim=hyperparameters.fusion_dim,
|
| 123 |
dropout=hyperparameters.dropout,
|
|
|
|
|
|
|
|
|
|
| 124 |
)
|
| 125 |
|
| 126 |
|
|
@@ -153,18 +207,8 @@ def train(
|
|
| 153 |
hyperparameters.validate()
|
| 154 |
set_reproducible_seed(hyperparameters.seed)
|
| 155 |
labels = workspace.labels
|
| 156 |
-
|
| 157 |
-
|
| 158 |
-
raise ValueError(
|
| 159 |
-
"Each class needs at least two samples for a stratified train/validation split."
|
| 160 |
-
)
|
| 161 |
-
|
| 162 |
-
indices = np.arange(len(labels))
|
| 163 |
-
train_index, validation_index = train_test_split(
|
| 164 |
-
indices,
|
| 165 |
-
test_size=hyperparameters.validation_fraction,
|
| 166 |
-
random_state=hyperparameters.seed,
|
| 167 |
-
stratify=labels,
|
| 168 |
)
|
| 169 |
gene_mean, gene_scale = _fit_scaler(
|
| 170 |
workspace.gene_expression[train_index]
|
|
@@ -204,6 +248,7 @@ def train(
|
|
| 204 |
optimizer = torch.optim.SGD(
|
| 205 |
model.parameters(),
|
| 206 |
lr=hyperparameters.learning_rate,
|
|
|
|
| 207 |
weight_decay=hyperparameters.weight_decay,
|
| 208 |
)
|
| 209 |
else:
|
|
@@ -357,9 +402,9 @@ def train(
|
|
| 357 |
"projection_dim": hyperparameters.projection_dim,
|
| 358 |
"fusion_dim": hyperparameters.fusion_dim,
|
| 359 |
"dropout": hyperparameters.dropout,
|
| 360 |
-
"biological_activation":
|
| 361 |
-
"projection_activation":
|
| 362 |
-
"fusion_activation":
|
| 363 |
},
|
| 364 |
}
|
| 365 |
bundle = ModelBundle(
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import copy
|
| 4 |
+
import math
|
| 5 |
import random
|
| 6 |
from dataclasses import asdict, dataclass
|
| 7 |
from typing import Callable
|
|
|
|
| 26 |
|
| 27 |
ProgressCallback = Callable[[float, str], None]
|
| 28 |
|
| 29 |
+
# 75% training / 25% validation. The validation partition drives early
|
| 30 |
+
# stopping and best-checkpoint selection, so it is not an untouched test set.
|
| 31 |
+
DEFAULT_VALIDATION_FRACTION = 0.25
|
| 32 |
|
| 33 |
+
# Activations BioLMNet accepts.
|
| 34 |
+
ACTIVATIONS = ("relu", "sigmoid", "tanh")
|
| 35 |
+
|
| 36 |
+
|
| 37 |
+
# Defaults follow the Bozdag Lab grid (J. Rifat, 2026-10-17): the configuration that stayed
|
| 38 |
+
# stable across 8 seeds on BRCA (macro F1 0.749 +/- 0.018). The published activations
|
| 39 |
+
# (relu/sigmoid/tanh) collapse at this learning rate and L2; see
|
| 40 |
+
# diagnostics/2026-10-30-lab-hyperparameter-grid.
|
| 41 |
@dataclass(frozen=True)
|
| 42 |
class Hyperparameters:
|
| 43 |
+
epochs: int = 200
|
| 44 |
+
batch_size: int = 32
|
| 45 |
+
learning_rate: float = 0.01
|
| 46 |
weight_decay: float = 0.01
|
| 47 |
dropout: float = 0.3
|
| 48 |
projection_dim: int = 64
|
| 49 |
fusion_dim: int = 12
|
| 50 |
+
validation_fraction: float = DEFAULT_VALIDATION_FRACTION
|
| 51 |
optimizer: str = "Adam"
|
| 52 |
class_weighting: bool = True
|
| 53 |
early_stopping_patience: int = 12
|
| 54 |
seed: int = 42
|
| 55 |
+
biological_activation: str = "tanh"
|
| 56 |
+
projection_activation: str = "relu"
|
| 57 |
+
fusion_activation: str = "tanh"
|
| 58 |
+
sgd_momentum: float = 0.03
|
| 59 |
|
| 60 |
def validate(self) -> None:
|
| 61 |
if not 1 <= self.epochs <= 1000:
|
|
|
|
| 70 |
raise ValueError("Validation fraction must be between 0.05 and 0.5.")
|
| 71 |
if self.optimizer.lower() not in {"adam", "sgd"}:
|
| 72 |
raise ValueError("Optimizer must be Adam or SGD.")
|
| 73 |
+
for name in ("biological_activation", "projection_activation", "fusion_activation"):
|
| 74 |
+
if getattr(self, name) not in ACTIVATIONS:
|
| 75 |
+
raise ValueError(f"{name.replace('_', ' ').capitalize()} must be one of {', '.join(ACTIVATIONS)}.")
|
| 76 |
+
if not 0 <= self.sgd_momentum < 1:
|
| 77 |
+
raise ValueError("SGD momentum must be in [0, 1).")
|
| 78 |
|
| 79 |
|
| 80 |
@dataclass
|
|
|
|
| 107 |
torch.cuda.manual_seed_all(seed)
|
| 108 |
|
| 109 |
|
| 110 |
+
def split_train_validation(
|
| 111 |
+
labels: np.ndarray, validation_fraction: float, seed: int
|
| 112 |
+
) -> tuple[np.ndarray, np.ndarray]:
|
| 113 |
+
"""Stratified sample-index split shared by both omics and the labels."""
|
| 114 |
+
classes, class_counts = np.unique(labels, return_counts=True)
|
| 115 |
+
if class_counts.min() < 2:
|
| 116 |
+
raise ValueError(
|
| 117 |
+
"Each class needs at least two samples for a stratified train/validation split."
|
| 118 |
+
)
|
| 119 |
+
sample_count = len(labels)
|
| 120 |
+
validation_count = math.ceil(validation_fraction * sample_count)
|
| 121 |
+
train_count = sample_count - validation_count
|
| 122 |
+
if min(validation_count, train_count) < len(classes):
|
| 123 |
+
raise ValueError(
|
| 124 |
+
f"A validation fraction of {validation_fraction:.2f} on {sample_count} samples "
|
| 125 |
+
f"gives {train_count} training and {validation_count} validation samples; "
|
| 126 |
+
f"each partition needs at least one sample per class ({len(classes)} classes) "
|
| 127 |
+
"for a stratified split. Adjust the validation fraction or add samples."
|
| 128 |
+
)
|
| 129 |
+
|
| 130 |
+
indices = np.arange(sample_count)
|
| 131 |
+
train_index, validation_index = train_test_split(
|
| 132 |
+
indices,
|
| 133 |
+
test_size=validation_fraction,
|
| 134 |
+
random_state=seed,
|
| 135 |
+
stratify=labels,
|
| 136 |
+
)
|
| 137 |
+
return train_index, validation_index
|
| 138 |
+
|
| 139 |
+
|
| 140 |
def _fit_scaler(values: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
|
| 141 |
mean = values.mean(axis=0, dtype=np.float64).astype(np.float32)
|
| 142 |
scale = values.std(axis=0, dtype=np.float64).astype(np.float32)
|
|
|
|
| 172 |
projection_dim=hyperparameters.projection_dim,
|
| 173 |
fusion_dim=hyperparameters.fusion_dim,
|
| 174 |
dropout=hyperparameters.dropout,
|
| 175 |
+
biological_activation=hyperparameters.biological_activation,
|
| 176 |
+
projection_activation=hyperparameters.projection_activation,
|
| 177 |
+
fusion_activation=hyperparameters.fusion_activation,
|
| 178 |
)
|
| 179 |
|
| 180 |
|
|
|
|
| 207 |
hyperparameters.validate()
|
| 208 |
set_reproducible_seed(hyperparameters.seed)
|
| 209 |
labels = workspace.labels
|
| 210 |
+
train_index, validation_index = split_train_validation(
|
| 211 |
+
labels, hyperparameters.validation_fraction, hyperparameters.seed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
)
|
| 213 |
gene_mean, gene_scale = _fit_scaler(
|
| 214 |
workspace.gene_expression[train_index]
|
|
|
|
| 248 |
optimizer = torch.optim.SGD(
|
| 249 |
model.parameters(),
|
| 250 |
lr=hyperparameters.learning_rate,
|
| 251 |
+
momentum=hyperparameters.sgd_momentum,
|
| 252 |
weight_decay=hyperparameters.weight_decay,
|
| 253 |
)
|
| 254 |
else:
|
|
|
|
| 402 |
"projection_dim": hyperparameters.projection_dim,
|
| 403 |
"fusion_dim": hyperparameters.fusion_dim,
|
| 404 |
"dropout": hyperparameters.dropout,
|
| 405 |
+
"biological_activation": hyperparameters.biological_activation,
|
| 406 |
+
"projection_activation": hyperparameters.projection_activation,
|
| 407 |
+
"fusion_activation": hyperparameters.fusion_activation,
|
| 408 |
},
|
| 409 |
}
|
| 410 |
bundle = ModelBundle(
|
biolmnet/ui/styles.py
CHANGED
|
@@ -236,6 +236,12 @@ body, .gradio-container {
|
|
| 236 |
flex: 1 1 auto !important;
|
| 237 |
width: calc(100% - 236px) !important;
|
| 238 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 239 |
|
| 240 |
/* rail row (overlay: visible .rr under an invisible full-size button) */
|
| 241 |
.rail-row-wrap { position: relative; }
|
|
@@ -312,7 +318,11 @@ body, .gradio-container {
|
|
| 312 |
.sect { margin: 0 0 9px; padding-bottom: 8px; border-bottom: 1px solid var(--color-text); }
|
| 313 |
.sect-spaced { margin-top: 26px !important; }
|
| 314 |
|
| 315 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
.actbar-note { font: 500 10px/1.4 var(--font-mono); color: var(--color-muted-2); }
|
| 317 |
.actbar-note.error { color: var(--color-error); }
|
| 318 |
.actbar-buttons {
|
|
@@ -424,6 +434,46 @@ body, .gradio-container {
|
|
| 424 |
.strip.error .strip-kicker { color: var(--color-error); }
|
| 425 |
.strip .strip-body { margin-top: 4px; font-size: 12.5px; line-height: 1.5; }
|
| 426 |
.empty-note { padding: 14px 0; color: var(--color-muted); font-size: 13px; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 427 |
|
| 428 |
/* ── slots (one-line gr.File) ─────────────────────────────────────────── */
|
| 429 |
.file-slot .file-preview { border: 1px solid var(--color-divider) !important; border-radius: var(--radius-md); background: #fff; font-size: 12.5px !important; }
|
|
@@ -571,7 +621,9 @@ body, .gradio-container {
|
|
| 571 |
.gradio-container table { color: var(--color-text) !important; font-size: 12.5px !important; }
|
| 572 |
.gradio-container thead th {
|
| 573 |
font: 500 10px/1 var(--font-mono) !important; letter-spacing: .1em; text-transform: uppercase;
|
| 574 |
-
color: var(--color-muted-2) !important;
|
|
|
|
|
|
|
| 575 |
border-bottom: 1px solid var(--color-divider) !important;
|
| 576 |
}
|
| 577 |
.gradio-container tbody td { border-bottom: 1px solid var(--color-row-rule) !important; }
|
|
@@ -723,13 +775,223 @@ body, .gradio-container {
|
|
| 723 |
|
| 724 |
/* ── responsive ───────────────────────────────────────────────────────── */
|
| 725 |
@media (max-width: 1000px) {
|
| 726 |
-
.app-shell {
|
| 727 |
-
|
| 728 |
-
|
| 729 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 730 |
}
|
| 731 |
@media (max-width: 620px) {
|
| 732 |
-
.
|
| 733 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 734 |
}
|
| 735 |
"""
|
|
|
|
| 236 |
flex: 1 1 auto !important;
|
| 237 |
width: calc(100% - 236px) !important;
|
| 238 |
}
|
| 239 |
+
.workspace-page,
|
| 240 |
+
.workspace-page > .form {
|
| 241 |
+
min-height: calc(100vh - 45px) !important;
|
| 242 |
+
display: flex !important;
|
| 243 |
+
flex-direction: column !important;
|
| 244 |
+
}
|
| 245 |
|
| 246 |
/* rail row (overlay: visible .rr under an invisible full-size button) */
|
| 247 |
.rail-row-wrap { position: relative; }
|
|
|
|
| 318 |
.sect { margin: 0 0 9px; padding-bottom: 8px; border-bottom: 1px solid var(--color-text); }
|
| 319 |
.sect-spaced { margin-top: 26px !important; }
|
| 320 |
|
| 321 |
+
/* Gradio's container sets overflow: hidden, which disables position: sticky inside it;
|
| 322 |
+
clip still clips stray content without breaking the sticky action bar below. */
|
| 323 |
+
.gradio-container { overflow: clip !important; }
|
| 324 |
+
/* Pinned to the bottom of the visible frame so the page's main action never needs a scroll to find. */
|
| 325 |
+
.actbar-row { position: sticky !important; bottom: 0; z-index: 20; margin-top: auto !important; align-items: center !important; justify-content: space-between !important; flex-wrap: nowrap !important; gap: 20px !important; padding: 16px 30px !important; border-top: 1px solid var(--color-divider) !important; background: color-mix(in srgb, var(--color-text) 3%, var(--color-bg)) !important; box-shadow: 0 -8px 18px -14px color-mix(in srgb, var(--color-text) 45%, transparent); }
|
| 326 |
.actbar-note { font: 500 10px/1.4 var(--font-mono); color: var(--color-muted-2); }
|
| 327 |
.actbar-note.error { color: var(--color-error); }
|
| 328 |
.actbar-buttons {
|
|
|
|
| 434 |
.strip.error .strip-kicker { color: var(--color-error); }
|
| 435 |
.strip .strip-body { margin-top: 4px; font-size: 12.5px; line-height: 1.5; }
|
| 436 |
.empty-note { padding: 14px 0; color: var(--color-muted); font-size: 13px; }
|
| 437 |
+
.field-hint { margin-top: 6px; color: var(--color-muted); font-size: 12px; line-height: 1.4; }
|
| 438 |
+
|
| 439 |
+
@media (min-width: 901px) and (max-height: 820px) {
|
| 440 |
+
.topbar {
|
| 441 |
+
padding-top: 10px;
|
| 442 |
+
padding-bottom: 10px;
|
| 443 |
+
}
|
| 444 |
+
.pghd {
|
| 445 |
+
padding-top: 18px;
|
| 446 |
+
}
|
| 447 |
+
.pghd h2 {
|
| 448 |
+
font-size: 31px;
|
| 449 |
+
}
|
| 450 |
+
.pghd .desc {
|
| 451 |
+
margin-top: 4px;
|
| 452 |
+
line-height: 1.35;
|
| 453 |
+
}
|
| 454 |
+
.stage-grid {
|
| 455 |
+
padding-top: 16px !important;
|
| 456 |
+
gap: 22px !important;
|
| 457 |
+
}
|
| 458 |
+
.data-workspace-page .section-heading-row {
|
| 459 |
+
margin-bottom: 8px !important;
|
| 460 |
+
}
|
| 461 |
+
.data-workspace-page .sect-spaced {
|
| 462 |
+
margin-top: 18px !important;
|
| 463 |
+
}
|
| 464 |
+
.data-workspace-page .srow-row {
|
| 465 |
+
min-height: 42px;
|
| 466 |
+
}
|
| 467 |
+
.data-workspace-page .dataframe,
|
| 468 |
+
.data-workspace-page .table-wrap {
|
| 469 |
+
max-height: 118px !important;
|
| 470 |
+
overflow: auto !important;
|
| 471 |
+
}
|
| 472 |
+
.actbar-row {
|
| 473 |
+
padding-top: 11px !important;
|
| 474 |
+
padding-bottom: 11px !important;
|
| 475 |
+
}
|
| 476 |
+
}
|
| 477 |
|
| 478 |
/* ── slots (one-line gr.File) ─────────────────────────────────────────── */
|
| 479 |
.file-slot .file-preview { border: 1px solid var(--color-divider) !important; border-radius: var(--radius-md); background: #fff; font-size: 12.5px !important; }
|
|
|
|
| 621 |
.gradio-container table { color: var(--color-text) !important; font-size: 12.5px !important; }
|
| 622 |
.gradio-container thead th {
|
| 623 |
font: 500 10px/1 var(--font-mono) !important; letter-spacing: .1em; text-transform: uppercase;
|
| 624 |
+
color: var(--color-muted-2) !important;
|
| 625 |
+
/* opaque so rows scrolling under the pinned header stay hidden */
|
| 626 |
+
background: var(--color-bg) !important;
|
| 627 |
border-bottom: 1px solid var(--color-divider) !important;
|
| 628 |
}
|
| 629 |
.gradio-container tbody td { border-bottom: 1px solid var(--color-row-rule) !important; }
|
|
|
|
| 775 |
|
| 776 |
/* ── responsive ───────────────────────────────────────────────────────── */
|
| 777 |
@media (max-width: 1000px) {
|
| 778 |
+
.app-shell {
|
| 779 |
+
display: block !important;
|
| 780 |
+
min-height: 100vh !important;
|
| 781 |
+
}
|
| 782 |
+
.rail-col {
|
| 783 |
+
min-width: 100% !important;
|
| 784 |
+
max-width: 100% !important;
|
| 785 |
+
width: 100% !important;
|
| 786 |
+
flex: none !important;
|
| 787 |
+
}
|
| 788 |
+
.rail {
|
| 789 |
+
position: sticky;
|
| 790 |
+
top: 0;
|
| 791 |
+
z-index: 40;
|
| 792 |
+
height: auto !important;
|
| 793 |
+
min-height: 0 !important;
|
| 794 |
+
padding: 12px 12px 10px;
|
| 795 |
+
border-right: 0;
|
| 796 |
+
border-bottom: 1px solid var(--color-divider);
|
| 797 |
+
background: color-mix(in srgb, var(--color-bg) 96%, #fff);
|
| 798 |
+
}
|
| 799 |
+
.rail-brand {
|
| 800 |
+
display: flex;
|
| 801 |
+
align-items: baseline;
|
| 802 |
+
gap: 8px;
|
| 803 |
+
padding: 0 4px 9px;
|
| 804 |
+
}
|
| 805 |
+
.rail-brand .name {
|
| 806 |
+
font-size: 22px;
|
| 807 |
+
}
|
| 808 |
+
.rail-brand .mono {
|
| 809 |
+
margin-top: 0 !important;
|
| 810 |
+
font-size: 8.5px;
|
| 811 |
+
}
|
| 812 |
+
.rail-kicker,
|
| 813 |
+
.rail-spacer {
|
| 814 |
+
display: none !important;
|
| 815 |
+
}
|
| 816 |
+
.rail-nav {
|
| 817 |
+
display: grid !important;
|
| 818 |
+
grid-auto-flow: column;
|
| 819 |
+
grid-auto-columns: minmax(154px, max-content);
|
| 820 |
+
gap: 6px;
|
| 821 |
+
overflow-x: auto;
|
| 822 |
+
overscroll-behavior-x: contain;
|
| 823 |
+
padding: 0 2px 2px;
|
| 824 |
+
scrollbar-width: none;
|
| 825 |
+
}
|
| 826 |
+
.rail-nav::-webkit-scrollbar {
|
| 827 |
+
display: none;
|
| 828 |
+
}
|
| 829 |
+
.rail-row-wrap {
|
| 830 |
+
min-width: 154px !important;
|
| 831 |
+
}
|
| 832 |
+
.rr {
|
| 833 |
+
min-height: 36px;
|
| 834 |
+
padding: 8px 9px 8px 8px;
|
| 835 |
+
gap: 8px;
|
| 836 |
+
border-left-width: 2px;
|
| 837 |
+
font-size: 12.5px;
|
| 838 |
+
white-space: nowrap;
|
| 839 |
+
}
|
| 840 |
+
.rr .rn {
|
| 841 |
+
width: 19px;
|
| 842 |
+
height: 19px;
|
| 843 |
+
font-size: 9.5px;
|
| 844 |
+
}
|
| 845 |
+
.rr .st {
|
| 846 |
+
font-size: 8px;
|
| 847 |
+
letter-spacing: .08em;
|
| 848 |
+
}
|
| 849 |
+
.workspace-col {
|
| 850 |
+
width: 100% !important;
|
| 851 |
+
min-width: 0 !important;
|
| 852 |
+
}
|
| 853 |
+
.topbar {
|
| 854 |
+
padding: 10px 116px 10px 14px;
|
| 855 |
+
gap: 10px;
|
| 856 |
+
}
|
| 857 |
+
.topbar > .num {
|
| 858 |
+
display: none;
|
| 859 |
+
}
|
| 860 |
+
.intro-open-btn {
|
| 861 |
+
right: 12px;
|
| 862 |
+
top: 5px;
|
| 863 |
+
}
|
| 864 |
+
.pghd {
|
| 865 |
+
padding: 20px 14px 0;
|
| 866 |
+
gap: 10px;
|
| 867 |
+
}
|
| 868 |
+
.pghd h2 {
|
| 869 |
+
font-size: 30px;
|
| 870 |
+
}
|
| 871 |
+
.pghd .desc {
|
| 872 |
+
max-width: none;
|
| 873 |
+
font-size: 13px;
|
| 874 |
+
}
|
| 875 |
+
.stage-grid,
|
| 876 |
+
.results-grid {
|
| 877 |
+
display: grid !important;
|
| 878 |
+
grid-template-columns: minmax(0, 1fr) !important;
|
| 879 |
+
padding: 20px 14px 0 !important;
|
| 880 |
+
gap: 22px !important;
|
| 881 |
+
}
|
| 882 |
+
.stage-grid > *,
|
| 883 |
+
.results-grid > * {
|
| 884 |
+
min-width: 0 !important;
|
| 885 |
+
max-width: 100% !important;
|
| 886 |
+
width: 100% !important;
|
| 887 |
+
}
|
| 888 |
+
.results-stat-row,
|
| 889 |
+
.stat-grid {
|
| 890 |
+
padding: 20px 14px 0 !important;
|
| 891 |
+
}
|
| 892 |
+
.metric-strip {
|
| 893 |
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
| 894 |
+
}
|
| 895 |
+
.field-pair {
|
| 896 |
+
display: grid !important;
|
| 897 |
+
grid-template-columns: minmax(0, 1fr) !important;
|
| 898 |
+
gap: 12px !important;
|
| 899 |
+
}
|
| 900 |
+
.srow-row {
|
| 901 |
+
display: grid !important;
|
| 902 |
+
grid-template-columns: minmax(118px, 34%) minmax(0, 1fr) !important;
|
| 903 |
+
gap: 12px !important;
|
| 904 |
+
padding: 8px 0 !important;
|
| 905 |
+
}
|
| 906 |
+
.srow-row > * {
|
| 907 |
+
min-width: 0 !important;
|
| 908 |
+
}
|
| 909 |
+
.actbar-row {
|
| 910 |
+
align-items: flex-start !important;
|
| 911 |
+
flex-wrap: wrap !important;
|
| 912 |
+
padding: 12px 14px !important;
|
| 913 |
+
gap: 12px !important;
|
| 914 |
+
}
|
| 915 |
+
.actbar-buttons {
|
| 916 |
+
width: 100% !important;
|
| 917 |
+
flex: 1 1 100% !important;
|
| 918 |
+
justify-content: flex-start !important;
|
| 919 |
+
flex-wrap: wrap !important;
|
| 920 |
+
}
|
| 921 |
+
.actbar-buttons button {
|
| 922 |
+
min-height: 34px !important;
|
| 923 |
+
padding: 0 12px !important;
|
| 924 |
+
}
|
| 925 |
+
.gradio-container .table-wrap,
|
| 926 |
+
.gradio-container .dataframe,
|
| 927 |
+
.gradio-container .wrap.svelte-1ipelgc,
|
| 928 |
+
.tbl {
|
| 929 |
+
max-width: 100%;
|
| 930 |
+
overflow-x: auto;
|
| 931 |
+
}
|
| 932 |
+
.intro-card {
|
| 933 |
+
width: min(556px, calc(100vw - 28px)) !important;
|
| 934 |
+
padding: 22px 20px 18px !important;
|
| 935 |
+
}
|
| 936 |
}
|
| 937 |
@media (max-width: 620px) {
|
| 938 |
+
.topbar {
|
| 939 |
+
padding-right: 112px;
|
| 940 |
+
}
|
| 941 |
+
.topbar .mono {
|
| 942 |
+
font-size: 8.5px;
|
| 943 |
+
letter-spacing: .06em;
|
| 944 |
+
}
|
| 945 |
+
.pghd h2 {
|
| 946 |
+
font-size: 27px;
|
| 947 |
+
}
|
| 948 |
+
.section-heading-row {
|
| 949 |
+
display: block !important;
|
| 950 |
+
}
|
| 951 |
+
.section-heading-row .mono {
|
| 952 |
+
margin-top: 6px;
|
| 953 |
+
text-align: left !important;
|
| 954 |
+
}
|
| 955 |
+
.seg-radio label {
|
| 956 |
+
padding: 7px 8px !important;
|
| 957 |
+
font-size: 12px !important;
|
| 958 |
+
}
|
| 959 |
+
.stat-grid,
|
| 960 |
+
.metric-strip {
|
| 961 |
+
grid-template-columns: 1fr !important;
|
| 962 |
+
}
|
| 963 |
+
.srow-row {
|
| 964 |
+
grid-template-columns: 1fr !important;
|
| 965 |
+
gap: 6px !important;
|
| 966 |
+
}
|
| 967 |
+
.srow-value-row {
|
| 968 |
+
justify-content: flex-start !important;
|
| 969 |
+
}
|
| 970 |
+
.rr {
|
| 971 |
+
font-size: 12px;
|
| 972 |
+
}
|
| 973 |
+
.rr .st {
|
| 974 |
+
display: none;
|
| 975 |
+
}
|
| 976 |
+
.rail-nav {
|
| 977 |
+
grid-auto-columns: minmax(126px, max-content);
|
| 978 |
+
}
|
| 979 |
+
.rail-row-wrap {
|
| 980 |
+
min-width: 126px !important;
|
| 981 |
+
}
|
| 982 |
+
.intro-card h4 {
|
| 983 |
+
font-size: 24px;
|
| 984 |
+
}
|
| 985 |
+
.intro-card p {
|
| 986 |
+
font-size: 13px;
|
| 987 |
+
}
|
| 988 |
+
.intro-card-foot {
|
| 989 |
+
align-items: flex-start !important;
|
| 990 |
+
}
|
| 991 |
+
.intro-card-actions {
|
| 992 |
+
justify-content: flex-start !important;
|
| 993 |
+
flex: 1 1 100% !important;
|
| 994 |
+
gap: 9px !important;
|
| 995 |
+
}
|
| 996 |
}
|
| 997 |
"""
|
diagnostics/2026-10-16-brca-training-collapse/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# BRCA training collapse diagnostics (2026-10-16)
|
| 2 |
+
|
| 3 |
+
These diagnostic runs explain why BRCA training in the Workbench predicted one class for every sample. None of this is production code: the scripts call the project's code unchanged and only override `Hyperparameters` fields.
|
| 4 |
+
|
| 5 |
+
## Layout
|
| 6 |
+
|
| 7 |
+
- `scripts/`
|
| 8 |
+
- `diagnose.py`: builds the BRCA workspace through `app.prepare_workspace`, then reports class counts, class weights, mask sparsity, per-epoch predictions and activations.
|
| 9 |
+
- `sweep.py`: weight-decay sweep at seed 42.
|
| 10 |
+
- `seeds.py`: 8 seeds at weight_decay 1e-4 and 0.01.
|
| 11 |
+
- `epochs.py <limit>`: 8 seeds at weight_decay 1e-4 with the given epoch limit.
|
| 12 |
+
- `epochs_summary.py`: summarises the three `epochs_*.json` files.
|
| 13 |
+
- `results/`: raw outputs from the runs on 2026-10-16.
|
| 14 |
+
- `brca_weighted.txt`: full `diagnose.py` output with the Workbench defaults.
|
| 15 |
+
- `weight_decay_sweep.txt`: weight-decay sweep.
|
| 16 |
+
- `paper_config_sgd.txt`: the notebook's SGD configuration.
|
| 17 |
+
- `effective_fanin_init.txt`: initialisation experiment, run inline with a monkeypatch.
|
| 18 |
+
- `seed_runs.csv` and `seed_runs.txt`: 8 seeds × 2 weight-decay values.
|
| 19 |
+
- `epochs_{50,100,200}.json`: per-run histories.
|
| 20 |
+
- `epochs_runs.csv`: per-run summary table.
|
| 21 |
+
- `upstream/`: copies of the bozdaglab/BioLM-NET notebooks used for the comparison.
|
| 22 |
+
|
| 23 |
+
## Reproduce
|
| 24 |
+
|
| 25 |
+
Run from the repository root with the project venv:
|
| 26 |
+
|
| 27 |
+
```bash
|
| 28 |
+
D=diagnostics/2026-10-16-brca-training-collapse/scripts
|
| 29 |
+
PYTHONPATH=$PWD .venv/bin/python $D/diagnose.py BRCA 1 50 # downloads data; caches workspace_BRCA.pkl (~37 MB) next to the scripts
|
| 30 |
+
PYTHONPATH=$PWD .venv/bin/python $D/seeds.py
|
| 31 |
+
for L in 50 100 200; do PYTHONPATH=$PWD .venv/bin/python $D/epochs.py $L; done
|
| 32 |
+
.venv/bin/python $D/epochs_summary.py
|
| 33 |
+
```
|
| 34 |
+
|
| 35 |
+
`workspace_BRCA.pkl` is a regenerable cache. Don't commit it.
|
| 36 |
+
|
| 37 |
+
Note: `epochs.py` and `epochs_summary.py` write their output files next to the scripts.
|
diagnostics/2026-10-16-brca-training-collapse/results/brca_weighted.txt
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
======== RAW FILES (BRCA) ========
|
| 3 |
+
gene shape=(875, 999) first cols=['A2ML1', 'ABAT', 'ABCA13']
|
| 4 |
+
dna shape=(875, 1000) first cols=['A2LD1', 'A2ML1', 'ABAT']
|
| 5 |
+
labels shape=(875, 1) first cols=['label']
|
| 6 |
+
raw label counts: {3.0: 436, 4.0: 147, 1.0: 131, 0.0: 115, 2.0: 46}
|
| 7 |
+
gene_pathways shape=(5614, 2) first cols=['SYMBOL', 'PathwayID']
|
| 8 |
+
dna_pathways shape=(5410, 2) first cols=['SYMBOL', 'PathwayID']
|
| 9 |
+
|
| 10 |
+
======== WORKSPACE ========
|
| 11 |
+
warnings: []
|
| 12 |
+
samples: 875 classes: ['0.0', '1.0', '2.0', '3.0', '4.0']
|
| 13 |
+
full class counts: {'0.0': 115, '1.0': 131, '2.0': 46, '3.0': 436, '4.0': 147}
|
| 14 |
+
gene: shape=(875, 999) min=0 max=1 mean=0.408 zero-var cols=0
|
| 15 |
+
dna: shape=(875, 1000) min=0 max=1 mean=0.52 zero-var cols=0
|
| 16 |
+
|
| 17 |
+
======== MASKS ========
|
| 18 |
+
gene: bio mask (999, 1008) density=0.2328% nnz=2,344 PDI=369 PPI=3559
|
| 19 |
+
inputs with 0 outgoing edges: 695/999 hidden genes in-degree median=1 max=32
|
| 20 |
+
nonzero mask values: min=0.988 median=0.998 max=1.000
|
| 21 |
+
pathway mask (1008, 133): hidden genes in no pathway=0/1008 genes/pathway median=35
|
| 22 |
+
dna: bio mask (1000, 840) density=0.1423% nnz=1,195 PDI=158 PPI=1566
|
| 23 |
+
inputs with 0 outgoing edges: 792/1000 hidden genes in-degree median=1 max=6
|
| 24 |
+
nonzero mask values: min=0.988 median=0.998 max=1.000
|
| 25 |
+
pathway mask (840, 142): hidden genes in no pathway=0/840 genes/pathway median=32
|
| 26 |
+
|
| 27 |
+
======== TRAINING Hyperparameters(epochs=50, batch_size=16, learning_rate=0.001, weight_decay=0.01, dropout=0.3, projection_dim=64, fusion_dim=12, validation_fraction=0.25, optimizer='Adam', class_weighting=True, early_stopping_patience=12, seed=42) ========
|
| 28 |
+
training class counts: {'0.0': 86, '1.0': 98, '2.0': 35, '3.0': 327, '4.0': 110}
|
| 29 |
+
validation class counts: {'0.0': 29, '1.0': 33, '2.0': 11, '3.0': 109, '4.0': 37}
|
| 30 |
+
|
| 31 |
+
======== CLASS WEIGHTS ========
|
| 32 |
+
weights passed to CrossEntropyLoss: [array([1.526, 1.339, 3.749, 0.401, 1.193], dtype=float32)]
|
| 33 |
+
weight attribute seen inside loss.forward: [1.526 1.339 3.749 0.401 1.193]
|
| 34 |
+
loss.forward calls: 1271
|
| 35 |
+
|
| 36 |
+
======== HISTORY ========
|
| 37 |
+
epoch training_loss validation_loss validation_accuracy validation_f1_macro
|
| 38 |
+
1.0 1.642350 1.601534 0.150685 0.052381
|
| 39 |
+
2.0 1.629108 1.576027 0.150685 0.052381
|
| 40 |
+
3.0 1.624403 1.574691 0.497717 0.132927
|
| 41 |
+
4.0 1.613764 1.588255 0.168950 0.057813
|
| 42 |
+
5.0 1.628252 1.574925 0.497717 0.132927
|
| 43 |
+
6.0 1.620439 1.678558 0.168950 0.057813
|
| 44 |
+
7.0 1.626308 1.564224 0.497717 0.132927
|
| 45 |
+
8.0 1.618647 1.550071 0.497717 0.132927
|
| 46 |
+
9.0 1.617843 1.545797 0.497717 0.132927
|
| 47 |
+
10.0 1.614722 1.622764 0.168950 0.057813
|
| 48 |
+
11.0 1.616705 1.577437 0.497717 0.132927
|
| 49 |
+
12.0 1.619570 1.585625 0.168950 0.057813
|
| 50 |
+
13.0 1.617500 1.541410 0.497717 0.132927
|
| 51 |
+
14.0 1.619081 1.613365 0.132420 0.046774
|
| 52 |
+
15.0 1.616881 1.572324 0.497717 0.132927
|
| 53 |
+
16.0 1.616340 1.557646 0.497717 0.132927
|
| 54 |
+
17.0 1.615816 1.569439 0.497717 0.132927
|
| 55 |
+
18.0 1.613130 1.558936 0.497717 0.132927
|
| 56 |
+
19.0 1.611621 1.538758 0.497717 0.132927
|
| 57 |
+
20.0 1.610360 1.565398 0.497717 0.132927
|
| 58 |
+
21.0 1.607601 1.592779 0.132420 0.046774
|
| 59 |
+
22.0 1.612177 1.580287 0.497717 0.132927
|
| 60 |
+
23.0 1.614574 1.590151 0.168950 0.057813
|
| 61 |
+
24.0 1.612279 1.569710 0.497717 0.132927
|
| 62 |
+
25.0 1.607981 1.565809 0.497717 0.132927
|
| 63 |
+
26.0 1.611930 1.564028 0.497717 0.132927
|
| 64 |
+
27.0 1.612068 1.584551 0.132420 0.046774
|
| 65 |
+
28.0 1.613480 1.597781 0.132420 0.046774
|
| 66 |
+
29.0 1.613598 1.575038 0.497717 0.132927
|
| 67 |
+
30.0 1.617835 1.584576 0.497717 0.132927
|
| 68 |
+
31.0 1.610216 1.583199 0.497717 0.132927
|
| 69 |
+
|
| 70 |
+
======== PER-EPOCH VALIDATION PREDICTION COUNTS ========
|
| 71 |
+
epoch 1: counts=[0, 219, 0, 0, 0] mean max-prob=0.205
|
| 72 |
+
epoch 2: counts=[0, 219, 0, 0, 0] mean max-prob=0.240
|
| 73 |
+
epoch 3: counts=[0, 0, 0, 219, 0] mean max-prob=0.216
|
| 74 |
+
epoch 4: counts=[0, 0, 0, 0, 219] mean max-prob=0.215
|
| 75 |
+
epoch 5: counts=[0, 0, 0, 219, 0] mean max-prob=0.216
|
| 76 |
+
epoch 6: counts=[0, 0, 0, 0, 219] mean max-prob=0.234
|
| 77 |
+
epoch 7: counts=[0, 0, 0, 219, 0] mean max-prob=0.223
|
| 78 |
+
epoch 8: counts=[0, 0, 0, 219, 0] mean max-prob=0.236
|
| 79 |
+
epoch 9: counts=[0, 0, 0, 219, 0] mean max-prob=0.239
|
| 80 |
+
epoch 10: counts=[0, 0, 0, 0, 219] mean max-prob=0.219
|
| 81 |
+
epoch 11: counts=[0, 0, 0, 219, 0] mean max-prob=0.212
|
| 82 |
+
epoch 12: counts=[0, 0, 0, 0, 219] mean max-prob=0.208
|
| 83 |
+
epoch 13: counts=[0, 0, 0, 219, 0] mean max-prob=0.232
|
| 84 |
+
epoch 14: counts=[219, 0, 0, 0, 0] mean max-prob=0.245
|
| 85 |
+
epoch 15: counts=[0, 0, 0, 219, 0] mean max-prob=0.216
|
| 86 |
+
epoch 16: counts=[0, 0, 0, 219, 0] mean max-prob=0.226
|
| 87 |
+
epoch 17: counts=[0, 0, 0, 219, 0] mean max-prob=0.218
|
| 88 |
+
epoch 18: counts=[0, 0, 0, 219, 0] mean max-prob=0.224
|
| 89 |
+
epoch 19: counts=[0, 0, 0, 219, 0] mean max-prob=0.234
|
| 90 |
+
epoch 20: counts=[0, 0, 0, 219, 0] mean max-prob=0.221
|
| 91 |
+
epoch 21: counts=[219, 0, 0, 0, 0] mean max-prob=0.214
|
| 92 |
+
epoch 22: counts=[0, 0, 0, 219, 0] mean max-prob=0.210
|
| 93 |
+
epoch 23: counts=[0, 0, 0, 0, 219] mean max-prob=0.209
|
| 94 |
+
epoch 24: counts=[0, 0, 0, 219, 0] mean max-prob=0.218
|
| 95 |
+
epoch 25: counts=[0, 0, 0, 219, 0] mean max-prob=0.223
|
| 96 |
+
epoch 26: counts=[0, 0, 0, 219, 0] mean max-prob=0.223
|
| 97 |
+
epoch 27: counts=[219, 0, 0, 0, 0] mean max-prob=0.212
|
| 98 |
+
epoch 28: counts=[219, 0, 0, 0, 0] mean max-prob=0.215
|
| 99 |
+
epoch 29: counts=[0, 0, 0, 219, 0] mean max-prob=0.217
|
| 100 |
+
epoch 30: counts=[0, 0, 0, 219, 0] mean max-prob=0.212
|
| 101 |
+
epoch 31: counts=[0, 0, 0, 219, 0] mean max-prob=0.211
|
| 102 |
+
|
| 103 |
+
======== FINAL (best checkpoint) VALIDATION ========
|
| 104 |
+
prediction counts: {'0.0': 0, '1.0': 0, '2.0': 0, '3.0': 219, '4.0': 0}
|
| 105 |
+
average predicted probability per class: {'0.0': 0.19499999284744263, '1.0': 0.210999995470047, '2.0': 0.16200000047683716, '3.0': 0.23399999737739563, '4.0': 0.1979999989271164}
|
| 106 |
+
training class prior: {'0.0': 0.131, '1.0': 0.149, '2.0': 0.053, '3.0': 0.498, '4.0': 0.168}
|
| 107 |
+
std of each class prob across samples: [0.0, 0.0, 0.0, 0.0, 0.0]
|
| 108 |
+
max-prob: min/median/max = [0.234, 0.234, 0.234]
|
| 109 |
+
margin top1-top2: median = 0.0232
|
| 110 |
+
first 8 validation rows (prob vectors):
|
| 111 |
+
[[0.195 0.211 0.162 0.234 0.198]
|
| 112 |
+
[0.195 0.211 0.162 0.234 0.198]
|
| 113 |
+
[0.195 0.211 0.162 0.234 0.198]
|
| 114 |
+
[0.195 0.211 0.162 0.234 0.198]
|
| 115 |
+
[0.195 0.211 0.162 0.234 0.198]
|
| 116 |
+
[0.195 0.211 0.162 0.234 0.198]
|
| 117 |
+
[0.195 0.211 0.162 0.234 0.198]
|
| 118 |
+
[0.195 0.211 0.162 0.234 0.198]]
|
| 119 |
+
metrics: {'validation_loss': 1.5387582778930664, 'accuracy': 0.4977168949771689, 'f1_macro': 0.1329268292682927, 'f1_weighted': 0.3307996436128745, 'precision_macro': 0.09954337899543378, 'recall_macro': 0.2, 'epochs_completed': 31, 'training_samples': 656, 'validation_samples': 219}
|
| 120 |
+
confusion:
|
| 121 |
+
[[ 0 0 0 29 0]
|
| 122 |
+
[ 0 0 0 33 0]
|
| 123 |
+
[ 0 0 0 11 0]
|
| 124 |
+
[ 0 0 0 109 0]
|
| 125 |
+
[ 0 0 0 37 0]]
|
| 126 |
+
|
| 127 |
+
======== LOGITS / ACTIVATIONS (best checkpoint, validation rows) ========
|
| 128 |
+
gene: bio pre-act mean=-4.48e-19 std=1.18e-16 dead ReLU units=6.6% pathway std across samples=4.02e-17 sigmoid saturated(<.02|>.98)=0.0% proj std across samples=0
|
| 129 |
+
dna: bio pre-act mean=-2.92e-21 std=1.15e-18 dead ReLU units=9.4% pathway std across samples=2.91e-19 sigmoid saturated(<.02|>.98)=0.0% proj std across samples=0
|
| 130 |
+
fusion tanh saturated(|x|>.98)=0.0% fused std across samples=0
|
| 131 |
+
logits mean per class: [-0.057 0.019 -0.246 0.124 -0.042] logits std across samples per class: [0. 0. 0. 0. 0.]
|
| 132 |
+
|
| 133 |
+
======== PARAMETER CHANGE FROM INIT ========
|
| 134 |
+
gene_branch.biological.weight rel change=1.0000
|
| 135 |
+
gene_branch.biological.bias rel change=1.0000
|
| 136 |
+
gene_branch.pathway_attention.query rel change=1.0000
|
| 137 |
+
gene_branch.projection.weight rel change=1.0000
|
| 138 |
+
gene_branch.projection.bias rel change=0.9941
|
| 139 |
+
dna_branch.biological.weight rel change=1.0000
|
| 140 |
+
dna_branch.biological.bias rel change=1.0000
|
| 141 |
+
dna_branch.pathway_attention.query rel change=1.0000
|
| 142 |
+
dna_branch.projection.weight rel change=1.0000
|
| 143 |
+
dna_branch.projection.bias rel change=0.9789
|
| 144 |
+
fusion.weight rel change=0.3960
|
| 145 |
+
fusion.bias rel change=0.2371
|
| 146 |
+
output.weight rel change=0.4115
|
| 147 |
+
output.bias rel change=0.2730
|
diagnostics/2026-10-16-brca-training-collapse/results/effective_fanin_init.txt
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Diagnostic only, NOT committed to biolmnet/model.py.
|
| 2 |
+
BioMaskedLinear.reset_parameters was monkeypatched inside the run to use LeCun-uniform
|
| 3 |
+
initialisation on each hidden gene's real (masked) in-degree, with zero bias:
|
| 4 |
+
|
| 5 |
+
def reset(self):
|
| 6 |
+
fan_in = self.mask.gt(0).sum(1).clamp(min=1).float() # real in-degree per hidden gene
|
| 7 |
+
bound = (3.0 / fan_in).sqrt().unsqueeze(1)
|
| 8 |
+
with torch.no_grad():
|
| 9 |
+
self.weight.copy_((torch.rand_like(self.weight) * 2 - 1) * bound)
|
| 10 |
+
if self.bias is not None: self.bias.zero_()
|
| 11 |
+
biolmnet.model.BioMaskedLinear.reset_parameters = reset
|
| 12 |
+
|
| 13 |
+
BRCA, seed 42, 75/25 split, class weighting on:
|
| 14 |
+
|
| 15 |
+
eff-fan-in init + current default (Adam wd=.01) acc=0.680 f1_macro=0.493 epochs=50 pred=[0, 34, 10, 159, 16] prob std=0.1422
|
| 16 |
+
eff-fan-in init + paper (SGD lr=.01 wd=.01 200ep) acc=0.511 f1_macro=0.497 epochs=148 pred=[80, 32, 9, 70, 28] prob std=0.1255
|
diagnostics/2026-10-16-brca-training-collapse/results/epochs_100.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
diagnostics/2026-10-16-brca-training-collapse/results/epochs_100.log
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
limit=100 seed=0 done: best=49/61 acc=0.763 f1m=0.724
|
| 2 |
+
limit=100 seed=1 done: best=50/62 acc=0.772 f1m=0.744
|
| 3 |
+
limit=100 seed=2 done: best=50/62 acc=0.790 f1m=0.761
|
| 4 |
+
limit=100 seed=3 done: best=71/83 acc=0.740 f1m=0.719
|
| 5 |
+
limit=100 seed=7 done: best=32/44 acc=0.772 f1m=0.752
|
| 6 |
+
limit=100 seed=42 done: best=38/50 acc=0.767 f1m=0.747
|
| 7 |
+
limit=100 seed=123 done: best=37/49 acc=0.763 f1m=0.740
|
| 8 |
+
limit=100 seed=2024 done: best=41/53 acc=0.758 f1m=0.737
|
| 9 |
+
limit=100 ALL DONE
|
diagnostics/2026-10-16-brca-training-collapse/results/epochs_200.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
diagnostics/2026-10-16-brca-training-collapse/results/epochs_200.log
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
limit=200 seed=0 done: best=49/61 acc=0.763 f1m=0.724
|
| 2 |
+
limit=200 seed=1 done: best=50/62 acc=0.772 f1m=0.744
|
| 3 |
+
limit=200 seed=2 done: best=50/62 acc=0.790 f1m=0.761
|
| 4 |
+
limit=200 seed=3 done: best=71/83 acc=0.740 f1m=0.719
|
| 5 |
+
limit=200 seed=7 done: best=32/44 acc=0.772 f1m=0.752
|
| 6 |
+
limit=200 seed=42 done: best=38/50 acc=0.767 f1m=0.747
|
| 7 |
+
limit=200 seed=123 done: best=37/49 acc=0.763 f1m=0.740
|
| 8 |
+
limit=200 seed=2024 done: best=41/53 acc=0.758 f1m=0.737
|
| 9 |
+
limit=200 ALL DONE
|
diagnostics/2026-10-16-brca-training-collapse/results/epochs_50.json
ADDED
|
@@ -0,0 +1,3105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"limit": 50,
|
| 4 |
+
"seed": 0,
|
| 5 |
+
"hyperparameters": {
|
| 6 |
+
"epochs": 50,
|
| 7 |
+
"batch_size": 16,
|
| 8 |
+
"learning_rate": 0.001,
|
| 9 |
+
"weight_decay": 0.0001,
|
| 10 |
+
"dropout": 0.3,
|
| 11 |
+
"projection_dim": 64,
|
| 12 |
+
"fusion_dim": 12,
|
| 13 |
+
"validation_fraction": 0.25,
|
| 14 |
+
"optimizer": "Adam",
|
| 15 |
+
"class_weighting": true,
|
| 16 |
+
"early_stopping_patience": 12,
|
| 17 |
+
"seed": 0
|
| 18 |
+
},
|
| 19 |
+
"epochs_completed": 50,
|
| 20 |
+
"best_epoch": 49,
|
| 21 |
+
"early_stopped": false,
|
| 22 |
+
"hit_max": true,
|
| 23 |
+
"train_loss_at_best": 0.6369955467014778,
|
| 24 |
+
"val_loss_at_best": 0.6139159798622131,
|
| 25 |
+
"accuracy": 0.7625570776255708,
|
| 26 |
+
"f1_macro": 0.7241977003359705,
|
| 27 |
+
"f1_weighted": 0.7688921750314536,
|
| 28 |
+
"recall": {
|
| 29 |
+
"0.0": 0.7931034482758621,
|
| 30 |
+
"1.0": 0.8181818181818182,
|
| 31 |
+
"2.0": 0.5454545454545454,
|
| 32 |
+
"3.0": 0.8073394495412844,
|
| 33 |
+
"4.0": 0.6216216216216216
|
| 34 |
+
},
|
| 35 |
+
"pred_counts": {
|
| 36 |
+
"0.0": 47,
|
| 37 |
+
"1.0": 28,
|
| 38 |
+
"2.0": 8,
|
| 39 |
+
"3.0": 105,
|
| 40 |
+
"4.0": 31
|
| 41 |
+
},
|
| 42 |
+
"collapsed": false,
|
| 43 |
+
"history": [
|
| 44 |
+
{
|
| 45 |
+
"epoch": 1.0,
|
| 46 |
+
"training_loss": 1.6172636282153245,
|
| 47 |
+
"validation_loss": 1.5241289138793945,
|
| 48 |
+
"validation_accuracy": 0.4977168949771689,
|
| 49 |
+
"validation_f1_macro": 0.1329268292682927
|
| 50 |
+
},
|
| 51 |
+
{
|
| 52 |
+
"epoch": 2.0,
|
| 53 |
+
"training_loss": 1.5862088872165214,
|
| 54 |
+
"validation_loss": 1.4785966873168945,
|
| 55 |
+
"validation_accuracy": 0.6484018264840182,
|
| 56 |
+
"validation_f1_macro": 0.4379253414135677
|
| 57 |
+
},
|
| 58 |
+
{
|
| 59 |
+
"epoch": 3.0,
|
| 60 |
+
"training_loss": 1.486709772086725,
|
| 61 |
+
"validation_loss": 1.3735746145248413,
|
| 62 |
+
"validation_accuracy": 0.5844748858447488,
|
| 63 |
+
"validation_f1_macro": 0.4254201336812392
|
| 64 |
+
},
|
| 65 |
+
{
|
| 66 |
+
"epoch": 4.0,
|
| 67 |
+
"training_loss": 1.3238095277693214,
|
| 68 |
+
"validation_loss": 1.1953068971633911,
|
| 69 |
+
"validation_accuracy": 0.593607305936073,
|
| 70 |
+
"validation_f1_macro": 0.4059264209867135
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"epoch": 5.0,
|
| 74 |
+
"training_loss": 1.1833144280968644,
|
| 75 |
+
"validation_loss": 1.0689646005630493,
|
| 76 |
+
"validation_accuracy": 0.634703196347032,
|
| 77 |
+
"validation_f1_macro": 0.5306606392472901
|
| 78 |
+
},
|
| 79 |
+
{
|
| 80 |
+
"epoch": 6.0,
|
| 81 |
+
"training_loss": 1.0947908875418872,
|
| 82 |
+
"validation_loss": 0.9768268465995789,
|
| 83 |
+
"validation_accuracy": 0.684931506849315,
|
| 84 |
+
"validation_f1_macro": 0.5910805860805861
|
| 85 |
+
},
|
| 86 |
+
{
|
| 87 |
+
"epoch": 7.0,
|
| 88 |
+
"training_loss": 1.0506021293198191,
|
| 89 |
+
"validation_loss": 0.9280396103858948,
|
| 90 |
+
"validation_accuracy": 0.680365296803653,
|
| 91 |
+
"validation_f1_macro": 0.5913701533244877
|
| 92 |
+
},
|
| 93 |
+
{
|
| 94 |
+
"epoch": 8.0,
|
| 95 |
+
"training_loss": 0.999169804700991,
|
| 96 |
+
"validation_loss": 0.903730571269989,
|
| 97 |
+
"validation_accuracy": 0.6986301369863014,
|
| 98 |
+
"validation_f1_macro": 0.624375070811654
|
| 99 |
+
},
|
| 100 |
+
{
|
| 101 |
+
"epoch": 9.0,
|
| 102 |
+
"training_loss": 0.9537633395776516,
|
| 103 |
+
"validation_loss": 0.8764855861663818,
|
| 104 |
+
"validation_accuracy": 0.6986301369863014,
|
| 105 |
+
"validation_f1_macro": 0.6222269848742044
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"epoch": 10.0,
|
| 109 |
+
"training_loss": 0.9284529744124994,
|
| 110 |
+
"validation_loss": 0.870495080947876,
|
| 111 |
+
"validation_accuracy": 0.7168949771689498,
|
| 112 |
+
"validation_f1_macro": 0.6800145976305553
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"epoch": 11.0,
|
| 116 |
+
"training_loss": 0.9191909265227434,
|
| 117 |
+
"validation_loss": 0.8306586742401123,
|
| 118 |
+
"validation_accuracy": 0.6940639269406392,
|
| 119 |
+
"validation_f1_macro": 0.6281475784972053
|
| 120 |
+
},
|
| 121 |
+
{
|
| 122 |
+
"epoch": 12.0,
|
| 123 |
+
"training_loss": 0.8589656418416558,
|
| 124 |
+
"validation_loss": 0.8354954123497009,
|
| 125 |
+
"validation_accuracy": 0.7351598173515982,
|
| 126 |
+
"validation_f1_macro": 0.7001971862442815
|
| 127 |
+
},
|
| 128 |
+
{
|
| 129 |
+
"epoch": 13.0,
|
| 130 |
+
"training_loss": 0.8755823068502473,
|
| 131 |
+
"validation_loss": 0.8147370219230652,
|
| 132 |
+
"validation_accuracy": 0.730593607305936,
|
| 133 |
+
"validation_f1_macro": 0.6888091074938482
|
| 134 |
+
},
|
| 135 |
+
{
|
| 136 |
+
"epoch": 14.0,
|
| 137 |
+
"training_loss": 0.8297777030526138,
|
| 138 |
+
"validation_loss": 0.7851540446281433,
|
| 139 |
+
"validation_accuracy": 0.7351598173515982,
|
| 140 |
+
"validation_f1_macro": 0.6843052757402035
|
| 141 |
+
},
|
| 142 |
+
{
|
| 143 |
+
"epoch": 15.0,
|
| 144 |
+
"training_loss": 0.7822338589807836,
|
| 145 |
+
"validation_loss": 0.777275562286377,
|
| 146 |
+
"validation_accuracy": 0.7579908675799086,
|
| 147 |
+
"validation_f1_macro": 0.7143041489780522
|
| 148 |
+
},
|
| 149 |
+
{
|
| 150 |
+
"epoch": 16.0,
|
| 151 |
+
"training_loss": 0.7837169664662059,
|
| 152 |
+
"validation_loss": 0.7484090328216553,
|
| 153 |
+
"validation_accuracy": 0.7077625570776256,
|
| 154 |
+
"validation_f1_macro": 0.62636908727515
|
| 155 |
+
},
|
| 156 |
+
{
|
| 157 |
+
"epoch": 17.0,
|
| 158 |
+
"training_loss": 0.7800104937902311,
|
| 159 |
+
"validation_loss": 0.7660107016563416,
|
| 160 |
+
"validation_accuracy": 0.7397260273972602,
|
| 161 |
+
"validation_f1_macro": 0.7004440484591072
|
| 162 |
+
},
|
| 163 |
+
{
|
| 164 |
+
"epoch": 18.0,
|
| 165 |
+
"training_loss": 0.7730191902416509,
|
| 166 |
+
"validation_loss": 0.7944260835647583,
|
| 167 |
+
"validation_accuracy": 0.7214611872146118,
|
| 168 |
+
"validation_f1_macro": 0.698860395932188
|
| 169 |
+
},
|
| 170 |
+
{
|
| 171 |
+
"epoch": 19.0,
|
| 172 |
+
"training_loss": 0.7873704033653911,
|
| 173 |
+
"validation_loss": 0.7639477252960205,
|
| 174 |
+
"validation_accuracy": 0.7397260273972602,
|
| 175 |
+
"validation_f1_macro": 0.7032332841288065
|
| 176 |
+
},
|
| 177 |
+
{
|
| 178 |
+
"epoch": 20.0,
|
| 179 |
+
"training_loss": 0.7558516823663944,
|
| 180 |
+
"validation_loss": 0.7414798736572266,
|
| 181 |
+
"validation_accuracy": 0.7397260273972602,
|
| 182 |
+
"validation_f1_macro": 0.7004440484591072
|
| 183 |
+
},
|
| 184 |
+
{
|
| 185 |
+
"epoch": 21.0,
|
| 186 |
+
"training_loss": 0.7153960161092805,
|
| 187 |
+
"validation_loss": 0.7372803688049316,
|
| 188 |
+
"validation_accuracy": 0.7397260273972602,
|
| 189 |
+
"validation_f1_macro": 0.7106842540796777
|
| 190 |
+
},
|
| 191 |
+
{
|
| 192 |
+
"epoch": 22.0,
|
| 193 |
+
"training_loss": 0.7558937465272298,
|
| 194 |
+
"validation_loss": 0.7276725172996521,
|
| 195 |
+
"validation_accuracy": 0.7351598173515982,
|
| 196 |
+
"validation_f1_macro": 0.6967894385370114
|
| 197 |
+
},
|
| 198 |
+
{
|
| 199 |
+
"epoch": 23.0,
|
| 200 |
+
"training_loss": 0.7580708134465102,
|
| 201 |
+
"validation_loss": 0.7531004548072815,
|
| 202 |
+
"validation_accuracy": 0.730593607305936,
|
| 203 |
+
"validation_f1_macro": 0.7047526663942533
|
| 204 |
+
},
|
| 205 |
+
{
|
| 206 |
+
"epoch": 24.0,
|
| 207 |
+
"training_loss": 0.745811897807005,
|
| 208 |
+
"validation_loss": 0.7062485218048096,
|
| 209 |
+
"validation_accuracy": 0.7534246575342466,
|
| 210 |
+
"validation_f1_macro": 0.7125710434661245
|
| 211 |
+
},
|
| 212 |
+
{
|
| 213 |
+
"epoch": 25.0,
|
| 214 |
+
"training_loss": 0.7463469519847776,
|
| 215 |
+
"validation_loss": 0.7009532451629639,
|
| 216 |
+
"validation_accuracy": 0.7488584474885844,
|
| 217 |
+
"validation_f1_macro": 0.7095670971936119
|
| 218 |
+
},
|
| 219 |
+
{
|
| 220 |
+
"epoch": 26.0,
|
| 221 |
+
"training_loss": 0.7205249856158,
|
| 222 |
+
"validation_loss": 0.7257617712020874,
|
| 223 |
+
"validation_accuracy": 0.730593607305936,
|
| 224 |
+
"validation_f1_macro": 0.7043211959834462
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"epoch": 27.0,
|
| 228 |
+
"training_loss": 0.7136954007352271,
|
| 229 |
+
"validation_loss": 0.7064869999885559,
|
| 230 |
+
"validation_accuracy": 0.7397260273972602,
|
| 231 |
+
"validation_f1_macro": 0.6991019731795038
|
| 232 |
+
},
|
| 233 |
+
{
|
| 234 |
+
"epoch": 28.0,
|
| 235 |
+
"training_loss": 0.6904271637521139,
|
| 236 |
+
"validation_loss": 0.6817423701286316,
|
| 237 |
+
"validation_accuracy": 0.7488584474885844,
|
| 238 |
+
"validation_f1_macro": 0.7013489796588387
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"epoch": 29.0,
|
| 242 |
+
"training_loss": 0.7016249146403336,
|
| 243 |
+
"validation_loss": 0.7140704989433289,
|
| 244 |
+
"validation_accuracy": 0.7442922374429224,
|
| 245 |
+
"validation_f1_macro": 0.7183729324463023
|
| 246 |
+
},
|
| 247 |
+
{
|
| 248 |
+
"epoch": 30.0,
|
| 249 |
+
"training_loss": 0.7061529159545898,
|
| 250 |
+
"validation_loss": 0.6985487341880798,
|
| 251 |
+
"validation_accuracy": 0.7579908675799086,
|
| 252 |
+
"validation_f1_macro": 0.7151389502609014
|
| 253 |
+
},
|
| 254 |
+
{
|
| 255 |
+
"epoch": 31.0,
|
| 256 |
+
"training_loss": 0.6901032234110483,
|
| 257 |
+
"validation_loss": 0.7164368033409119,
|
| 258 |
+
"validation_accuracy": 0.7534246575342466,
|
| 259 |
+
"validation_f1_macro": 0.7228159409058066
|
| 260 |
+
},
|
| 261 |
+
{
|
| 262 |
+
"epoch": 32.0,
|
| 263 |
+
"training_loss": 0.6837317685528499,
|
| 264 |
+
"validation_loss": 0.6936579346656799,
|
| 265 |
+
"validation_accuracy": 0.7534246575342466,
|
| 266 |
+
"validation_f1_macro": 0.7228092332549204
|
| 267 |
+
},
|
| 268 |
+
{
|
| 269 |
+
"epoch": 33.0,
|
| 270 |
+
"training_loss": 0.687675036308242,
|
| 271 |
+
"validation_loss": 0.6586704850196838,
|
| 272 |
+
"validation_accuracy": 0.7488584474885844,
|
| 273 |
+
"validation_f1_macro": 0.7046216551479709
|
| 274 |
+
},
|
| 275 |
+
{
|
| 276 |
+
"epoch": 34.0,
|
| 277 |
+
"training_loss": 0.6865368398224435,
|
| 278 |
+
"validation_loss": 0.6734499335289001,
|
| 279 |
+
"validation_accuracy": 0.7534246575342466,
|
| 280 |
+
"validation_f1_macro": 0.7203484733365098
|
| 281 |
+
},
|
| 282 |
+
{
|
| 283 |
+
"epoch": 35.0,
|
| 284 |
+
"training_loss": 0.6697868941033759,
|
| 285 |
+
"validation_loss": 0.7118483781814575,
|
| 286 |
+
"validation_accuracy": 0.7534246575342466,
|
| 287 |
+
"validation_f1_macro": 0.7191380349608197
|
| 288 |
+
},
|
| 289 |
+
{
|
| 290 |
+
"epoch": 36.0,
|
| 291 |
+
"training_loss": 0.6508736701273337,
|
| 292 |
+
"validation_loss": 0.6616345643997192,
|
| 293 |
+
"validation_accuracy": 0.7625570776255708,
|
| 294 |
+
"validation_f1_macro": 0.7231272175643826
|
| 295 |
+
},
|
| 296 |
+
{
|
| 297 |
+
"epoch": 37.0,
|
| 298 |
+
"training_loss": 0.6505100578069687,
|
| 299 |
+
"validation_loss": 0.6596866250038147,
|
| 300 |
+
"validation_accuracy": 0.7579908675799086,
|
| 301 |
+
"validation_f1_macro": 0.7151389502609014
|
| 302 |
+
},
|
| 303 |
+
{
|
| 304 |
+
"epoch": 38.0,
|
| 305 |
+
"training_loss": 0.6638081597118843,
|
| 306 |
+
"validation_loss": 0.6713008284568787,
|
| 307 |
+
"validation_accuracy": 0.7625570776255708,
|
| 308 |
+
"validation_f1_macro": 0.7279401737565508
|
| 309 |
+
},
|
| 310 |
+
{
|
| 311 |
+
"epoch": 39.0,
|
| 312 |
+
"training_loss": 0.6587427185802925,
|
| 313 |
+
"validation_loss": 0.655285656452179,
|
| 314 |
+
"validation_accuracy": 0.7625570776255708,
|
| 315 |
+
"validation_f1_macro": 0.7182102678099487
|
| 316 |
+
},
|
| 317 |
+
{
|
| 318 |
+
"epoch": 40.0,
|
| 319 |
+
"training_loss": 0.6385705103961433,
|
| 320 |
+
"validation_loss": 0.6573081016540527,
|
| 321 |
+
"validation_accuracy": 0.7625570776255708,
|
| 322 |
+
"validation_f1_macro": 0.7231272175643826
|
| 323 |
+
},
|
| 324 |
+
{
|
| 325 |
+
"epoch": 41.0,
|
| 326 |
+
"training_loss": 0.6348427366919633,
|
| 327 |
+
"validation_loss": 0.651576578617096,
|
| 328 |
+
"validation_accuracy": 0.7671232876712328,
|
| 329 |
+
"validation_f1_macro": 0.7288319857577331
|
| 330 |
+
},
|
| 331 |
+
{
|
| 332 |
+
"epoch": 42.0,
|
| 333 |
+
"training_loss": 0.6565009624492831,
|
| 334 |
+
"validation_loss": 0.6397656798362732,
|
| 335 |
+
"validation_accuracy": 0.7625570776255708,
|
| 336 |
+
"validation_f1_macro": 0.7188321070054815
|
| 337 |
+
},
|
| 338 |
+
{
|
| 339 |
+
"epoch": 43.0,
|
| 340 |
+
"training_loss": 0.6659962752970253,
|
| 341 |
+
"validation_loss": 0.6891706585884094,
|
| 342 |
+
"validation_accuracy": 0.771689497716895,
|
| 343 |
+
"validation_f1_macro": 0.7309385419512768
|
| 344 |
+
},
|
| 345 |
+
{
|
| 346 |
+
"epoch": 44.0,
|
| 347 |
+
"training_loss": 0.6738467928839893,
|
| 348 |
+
"validation_loss": 0.6647281646728516,
|
| 349 |
+
"validation_accuracy": 0.7671232876712328,
|
| 350 |
+
"validation_f1_macro": 0.7263824879672347
|
| 351 |
+
},
|
| 352 |
+
{
|
| 353 |
+
"epoch": 45.0,
|
| 354 |
+
"training_loss": 0.6135960897294487,
|
| 355 |
+
"validation_loss": 0.6542041897773743,
|
| 356 |
+
"validation_accuracy": 0.7488584474885844,
|
| 357 |
+
"validation_f1_macro": 0.7170297061311794
|
| 358 |
+
},
|
| 359 |
+
{
|
| 360 |
+
"epoch": 46.0,
|
| 361 |
+
"training_loss": 0.6420483487408336,
|
| 362 |
+
"validation_loss": 0.6627779006958008,
|
| 363 |
+
"validation_accuracy": 0.7534246575342466,
|
| 364 |
+
"validation_f1_macro": 0.7339515372302257
|
| 365 |
+
},
|
| 366 |
+
{
|
| 367 |
+
"epoch": 47.0,
|
| 368 |
+
"training_loss": 0.6316513110224794,
|
| 369 |
+
"validation_loss": 0.6684327721595764,
|
| 370 |
+
"validation_accuracy": 0.7579908675799086,
|
| 371 |
+
"validation_f1_macro": 0.7322278512955682
|
| 372 |
+
},
|
| 373 |
+
{
|
| 374 |
+
"epoch": 48.0,
|
| 375 |
+
"training_loss": 0.5976518806887836,
|
| 376 |
+
"validation_loss": 0.6376972794532776,
|
| 377 |
+
"validation_accuracy": 0.7579908675799086,
|
| 378 |
+
"validation_f1_macro": 0.72072080654124
|
| 379 |
+
},
|
| 380 |
+
{
|
| 381 |
+
"epoch": 49.0,
|
| 382 |
+
"training_loss": 0.6369955467014778,
|
| 383 |
+
"validation_loss": 0.6139159798622131,
|
| 384 |
+
"validation_accuracy": 0.7625570776255708,
|
| 385 |
+
"validation_f1_macro": 0.7241977003359705
|
| 386 |
+
},
|
| 387 |
+
{
|
| 388 |
+
"epoch": 50.0,
|
| 389 |
+
"training_loss": 0.6086341200805292,
|
| 390 |
+
"validation_loss": 0.6317619681358337,
|
| 391 |
+
"validation_accuracy": 0.7534246575342466,
|
| 392 |
+
"validation_f1_macro": 0.7226772044924286
|
| 393 |
+
}
|
| 394 |
+
]
|
| 395 |
+
},
|
| 396 |
+
{
|
| 397 |
+
"limit": 50,
|
| 398 |
+
"seed": 1,
|
| 399 |
+
"hyperparameters": {
|
| 400 |
+
"epochs": 50,
|
| 401 |
+
"batch_size": 16,
|
| 402 |
+
"learning_rate": 0.001,
|
| 403 |
+
"weight_decay": 0.0001,
|
| 404 |
+
"dropout": 0.3,
|
| 405 |
+
"projection_dim": 64,
|
| 406 |
+
"fusion_dim": 12,
|
| 407 |
+
"validation_fraction": 0.25,
|
| 408 |
+
"optimizer": "Adam",
|
| 409 |
+
"class_weighting": true,
|
| 410 |
+
"early_stopping_patience": 12,
|
| 411 |
+
"seed": 1
|
| 412 |
+
},
|
| 413 |
+
"epochs_completed": 50,
|
| 414 |
+
"best_epoch": 50,
|
| 415 |
+
"early_stopped": false,
|
| 416 |
+
"hit_max": true,
|
| 417 |
+
"train_loss_at_best": 0.6737533146288337,
|
| 418 |
+
"val_loss_at_best": 0.5473684668540955,
|
| 419 |
+
"accuracy": 0.771689497716895,
|
| 420 |
+
"f1_macro": 0.7440047141753251,
|
| 421 |
+
"f1_weighted": 0.780656107342426,
|
| 422 |
+
"recall": {
|
| 423 |
+
"0.0": 0.8275862068965517,
|
| 424 |
+
"1.0": 0.8484848484848485,
|
| 425 |
+
"2.0": 0.7272727272727273,
|
| 426 |
+
"3.0": 0.7889908256880734,
|
| 427 |
+
"4.0": 0.6216216216216216
|
| 428 |
+
},
|
| 429 |
+
"pred_counts": {
|
| 430 |
+
"0.0": 50,
|
| 431 |
+
"1.0": 30,
|
| 432 |
+
"2.0": 12,
|
| 433 |
+
"3.0": 98,
|
| 434 |
+
"4.0": 29
|
| 435 |
+
},
|
| 436 |
+
"collapsed": false,
|
| 437 |
+
"history": [
|
| 438 |
+
{
|
| 439 |
+
"epoch": 1.0,
|
| 440 |
+
"training_loss": 1.6146349499865276,
|
| 441 |
+
"validation_loss": 1.575058102607727,
|
| 442 |
+
"validation_accuracy": 0.1324200913242009,
|
| 443 |
+
"validation_f1_macro": 0.050216450216450215
|
| 444 |
+
},
|
| 445 |
+
{
|
| 446 |
+
"epoch": 2.0,
|
| 447 |
+
"training_loss": 1.5576762571567442,
|
| 448 |
+
"validation_loss": 1.4663180112838745,
|
| 449 |
+
"validation_accuracy": 0.6712328767123288,
|
| 450 |
+
"validation_f1_macro": 0.42016638018716657
|
| 451 |
+
},
|
| 452 |
+
{
|
| 453 |
+
"epoch": 3.0,
|
| 454 |
+
"training_loss": 1.429895084078719,
|
| 455 |
+
"validation_loss": 1.3014626502990723,
|
| 456 |
+
"validation_accuracy": 0.5114155251141552,
|
| 457 |
+
"validation_f1_macro": 0.43583686743324107
|
| 458 |
+
},
|
| 459 |
+
{
|
| 460 |
+
"epoch": 4.0,
|
| 461 |
+
"training_loss": 1.3091918404509382,
|
| 462 |
+
"validation_loss": 1.1551529169082642,
|
| 463 |
+
"validation_accuracy": 0.7168949771689498,
|
| 464 |
+
"validation_f1_macro": 0.5488767922611446
|
| 465 |
+
},
|
| 466 |
+
{
|
| 467 |
+
"epoch": 5.0,
|
| 468 |
+
"training_loss": 1.22728247904196,
|
| 469 |
+
"validation_loss": 1.106502652168274,
|
| 470 |
+
"validation_accuracy": 0.6757990867579908,
|
| 471 |
+
"validation_f1_macro": 0.5671942031903903
|
| 472 |
+
},
|
| 473 |
+
{
|
| 474 |
+
"epoch": 6.0,
|
| 475 |
+
"training_loss": 1.1522581679065054,
|
| 476 |
+
"validation_loss": 1.0021183490753174,
|
| 477 |
+
"validation_accuracy": 0.7351598173515982,
|
| 478 |
+
"validation_f1_macro": 0.641220618738691
|
| 479 |
+
},
|
| 480 |
+
{
|
| 481 |
+
"epoch": 7.0,
|
| 482 |
+
"training_loss": 1.0948621368989713,
|
| 483 |
+
"validation_loss": 0.9995510578155518,
|
| 484 |
+
"validation_accuracy": 0.7123287671232876,
|
| 485 |
+
"validation_f1_macro": 0.6484724275824066
|
| 486 |
+
},
|
| 487 |
+
{
|
| 488 |
+
"epoch": 8.0,
|
| 489 |
+
"training_loss": 1.039277656776149,
|
| 490 |
+
"validation_loss": 0.9134731292724609,
|
| 491 |
+
"validation_accuracy": 0.7077625570776256,
|
| 492 |
+
"validation_f1_macro": 0.600579379222993
|
| 493 |
+
},
|
| 494 |
+
{
|
| 495 |
+
"epoch": 9.0,
|
| 496 |
+
"training_loss": 0.9888714748184856,
|
| 497 |
+
"validation_loss": 0.8895769715309143,
|
| 498 |
+
"validation_accuracy": 0.7123287671232876,
|
| 499 |
+
"validation_f1_macro": 0.6438500618850422
|
| 500 |
+
},
|
| 501 |
+
{
|
| 502 |
+
"epoch": 10.0,
|
| 503 |
+
"training_loss": 0.9783786477112189,
|
| 504 |
+
"validation_loss": 0.8380142450332642,
|
| 505 |
+
"validation_accuracy": 0.7168949771689498,
|
| 506 |
+
"validation_f1_macro": 0.6358597527533143
|
| 507 |
+
},
|
| 508 |
+
{
|
| 509 |
+
"epoch": 11.0,
|
| 510 |
+
"training_loss": 0.960785810540362,
|
| 511 |
+
"validation_loss": 0.789691686630249,
|
| 512 |
+
"validation_accuracy": 0.7442922374429224,
|
| 513 |
+
"validation_f1_macro": 0.6705080988917306
|
| 514 |
+
},
|
| 515 |
+
{
|
| 516 |
+
"epoch": 12.0,
|
| 517 |
+
"training_loss": 0.932400470826684,
|
| 518 |
+
"validation_loss": 0.7533499598503113,
|
| 519 |
+
"validation_accuracy": 0.7351598173515982,
|
| 520 |
+
"validation_f1_macro": 0.6678743728192538
|
| 521 |
+
},
|
| 522 |
+
{
|
| 523 |
+
"epoch": 13.0,
|
| 524 |
+
"training_loss": 0.9086572571498591,
|
| 525 |
+
"validation_loss": 0.7680419683456421,
|
| 526 |
+
"validation_accuracy": 0.7671232876712328,
|
| 527 |
+
"validation_f1_macro": 0.7357015533486121
|
| 528 |
+
},
|
| 529 |
+
{
|
| 530 |
+
"epoch": 14.0,
|
| 531 |
+
"training_loss": 0.8951937149210674,
|
| 532 |
+
"validation_loss": 0.7899214029312134,
|
| 533 |
+
"validation_accuracy": 0.7442922374429224,
|
| 534 |
+
"validation_f1_macro": 0.6859978502715481
|
| 535 |
+
},
|
| 536 |
+
{
|
| 537 |
+
"epoch": 15.0,
|
| 538 |
+
"training_loss": 0.8932757028719274,
|
| 539 |
+
"validation_loss": 0.7378162145614624,
|
| 540 |
+
"validation_accuracy": 0.771689497716895,
|
| 541 |
+
"validation_f1_macro": 0.7412681571302261
|
| 542 |
+
},
|
| 543 |
+
{
|
| 544 |
+
"epoch": 16.0,
|
| 545 |
+
"training_loss": 0.8621222921987859,
|
| 546 |
+
"validation_loss": 0.709632158279419,
|
| 547 |
+
"validation_accuracy": 0.7808219178082192,
|
| 548 |
+
"validation_f1_macro": 0.7469195430713926
|
| 549 |
+
},
|
| 550 |
+
{
|
| 551 |
+
"epoch": 17.0,
|
| 552 |
+
"training_loss": 0.8679965152973081,
|
| 553 |
+
"validation_loss": 0.700313925743103,
|
| 554 |
+
"validation_accuracy": 0.776255707762557,
|
| 555 |
+
"validation_f1_macro": 0.7520373878994568
|
| 556 |
+
},
|
| 557 |
+
{
|
| 558 |
+
"epoch": 18.0,
|
| 559 |
+
"training_loss": 0.856050679596459,
|
| 560 |
+
"validation_loss": 0.7888535857200623,
|
| 561 |
+
"validation_accuracy": 0.730593607305936,
|
| 562 |
+
"validation_f1_macro": 0.720227319958807
|
| 563 |
+
},
|
| 564 |
+
{
|
| 565 |
+
"epoch": 19.0,
|
| 566 |
+
"training_loss": 0.8359041402979595,
|
| 567 |
+
"validation_loss": 0.7383802533149719,
|
| 568 |
+
"validation_accuracy": 0.7579908675799086,
|
| 569 |
+
"validation_f1_macro": 0.7502831048969638
|
| 570 |
+
},
|
| 571 |
+
{
|
| 572 |
+
"epoch": 20.0,
|
| 573 |
+
"training_loss": 0.8181704050157128,
|
| 574 |
+
"validation_loss": 0.6877511143684387,
|
| 575 |
+
"validation_accuracy": 0.771689497716895,
|
| 576 |
+
"validation_f1_macro": 0.7477847298339626
|
| 577 |
+
},
|
| 578 |
+
{
|
| 579 |
+
"epoch": 21.0,
|
| 580 |
+
"training_loss": 0.8081453064592873,
|
| 581 |
+
"validation_loss": 0.6738131642341614,
|
| 582 |
+
"validation_accuracy": 0.771689497716895,
|
| 583 |
+
"validation_f1_macro": 0.7477847298339626
|
| 584 |
+
},
|
| 585 |
+
{
|
| 586 |
+
"epoch": 22.0,
|
| 587 |
+
"training_loss": 0.8146184283058818,
|
| 588 |
+
"validation_loss": 0.6859759092330933,
|
| 589 |
+
"validation_accuracy": 0.776255707762557,
|
| 590 |
+
"validation_f1_macro": 0.7519691047333475
|
| 591 |
+
},
|
| 592 |
+
{
|
| 593 |
+
"epoch": 23.0,
|
| 594 |
+
"training_loss": 0.7658585833340157,
|
| 595 |
+
"validation_loss": 0.6654026508331299,
|
| 596 |
+
"validation_accuracy": 0.771689497716895,
|
| 597 |
+
"validation_f1_macro": 0.7481259028885503
|
| 598 |
+
},
|
| 599 |
+
{
|
| 600 |
+
"epoch": 24.0,
|
| 601 |
+
"training_loss": 0.795221415961661,
|
| 602 |
+
"validation_loss": 0.6880972385406494,
|
| 603 |
+
"validation_accuracy": 0.7671232876712328,
|
| 604 |
+
"validation_f1_macro": 0.749113261531172
|
| 605 |
+
},
|
| 606 |
+
{
|
| 607 |
+
"epoch": 25.0,
|
| 608 |
+
"training_loss": 0.766509844762523,
|
| 609 |
+
"validation_loss": 0.6547732353210449,
|
| 610 |
+
"validation_accuracy": 0.776255707762557,
|
| 611 |
+
"validation_f1_macro": 0.7504815593738889
|
| 612 |
+
},
|
| 613 |
+
{
|
| 614 |
+
"epoch": 26.0,
|
| 615 |
+
"training_loss": 0.7451754779350467,
|
| 616 |
+
"validation_loss": 0.641086757183075,
|
| 617 |
+
"validation_accuracy": 0.776255707762557,
|
| 618 |
+
"validation_f1_macro": 0.7513249611234765
|
| 619 |
+
},
|
| 620 |
+
{
|
| 621 |
+
"epoch": 27.0,
|
| 622 |
+
"training_loss": 0.7445048566271619,
|
| 623 |
+
"validation_loss": 0.6966652870178223,
|
| 624 |
+
"validation_accuracy": 0.7579908675799086,
|
| 625 |
+
"validation_f1_macro": 0.7606411893521148
|
| 626 |
+
},
|
| 627 |
+
{
|
| 628 |
+
"epoch": 28.0,
|
| 629 |
+
"training_loss": 0.7651737048858549,
|
| 630 |
+
"validation_loss": 0.6241215467453003,
|
| 631 |
+
"validation_accuracy": 0.771689497716895,
|
| 632 |
+
"validation_f1_macro": 0.7420460368375397
|
| 633 |
+
},
|
| 634 |
+
{
|
| 635 |
+
"epoch": 29.0,
|
| 636 |
+
"training_loss": 0.7353100442304844,
|
| 637 |
+
"validation_loss": 0.6544505953788757,
|
| 638 |
+
"validation_accuracy": 0.776255707762557,
|
| 639 |
+
"validation_f1_macro": 0.7657700127712094
|
| 640 |
+
},
|
| 641 |
+
{
|
| 642 |
+
"epoch": 30.0,
|
| 643 |
+
"training_loss": 0.7035701282140685,
|
| 644 |
+
"validation_loss": 0.6174139380455017,
|
| 645 |
+
"validation_accuracy": 0.771689497716895,
|
| 646 |
+
"validation_f1_macro": 0.7498252638827072
|
| 647 |
+
},
|
| 648 |
+
{
|
| 649 |
+
"epoch": 31.0,
|
| 650 |
+
"training_loss": 0.7469911822458593,
|
| 651 |
+
"validation_loss": 0.6883834004402161,
|
| 652 |
+
"validation_accuracy": 0.7488584474885844,
|
| 653 |
+
"validation_f1_macro": 0.7347811350746591
|
| 654 |
+
},
|
| 655 |
+
{
|
| 656 |
+
"epoch": 32.0,
|
| 657 |
+
"training_loss": 0.7179534958630074,
|
| 658 |
+
"validation_loss": 0.6455731391906738,
|
| 659 |
+
"validation_accuracy": 0.7534246575342466,
|
| 660 |
+
"validation_f1_macro": 0.732234748765767
|
| 661 |
+
},
|
| 662 |
+
{
|
| 663 |
+
"epoch": 33.0,
|
| 664 |
+
"training_loss": 0.7100564270484738,
|
| 665 |
+
"validation_loss": 0.6091746687889099,
|
| 666 |
+
"validation_accuracy": 0.7671232876712328,
|
| 667 |
+
"validation_f1_macro": 0.7317109445711596
|
| 668 |
+
},
|
| 669 |
+
{
|
| 670 |
+
"epoch": 34.0,
|
| 671 |
+
"training_loss": 0.7199300287700281,
|
| 672 |
+
"validation_loss": 0.6026328206062317,
|
| 673 |
+
"validation_accuracy": 0.7625570776255708,
|
| 674 |
+
"validation_f1_macro": 0.7308664449238883
|
| 675 |
+
},
|
| 676 |
+
{
|
| 677 |
+
"epoch": 35.0,
|
| 678 |
+
"training_loss": 0.6912782046853042,
|
| 679 |
+
"validation_loss": 0.5964751243591309,
|
| 680 |
+
"validation_accuracy": 0.7671232876712328,
|
| 681 |
+
"validation_f1_macro": 0.7353358103716783
|
| 682 |
+
},
|
| 683 |
+
{
|
| 684 |
+
"epoch": 36.0,
|
| 685 |
+
"training_loss": 0.699575291174214,
|
| 686 |
+
"validation_loss": 0.6650922894477844,
|
| 687 |
+
"validation_accuracy": 0.7488584474885844,
|
| 688 |
+
"validation_f1_macro": 0.7315696649029981
|
| 689 |
+
},
|
| 690 |
+
{
|
| 691 |
+
"epoch": 37.0,
|
| 692 |
+
"training_loss": 0.663958967458911,
|
| 693 |
+
"validation_loss": 0.6142030954360962,
|
| 694 |
+
"validation_accuracy": 0.776255707762557,
|
| 695 |
+
"validation_f1_macro": 0.7528734567901234
|
| 696 |
+
},
|
| 697 |
+
{
|
| 698 |
+
"epoch": 38.0,
|
| 699 |
+
"training_loss": 0.7137848516789879,
|
| 700 |
+
"validation_loss": 0.6241359710693359,
|
| 701 |
+
"validation_accuracy": 0.7671232876712328,
|
| 702 |
+
"validation_f1_macro": 0.752736056214317
|
| 703 |
+
},
|
| 704 |
+
{
|
| 705 |
+
"epoch": 39.0,
|
| 706 |
+
"training_loss": 0.6935832740330115,
|
| 707 |
+
"validation_loss": 0.6146963238716125,
|
| 708 |
+
"validation_accuracy": 0.776255707762557,
|
| 709 |
+
"validation_f1_macro": 0.7642682594117683
|
| 710 |
+
},
|
| 711 |
+
{
|
| 712 |
+
"epoch": 40.0,
|
| 713 |
+
"training_loss": 0.6634499815905966,
|
| 714 |
+
"validation_loss": 0.647922694683075,
|
| 715 |
+
"validation_accuracy": 0.7442922374429224,
|
| 716 |
+
"validation_f1_macro": 0.7336896086369771
|
| 717 |
+
},
|
| 718 |
+
{
|
| 719 |
+
"epoch": 41.0,
|
| 720 |
+
"training_loss": 0.6981347810204436,
|
| 721 |
+
"validation_loss": 0.6087270379066467,
|
| 722 |
+
"validation_accuracy": 0.7579908675799086,
|
| 723 |
+
"validation_f1_macro": 0.740196849837119
|
| 724 |
+
},
|
| 725 |
+
{
|
| 726 |
+
"epoch": 42.0,
|
| 727 |
+
"training_loss": 0.6437401011949633,
|
| 728 |
+
"validation_loss": 0.5964922904968262,
|
| 729 |
+
"validation_accuracy": 0.771689497716895,
|
| 730 |
+
"validation_f1_macro": 0.7530886671461106
|
| 731 |
+
},
|
| 732 |
+
{
|
| 733 |
+
"epoch": 43.0,
|
| 734 |
+
"training_loss": 0.6792685098764373,
|
| 735 |
+
"validation_loss": 0.625365674495697,
|
| 736 |
+
"validation_accuracy": 0.7625570776255708,
|
| 737 |
+
"validation_f1_macro": 0.7529175812892382
|
| 738 |
+
},
|
| 739 |
+
{
|
| 740 |
+
"epoch": 44.0,
|
| 741 |
+
"training_loss": 0.6364530761067461,
|
| 742 |
+
"validation_loss": 0.5903960466384888,
|
| 743 |
+
"validation_accuracy": 0.7579908675799086,
|
| 744 |
+
"validation_f1_macro": 0.743187921582135
|
| 745 |
+
},
|
| 746 |
+
{
|
| 747 |
+
"epoch": 45.0,
|
| 748 |
+
"training_loss": 0.6544558653017369,
|
| 749 |
+
"validation_loss": 0.6682825684547424,
|
| 750 |
+
"validation_accuracy": 0.7579908675799086,
|
| 751 |
+
"validation_f1_macro": 0.757454120777634
|
| 752 |
+
},
|
| 753 |
+
{
|
| 754 |
+
"epoch": 46.0,
|
| 755 |
+
"training_loss": 0.6508243360170504,
|
| 756 |
+
"validation_loss": 0.5978586077690125,
|
| 757 |
+
"validation_accuracy": 0.7625570776255708,
|
| 758 |
+
"validation_f1_macro": 0.7392423117547007
|
| 759 |
+
},
|
| 760 |
+
{
|
| 761 |
+
"epoch": 47.0,
|
| 762 |
+
"training_loss": 0.6495987329541183,
|
| 763 |
+
"validation_loss": 0.6385520100593567,
|
| 764 |
+
"validation_accuracy": 0.7625570776255708,
|
| 765 |
+
"validation_f1_macro": 0.7542611570673247
|
| 766 |
+
},
|
| 767 |
+
{
|
| 768 |
+
"epoch": 48.0,
|
| 769 |
+
"training_loss": 0.6470511155884441,
|
| 770 |
+
"validation_loss": 0.6651841998100281,
|
| 771 |
+
"validation_accuracy": 0.7534246575342466,
|
| 772 |
+
"validation_f1_macro": 0.7437327104909329
|
| 773 |
+
},
|
| 774 |
+
{
|
| 775 |
+
"epoch": 49.0,
|
| 776 |
+
"training_loss": 0.6453332679300774,
|
| 777 |
+
"validation_loss": 0.5932057499885559,
|
| 778 |
+
"validation_accuracy": 0.771689497716895,
|
| 779 |
+
"validation_f1_macro": 0.7604378496705634
|
| 780 |
+
},
|
| 781 |
+
{
|
| 782 |
+
"epoch": 50.0,
|
| 783 |
+
"training_loss": 0.6737533146288337,
|
| 784 |
+
"validation_loss": 0.5473684668540955,
|
| 785 |
+
"validation_accuracy": 0.771689497716895,
|
| 786 |
+
"validation_f1_macro": 0.7440047141753251
|
| 787 |
+
}
|
| 788 |
+
]
|
| 789 |
+
},
|
| 790 |
+
{
|
| 791 |
+
"limit": 50,
|
| 792 |
+
"seed": 2,
|
| 793 |
+
"hyperparameters": {
|
| 794 |
+
"epochs": 50,
|
| 795 |
+
"batch_size": 16,
|
| 796 |
+
"learning_rate": 0.001,
|
| 797 |
+
"weight_decay": 0.0001,
|
| 798 |
+
"dropout": 0.3,
|
| 799 |
+
"projection_dim": 64,
|
| 800 |
+
"fusion_dim": 12,
|
| 801 |
+
"validation_fraction": 0.25,
|
| 802 |
+
"optimizer": "Adam",
|
| 803 |
+
"class_weighting": true,
|
| 804 |
+
"early_stopping_patience": 12,
|
| 805 |
+
"seed": 2
|
| 806 |
+
},
|
| 807 |
+
"epochs_completed": 50,
|
| 808 |
+
"best_epoch": 50,
|
| 809 |
+
"early_stopped": false,
|
| 810 |
+
"hit_max": true,
|
| 811 |
+
"train_loss_at_best": 0.6226128528757793,
|
| 812 |
+
"val_loss_at_best": 0.6078133583068848,
|
| 813 |
+
"accuracy": 0.7899543378995434,
|
| 814 |
+
"f1_macro": 0.7605265274426602,
|
| 815 |
+
"f1_weighted": 0.8021877366164152,
|
| 816 |
+
"recall": {
|
| 817 |
+
"0.0": 0.8620689655172413,
|
| 818 |
+
"1.0": 0.7878787878787878,
|
| 819 |
+
"2.0": 0.9090909090909091,
|
| 820 |
+
"3.0": 0.7981651376146789,
|
| 821 |
+
"4.0": 0.6756756756756757
|
| 822 |
+
},
|
| 823 |
+
"pred_counts": {
|
| 824 |
+
"0.0": 51,
|
| 825 |
+
"1.0": 27,
|
| 826 |
+
"2.0": 17,
|
| 827 |
+
"3.0": 93,
|
| 828 |
+
"4.0": 31
|
| 829 |
+
},
|
| 830 |
+
"collapsed": false,
|
| 831 |
+
"history": [
|
| 832 |
+
{
|
| 833 |
+
"epoch": 1.0,
|
| 834 |
+
"training_loss": 1.6174468180028403,
|
| 835 |
+
"validation_loss": 1.546391487121582,
|
| 836 |
+
"validation_accuracy": 0.4977168949771689,
|
| 837 |
+
"validation_f1_macro": 0.1329268292682927
|
| 838 |
+
},
|
| 839 |
+
{
|
| 840 |
+
"epoch": 2.0,
|
| 841 |
+
"training_loss": 1.58593586596047,
|
| 842 |
+
"validation_loss": 1.4984139204025269,
|
| 843 |
+
"validation_accuracy": 0.634703196347032,
|
| 844 |
+
"validation_f1_macro": 0.32264243870355924
|
| 845 |
+
},
|
| 846 |
+
{
|
| 847 |
+
"epoch": 3.0,
|
| 848 |
+
"training_loss": 1.5026960140321313,
|
| 849 |
+
"validation_loss": 1.3888118267059326,
|
| 850 |
+
"validation_accuracy": 0.6301369863013698,
|
| 851 |
+
"validation_f1_macro": 0.4463465487656915
|
| 852 |
+
},
|
| 853 |
+
{
|
| 854 |
+
"epoch": 4.0,
|
| 855 |
+
"training_loss": 1.366911018767008,
|
| 856 |
+
"validation_loss": 1.223652720451355,
|
| 857 |
+
"validation_accuracy": 0.6666666666666666,
|
| 858 |
+
"validation_f1_macro": 0.48780167888527026
|
| 859 |
+
},
|
| 860 |
+
{
|
| 861 |
+
"epoch": 5.0,
|
| 862 |
+
"training_loss": 1.242981534178664,
|
| 863 |
+
"validation_loss": 1.0726312398910522,
|
| 864 |
+
"validation_accuracy": 0.6894977168949772,
|
| 865 |
+
"validation_f1_macro": 0.5486778629605984
|
| 866 |
+
},
|
| 867 |
+
{
|
| 868 |
+
"epoch": 6.0,
|
| 869 |
+
"training_loss": 1.162133698056384,
|
| 870 |
+
"validation_loss": 1.0369216203689575,
|
| 871 |
+
"validation_accuracy": 0.7077625570776256,
|
| 872 |
+
"validation_f1_macro": 0.5994216476773437
|
| 873 |
+
},
|
| 874 |
+
{
|
| 875 |
+
"epoch": 7.0,
|
| 876 |
+
"training_loss": 1.0751376282878038,
|
| 877 |
+
"validation_loss": 0.9657370448112488,
|
| 878 |
+
"validation_accuracy": 0.7214611872146118,
|
| 879 |
+
"validation_f1_macro": 0.6168606528606528
|
| 880 |
+
},
|
| 881 |
+
{
|
| 882 |
+
"epoch": 8.0,
|
| 883 |
+
"training_loss": 1.0233616610852683,
|
| 884 |
+
"validation_loss": 0.9052940607070923,
|
| 885 |
+
"validation_accuracy": 0.7214611872146118,
|
| 886 |
+
"validation_f1_macro": 0.6206169633347545
|
| 887 |
+
},
|
| 888 |
+
{
|
| 889 |
+
"epoch": 9.0,
|
| 890 |
+
"training_loss": 0.9568443654513941,
|
| 891 |
+
"validation_loss": 0.8481383919715881,
|
| 892 |
+
"validation_accuracy": 0.7442922374429224,
|
| 893 |
+
"validation_f1_macro": 0.6569653120795127
|
| 894 |
+
},
|
| 895 |
+
{
|
| 896 |
+
"epoch": 10.0,
|
| 897 |
+
"training_loss": 0.965624666795498,
|
| 898 |
+
"validation_loss": 0.8241379857063293,
|
| 899 |
+
"validation_accuracy": 0.7488584474885844,
|
| 900 |
+
"validation_f1_macro": 0.6993045121283534
|
| 901 |
+
},
|
| 902 |
+
{
|
| 903 |
+
"epoch": 11.0,
|
| 904 |
+
"training_loss": 0.9236650459650086,
|
| 905 |
+
"validation_loss": 0.7953732013702393,
|
| 906 |
+
"validation_accuracy": 0.7397260273972602,
|
| 907 |
+
"validation_f1_macro": 0.6642163006401307
|
| 908 |
+
},
|
| 909 |
+
{
|
| 910 |
+
"epoch": 12.0,
|
| 911 |
+
"training_loss": 0.9139396679110643,
|
| 912 |
+
"validation_loss": 0.8159263730049133,
|
| 913 |
+
"validation_accuracy": 0.7625570776255708,
|
| 914 |
+
"validation_f1_macro": 0.7289687504443403
|
| 915 |
+
},
|
| 916 |
+
{
|
| 917 |
+
"epoch": 13.0,
|
| 918 |
+
"training_loss": 0.8704477693976426,
|
| 919 |
+
"validation_loss": 0.7864435911178589,
|
| 920 |
+
"validation_accuracy": 0.7671232876712328,
|
| 921 |
+
"validation_f1_macro": 0.7298061488176467
|
| 922 |
+
},
|
| 923 |
+
{
|
| 924 |
+
"epoch": 14.0,
|
| 925 |
+
"training_loss": 0.8610671446090792,
|
| 926 |
+
"validation_loss": 0.7811137437820435,
|
| 927 |
+
"validation_accuracy": 0.771689497716895,
|
| 928 |
+
"validation_f1_macro": 0.7461521382117662
|
| 929 |
+
},
|
| 930 |
+
{
|
| 931 |
+
"epoch": 15.0,
|
| 932 |
+
"training_loss": 0.8468370241362874,
|
| 933 |
+
"validation_loss": 0.7946519255638123,
|
| 934 |
+
"validation_accuracy": 0.7579908675799086,
|
| 935 |
+
"validation_f1_macro": 0.7148572825024437
|
| 936 |
+
},
|
| 937 |
+
{
|
| 938 |
+
"epoch": 16.0,
|
| 939 |
+
"training_loss": 0.8112003149055853,
|
| 940 |
+
"validation_loss": 0.759267270565033,
|
| 941 |
+
"validation_accuracy": 0.771689497716895,
|
| 942 |
+
"validation_f1_macro": 0.7438968232086511
|
| 943 |
+
},
|
| 944 |
+
{
|
| 945 |
+
"epoch": 17.0,
|
| 946 |
+
"training_loss": 0.8073849859761029,
|
| 947 |
+
"validation_loss": 0.7926062941551208,
|
| 948 |
+
"validation_accuracy": 0.7579908675799086,
|
| 949 |
+
"validation_f1_macro": 0.7186664392134682
|
| 950 |
+
},
|
| 951 |
+
{
|
| 952 |
+
"epoch": 18.0,
|
| 953 |
+
"training_loss": 0.816777443740426,
|
| 954 |
+
"validation_loss": 0.7469311952590942,
|
| 955 |
+
"validation_accuracy": 0.7579908675799086,
|
| 956 |
+
"validation_f1_macro": 0.7219948399680252
|
| 957 |
+
},
|
| 958 |
+
{
|
| 959 |
+
"epoch": 19.0,
|
| 960 |
+
"training_loss": 0.7756974529929277,
|
| 961 |
+
"validation_loss": 0.7867042422294617,
|
| 962 |
+
"validation_accuracy": 0.7534246575342466,
|
| 963 |
+
"validation_f1_macro": 0.7173738004352781
|
| 964 |
+
},
|
| 965 |
+
{
|
| 966 |
+
"epoch": 20.0,
|
| 967 |
+
"training_loss": 0.7760032975092167,
|
| 968 |
+
"validation_loss": 0.742599606513977,
|
| 969 |
+
"validation_accuracy": 0.7579908675799086,
|
| 970 |
+
"validation_f1_macro": 0.7142244295830055
|
| 971 |
+
},
|
| 972 |
+
{
|
| 973 |
+
"epoch": 21.0,
|
| 974 |
+
"training_loss": 0.7517595632774073,
|
| 975 |
+
"validation_loss": 0.7031355500221252,
|
| 976 |
+
"validation_accuracy": 0.771689497716895,
|
| 977 |
+
"validation_f1_macro": 0.7442643678160918
|
| 978 |
+
},
|
| 979 |
+
{
|
| 980 |
+
"epoch": 22.0,
|
| 981 |
+
"training_loss": 0.7545412931500411,
|
| 982 |
+
"validation_loss": 0.6887046694755554,
|
| 983 |
+
"validation_accuracy": 0.7808219178082192,
|
| 984 |
+
"validation_f1_macro": 0.7562175932096297
|
| 985 |
+
},
|
| 986 |
+
{
|
| 987 |
+
"epoch": 23.0,
|
| 988 |
+
"training_loss": 0.7387897721151027,
|
| 989 |
+
"validation_loss": 0.7003820538520813,
|
| 990 |
+
"validation_accuracy": 0.776255707762557,
|
| 991 |
+
"validation_f1_macro": 0.7543517355165935
|
| 992 |
+
},
|
| 993 |
+
{
|
| 994 |
+
"epoch": 24.0,
|
| 995 |
+
"training_loss": 0.735975246603896,
|
| 996 |
+
"validation_loss": 0.7061943411827087,
|
| 997 |
+
"validation_accuracy": 0.7579908675799086,
|
| 998 |
+
"validation_f1_macro": 0.7328107884559498
|
| 999 |
+
},
|
| 1000 |
+
{
|
| 1001 |
+
"epoch": 25.0,
|
| 1002 |
+
"training_loss": 0.7385040648826738,
|
| 1003 |
+
"validation_loss": 0.6894986033439636,
|
| 1004 |
+
"validation_accuracy": 0.7625570776255708,
|
| 1005 |
+
"validation_f1_macro": 0.7331689455756886
|
| 1006 |
+
},
|
| 1007 |
+
{
|
| 1008 |
+
"epoch": 26.0,
|
| 1009 |
+
"training_loss": 0.7225778640770331,
|
| 1010 |
+
"validation_loss": 0.6931126713752747,
|
| 1011 |
+
"validation_accuracy": 0.7853881278538812,
|
| 1012 |
+
"validation_f1_macro": 0.7605941350168008
|
| 1013 |
+
},
|
| 1014 |
+
{
|
| 1015 |
+
"epoch": 27.0,
|
| 1016 |
+
"training_loss": 0.7251168932856583,
|
| 1017 |
+
"validation_loss": 0.6966921091079712,
|
| 1018 |
+
"validation_accuracy": 0.776255707762557,
|
| 1019 |
+
"validation_f1_macro": 0.7558511749080189
|
| 1020 |
+
},
|
| 1021 |
+
{
|
| 1022 |
+
"epoch": 28.0,
|
| 1023 |
+
"training_loss": 0.6874374543748251,
|
| 1024 |
+
"validation_loss": 0.6818851232528687,
|
| 1025 |
+
"validation_accuracy": 0.776255707762557,
|
| 1026 |
+
"validation_f1_macro": 0.7543517355165935
|
| 1027 |
+
},
|
| 1028 |
+
{
|
| 1029 |
+
"epoch": 29.0,
|
| 1030 |
+
"training_loss": 0.6856663837665464,
|
| 1031 |
+
"validation_loss": 0.6972566246986389,
|
| 1032 |
+
"validation_accuracy": 0.7625570776255708,
|
| 1033 |
+
"validation_f1_macro": 0.7455299037752814
|
| 1034 |
+
},
|
| 1035 |
+
{
|
| 1036 |
+
"epoch": 30.0,
|
| 1037 |
+
"training_loss": 0.7368745691165691,
|
| 1038 |
+
"validation_loss": 0.6822320222854614,
|
| 1039 |
+
"validation_accuracy": 0.771689497716895,
|
| 1040 |
+
"validation_f1_macro": 0.7516292198922165
|
| 1041 |
+
},
|
| 1042 |
+
{
|
| 1043 |
+
"epoch": 31.0,
|
| 1044 |
+
"training_loss": 0.6798700966486116,
|
| 1045 |
+
"validation_loss": 0.6768004298210144,
|
| 1046 |
+
"validation_accuracy": 0.7534246575342466,
|
| 1047 |
+
"validation_f1_macro": 0.7219549374996355
|
| 1048 |
+
},
|
| 1049 |
+
{
|
| 1050 |
+
"epoch": 32.0,
|
| 1051 |
+
"training_loss": 0.6843307061893183,
|
| 1052 |
+
"validation_loss": 0.6862162947654724,
|
| 1053 |
+
"validation_accuracy": 0.7625570776255708,
|
| 1054 |
+
"validation_f1_macro": 0.7359209675538737
|
| 1055 |
+
},
|
| 1056 |
+
{
|
| 1057 |
+
"epoch": 33.0,
|
| 1058 |
+
"training_loss": 0.6932616771721258,
|
| 1059 |
+
"validation_loss": 0.6602873206138611,
|
| 1060 |
+
"validation_accuracy": 0.7808219178082192,
|
| 1061 |
+
"validation_f1_macro": 0.745427030596522
|
| 1062 |
+
},
|
| 1063 |
+
{
|
| 1064 |
+
"epoch": 34.0,
|
| 1065 |
+
"training_loss": 0.6615989964182784,
|
| 1066 |
+
"validation_loss": 0.6448985934257507,
|
| 1067 |
+
"validation_accuracy": 0.771689497716895,
|
| 1068 |
+
"validation_f1_macro": 0.7500281260358693
|
| 1069 |
+
},
|
| 1070 |
+
{
|
| 1071 |
+
"epoch": 35.0,
|
| 1072 |
+
"training_loss": 0.6791574282617103,
|
| 1073 |
+
"validation_loss": 0.6585924029350281,
|
| 1074 |
+
"validation_accuracy": 0.7853881278538812,
|
| 1075 |
+
"validation_f1_macro": 0.7664376696199262
|
| 1076 |
+
},
|
| 1077 |
+
{
|
| 1078 |
+
"epoch": 36.0,
|
| 1079 |
+
"training_loss": 0.657524651507052,
|
| 1080 |
+
"validation_loss": 0.6542724967002869,
|
| 1081 |
+
"validation_accuracy": 0.7808219178082192,
|
| 1082 |
+
"validation_f1_macro": 0.7626256130648112
|
| 1083 |
+
},
|
| 1084 |
+
{
|
| 1085 |
+
"epoch": 37.0,
|
| 1086 |
+
"training_loss": 0.6647858172655106,
|
| 1087 |
+
"validation_loss": 0.6971855759620667,
|
| 1088 |
+
"validation_accuracy": 0.771689497716895,
|
| 1089 |
+
"validation_f1_macro": 0.753978494623656
|
| 1090 |
+
},
|
| 1091 |
+
{
|
| 1092 |
+
"epoch": 38.0,
|
| 1093 |
+
"training_loss": 0.6512645035982132,
|
| 1094 |
+
"validation_loss": 0.666414737701416,
|
| 1095 |
+
"validation_accuracy": 0.7853881278538812,
|
| 1096 |
+
"validation_f1_macro": 0.7705946470426236
|
| 1097 |
+
},
|
| 1098 |
+
{
|
| 1099 |
+
"epoch": 39.0,
|
| 1100 |
+
"training_loss": 0.6842886165874761,
|
| 1101 |
+
"validation_loss": 0.637172281742096,
|
| 1102 |
+
"validation_accuracy": 0.7853881278538812,
|
| 1103 |
+
"validation_f1_macro": 0.7539143744415602
|
| 1104 |
+
},
|
| 1105 |
+
{
|
| 1106 |
+
"epoch": 40.0,
|
| 1107 |
+
"training_loss": 0.6806678484852721,
|
| 1108 |
+
"validation_loss": 0.6234135627746582,
|
| 1109 |
+
"validation_accuracy": 0.776255707762557,
|
| 1110 |
+
"validation_f1_macro": 0.7615367535963815
|
| 1111 |
+
},
|
| 1112 |
+
{
|
| 1113 |
+
"epoch": 41.0,
|
| 1114 |
+
"training_loss": 0.616909401082411,
|
| 1115 |
+
"validation_loss": 0.6653591394424438,
|
| 1116 |
+
"validation_accuracy": 0.7808219178082192,
|
| 1117 |
+
"validation_f1_macro": 0.755696817874246
|
| 1118 |
+
},
|
| 1119 |
+
{
|
| 1120 |
+
"epoch": 42.0,
|
| 1121 |
+
"training_loss": 0.6306327792202554,
|
| 1122 |
+
"validation_loss": 0.6591380834579468,
|
| 1123 |
+
"validation_accuracy": 0.7853881278538812,
|
| 1124 |
+
"validation_f1_macro": 0.7742082670405406
|
| 1125 |
+
},
|
| 1126 |
+
{
|
| 1127 |
+
"epoch": 43.0,
|
| 1128 |
+
"training_loss": 0.613016491982995,
|
| 1129 |
+
"validation_loss": 0.6415198445320129,
|
| 1130 |
+
"validation_accuracy": 0.7945205479452054,
|
| 1131 |
+
"validation_f1_macro": 0.7785763733179202
|
| 1132 |
+
},
|
| 1133 |
+
{
|
| 1134 |
+
"epoch": 44.0,
|
| 1135 |
+
"training_loss": 0.6375173973601039,
|
| 1136 |
+
"validation_loss": 0.6755697727203369,
|
| 1137 |
+
"validation_accuracy": 0.776255707762557,
|
| 1138 |
+
"validation_f1_macro": 0.762229243198948
|
| 1139 |
+
},
|
| 1140 |
+
{
|
| 1141 |
+
"epoch": 45.0,
|
| 1142 |
+
"training_loss": 0.6442778532097979,
|
| 1143 |
+
"validation_loss": 0.6340303421020508,
|
| 1144 |
+
"validation_accuracy": 0.7808219178082192,
|
| 1145 |
+
"validation_f1_macro": 0.7672196170102448
|
| 1146 |
+
},
|
| 1147 |
+
{
|
| 1148 |
+
"epoch": 46.0,
|
| 1149 |
+
"training_loss": 0.6433215337555583,
|
| 1150 |
+
"validation_loss": 0.6413596272468567,
|
| 1151 |
+
"validation_accuracy": 0.776255707762557,
|
| 1152 |
+
"validation_f1_macro": 0.7579256303497852
|
| 1153 |
+
},
|
| 1154 |
+
{
|
| 1155 |
+
"epoch": 47.0,
|
| 1156 |
+
"training_loss": 0.6104130672245491,
|
| 1157 |
+
"validation_loss": 0.691887617111206,
|
| 1158 |
+
"validation_accuracy": 0.776255707762557,
|
| 1159 |
+
"validation_f1_macro": 0.7639407057578872
|
| 1160 |
+
},
|
| 1161 |
+
{
|
| 1162 |
+
"epoch": 48.0,
|
| 1163 |
+
"training_loss": 0.6267564820080269,
|
| 1164 |
+
"validation_loss": 0.6122168302536011,
|
| 1165 |
+
"validation_accuracy": 0.776255707762557,
|
| 1166 |
+
"validation_f1_macro": 0.7422206267279872
|
| 1167 |
+
},
|
| 1168 |
+
{
|
| 1169 |
+
"epoch": 49.0,
|
| 1170 |
+
"training_loss": 0.6220824849314806,
|
| 1171 |
+
"validation_loss": 0.6251174807548523,
|
| 1172 |
+
"validation_accuracy": 0.7945205479452054,
|
| 1173 |
+
"validation_f1_macro": 0.7765977910787982
|
| 1174 |
+
},
|
| 1175 |
+
{
|
| 1176 |
+
"epoch": 50.0,
|
| 1177 |
+
"training_loss": 0.6226128528757793,
|
| 1178 |
+
"validation_loss": 0.6078133583068848,
|
| 1179 |
+
"validation_accuracy": 0.7899543378995434,
|
| 1180 |
+
"validation_f1_macro": 0.7605265274426602
|
| 1181 |
+
}
|
| 1182 |
+
]
|
| 1183 |
+
},
|
| 1184 |
+
{
|
| 1185 |
+
"limit": 50,
|
| 1186 |
+
"seed": 3,
|
| 1187 |
+
"hyperparameters": {
|
| 1188 |
+
"epochs": 50,
|
| 1189 |
+
"batch_size": 16,
|
| 1190 |
+
"learning_rate": 0.001,
|
| 1191 |
+
"weight_decay": 0.0001,
|
| 1192 |
+
"dropout": 0.3,
|
| 1193 |
+
"projection_dim": 64,
|
| 1194 |
+
"fusion_dim": 12,
|
| 1195 |
+
"validation_fraction": 0.25,
|
| 1196 |
+
"optimizer": "Adam",
|
| 1197 |
+
"class_weighting": true,
|
| 1198 |
+
"early_stopping_patience": 12,
|
| 1199 |
+
"seed": 3
|
| 1200 |
+
},
|
| 1201 |
+
"epochs_completed": 50,
|
| 1202 |
+
"best_epoch": 47,
|
| 1203 |
+
"early_stopped": false,
|
| 1204 |
+
"hit_max": true,
|
| 1205 |
+
"train_loss_at_best": 0.6082611465599479,
|
| 1206 |
+
"val_loss_at_best": 0.7235217690467834,
|
| 1207 |
+
"accuracy": 0.730593607305936,
|
| 1208 |
+
"f1_macro": 0.714038944252953,
|
| 1209 |
+
"f1_weighted": 0.7389451956635594,
|
| 1210 |
+
"recall": {
|
| 1211 |
+
"0.0": 0.7931034482758621,
|
| 1212 |
+
"1.0": 0.8181818181818182,
|
| 1213 |
+
"2.0": 0.5454545454545454,
|
| 1214 |
+
"3.0": 0.7431192660550459,
|
| 1215 |
+
"4.0": 0.6216216216216216
|
| 1216 |
+
},
|
| 1217 |
+
"pred_counts": {
|
| 1218 |
+
"0.0": 48,
|
| 1219 |
+
"1.0": 29,
|
| 1220 |
+
"2.0": 6,
|
| 1221 |
+
"3.0": 98,
|
| 1222 |
+
"4.0": 38
|
| 1223 |
+
},
|
| 1224 |
+
"collapsed": false,
|
| 1225 |
+
"history": [
|
| 1226 |
+
{
|
| 1227 |
+
"epoch": 1.0,
|
| 1228 |
+
"training_loss": 1.6220814803751504,
|
| 1229 |
+
"validation_loss": 1.5875742435455322,
|
| 1230 |
+
"validation_accuracy": 0.1689497716894977,
|
| 1231 |
+
"validation_f1_macro": 0.058039215686274515
|
| 1232 |
+
},
|
| 1233 |
+
{
|
| 1234 |
+
"epoch": 2.0,
|
| 1235 |
+
"training_loss": 1.5936871476289702,
|
| 1236 |
+
"validation_loss": 1.5093015432357788,
|
| 1237 |
+
"validation_accuracy": 0.5296803652968036,
|
| 1238 |
+
"validation_f1_macro": 0.24350741457124436
|
| 1239 |
+
},
|
| 1240 |
+
{
|
| 1241 |
+
"epoch": 3.0,
|
| 1242 |
+
"training_loss": 1.4826284995893153,
|
| 1243 |
+
"validation_loss": 1.3824553489685059,
|
| 1244 |
+
"validation_accuracy": 0.6529680365296804,
|
| 1245 |
+
"validation_f1_macro": 0.4183523781204423
|
| 1246 |
+
},
|
| 1247 |
+
{
|
| 1248 |
+
"epoch": 4.0,
|
| 1249 |
+
"training_loss": 1.3528232690764637,
|
| 1250 |
+
"validation_loss": 1.1993681192398071,
|
| 1251 |
+
"validation_accuracy": 0.6210045662100456,
|
| 1252 |
+
"validation_f1_macro": 0.37834817436637735
|
| 1253 |
+
},
|
| 1254 |
+
{
|
| 1255 |
+
"epoch": 5.0,
|
| 1256 |
+
"training_loss": 1.2376714392406185,
|
| 1257 |
+
"validation_loss": 1.1297868490219116,
|
| 1258 |
+
"validation_accuracy": 0.680365296803653,
|
| 1259 |
+
"validation_f1_macro": 0.5830366044722973
|
| 1260 |
+
},
|
| 1261 |
+
{
|
| 1262 |
+
"epoch": 6.0,
|
| 1263 |
+
"training_loss": 1.1285978991810868,
|
| 1264 |
+
"validation_loss": 1.022017002105713,
|
| 1265 |
+
"validation_accuracy": 0.6757990867579908,
|
| 1266 |
+
"validation_f1_macro": 0.5483004580309334
|
| 1267 |
+
},
|
| 1268 |
+
{
|
| 1269 |
+
"epoch": 7.0,
|
| 1270 |
+
"training_loss": 1.0585624633765802,
|
| 1271 |
+
"validation_loss": 0.9644467234611511,
|
| 1272 |
+
"validation_accuracy": 0.6940639269406392,
|
| 1273 |
+
"validation_f1_macro": 0.6055969275814801
|
| 1274 |
+
},
|
| 1275 |
+
{
|
| 1276 |
+
"epoch": 8.0,
|
| 1277 |
+
"training_loss": 0.9813799683640643,
|
| 1278 |
+
"validation_loss": 0.9254334568977356,
|
| 1279 |
+
"validation_accuracy": 0.684931506849315,
|
| 1280 |
+
"validation_f1_macro": 0.6203979879120456
|
| 1281 |
+
},
|
| 1282 |
+
{
|
| 1283 |
+
"epoch": 9.0,
|
| 1284 |
+
"training_loss": 0.9255651540872527,
|
| 1285 |
+
"validation_loss": 0.8911700248718262,
|
| 1286 |
+
"validation_accuracy": 0.6940639269406392,
|
| 1287 |
+
"validation_f1_macro": 0.6447277343192168
|
| 1288 |
+
},
|
| 1289 |
+
{
|
| 1290 |
+
"epoch": 10.0,
|
| 1291 |
+
"training_loss": 0.8835772624829921,
|
| 1292 |
+
"validation_loss": 0.8481254577636719,
|
| 1293 |
+
"validation_accuracy": 0.6940639269406392,
|
| 1294 |
+
"validation_f1_macro": 0.6407901155929054
|
| 1295 |
+
},
|
| 1296 |
+
{
|
| 1297 |
+
"epoch": 11.0,
|
| 1298 |
+
"training_loss": 0.8595382840168185,
|
| 1299 |
+
"validation_loss": 0.8351685404777527,
|
| 1300 |
+
"validation_accuracy": 0.6986301369863014,
|
| 1301 |
+
"validation_f1_macro": 0.6622263514454271
|
| 1302 |
+
},
|
| 1303 |
+
{
|
| 1304 |
+
"epoch": 12.0,
|
| 1305 |
+
"training_loss": 0.8846968368786138,
|
| 1306 |
+
"validation_loss": 0.8464142680168152,
|
| 1307 |
+
"validation_accuracy": 0.6940639269406392,
|
| 1308 |
+
"validation_f1_macro": 0.6477420680141102
|
| 1309 |
+
},
|
| 1310 |
+
{
|
| 1311 |
+
"epoch": 13.0,
|
| 1312 |
+
"training_loss": 0.8019941928910046,
|
| 1313 |
+
"validation_loss": 0.804776668548584,
|
| 1314 |
+
"validation_accuracy": 0.6940639269406392,
|
| 1315 |
+
"validation_f1_macro": 0.659608964024234
|
| 1316 |
+
},
|
| 1317 |
+
{
|
| 1318 |
+
"epoch": 14.0,
|
| 1319 |
+
"training_loss": 0.8261272681922447,
|
| 1320 |
+
"validation_loss": 0.8410500884056091,
|
| 1321 |
+
"validation_accuracy": 0.6986301369863014,
|
| 1322 |
+
"validation_f1_macro": 0.6681086611998096
|
| 1323 |
+
},
|
| 1324 |
+
{
|
| 1325 |
+
"epoch": 15.0,
|
| 1326 |
+
"training_loss": 0.7871945776590487,
|
| 1327 |
+
"validation_loss": 0.7961083054542542,
|
| 1328 |
+
"validation_accuracy": 0.6940639269406392,
|
| 1329 |
+
"validation_f1_macro": 0.6631208004473412
|
| 1330 |
+
},
|
| 1331 |
+
{
|
| 1332 |
+
"epoch": 16.0,
|
| 1333 |
+
"training_loss": 0.7758532391815651,
|
| 1334 |
+
"validation_loss": 0.7845243811607361,
|
| 1335 |
+
"validation_accuracy": 0.6986301369863014,
|
| 1336 |
+
"validation_f1_macro": 0.671621371001291
|
| 1337 |
+
},
|
| 1338 |
+
{
|
| 1339 |
+
"epoch": 17.0,
|
| 1340 |
+
"training_loss": 0.7620533690219973,
|
| 1341 |
+
"validation_loss": 0.7771141529083252,
|
| 1342 |
+
"validation_accuracy": 0.7031963470319634,
|
| 1343 |
+
"validation_f1_macro": 0.6743542188258713
|
| 1344 |
+
},
|
| 1345 |
+
{
|
| 1346 |
+
"epoch": 18.0,
|
| 1347 |
+
"training_loss": 0.7353853663293327,
|
| 1348 |
+
"validation_loss": 0.7856449484825134,
|
| 1349 |
+
"validation_accuracy": 0.7031963470319634,
|
| 1350 |
+
"validation_f1_macro": 0.6742213392095463
|
| 1351 |
+
},
|
| 1352 |
+
{
|
| 1353 |
+
"epoch": 19.0,
|
| 1354 |
+
"training_loss": 0.7261699917839795,
|
| 1355 |
+
"validation_loss": 0.7977001070976257,
|
| 1356 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1357 |
+
"validation_f1_macro": 0.6888408000002927
|
| 1358 |
+
},
|
| 1359 |
+
{
|
| 1360 |
+
"epoch": 20.0,
|
| 1361 |
+
"training_loss": 0.7368398461400009,
|
| 1362 |
+
"validation_loss": 0.7927899360656738,
|
| 1363 |
+
"validation_accuracy": 0.7077625570776256,
|
| 1364 |
+
"validation_f1_macro": 0.692141508174205
|
| 1365 |
+
},
|
| 1366 |
+
{
|
| 1367 |
+
"epoch": 21.0,
|
| 1368 |
+
"training_loss": 0.7344355328780848,
|
| 1369 |
+
"validation_loss": 0.7827250957489014,
|
| 1370 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1371 |
+
"validation_f1_macro": 0.6867708679747256
|
| 1372 |
+
},
|
| 1373 |
+
{
|
| 1374 |
+
"epoch": 22.0,
|
| 1375 |
+
"training_loss": 0.6790950581794832,
|
| 1376 |
+
"validation_loss": 0.7775569558143616,
|
| 1377 |
+
"validation_accuracy": 0.7031963470319634,
|
| 1378 |
+
"validation_f1_macro": 0.6765388587616696
|
| 1379 |
+
},
|
| 1380 |
+
{
|
| 1381 |
+
"epoch": 23.0,
|
| 1382 |
+
"training_loss": 0.6984621402693958,
|
| 1383 |
+
"validation_loss": 0.7734518051147461,
|
| 1384 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1385 |
+
"validation_f1_macro": 0.6877153551218909
|
| 1386 |
+
},
|
| 1387 |
+
{
|
| 1388 |
+
"epoch": 24.0,
|
| 1389 |
+
"training_loss": 0.6878889508363677,
|
| 1390 |
+
"validation_loss": 0.7655962705612183,
|
| 1391 |
+
"validation_accuracy": 0.7168949771689498,
|
| 1392 |
+
"validation_f1_macro": 0.7023463479684678
|
| 1393 |
+
},
|
| 1394 |
+
{
|
| 1395 |
+
"epoch": 25.0,
|
| 1396 |
+
"training_loss": 0.6925383333752795,
|
| 1397 |
+
"validation_loss": 0.757779061794281,
|
| 1398 |
+
"validation_accuracy": 0.7077625570776256,
|
| 1399 |
+
"validation_f1_macro": 0.6825144295123554
|
| 1400 |
+
},
|
| 1401 |
+
{
|
| 1402 |
+
"epoch": 26.0,
|
| 1403 |
+
"training_loss": 0.6952342565466718,
|
| 1404 |
+
"validation_loss": 0.7567448616027832,
|
| 1405 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1406 |
+
"validation_f1_macro": 0.6996234126404904
|
| 1407 |
+
},
|
| 1408 |
+
{
|
| 1409 |
+
"epoch": 27.0,
|
| 1410 |
+
"training_loss": 0.6490353898304265,
|
| 1411 |
+
"validation_loss": 0.7367990016937256,
|
| 1412 |
+
"validation_accuracy": 0.6894977168949772,
|
| 1413 |
+
"validation_f1_macro": 0.6604909727865581
|
| 1414 |
+
},
|
| 1415 |
+
{
|
| 1416 |
+
"epoch": 28.0,
|
| 1417 |
+
"training_loss": 0.6474557097365217,
|
| 1418 |
+
"validation_loss": 0.7714822888374329,
|
| 1419 |
+
"validation_accuracy": 0.7077625570776256,
|
| 1420 |
+
"validation_f1_macro": 0.6954321333750253
|
| 1421 |
+
},
|
| 1422 |
+
{
|
| 1423 |
+
"epoch": 29.0,
|
| 1424 |
+
"training_loss": 0.6501478698195481,
|
| 1425 |
+
"validation_loss": 0.7639806866645813,
|
| 1426 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1427 |
+
"validation_f1_macro": 0.7140885958427835
|
| 1428 |
+
},
|
| 1429 |
+
{
|
| 1430 |
+
"epoch": 30.0,
|
| 1431 |
+
"training_loss": 0.6764153576478725,
|
| 1432 |
+
"validation_loss": 0.7494249939918518,
|
| 1433 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1434 |
+
"validation_f1_macro": 0.6996234126404904
|
| 1435 |
+
},
|
| 1436 |
+
{
|
| 1437 |
+
"epoch": 31.0,
|
| 1438 |
+
"training_loss": 0.6499752293272716,
|
| 1439 |
+
"validation_loss": 0.7761468291282654,
|
| 1440 |
+
"validation_accuracy": 0.7214611872146118,
|
| 1441 |
+
"validation_f1_macro": 0.708692259472666
|
| 1442 |
+
},
|
| 1443 |
+
{
|
| 1444 |
+
"epoch": 32.0,
|
| 1445 |
+
"training_loss": 0.6555054213215665,
|
| 1446 |
+
"validation_loss": 0.7684013247489929,
|
| 1447 |
+
"validation_accuracy": 0.7031963470319634,
|
| 1448 |
+
"validation_f1_macro": 0.6801009433656993
|
| 1449 |
+
},
|
| 1450 |
+
{
|
| 1451 |
+
"epoch": 33.0,
|
| 1452 |
+
"training_loss": 0.6549598781800852,
|
| 1453 |
+
"validation_loss": 0.7674687504768372,
|
| 1454 |
+
"validation_accuracy": 0.7031963470319634,
|
| 1455 |
+
"validation_f1_macro": 0.6881563966843104
|
| 1456 |
+
},
|
| 1457 |
+
{
|
| 1458 |
+
"epoch": 34.0,
|
| 1459 |
+
"training_loss": 0.6319407271902736,
|
| 1460 |
+
"validation_loss": 0.7449424266815186,
|
| 1461 |
+
"validation_accuracy": 0.7031963470319634,
|
| 1462 |
+
"validation_f1_macro": 0.693226179799515
|
| 1463 |
+
},
|
| 1464 |
+
{
|
| 1465 |
+
"epoch": 35.0,
|
| 1466 |
+
"training_loss": 0.6287453588916034,
|
| 1467 |
+
"validation_loss": 0.7504529356956482,
|
| 1468 |
+
"validation_accuracy": 0.7031963470319634,
|
| 1469 |
+
"validation_f1_macro": 0.693226179799515
|
| 1470 |
+
},
|
| 1471 |
+
{
|
| 1472 |
+
"epoch": 36.0,
|
| 1473 |
+
"training_loss": 0.6294544270125831,
|
| 1474 |
+
"validation_loss": 0.7591035962104797,
|
| 1475 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1476 |
+
"validation_f1_macro": 0.7009088674911956
|
| 1477 |
+
},
|
| 1478 |
+
{
|
| 1479 |
+
"epoch": 37.0,
|
| 1480 |
+
"training_loss": 0.6553425941525436,
|
| 1481 |
+
"validation_loss": 0.768791139125824,
|
| 1482 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1483 |
+
"validation_f1_macro": 0.694211786459072
|
| 1484 |
+
},
|
| 1485 |
+
{
|
| 1486 |
+
"epoch": 38.0,
|
| 1487 |
+
"training_loss": 0.6051805818953165,
|
| 1488 |
+
"validation_loss": 0.7681089639663696,
|
| 1489 |
+
"validation_accuracy": 0.7214611872146118,
|
| 1490 |
+
"validation_f1_macro": 0.7162450669231648
|
| 1491 |
+
},
|
| 1492 |
+
{
|
| 1493 |
+
"epoch": 39.0,
|
| 1494 |
+
"training_loss": 0.6314349792352537,
|
| 1495 |
+
"validation_loss": 0.7359892725944519,
|
| 1496 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1497 |
+
"validation_f1_macro": 0.6996234126404904
|
| 1498 |
+
},
|
| 1499 |
+
{
|
| 1500 |
+
"epoch": 40.0,
|
| 1501 |
+
"training_loss": 0.6244277274463235,
|
| 1502 |
+
"validation_loss": 0.7540702223777771,
|
| 1503 |
+
"validation_accuracy": 0.7168949771689498,
|
| 1504 |
+
"validation_f1_macro": 0.7048316602752086
|
| 1505 |
+
},
|
| 1506 |
+
{
|
| 1507 |
+
"epoch": 41.0,
|
| 1508 |
+
"training_loss": 0.6361175441160435,
|
| 1509 |
+
"validation_loss": 0.7612143754959106,
|
| 1510 |
+
"validation_accuracy": 0.7123287671232876,
|
| 1511 |
+
"validation_f1_macro": 0.7021036366124976
|
| 1512 |
+
},
|
| 1513 |
+
{
|
| 1514 |
+
"epoch": 42.0,
|
| 1515 |
+
"training_loss": 0.6066937213990746,
|
| 1516 |
+
"validation_loss": 0.7710081934928894,
|
| 1517 |
+
"validation_accuracy": 0.7168949771689498,
|
| 1518 |
+
"validation_f1_macro": 0.7149340559925526
|
| 1519 |
+
},
|
| 1520 |
+
{
|
| 1521 |
+
"epoch": 43.0,
|
| 1522 |
+
"training_loss": 0.6121673482220348,
|
| 1523 |
+
"validation_loss": 0.7481098771095276,
|
| 1524 |
+
"validation_accuracy": 0.726027397260274,
|
| 1525 |
+
"validation_f1_macro": 0.7149526054029889
|
| 1526 |
+
},
|
| 1527 |
+
{
|
| 1528 |
+
"epoch": 44.0,
|
| 1529 |
+
"training_loss": 0.6385712423702565,
|
| 1530 |
+
"validation_loss": 0.7499731183052063,
|
| 1531 |
+
"validation_accuracy": 0.7077625570776256,
|
| 1532 |
+
"validation_f1_macro": 0.6983818499613152
|
| 1533 |
+
},
|
| 1534 |
+
{
|
| 1535 |
+
"epoch": 45.0,
|
| 1536 |
+
"training_loss": 0.6101498901844025,
|
| 1537 |
+
"validation_loss": 0.734427809715271,
|
| 1538 |
+
"validation_accuracy": 0.7168949771689498,
|
| 1539 |
+
"validation_f1_macro": 0.6948720961647448
|
| 1540 |
+
},
|
| 1541 |
+
{
|
| 1542 |
+
"epoch": 46.0,
|
| 1543 |
+
"training_loss": 0.5905797506977872,
|
| 1544 |
+
"validation_loss": 0.7421669363975525,
|
| 1545 |
+
"validation_accuracy": 0.7168949771689498,
|
| 1546 |
+
"validation_f1_macro": 0.7123222741391517
|
| 1547 |
+
},
|
| 1548 |
+
{
|
| 1549 |
+
"epoch": 47.0,
|
| 1550 |
+
"training_loss": 0.6082611465599479,
|
| 1551 |
+
"validation_loss": 0.7235217690467834,
|
| 1552 |
+
"validation_accuracy": 0.730593607305936,
|
| 1553 |
+
"validation_f1_macro": 0.714038944252953
|
| 1554 |
+
},
|
| 1555 |
+
{
|
| 1556 |
+
"epoch": 48.0,
|
| 1557 |
+
"training_loss": 0.5902958159766546,
|
| 1558 |
+
"validation_loss": 0.779229998588562,
|
| 1559 |
+
"validation_accuracy": 0.726027397260274,
|
| 1560 |
+
"validation_f1_macro": 0.7216398602451733
|
| 1561 |
+
},
|
| 1562 |
+
{
|
| 1563 |
+
"epoch": 49.0,
|
| 1564 |
+
"training_loss": 0.5838393728907515,
|
| 1565 |
+
"validation_loss": 0.7277742624282837,
|
| 1566 |
+
"validation_accuracy": 0.730593607305936,
|
| 1567 |
+
"validation_f1_macro": 0.7205624757048593
|
| 1568 |
+
},
|
| 1569 |
+
{
|
| 1570 |
+
"epoch": 50.0,
|
| 1571 |
+
"training_loss": 0.5906014115345187,
|
| 1572 |
+
"validation_loss": 0.7636589407920837,
|
| 1573 |
+
"validation_accuracy": 0.7168949771689498,
|
| 1574 |
+
"validation_f1_macro": 0.7135170432604537
|
| 1575 |
+
}
|
| 1576 |
+
]
|
| 1577 |
+
},
|
| 1578 |
+
{
|
| 1579 |
+
"limit": 50,
|
| 1580 |
+
"seed": 7,
|
| 1581 |
+
"hyperparameters": {
|
| 1582 |
+
"epochs": 50,
|
| 1583 |
+
"batch_size": 16,
|
| 1584 |
+
"learning_rate": 0.001,
|
| 1585 |
+
"weight_decay": 0.0001,
|
| 1586 |
+
"dropout": 0.3,
|
| 1587 |
+
"projection_dim": 64,
|
| 1588 |
+
"fusion_dim": 12,
|
| 1589 |
+
"validation_fraction": 0.25,
|
| 1590 |
+
"optimizer": "Adam",
|
| 1591 |
+
"class_weighting": true,
|
| 1592 |
+
"early_stopping_patience": 12,
|
| 1593 |
+
"seed": 7
|
| 1594 |
+
},
|
| 1595 |
+
"epochs_completed": 44,
|
| 1596 |
+
"best_epoch": 32,
|
| 1597 |
+
"early_stopped": true,
|
| 1598 |
+
"hit_max": false,
|
| 1599 |
+
"train_loss_at_best": 0.661002103875323,
|
| 1600 |
+
"val_loss_at_best": 0.6984432935714722,
|
| 1601 |
+
"accuracy": 0.771689497716895,
|
| 1602 |
+
"f1_macro": 0.7524499679210638,
|
| 1603 |
+
"f1_weighted": 0.7826279144428353,
|
| 1604 |
+
"recall": {
|
| 1605 |
+
"0.0": 0.8620689655172413,
|
| 1606 |
+
"1.0": 0.7878787878787878,
|
| 1607 |
+
"2.0": 0.6363636363636364,
|
| 1608 |
+
"3.0": 0.7614678899082569,
|
| 1609 |
+
"4.0": 0.7567567567567568
|
| 1610 |
+
},
|
| 1611 |
+
"pred_counts": {
|
| 1612 |
+
"0.0": 51,
|
| 1613 |
+
"1.0": 28,
|
| 1614 |
+
"2.0": 8,
|
| 1615 |
+
"3.0": 91,
|
| 1616 |
+
"4.0": 41
|
| 1617 |
+
},
|
| 1618 |
+
"collapsed": false,
|
| 1619 |
+
"history": [
|
| 1620 |
+
{
|
| 1621 |
+
"epoch": 1.0,
|
| 1622 |
+
"training_loss": 1.62655437574154,
|
| 1623 |
+
"validation_loss": 1.589923620223999,
|
| 1624 |
+
"validation_accuracy": 0.5296803652968036,
|
| 1625 |
+
"validation_f1_macro": 0.20888953657825704
|
| 1626 |
+
},
|
| 1627 |
+
{
|
| 1628 |
+
"epoch": 2.0,
|
| 1629 |
+
"training_loss": 1.5845980702376947,
|
| 1630 |
+
"validation_loss": 1.548748254776001,
|
| 1631 |
+
"validation_accuracy": 0.2785388127853881,
|
| 1632 |
+
"validation_f1_macro": 0.21267281105990782
|
| 1633 |
+
},
|
| 1634 |
+
{
|
| 1635 |
+
"epoch": 3.0,
|
| 1636 |
+
"training_loss": 1.468249797821045,
|
| 1637 |
+
"validation_loss": 1.371727466583252,
|
| 1638 |
+
"validation_accuracy": 0.680365296803653,
|
| 1639 |
+
"validation_f1_macro": 0.5202160299834718
|
| 1640 |
+
},
|
| 1641 |
+
{
|
| 1642 |
+
"epoch": 4.0,
|
| 1643 |
+
"training_loss": 1.32800172596443,
|
| 1644 |
+
"validation_loss": 1.2302584648132324,
|
| 1645 |
+
"validation_accuracy": 0.6666666666666666,
|
| 1646 |
+
"validation_f1_macro": 0.5269408837466517
|
| 1647 |
+
},
|
| 1648 |
+
{
|
| 1649 |
+
"epoch": 5.0,
|
| 1650 |
+
"training_loss": 1.1880390469620867,
|
| 1651 |
+
"validation_loss": 1.1226760149002075,
|
| 1652 |
+
"validation_accuracy": 0.684931506849315,
|
| 1653 |
+
"validation_f1_macro": 0.5486220093958027
|
| 1654 |
+
},
|
| 1655 |
+
{
|
| 1656 |
+
"epoch": 6.0,
|
| 1657 |
+
"training_loss": 1.0946302021422036,
|
| 1658 |
+
"validation_loss": 1.04401433467865,
|
| 1659 |
+
"validation_accuracy": 0.6894977168949772,
|
| 1660 |
+
"validation_f1_macro": 0.5714749984315202
|
| 1661 |
+
},
|
| 1662 |
+
{
|
| 1663 |
+
"epoch": 7.0,
|
| 1664 |
+
"training_loss": 1.030611061468357,
|
| 1665 |
+
"validation_loss": 1.023421287536621,
|
| 1666 |
+
"validation_accuracy": 0.6712328767123288,
|
| 1667 |
+
"validation_f1_macro": 0.5742135730750795
|
| 1668 |
+
},
|
| 1669 |
+
{
|
| 1670 |
+
"epoch": 8.0,
|
| 1671 |
+
"training_loss": 0.9878716337971571,
|
| 1672 |
+
"validation_loss": 0.9709606170654297,
|
| 1673 |
+
"validation_accuracy": 0.684931506849315,
|
| 1674 |
+
"validation_f1_macro": 0.5975834311588126
|
| 1675 |
+
},
|
| 1676 |
+
{
|
| 1677 |
+
"epoch": 9.0,
|
| 1678 |
+
"training_loss": 0.9323210745322995,
|
| 1679 |
+
"validation_loss": 0.9185066819190979,
|
| 1680 |
+
"validation_accuracy": 0.7168949771689498,
|
| 1681 |
+
"validation_f1_macro": 0.6833981316972961
|
| 1682 |
+
},
|
| 1683 |
+
{
|
| 1684 |
+
"epoch": 10.0,
|
| 1685 |
+
"training_loss": 0.917416339967309,
|
| 1686 |
+
"validation_loss": 0.8980910181999207,
|
| 1687 |
+
"validation_accuracy": 0.726027397260274,
|
| 1688 |
+
"validation_f1_macro": 0.6809404013460666
|
| 1689 |
+
},
|
| 1690 |
+
{
|
| 1691 |
+
"epoch": 11.0,
|
| 1692 |
+
"training_loss": 0.8819241145762001,
|
| 1693 |
+
"validation_loss": 0.8560897707939148,
|
| 1694 |
+
"validation_accuracy": 0.7488584474885844,
|
| 1695 |
+
"validation_f1_macro": 0.727852427060365
|
| 1696 |
+
},
|
| 1697 |
+
{
|
| 1698 |
+
"epoch": 12.0,
|
| 1699 |
+
"training_loss": 0.8653858725617571,
|
| 1700 |
+
"validation_loss": 0.8336981534957886,
|
| 1701 |
+
"validation_accuracy": 0.7442922374429224,
|
| 1702 |
+
"validation_f1_macro": 0.7134181842050694
|
| 1703 |
+
},
|
| 1704 |
+
{
|
| 1705 |
+
"epoch": 13.0,
|
| 1706 |
+
"training_loss": 0.8303249274812093,
|
| 1707 |
+
"validation_loss": 0.8161752820014954,
|
| 1708 |
+
"validation_accuracy": 0.7488584474885844,
|
| 1709 |
+
"validation_f1_macro": 0.7285636610973818
|
| 1710 |
+
},
|
| 1711 |
+
{
|
| 1712 |
+
"epoch": 14.0,
|
| 1713 |
+
"training_loss": 0.8463927158495275,
|
| 1714 |
+
"validation_loss": 0.7870453000068665,
|
| 1715 |
+
"validation_accuracy": 0.7488584474885844,
|
| 1716 |
+
"validation_f1_macro": 0.7248277326555709
|
| 1717 |
+
},
|
| 1718 |
+
{
|
| 1719 |
+
"epoch": 15.0,
|
| 1720 |
+
"training_loss": 0.8173226692327639,
|
| 1721 |
+
"validation_loss": 0.8049059510231018,
|
| 1722 |
+
"validation_accuracy": 0.7397260273972602,
|
| 1723 |
+
"validation_f1_macro": 0.7151836250752119
|
| 1724 |
+
},
|
| 1725 |
+
{
|
| 1726 |
+
"epoch": 16.0,
|
| 1727 |
+
"training_loss": 0.8112960501414973,
|
| 1728 |
+
"validation_loss": 0.8151602745056152,
|
| 1729 |
+
"validation_accuracy": 0.730593607305936,
|
| 1730 |
+
"validation_f1_macro": 0.7007828498472742
|
| 1731 |
+
},
|
| 1732 |
+
{
|
| 1733 |
+
"epoch": 17.0,
|
| 1734 |
+
"training_loss": 0.7827643555838887,
|
| 1735 |
+
"validation_loss": 0.8070281744003296,
|
| 1736 |
+
"validation_accuracy": 0.7351598173515982,
|
| 1737 |
+
"validation_f1_macro": 0.7055984574326514
|
| 1738 |
+
},
|
| 1739 |
+
{
|
| 1740 |
+
"epoch": 18.0,
|
| 1741 |
+
"training_loss": 0.8010357509299022,
|
| 1742 |
+
"validation_loss": 0.7747320532798767,
|
| 1743 |
+
"validation_accuracy": 0.7442922374429224,
|
| 1744 |
+
"validation_f1_macro": 0.7083783373985632
|
| 1745 |
+
},
|
| 1746 |
+
{
|
| 1747 |
+
"epoch": 19.0,
|
| 1748 |
+
"training_loss": 0.7957447483772184,
|
| 1749 |
+
"validation_loss": 0.7730648517608643,
|
| 1750 |
+
"validation_accuracy": 0.7397260273972602,
|
| 1751 |
+
"validation_f1_macro": 0.7056989471814845
|
| 1752 |
+
},
|
| 1753 |
+
{
|
| 1754 |
+
"epoch": 20.0,
|
| 1755 |
+
"training_loss": 0.7606793692926082,
|
| 1756 |
+
"validation_loss": 0.756865918636322,
|
| 1757 |
+
"validation_accuracy": 0.7442922374429224,
|
| 1758 |
+
"validation_f1_macro": 0.724972322759208
|
| 1759 |
+
},
|
| 1760 |
+
{
|
| 1761 |
+
"epoch": 21.0,
|
| 1762 |
+
"training_loss": 0.7359354161634678,
|
| 1763 |
+
"validation_loss": 0.7705332636833191,
|
| 1764 |
+
"validation_accuracy": 0.7442922374429224,
|
| 1765 |
+
"validation_f1_macro": 0.7109910765242468
|
| 1766 |
+
},
|
| 1767 |
+
{
|
| 1768 |
+
"epoch": 22.0,
|
| 1769 |
+
"training_loss": 0.7506408742288264,
|
| 1770 |
+
"validation_loss": 0.7497557997703552,
|
| 1771 |
+
"validation_accuracy": 0.7488584474885844,
|
| 1772 |
+
"validation_f1_macro": 0.7229705455948657
|
| 1773 |
+
},
|
| 1774 |
+
{
|
| 1775 |
+
"epoch": 23.0,
|
| 1776 |
+
"training_loss": 0.7357381807594765,
|
| 1777 |
+
"validation_loss": 0.7553285956382751,
|
| 1778 |
+
"validation_accuracy": 0.7397260273972602,
|
| 1779 |
+
"validation_f1_macro": 0.7082830552595245
|
| 1780 |
+
},
|
| 1781 |
+
{
|
| 1782 |
+
"epoch": 24.0,
|
| 1783 |
+
"training_loss": 0.7082513803389014,
|
| 1784 |
+
"validation_loss": 0.75914466381073,
|
| 1785 |
+
"validation_accuracy": 0.7351598173515982,
|
| 1786 |
+
"validation_f1_macro": 0.7139834784486362
|
| 1787 |
+
},
|
| 1788 |
+
{
|
| 1789 |
+
"epoch": 25.0,
|
| 1790 |
+
"training_loss": 0.7012432530158903,
|
| 1791 |
+
"validation_loss": 0.7224891185760498,
|
| 1792 |
+
"validation_accuracy": 0.771689497716895,
|
| 1793 |
+
"validation_f1_macro": 0.7516536481181431
|
| 1794 |
+
},
|
| 1795 |
+
{
|
| 1796 |
+
"epoch": 26.0,
|
| 1797 |
+
"training_loss": 0.702656633970214,
|
| 1798 |
+
"validation_loss": 0.7347502708435059,
|
| 1799 |
+
"validation_accuracy": 0.7442922374429224,
|
| 1800 |
+
"validation_f1_macro": 0.7160051749244645
|
| 1801 |
+
},
|
| 1802 |
+
{
|
| 1803 |
+
"epoch": 27.0,
|
| 1804 |
+
"training_loss": 0.699109113071023,
|
| 1805 |
+
"validation_loss": 0.7329419851303101,
|
| 1806 |
+
"validation_accuracy": 0.7488584474885844,
|
| 1807 |
+
"validation_f1_macro": 0.7380830487817869
|
| 1808 |
+
},
|
| 1809 |
+
{
|
| 1810 |
+
"epoch": 28.0,
|
| 1811 |
+
"training_loss": 0.6665385103807216,
|
| 1812 |
+
"validation_loss": 0.7400558590888977,
|
| 1813 |
+
"validation_accuracy": 0.7397260273972602,
|
| 1814 |
+
"validation_f1_macro": 0.7070388770928432
|
| 1815 |
+
},
|
| 1816 |
+
{
|
| 1817 |
+
"epoch": 29.0,
|
| 1818 |
+
"training_loss": 0.6689512576998734,
|
| 1819 |
+
"validation_loss": 0.7360281944274902,
|
| 1820 |
+
"validation_accuracy": 0.7488584474885844,
|
| 1821 |
+
"validation_f1_macro": 0.7391559722160727
|
| 1822 |
+
},
|
| 1823 |
+
{
|
| 1824 |
+
"epoch": 30.0,
|
| 1825 |
+
"training_loss": 0.6843016118538089,
|
| 1826 |
+
"validation_loss": 0.7508696913719177,
|
| 1827 |
+
"validation_accuracy": 0.7397260273972602,
|
| 1828 |
+
"validation_f1_macro": 0.7082830552595245
|
| 1829 |
+
},
|
| 1830 |
+
{
|
| 1831 |
+
"epoch": 31.0,
|
| 1832 |
+
"training_loss": 0.6739339893910943,
|
| 1833 |
+
"validation_loss": 0.7405543923377991,
|
| 1834 |
+
"validation_accuracy": 0.7351598173515982,
|
| 1835 |
+
"validation_f1_macro": 0.7156167475000182
|
| 1836 |
+
},
|
| 1837 |
+
{
|
| 1838 |
+
"epoch": 32.0,
|
| 1839 |
+
"training_loss": 0.661002103875323,
|
| 1840 |
+
"validation_loss": 0.6984432935714722,
|
| 1841 |
+
"validation_accuracy": 0.771689497716895,
|
| 1842 |
+
"validation_f1_macro": 0.7524499679210638
|
| 1843 |
+
},
|
| 1844 |
+
{
|
| 1845 |
+
"epoch": 33.0,
|
| 1846 |
+
"training_loss": 0.6655780258702069,
|
| 1847 |
+
"validation_loss": 0.7283544540405273,
|
| 1848 |
+
"validation_accuracy": 0.7488584474885844,
|
| 1849 |
+
"validation_f1_macro": 0.7389977447779943
|
| 1850 |
+
},
|
| 1851 |
+
{
|
| 1852 |
+
"epoch": 34.0,
|
| 1853 |
+
"training_loss": 0.658410701082974,
|
| 1854 |
+
"validation_loss": 0.7165646553039551,
|
| 1855 |
+
"validation_accuracy": 0.7534246575342466,
|
| 1856 |
+
"validation_f1_macro": 0.7410359336394337
|
| 1857 |
+
},
|
| 1858 |
+
{
|
| 1859 |
+
"epoch": 35.0,
|
| 1860 |
+
"training_loss": 0.6328801788934847,
|
| 1861 |
+
"validation_loss": 0.7204789519309998,
|
| 1862 |
+
"validation_accuracy": 0.7534246575342466,
|
| 1863 |
+
"validation_f1_macro": 0.7420996007457028
|
| 1864 |
+
},
|
| 1865 |
+
{
|
| 1866 |
+
"epoch": 36.0,
|
| 1867 |
+
"training_loss": 0.634215030001431,
|
| 1868 |
+
"validation_loss": 0.7153851389884949,
|
| 1869 |
+
"validation_accuracy": 0.7534246575342466,
|
| 1870 |
+
"validation_f1_macro": 0.7344943048421657
|
| 1871 |
+
},
|
| 1872 |
+
{
|
| 1873 |
+
"epoch": 37.0,
|
| 1874 |
+
"training_loss": 0.6196055564938522,
|
| 1875 |
+
"validation_loss": 0.7263249158859253,
|
| 1876 |
+
"validation_accuracy": 0.7488584474885844,
|
| 1877 |
+
"validation_f1_macro": 0.7404189709107568
|
| 1878 |
+
},
|
| 1879 |
+
{
|
| 1880 |
+
"epoch": 38.0,
|
| 1881 |
+
"training_loss": 0.6232949244539913,
|
| 1882 |
+
"validation_loss": 0.7163978219032288,
|
| 1883 |
+
"validation_accuracy": 0.7579908675799086,
|
| 1884 |
+
"validation_f1_macro": 0.7450726024380072
|
| 1885 |
+
},
|
| 1886 |
+
{
|
| 1887 |
+
"epoch": 39.0,
|
| 1888 |
+
"training_loss": 0.627199369232829,
|
| 1889 |
+
"validation_loss": 0.7059804201126099,
|
| 1890 |
+
"validation_accuracy": 0.7579908675799086,
|
| 1891 |
+
"validation_f1_macro": 0.7450726024380072
|
| 1892 |
+
},
|
| 1893 |
+
{
|
| 1894 |
+
"epoch": 40.0,
|
| 1895 |
+
"training_loss": 0.6092390396246096,
|
| 1896 |
+
"validation_loss": 0.703453004360199,
|
| 1897 |
+
"validation_accuracy": 0.7534246575342466,
|
| 1898 |
+
"validation_f1_macro": 0.7410359336394337
|
| 1899 |
+
},
|
| 1900 |
+
{
|
| 1901 |
+
"epoch": 41.0,
|
| 1902 |
+
"training_loss": 0.6367075861227222,
|
| 1903 |
+
"validation_loss": 0.7127879858016968,
|
| 1904 |
+
"validation_accuracy": 0.7579908675799086,
|
| 1905 |
+
"validation_f1_macro": 0.7450726024380072
|
| 1906 |
+
},
|
| 1907 |
+
{
|
| 1908 |
+
"epoch": 42.0,
|
| 1909 |
+
"training_loss": 0.6207717867886148,
|
| 1910 |
+
"validation_loss": 0.7062743902206421,
|
| 1911 |
+
"validation_accuracy": 0.7579908675799086,
|
| 1912 |
+
"validation_f1_macro": 0.7450726024380072
|
| 1913 |
+
},
|
| 1914 |
+
{
|
| 1915 |
+
"epoch": 43.0,
|
| 1916 |
+
"training_loss": 0.599103124403372,
|
| 1917 |
+
"validation_loss": 0.7054443955421448,
|
| 1918 |
+
"validation_accuracy": 0.7534246575342466,
|
| 1919 |
+
"validation_f1_macro": 0.7410359336394337
|
| 1920 |
+
},
|
| 1921 |
+
{
|
| 1922 |
+
"epoch": 44.0,
|
| 1923 |
+
"training_loss": 0.5925045471365858,
|
| 1924 |
+
"validation_loss": 0.7284175157546997,
|
| 1925 |
+
"validation_accuracy": 0.7534246575342466,
|
| 1926 |
+
"validation_f1_macro": 0.7344943048421657
|
| 1927 |
+
}
|
| 1928 |
+
]
|
| 1929 |
+
},
|
| 1930 |
+
{
|
| 1931 |
+
"limit": 50,
|
| 1932 |
+
"seed": 42,
|
| 1933 |
+
"hyperparameters": {
|
| 1934 |
+
"epochs": 50,
|
| 1935 |
+
"batch_size": 16,
|
| 1936 |
+
"learning_rate": 0.001,
|
| 1937 |
+
"weight_decay": 0.0001,
|
| 1938 |
+
"dropout": 0.3,
|
| 1939 |
+
"projection_dim": 64,
|
| 1940 |
+
"fusion_dim": 12,
|
| 1941 |
+
"validation_fraction": 0.25,
|
| 1942 |
+
"optimizer": "Adam",
|
| 1943 |
+
"class_weighting": true,
|
| 1944 |
+
"early_stopping_patience": 12,
|
| 1945 |
+
"seed": 42
|
| 1946 |
+
},
|
| 1947 |
+
"epochs_completed": 50,
|
| 1948 |
+
"best_epoch": 38,
|
| 1949 |
+
"early_stopped": true,
|
| 1950 |
+
"hit_max": false,
|
| 1951 |
+
"train_loss_at_best": 0.6739114813688325,
|
| 1952 |
+
"val_loss_at_best": 0.6592805981636047,
|
| 1953 |
+
"accuracy": 0.7671232876712328,
|
| 1954 |
+
"f1_macro": 0.7474258785478297,
|
| 1955 |
+
"f1_weighted": 0.7740214080920172,
|
| 1956 |
+
"recall": {
|
| 1957 |
+
"0.0": 0.7586206896551724,
|
| 1958 |
+
"1.0": 0.9393939393939394,
|
| 1959 |
+
"2.0": 0.9090909090909091,
|
| 1960 |
+
"3.0": 0.7706422018348624,
|
| 1961 |
+
"4.0": 0.5675675675675675
|
| 1962 |
+
},
|
| 1963 |
+
"pred_counts": {
|
| 1964 |
+
"0.0": 46,
|
| 1965 |
+
"1.0": 32,
|
| 1966 |
+
"2.0": 16,
|
| 1967 |
+
"3.0": 96,
|
| 1968 |
+
"4.0": 29
|
| 1969 |
+
},
|
| 1970 |
+
"collapsed": false,
|
| 1971 |
+
"history": [
|
| 1972 |
+
{
|
| 1973 |
+
"epoch": 1.0,
|
| 1974 |
+
"training_loss": 1.6413315621817983,
|
| 1975 |
+
"validation_loss": 1.5951603651046753,
|
| 1976 |
+
"validation_accuracy": 0.2054794520547945,
|
| 1977 |
+
"validation_f1_macro": 0.09564573659061848
|
| 1978 |
+
},
|
| 1979 |
+
{
|
| 1980 |
+
"epoch": 2.0,
|
| 1981 |
+
"training_loss": 1.6051898903963042,
|
| 1982 |
+
"validation_loss": 1.5471464395523071,
|
| 1983 |
+
"validation_accuracy": 0.1506849315068493,
|
| 1984 |
+
"validation_f1_macro": 0.05238095238095238
|
| 1985 |
+
},
|
| 1986 |
+
{
|
| 1987 |
+
"epoch": 3.0,
|
| 1988 |
+
"training_loss": 1.541287974613469,
|
| 1989 |
+
"validation_loss": 1.4482790231704712,
|
| 1990 |
+
"validation_accuracy": 0.3744292237442922,
|
| 1991 |
+
"validation_f1_macro": 0.3273361566811023
|
| 1992 |
+
},
|
| 1993 |
+
{
|
| 1994 |
+
"epoch": 4.0,
|
| 1995 |
+
"training_loss": 1.4257210987370188,
|
| 1996 |
+
"validation_loss": 1.3203811645507812,
|
| 1997 |
+
"validation_accuracy": 0.6986301369863014,
|
| 1998 |
+
"validation_f1_macro": 0.5610404919891623
|
| 1999 |
+
},
|
| 2000 |
+
{
|
| 2001 |
+
"epoch": 5.0,
|
| 2002 |
+
"training_loss": 1.2903572379088983,
|
| 2003 |
+
"validation_loss": 1.1790156364440918,
|
| 2004 |
+
"validation_accuracy": 0.6712328767123288,
|
| 2005 |
+
"validation_f1_macro": 0.5303037900262373
|
| 2006 |
+
},
|
| 2007 |
+
{
|
| 2008 |
+
"epoch": 6.0,
|
| 2009 |
+
"training_loss": 1.192301835955643,
|
| 2010 |
+
"validation_loss": 1.1542149782180786,
|
| 2011 |
+
"validation_accuracy": 0.6301369863013698,
|
| 2012 |
+
"validation_f1_macro": 0.5829572914647542
|
| 2013 |
+
},
|
| 2014 |
+
{
|
| 2015 |
+
"epoch": 7.0,
|
| 2016 |
+
"training_loss": 1.0858885224272565,
|
| 2017 |
+
"validation_loss": 0.9872011542320251,
|
| 2018 |
+
"validation_accuracy": 0.7123287671232876,
|
| 2019 |
+
"validation_f1_macro": 0.6546160686293118
|
| 2020 |
+
},
|
| 2021 |
+
{
|
| 2022 |
+
"epoch": 8.0,
|
| 2023 |
+
"training_loss": 1.0201251594031728,
|
| 2024 |
+
"validation_loss": 0.8829815983772278,
|
| 2025 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2026 |
+
"validation_f1_macro": 0.6462817282590345
|
| 2027 |
+
},
|
| 2028 |
+
{
|
| 2029 |
+
"epoch": 9.0,
|
| 2030 |
+
"training_loss": 0.9495046894724776,
|
| 2031 |
+
"validation_loss": 0.8631280064582825,
|
| 2032 |
+
"validation_accuracy": 0.7397260273972602,
|
| 2033 |
+
"validation_f1_macro": 0.6743014067193173
|
| 2034 |
+
},
|
| 2035 |
+
{
|
| 2036 |
+
"epoch": 10.0,
|
| 2037 |
+
"training_loss": 0.9342777976175634,
|
| 2038 |
+
"validation_loss": 0.9005348086357117,
|
| 2039 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2040 |
+
"validation_f1_macro": 0.689469101097008
|
| 2041 |
+
},
|
| 2042 |
+
{
|
| 2043 |
+
"epoch": 11.0,
|
| 2044 |
+
"training_loss": 0.9066276433991223,
|
| 2045 |
+
"validation_loss": 0.8241670727729797,
|
| 2046 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2047 |
+
"validation_f1_macro": 0.678359222040761
|
| 2048 |
+
},
|
| 2049 |
+
{
|
| 2050 |
+
"epoch": 12.0,
|
| 2051 |
+
"training_loss": 0.87182052833278,
|
| 2052 |
+
"validation_loss": 0.8306285738945007,
|
| 2053 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2054 |
+
"validation_f1_macro": 0.7570054945054945
|
| 2055 |
+
},
|
| 2056 |
+
{
|
| 2057 |
+
"epoch": 13.0,
|
| 2058 |
+
"training_loss": 0.8655777348250877,
|
| 2059 |
+
"validation_loss": 0.7712150812149048,
|
| 2060 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2061 |
+
"validation_f1_macro": 0.7153631638631638
|
| 2062 |
+
},
|
| 2063 |
+
{
|
| 2064 |
+
"epoch": 14.0,
|
| 2065 |
+
"training_loss": 0.8454430975565096,
|
| 2066 |
+
"validation_loss": 0.7842550277709961,
|
| 2067 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2068 |
+
"validation_f1_macro": 0.7185530009472144
|
| 2069 |
+
},
|
| 2070 |
+
{
|
| 2071 |
+
"epoch": 15.0,
|
| 2072 |
+
"training_loss": 0.8387555247399865,
|
| 2073 |
+
"validation_loss": 0.797715425491333,
|
| 2074 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2075 |
+
"validation_f1_macro": 0.7263994447222295
|
| 2076 |
+
},
|
| 2077 |
+
{
|
| 2078 |
+
"epoch": 16.0,
|
| 2079 |
+
"training_loss": 0.8214820347181181,
|
| 2080 |
+
"validation_loss": 0.7511270642280579,
|
| 2081 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2082 |
+
"validation_f1_macro": 0.714060392728248
|
| 2083 |
+
},
|
| 2084 |
+
{
|
| 2085 |
+
"epoch": 17.0,
|
| 2086 |
+
"training_loss": 0.8219952263483187,
|
| 2087 |
+
"validation_loss": 0.8021854162216187,
|
| 2088 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2089 |
+
"validation_f1_macro": 0.7480525030525029
|
| 2090 |
+
},
|
| 2091 |
+
{
|
| 2092 |
+
"epoch": 18.0,
|
| 2093 |
+
"training_loss": 0.7887809269311952,
|
| 2094 |
+
"validation_loss": 0.7537360787391663,
|
| 2095 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2096 |
+
"validation_f1_macro": 0.747718705511105
|
| 2097 |
+
},
|
| 2098 |
+
{
|
| 2099 |
+
"epoch": 19.0,
|
| 2100 |
+
"training_loss": 0.7926808195870098,
|
| 2101 |
+
"validation_loss": 0.7402254343032837,
|
| 2102 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2103 |
+
"validation_f1_macro": 0.7275013872674709
|
| 2104 |
+
},
|
| 2105 |
+
{
|
| 2106 |
+
"epoch": 20.0,
|
| 2107 |
+
"training_loss": 0.7622463841263841,
|
| 2108 |
+
"validation_loss": 0.7453633546829224,
|
| 2109 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2110 |
+
"validation_f1_macro": 0.7481171465278779
|
| 2111 |
+
},
|
| 2112 |
+
{
|
| 2113 |
+
"epoch": 21.0,
|
| 2114 |
+
"training_loss": 0.775284816579121,
|
| 2115 |
+
"validation_loss": 0.7456088662147522,
|
| 2116 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2117 |
+
"validation_f1_macro": 0.7482920706416814
|
| 2118 |
+
},
|
| 2119 |
+
{
|
| 2120 |
+
"epoch": 22.0,
|
| 2121 |
+
"training_loss": 0.7533575325477414,
|
| 2122 |
+
"validation_loss": 0.7158185243606567,
|
| 2123 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2124 |
+
"validation_f1_macro": 0.7533803044226147
|
| 2125 |
+
},
|
| 2126 |
+
{
|
| 2127 |
+
"epoch": 23.0,
|
| 2128 |
+
"training_loss": 0.7445236517161857,
|
| 2129 |
+
"validation_loss": 0.7244470119476318,
|
| 2130 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2131 |
+
"validation_f1_macro": 0.761157481482884
|
| 2132 |
+
},
|
| 2133 |
+
{
|
| 2134 |
+
"epoch": 24.0,
|
| 2135 |
+
"training_loss": 0.777114295377964,
|
| 2136 |
+
"validation_loss": 0.7160983085632324,
|
| 2137 |
+
"validation_accuracy": 0.7671232876712328,
|
| 2138 |
+
"validation_f1_macro": 0.7669865422393788
|
| 2139 |
+
},
|
| 2140 |
+
{
|
| 2141 |
+
"epoch": 25.0,
|
| 2142 |
+
"training_loss": 0.7019447509835406,
|
| 2143 |
+
"validation_loss": 0.7080726623535156,
|
| 2144 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2145 |
+
"validation_f1_macro": 0.7259406795109891
|
| 2146 |
+
},
|
| 2147 |
+
{
|
| 2148 |
+
"epoch": 26.0,
|
| 2149 |
+
"training_loss": 0.7030961208227204,
|
| 2150 |
+
"validation_loss": 0.7158434391021729,
|
| 2151 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2152 |
+
"validation_f1_macro": 0.7512252258700489
|
| 2153 |
+
},
|
| 2154 |
+
{
|
| 2155 |
+
"epoch": 27.0,
|
| 2156 |
+
"training_loss": 0.7424630958859514,
|
| 2157 |
+
"validation_loss": 0.7906358242034912,
|
| 2158 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2159 |
+
"validation_f1_macro": 0.7316288331342096
|
| 2160 |
+
},
|
| 2161 |
+
{
|
| 2162 |
+
"epoch": 28.0,
|
| 2163 |
+
"training_loss": 0.7209375667862776,
|
| 2164 |
+
"validation_loss": 0.7476458549499512,
|
| 2165 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2166 |
+
"validation_f1_macro": 0.7402686202686202
|
| 2167 |
+
},
|
| 2168 |
+
{
|
| 2169 |
+
"epoch": 29.0,
|
| 2170 |
+
"training_loss": 0.69572512696429,
|
| 2171 |
+
"validation_loss": 0.7600176334381104,
|
| 2172 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2173 |
+
"validation_f1_macro": 0.7432034632034632
|
| 2174 |
+
},
|
| 2175 |
+
{
|
| 2176 |
+
"epoch": 30.0,
|
| 2177 |
+
"training_loss": 0.7271860489031163,
|
| 2178 |
+
"validation_loss": 0.6967012882232666,
|
| 2179 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2180 |
+
"validation_f1_macro": 0.748410452041456
|
| 2181 |
+
},
|
| 2182 |
+
{
|
| 2183 |
+
"epoch": 31.0,
|
| 2184 |
+
"training_loss": 0.7023421089823653,
|
| 2185 |
+
"validation_loss": 0.6869670152664185,
|
| 2186 |
+
"validation_accuracy": 0.771689497716895,
|
| 2187 |
+
"validation_f1_macro": 0.7708608058608057
|
| 2188 |
+
},
|
| 2189 |
+
{
|
| 2190 |
+
"epoch": 32.0,
|
| 2191 |
+
"training_loss": 0.7001944823962886,
|
| 2192 |
+
"validation_loss": 0.6629666686058044,
|
| 2193 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2194 |
+
"validation_f1_macro": 0.7455364218244153
|
| 2195 |
+
},
|
| 2196 |
+
{
|
| 2197 |
+
"epoch": 33.0,
|
| 2198 |
+
"training_loss": 0.6928130410066465,
|
| 2199 |
+
"validation_loss": 0.7037253975868225,
|
| 2200 |
+
"validation_accuracy": 0.771689497716895,
|
| 2201 |
+
"validation_f1_macro": 0.7682012832528295
|
| 2202 |
+
},
|
| 2203 |
+
{
|
| 2204 |
+
"epoch": 34.0,
|
| 2205 |
+
"training_loss": 0.6658707871669676,
|
| 2206 |
+
"validation_loss": 0.7267974615097046,
|
| 2207 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2208 |
+
"validation_f1_macro": 0.7537267670601004
|
| 2209 |
+
},
|
| 2210 |
+
{
|
| 2211 |
+
"epoch": 35.0,
|
| 2212 |
+
"training_loss": 0.6562810256713774,
|
| 2213 |
+
"validation_loss": 0.7219017148017883,
|
| 2214 |
+
"validation_accuracy": 0.771689497716895,
|
| 2215 |
+
"validation_f1_macro": 0.7664590697119064
|
| 2216 |
+
},
|
| 2217 |
+
{
|
| 2218 |
+
"epoch": 36.0,
|
| 2219 |
+
"training_loss": 0.6679604137089195,
|
| 2220 |
+
"validation_loss": 0.7252770662307739,
|
| 2221 |
+
"validation_accuracy": 0.7671232876712328,
|
| 2222 |
+
"validation_f1_macro": 0.757229532482369
|
| 2223 |
+
},
|
| 2224 |
+
{
|
| 2225 |
+
"epoch": 37.0,
|
| 2226 |
+
"training_loss": 0.6854233596383071,
|
| 2227 |
+
"validation_loss": 0.7343176007270813,
|
| 2228 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2229 |
+
"validation_f1_macro": 0.754186366259151
|
| 2230 |
+
},
|
| 2231 |
+
{
|
| 2232 |
+
"epoch": 38.0,
|
| 2233 |
+
"training_loss": 0.6739114813688325,
|
| 2234 |
+
"validation_loss": 0.6592805981636047,
|
| 2235 |
+
"validation_accuracy": 0.7671232876712328,
|
| 2236 |
+
"validation_f1_macro": 0.7474258785478297
|
| 2237 |
+
},
|
| 2238 |
+
{
|
| 2239 |
+
"epoch": 39.0,
|
| 2240 |
+
"training_loss": 0.6822220225159715,
|
| 2241 |
+
"validation_loss": 0.6769421696662903,
|
| 2242 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2243 |
+
"validation_f1_macro": 0.7536289821289821
|
| 2244 |
+
},
|
| 2245 |
+
{
|
| 2246 |
+
"epoch": 40.0,
|
| 2247 |
+
"training_loss": 0.6873945408478016,
|
| 2248 |
+
"validation_loss": 0.7250295877456665,
|
| 2249 |
+
"validation_accuracy": 0.7671232876712328,
|
| 2250 |
+
"validation_f1_macro": 0.7680280026990554
|
| 2251 |
+
},
|
| 2252 |
+
{
|
| 2253 |
+
"epoch": 41.0,
|
| 2254 |
+
"training_loss": 0.6764432002858418,
|
| 2255 |
+
"validation_loss": 0.7391007542610168,
|
| 2256 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2257 |
+
"validation_f1_macro": 0.7396409969111502
|
| 2258 |
+
},
|
| 2259 |
+
{
|
| 2260 |
+
"epoch": 42.0,
|
| 2261 |
+
"training_loss": 0.6339026725873714,
|
| 2262 |
+
"validation_loss": 0.6608799695968628,
|
| 2263 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2264 |
+
"validation_f1_macro": 0.7407714164293111
|
| 2265 |
+
},
|
| 2266 |
+
{
|
| 2267 |
+
"epoch": 43.0,
|
| 2268 |
+
"training_loss": 0.6590220651975492,
|
| 2269 |
+
"validation_loss": 0.6673893332481384,
|
| 2270 |
+
"validation_accuracy": 0.776255707762557,
|
| 2271 |
+
"validation_f1_macro": 0.7676702673517622
|
| 2272 |
+
},
|
| 2273 |
+
{
|
| 2274 |
+
"epoch": 44.0,
|
| 2275 |
+
"training_loss": 0.6262539588823551,
|
| 2276 |
+
"validation_loss": 0.6594874262809753,
|
| 2277 |
+
"validation_accuracy": 0.771689497716895,
|
| 2278 |
+
"validation_f1_macro": 0.771904365904366
|
| 2279 |
+
},
|
| 2280 |
+
{
|
| 2281 |
+
"epoch": 45.0,
|
| 2282 |
+
"training_loss": 0.6377055292449346,
|
| 2283 |
+
"validation_loss": 0.729316771030426,
|
| 2284 |
+
"validation_accuracy": 0.7671232876712328,
|
| 2285 |
+
"validation_f1_macro": 0.7633931438869814
|
| 2286 |
+
},
|
| 2287 |
+
{
|
| 2288 |
+
"epoch": 46.0,
|
| 2289 |
+
"training_loss": 0.6469743251800537,
|
| 2290 |
+
"validation_loss": 0.6833896636962891,
|
| 2291 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2292 |
+
"validation_f1_macro": 0.7558843937791307
|
| 2293 |
+
},
|
| 2294 |
+
{
|
| 2295 |
+
"epoch": 47.0,
|
| 2296 |
+
"training_loss": 0.6347538745257912,
|
| 2297 |
+
"validation_loss": 0.6690486669540405,
|
| 2298 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2299 |
+
"validation_f1_macro": 0.7504796029796029
|
| 2300 |
+
},
|
| 2301 |
+
{
|
| 2302 |
+
"epoch": 48.0,
|
| 2303 |
+
"training_loss": 0.6262150170599542,
|
| 2304 |
+
"validation_loss": 0.7333135008811951,
|
| 2305 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2306 |
+
"validation_f1_macro": 0.7590531975184693
|
| 2307 |
+
},
|
| 2308 |
+
{
|
| 2309 |
+
"epoch": 49.0,
|
| 2310 |
+
"training_loss": 0.6454702768383956,
|
| 2311 |
+
"validation_loss": 0.6962722539901733,
|
| 2312 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2313 |
+
"validation_f1_macro": 0.7579154497562188
|
| 2314 |
+
},
|
| 2315 |
+
{
|
| 2316 |
+
"epoch": 50.0,
|
| 2317 |
+
"training_loss": 0.652672092362148,
|
| 2318 |
+
"validation_loss": 0.7580622434616089,
|
| 2319 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2320 |
+
"validation_f1_macro": 0.7515952999180847
|
| 2321 |
+
}
|
| 2322 |
+
]
|
| 2323 |
+
},
|
| 2324 |
+
{
|
| 2325 |
+
"limit": 50,
|
| 2326 |
+
"seed": 123,
|
| 2327 |
+
"hyperparameters": {
|
| 2328 |
+
"epochs": 50,
|
| 2329 |
+
"batch_size": 16,
|
| 2330 |
+
"learning_rate": 0.001,
|
| 2331 |
+
"weight_decay": 0.0001,
|
| 2332 |
+
"dropout": 0.3,
|
| 2333 |
+
"projection_dim": 64,
|
| 2334 |
+
"fusion_dim": 12,
|
| 2335 |
+
"validation_fraction": 0.25,
|
| 2336 |
+
"optimizer": "Adam",
|
| 2337 |
+
"class_weighting": true,
|
| 2338 |
+
"early_stopping_patience": 12,
|
| 2339 |
+
"seed": 123
|
| 2340 |
+
},
|
| 2341 |
+
"epochs_completed": 49,
|
| 2342 |
+
"best_epoch": 37,
|
| 2343 |
+
"early_stopped": true,
|
| 2344 |
+
"hit_max": false,
|
| 2345 |
+
"train_loss_at_best": 0.7013607054221921,
|
| 2346 |
+
"val_loss_at_best": 0.6157943606376648,
|
| 2347 |
+
"accuracy": 0.7625570776255708,
|
| 2348 |
+
"f1_macro": 0.7396509109600558,
|
| 2349 |
+
"f1_weighted": 0.773059563038045,
|
| 2350 |
+
"recall": {
|
| 2351 |
+
"0.0": 0.896551724137931,
|
| 2352 |
+
"1.0": 0.8787878787878788,
|
| 2353 |
+
"2.0": 0.7272727272727273,
|
| 2354 |
+
"3.0": 0.7431192660550459,
|
| 2355 |
+
"4.0": 0.6216216216216216
|
| 2356 |
+
},
|
| 2357 |
+
"pred_counts": {
|
| 2358 |
+
"0.0": 53,
|
| 2359 |
+
"1.0": 29,
|
| 2360 |
+
"2.0": 13,
|
| 2361 |
+
"3.0": 90,
|
| 2362 |
+
"4.0": 34
|
| 2363 |
+
},
|
| 2364 |
+
"collapsed": false,
|
| 2365 |
+
"history": [
|
| 2366 |
+
{
|
| 2367 |
+
"epoch": 1.0,
|
| 2368 |
+
"training_loss": 1.635941365870034,
|
| 2369 |
+
"validation_loss": 1.5491065979003906,
|
| 2370 |
+
"validation_accuracy": 0.4977168949771689,
|
| 2371 |
+
"validation_f1_macro": 0.1329268292682927
|
| 2372 |
+
},
|
| 2373 |
+
{
|
| 2374 |
+
"epoch": 2.0,
|
| 2375 |
+
"training_loss": 1.60081900619879,
|
| 2376 |
+
"validation_loss": 1.565390706062317,
|
| 2377 |
+
"validation_accuracy": 0.2054794520547945,
|
| 2378 |
+
"validation_f1_macro": 0.13772619984264362
|
| 2379 |
+
},
|
| 2380 |
+
{
|
| 2381 |
+
"epoch": 3.0,
|
| 2382 |
+
"training_loss": 1.558504796609646,
|
| 2383 |
+
"validation_loss": 1.463072657585144,
|
| 2384 |
+
"validation_accuracy": 0.3515981735159817,
|
| 2385 |
+
"validation_f1_macro": 0.34616743982970455
|
| 2386 |
+
},
|
| 2387 |
+
{
|
| 2388 |
+
"epoch": 4.0,
|
| 2389 |
+
"training_loss": 1.4567168573053872,
|
| 2390 |
+
"validation_loss": 1.3390640020370483,
|
| 2391 |
+
"validation_accuracy": 0.684931506849315,
|
| 2392 |
+
"validation_f1_macro": 0.5221375511647885
|
| 2393 |
+
},
|
| 2394 |
+
{
|
| 2395 |
+
"epoch": 5.0,
|
| 2396 |
+
"training_loss": 1.3068824832032366,
|
| 2397 |
+
"validation_loss": 1.1395671367645264,
|
| 2398 |
+
"validation_accuracy": 0.6438356164383562,
|
| 2399 |
+
"validation_f1_macro": 0.38348620210442724
|
| 2400 |
+
},
|
| 2401 |
+
{
|
| 2402 |
+
"epoch": 6.0,
|
| 2403 |
+
"training_loss": 1.2041963615068576,
|
| 2404 |
+
"validation_loss": 1.1338005065917969,
|
| 2405 |
+
"validation_accuracy": 0.639269406392694,
|
| 2406 |
+
"validation_f1_macro": 0.6026584562317626
|
| 2407 |
+
},
|
| 2408 |
+
{
|
| 2409 |
+
"epoch": 7.0,
|
| 2410 |
+
"training_loss": 1.1291042668063467,
|
| 2411 |
+
"validation_loss": 1.0177698135375977,
|
| 2412 |
+
"validation_accuracy": 0.6986301369863014,
|
| 2413 |
+
"validation_f1_macro": 0.6605897494132789
|
| 2414 |
+
},
|
| 2415 |
+
{
|
| 2416 |
+
"epoch": 8.0,
|
| 2417 |
+
"training_loss": 1.0272816027083047,
|
| 2418 |
+
"validation_loss": 0.9249964356422424,
|
| 2419 |
+
"validation_accuracy": 0.726027397260274,
|
| 2420 |
+
"validation_f1_macro": 0.6695071782095134
|
| 2421 |
+
},
|
| 2422 |
+
{
|
| 2423 |
+
"epoch": 9.0,
|
| 2424 |
+
"training_loss": 0.9894306848688823,
|
| 2425 |
+
"validation_loss": 0.8962472677230835,
|
| 2426 |
+
"validation_accuracy": 0.7031963470319634,
|
| 2427 |
+
"validation_f1_macro": 0.6633021248201514
|
| 2428 |
+
},
|
| 2429 |
+
{
|
| 2430 |
+
"epoch": 10.0,
|
| 2431 |
+
"training_loss": 0.9454721168773931,
|
| 2432 |
+
"validation_loss": 0.8671642541885376,
|
| 2433 |
+
"validation_accuracy": 0.7168949771689498,
|
| 2434 |
+
"validation_f1_macro": 0.6884058429093891
|
| 2435 |
+
},
|
| 2436 |
+
{
|
| 2437 |
+
"epoch": 11.0,
|
| 2438 |
+
"training_loss": 0.9224555572358574,
|
| 2439 |
+
"validation_loss": 0.8263513445854187,
|
| 2440 |
+
"validation_accuracy": 0.7214611872146118,
|
| 2441 |
+
"validation_f1_macro": 0.6688240031872784
|
| 2442 |
+
},
|
| 2443 |
+
{
|
| 2444 |
+
"epoch": 12.0,
|
| 2445 |
+
"training_loss": 0.902957145760699,
|
| 2446 |
+
"validation_loss": 0.8039170503616333,
|
| 2447 |
+
"validation_accuracy": 0.726027397260274,
|
| 2448 |
+
"validation_f1_macro": 0.6904180841904947
|
| 2449 |
+
},
|
| 2450 |
+
{
|
| 2451 |
+
"epoch": 13.0,
|
| 2452 |
+
"training_loss": 0.8497625836511937,
|
| 2453 |
+
"validation_loss": 0.7779726386070251,
|
| 2454 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2455 |
+
"validation_f1_macro": 0.7200793198284486
|
| 2456 |
+
},
|
| 2457 |
+
{
|
| 2458 |
+
"epoch": 14.0,
|
| 2459 |
+
"training_loss": 0.835496270075077,
|
| 2460 |
+
"validation_loss": 0.8103938102722168,
|
| 2461 |
+
"validation_accuracy": 0.7168949771689498,
|
| 2462 |
+
"validation_f1_macro": 0.6977670831675085
|
| 2463 |
+
},
|
| 2464 |
+
{
|
| 2465 |
+
"epoch": 15.0,
|
| 2466 |
+
"training_loss": 0.8223561884426489,
|
| 2467 |
+
"validation_loss": 0.7685360908508301,
|
| 2468 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2469 |
+
"validation_f1_macro": 0.7046996399222168
|
| 2470 |
+
},
|
| 2471 |
+
{
|
| 2472 |
+
"epoch": 16.0,
|
| 2473 |
+
"training_loss": 0.811010141925114,
|
| 2474 |
+
"validation_loss": 0.7409086227416992,
|
| 2475 |
+
"validation_accuracy": 0.7397260273972602,
|
| 2476 |
+
"validation_f1_macro": 0.7090524723509385
|
| 2477 |
+
},
|
| 2478 |
+
{
|
| 2479 |
+
"epoch": 17.0,
|
| 2480 |
+
"training_loss": 0.7999161881644551,
|
| 2481 |
+
"validation_loss": 0.7301066517829895,
|
| 2482 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2483 |
+
"validation_f1_macro": 0.7120104277129728
|
| 2484 |
+
},
|
| 2485 |
+
{
|
| 2486 |
+
"epoch": 18.0,
|
| 2487 |
+
"training_loss": 0.7460179510639935,
|
| 2488 |
+
"validation_loss": 0.7436771988868713,
|
| 2489 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2490 |
+
"validation_f1_macro": 0.7203665088299235
|
| 2491 |
+
},
|
| 2492 |
+
{
|
| 2493 |
+
"epoch": 19.0,
|
| 2494 |
+
"training_loss": 0.7962587337668349,
|
| 2495 |
+
"validation_loss": 0.7397180795669556,
|
| 2496 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2497 |
+
"validation_f1_macro": 0.7236053752266847
|
| 2498 |
+
},
|
| 2499 |
+
{
|
| 2500 |
+
"epoch": 20.0,
|
| 2501 |
+
"training_loss": 0.7818930701511663,
|
| 2502 |
+
"validation_loss": 0.7297154068946838,
|
| 2503 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2504 |
+
"validation_f1_macro": 0.7188234593548022
|
| 2505 |
+
},
|
| 2506 |
+
{
|
| 2507 |
+
"epoch": 21.0,
|
| 2508 |
+
"training_loss": 0.7805201520280141,
|
| 2509 |
+
"validation_loss": 0.7355466485023499,
|
| 2510 |
+
"validation_accuracy": 0.7397260273972602,
|
| 2511 |
+
"validation_f1_macro": 0.7253273117532787
|
| 2512 |
+
},
|
| 2513 |
+
{
|
| 2514 |
+
"epoch": 22.0,
|
| 2515 |
+
"training_loss": 0.7384932738978688,
|
| 2516 |
+
"validation_loss": 0.6986443996429443,
|
| 2517 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2518 |
+
"validation_f1_macro": 0.7195532673450402
|
| 2519 |
+
},
|
| 2520 |
+
{
|
| 2521 |
+
"epoch": 23.0,
|
| 2522 |
+
"training_loss": 0.7141552843698641,
|
| 2523 |
+
"validation_loss": 0.6742230653762817,
|
| 2524 |
+
"validation_accuracy": 0.7671232876712328,
|
| 2525 |
+
"validation_f1_macro": 0.7405008288847317
|
| 2526 |
+
},
|
| 2527 |
+
{
|
| 2528 |
+
"epoch": 24.0,
|
| 2529 |
+
"training_loss": 0.7321291711272263,
|
| 2530 |
+
"validation_loss": 0.6987788081169128,
|
| 2531 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2532 |
+
"validation_f1_macro": 0.7281183285945602
|
| 2533 |
+
},
|
| 2534 |
+
{
|
| 2535 |
+
"epoch": 25.0,
|
| 2536 |
+
"training_loss": 0.6965155884986971,
|
| 2537 |
+
"validation_loss": 0.7463865876197815,
|
| 2538 |
+
"validation_accuracy": 0.730593607305936,
|
| 2539 |
+
"validation_f1_macro": 0.7170696172579023
|
| 2540 |
+
},
|
| 2541 |
+
{
|
| 2542 |
+
"epoch": 26.0,
|
| 2543 |
+
"training_loss": 0.6961427418197074,
|
| 2544 |
+
"validation_loss": 0.6954517364501953,
|
| 2545 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2546 |
+
"validation_f1_macro": 0.7281183285945602
|
| 2547 |
+
},
|
| 2548 |
+
{
|
| 2549 |
+
"epoch": 27.0,
|
| 2550 |
+
"training_loss": 0.7121596714345421,
|
| 2551 |
+
"validation_loss": 0.6809113621711731,
|
| 2552 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2553 |
+
"validation_f1_macro": 0.7431894328050214
|
| 2554 |
+
},
|
| 2555 |
+
{
|
| 2556 |
+
"epoch": 28.0,
|
| 2557 |
+
"training_loss": 0.7088243794150468,
|
| 2558 |
+
"validation_loss": 0.6739152669906616,
|
| 2559 |
+
"validation_accuracy": 0.7397260273972602,
|
| 2560 |
+
"validation_f1_macro": 0.725214910428325
|
| 2561 |
+
},
|
| 2562 |
+
{
|
| 2563 |
+
"epoch": 29.0,
|
| 2564 |
+
"training_loss": 0.7163037883072365,
|
| 2565 |
+
"validation_loss": 0.675110399723053,
|
| 2566 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2567 |
+
"validation_f1_macro": 0.7234408217962469
|
| 2568 |
+
},
|
| 2569 |
+
{
|
| 2570 |
+
"epoch": 30.0,
|
| 2571 |
+
"training_loss": 0.6662919306900443,
|
| 2572 |
+
"validation_loss": 0.6735612750053406,
|
| 2573 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2574 |
+
"validation_f1_macro": 0.7343850277506163
|
| 2575 |
+
},
|
| 2576 |
+
{
|
| 2577 |
+
"epoch": 31.0,
|
| 2578 |
+
"training_loss": 0.7074004760602626,
|
| 2579 |
+
"validation_loss": 0.6266469955444336,
|
| 2580 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2581 |
+
"validation_f1_macro": 0.7166526021057865
|
| 2582 |
+
},
|
| 2583 |
+
{
|
| 2584 |
+
"epoch": 32.0,
|
| 2585 |
+
"training_loss": 0.6581337015803267,
|
| 2586 |
+
"validation_loss": 0.7085683345794678,
|
| 2587 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2588 |
+
"validation_f1_macro": 0.7259083059953252
|
| 2589 |
+
},
|
| 2590 |
+
{
|
| 2591 |
+
"epoch": 33.0,
|
| 2592 |
+
"training_loss": 0.7113121275494738,
|
| 2593 |
+
"validation_loss": 0.6482834219932556,
|
| 2594 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2595 |
+
"validation_f1_macro": 0.7338258176370583
|
| 2596 |
+
},
|
| 2597 |
+
{
|
| 2598 |
+
"epoch": 34.0,
|
| 2599 |
+
"training_loss": 0.6737250231388139,
|
| 2600 |
+
"validation_loss": 0.6657728552818298,
|
| 2601 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2602 |
+
"validation_f1_macro": 0.7259177036668325
|
| 2603 |
+
},
|
| 2604 |
+
{
|
| 2605 |
+
"epoch": 35.0,
|
| 2606 |
+
"training_loss": 0.6514683213175797,
|
| 2607 |
+
"validation_loss": 0.6538190245628357,
|
| 2608 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2609 |
+
"validation_f1_macro": 0.7388930908490514
|
| 2610 |
+
},
|
| 2611 |
+
{
|
| 2612 |
+
"epoch": 36.0,
|
| 2613 |
+
"training_loss": 0.688026835278767,
|
| 2614 |
+
"validation_loss": 0.6805294752120972,
|
| 2615 |
+
"validation_accuracy": 0.7397260273972602,
|
| 2616 |
+
"validation_f1_macro": 0.7273117482908698
|
| 2617 |
+
},
|
| 2618 |
+
{
|
| 2619 |
+
"epoch": 37.0,
|
| 2620 |
+
"training_loss": 0.7013607054221921,
|
| 2621 |
+
"validation_loss": 0.6157943606376648,
|
| 2622 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2623 |
+
"validation_f1_macro": 0.7396509109600558
|
| 2624 |
+
},
|
| 2625 |
+
{
|
| 2626 |
+
"epoch": 38.0,
|
| 2627 |
+
"training_loss": 0.6459702645860067,
|
| 2628 |
+
"validation_loss": 0.6483727693557739,
|
| 2629 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2630 |
+
"validation_f1_macro": 0.7292628517453911
|
| 2631 |
+
},
|
| 2632 |
+
{
|
| 2633 |
+
"epoch": 39.0,
|
| 2634 |
+
"training_loss": 0.6444681490339884,
|
| 2635 |
+
"validation_loss": 0.638465166091919,
|
| 2636 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2637 |
+
"validation_f1_macro": 0.7423711371070605
|
| 2638 |
+
},
|
| 2639 |
+
{
|
| 2640 |
+
"epoch": 40.0,
|
| 2641 |
+
"training_loss": 0.6560473761907438,
|
| 2642 |
+
"validation_loss": 0.6490275263786316,
|
| 2643 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2644 |
+
"validation_f1_macro": 0.733175554993892
|
| 2645 |
+
},
|
| 2646 |
+
{
|
| 2647 |
+
"epoch": 41.0,
|
| 2648 |
+
"training_loss": 0.6408006159997568,
|
| 2649 |
+
"validation_loss": 0.6614896059036255,
|
| 2650 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2651 |
+
"validation_f1_macro": 0.7379692009517402
|
| 2652 |
+
},
|
| 2653 |
+
{
|
| 2654 |
+
"epoch": 42.0,
|
| 2655 |
+
"training_loss": 0.6322115252657634,
|
| 2656 |
+
"validation_loss": 0.6705759167671204,
|
| 2657 |
+
"validation_accuracy": 0.7397260273972602,
|
| 2658 |
+
"validation_f1_macro": 0.7258992769847068
|
| 2659 |
+
},
|
| 2660 |
+
{
|
| 2661 |
+
"epoch": 43.0,
|
| 2662 |
+
"training_loss": 0.6636554475237684,
|
| 2663 |
+
"validation_loss": 0.6184088587760925,
|
| 2664 |
+
"validation_accuracy": 0.771689497716895,
|
| 2665 |
+
"validation_f1_macro": 0.7516816985948285
|
| 2666 |
+
},
|
| 2667 |
+
{
|
| 2668 |
+
"epoch": 44.0,
|
| 2669 |
+
"training_loss": 0.6606775471350042,
|
| 2670 |
+
"validation_loss": 0.6265592575073242,
|
| 2671 |
+
"validation_accuracy": 0.7579908675799086,
|
| 2672 |
+
"validation_f1_macro": 0.7323776838957562
|
| 2673 |
+
},
|
| 2674 |
+
{
|
| 2675 |
+
"epoch": 45.0,
|
| 2676 |
+
"training_loss": 0.6194041851090222,
|
| 2677 |
+
"validation_loss": 0.6486321091651917,
|
| 2678 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2679 |
+
"validation_f1_macro": 0.734953370421454
|
| 2680 |
+
},
|
| 2681 |
+
{
|
| 2682 |
+
"epoch": 46.0,
|
| 2683 |
+
"training_loss": 0.6432370637975088,
|
| 2684 |
+
"validation_loss": 0.6816199421882629,
|
| 2685 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2686 |
+
"validation_f1_macro": 0.7333772212502159
|
| 2687 |
+
},
|
| 2688 |
+
{
|
| 2689 |
+
"epoch": 47.0,
|
| 2690 |
+
"training_loss": 0.6377307420096746,
|
| 2691 |
+
"validation_loss": 0.6541978120803833,
|
| 2692 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2693 |
+
"validation_f1_macro": 0.7303845381526105
|
| 2694 |
+
},
|
| 2695 |
+
{
|
| 2696 |
+
"epoch": 48.0,
|
| 2697 |
+
"training_loss": 0.6303909973400396,
|
| 2698 |
+
"validation_loss": 0.6276454329490662,
|
| 2699 |
+
"validation_accuracy": 0.7534246575342466,
|
| 2700 |
+
"validation_f1_macro": 0.7408801972754376
|
| 2701 |
+
},
|
| 2702 |
+
{
|
| 2703 |
+
"epoch": 49.0,
|
| 2704 |
+
"training_loss": 0.61785961215089,
|
| 2705 |
+
"validation_loss": 0.6480539441108704,
|
| 2706 |
+
"validation_accuracy": 0.7488584474885844,
|
| 2707 |
+
"validation_f1_macro": 0.7393257736451248
|
| 2708 |
+
}
|
| 2709 |
+
]
|
| 2710 |
+
},
|
| 2711 |
+
{
|
| 2712 |
+
"limit": 50,
|
| 2713 |
+
"seed": 2024,
|
| 2714 |
+
"hyperparameters": {
|
| 2715 |
+
"epochs": 50,
|
| 2716 |
+
"batch_size": 16,
|
| 2717 |
+
"learning_rate": 0.001,
|
| 2718 |
+
"weight_decay": 0.0001,
|
| 2719 |
+
"dropout": 0.3,
|
| 2720 |
+
"projection_dim": 64,
|
| 2721 |
+
"fusion_dim": 12,
|
| 2722 |
+
"validation_fraction": 0.25,
|
| 2723 |
+
"optimizer": "Adam",
|
| 2724 |
+
"class_weighting": true,
|
| 2725 |
+
"early_stopping_patience": 12,
|
| 2726 |
+
"seed": 2024
|
| 2727 |
+
},
|
| 2728 |
+
"epochs_completed": 50,
|
| 2729 |
+
"best_epoch": 41,
|
| 2730 |
+
"early_stopped": false,
|
| 2731 |
+
"hit_max": true,
|
| 2732 |
+
"train_loss_at_best": 0.6359976275665004,
|
| 2733 |
+
"val_loss_at_best": 0.6597247123718262,
|
| 2734 |
+
"accuracy": 0.7579908675799086,
|
| 2735 |
+
"f1_macro": 0.7372566114501599,
|
| 2736 |
+
"f1_weighted": 0.7695326473497044,
|
| 2737 |
+
"recall": {
|
| 2738 |
+
"0.0": 0.7586206896551724,
|
| 2739 |
+
"1.0": 0.8181818181818182,
|
| 2740 |
+
"2.0": 0.7272727272727273,
|
| 2741 |
+
"3.0": 0.7798165137614679,
|
| 2742 |
+
"4.0": 0.6486486486486487
|
| 2743 |
+
},
|
| 2744 |
+
"pred_counts": {
|
| 2745 |
+
"0.0": 48,
|
| 2746 |
+
"1.0": 29,
|
| 2747 |
+
"2.0": 10,
|
| 2748 |
+
"3.0": 95,
|
| 2749 |
+
"4.0": 37
|
| 2750 |
+
},
|
| 2751 |
+
"collapsed": false,
|
| 2752 |
+
"history": [
|
| 2753 |
+
{
|
| 2754 |
+
"epoch": 1.0,
|
| 2755 |
+
"training_loss": 1.6225681711987752,
|
| 2756 |
+
"validation_loss": 1.511662483215332,
|
| 2757 |
+
"validation_accuracy": 0.4977168949771689,
|
| 2758 |
+
"validation_f1_macro": 0.1329268292682927
|
| 2759 |
+
},
|
| 2760 |
+
{
|
| 2761 |
+
"epoch": 2.0,
|
| 2762 |
+
"training_loss": 1.569906612721885,
|
| 2763 |
+
"validation_loss": 1.5234297513961792,
|
| 2764 |
+
"validation_accuracy": 0.4703196347031963,
|
| 2765 |
+
"validation_f1_macro": 0.2245614035087719
|
| 2766 |
+
},
|
| 2767 |
+
{
|
| 2768 |
+
"epoch": 3.0,
|
| 2769 |
+
"training_loss": 1.4499594322065028,
|
| 2770 |
+
"validation_loss": 1.3053251504898071,
|
| 2771 |
+
"validation_accuracy": 0.6894977168949772,
|
| 2772 |
+
"validation_f1_macro": 0.4256609173759133
|
| 2773 |
+
},
|
| 2774 |
+
{
|
| 2775 |
+
"epoch": 4.0,
|
| 2776 |
+
"training_loss": 1.3003037121237777,
|
| 2777 |
+
"validation_loss": 1.198732852935791,
|
| 2778 |
+
"validation_accuracy": 0.634703196347032,
|
| 2779 |
+
"validation_f1_macro": 0.440913835023424
|
| 2780 |
+
},
|
| 2781 |
+
{
|
| 2782 |
+
"epoch": 5.0,
|
| 2783 |
+
"training_loss": 1.2116903895285072,
|
| 2784 |
+
"validation_loss": 1.080140471458435,
|
| 2785 |
+
"validation_accuracy": 0.684931506849315,
|
| 2786 |
+
"validation_f1_macro": 0.5687377787336579
|
| 2787 |
+
},
|
| 2788 |
+
{
|
| 2789 |
+
"epoch": 6.0,
|
| 2790 |
+
"training_loss": 1.100791285677654,
|
| 2791 |
+
"validation_loss": 1.0347250699996948,
|
| 2792 |
+
"validation_accuracy": 0.6940639269406392,
|
| 2793 |
+
"validation_f1_macro": 0.6177055752611009
|
| 2794 |
+
},
|
| 2795 |
+
{
|
| 2796 |
+
"epoch": 7.0,
|
| 2797 |
+
"training_loss": 1.0073844906760425,
|
| 2798 |
+
"validation_loss": 0.937835693359375,
|
| 2799 |
+
"validation_accuracy": 0.7123287671232876,
|
| 2800 |
+
"validation_f1_macro": 0.6832595686116318
|
| 2801 |
+
},
|
| 2802 |
+
{
|
| 2803 |
+
"epoch": 8.0,
|
| 2804 |
+
"training_loss": 0.938835183294808,
|
| 2805 |
+
"validation_loss": 0.9243969917297363,
|
| 2806 |
+
"validation_accuracy": 0.7031963470319634,
|
| 2807 |
+
"validation_f1_macro": 0.6607865027822933
|
| 2808 |
+
},
|
| 2809 |
+
{
|
| 2810 |
+
"epoch": 9.0,
|
| 2811 |
+
"training_loss": 0.8966184040395225,
|
| 2812 |
+
"validation_loss": 0.8663153052330017,
|
| 2813 |
+
"validation_accuracy": 0.7168949771689498,
|
| 2814 |
+
"validation_f1_macro": 0.6923081349030715
|
| 2815 |
+
},
|
| 2816 |
+
{
|
| 2817 |
+
"epoch": 10.0,
|
| 2818 |
+
"training_loss": 0.8589439442971858,
|
| 2819 |
+
"validation_loss": 0.8406924605369568,
|
| 2820 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2821 |
+
"validation_f1_macro": 0.7221737682971412
|
| 2822 |
+
},
|
| 2823 |
+
{
|
| 2824 |
+
"epoch": 11.0,
|
| 2825 |
+
"training_loss": 0.85784370870125,
|
| 2826 |
+
"validation_loss": 0.8226235508918762,
|
| 2827 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2828 |
+
"validation_f1_macro": 0.7167905712472775
|
| 2829 |
+
},
|
| 2830 |
+
{
|
| 2831 |
+
"epoch": 12.0,
|
| 2832 |
+
"training_loss": 0.8242414804493509,
|
| 2833 |
+
"validation_loss": 0.8313245177268982,
|
| 2834 |
+
"validation_accuracy": 0.6986301369863014,
|
| 2835 |
+
"validation_f1_macro": 0.6600682809617517
|
| 2836 |
+
},
|
| 2837 |
+
{
|
| 2838 |
+
"epoch": 13.0,
|
| 2839 |
+
"training_loss": 0.8054670357122654,
|
| 2840 |
+
"validation_loss": 0.7694411873817444,
|
| 2841 |
+
"validation_accuracy": 0.7397260273972602,
|
| 2842 |
+
"validation_f1_macro": 0.7182388720082254
|
| 2843 |
+
},
|
| 2844 |
+
{
|
| 2845 |
+
"epoch": 14.0,
|
| 2846 |
+
"training_loss": 0.78004708450015,
|
| 2847 |
+
"validation_loss": 0.8055667281150818,
|
| 2848 |
+
"validation_accuracy": 0.7077625570776256,
|
| 2849 |
+
"validation_f1_macro": 0.6869753086419753
|
| 2850 |
+
},
|
| 2851 |
+
{
|
| 2852 |
+
"epoch": 15.0,
|
| 2853 |
+
"training_loss": 0.7828267034960956,
|
| 2854 |
+
"validation_loss": 0.7524726390838623,
|
| 2855 |
+
"validation_accuracy": 0.7397260273972602,
|
| 2856 |
+
"validation_f1_macro": 0.7179090965205553
|
| 2857 |
+
},
|
| 2858 |
+
{
|
| 2859 |
+
"epoch": 16.0,
|
| 2860 |
+
"training_loss": 0.7784952884767113,
|
| 2861 |
+
"validation_loss": 0.743364155292511,
|
| 2862 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2863 |
+
"validation_f1_macro": 0.7206798541605313
|
| 2864 |
+
},
|
| 2865 |
+
{
|
| 2866 |
+
"epoch": 17.0,
|
| 2867 |
+
"training_loss": 0.7457227278046492,
|
| 2868 |
+
"validation_loss": 0.7856912016868591,
|
| 2869 |
+
"validation_accuracy": 0.7123287671232876,
|
| 2870 |
+
"validation_f1_macro": 0.7093765406198898
|
| 2871 |
+
},
|
| 2872 |
+
{
|
| 2873 |
+
"epoch": 18.0,
|
| 2874 |
+
"training_loss": 0.7468449764135408,
|
| 2875 |
+
"validation_loss": 0.7758557200431824,
|
| 2876 |
+
"validation_accuracy": 0.7123287671232876,
|
| 2877 |
+
"validation_f1_macro": 0.7032627437525654
|
| 2878 |
+
},
|
| 2879 |
+
{
|
| 2880 |
+
"epoch": 19.0,
|
| 2881 |
+
"training_loss": 0.7238862507226991,
|
| 2882 |
+
"validation_loss": 0.7738156914710999,
|
| 2883 |
+
"validation_accuracy": 0.7168949771689498,
|
| 2884 |
+
"validation_f1_macro": 0.707996859273741
|
| 2885 |
+
},
|
| 2886 |
+
{
|
| 2887 |
+
"epoch": 20.0,
|
| 2888 |
+
"training_loss": 0.7094513577658955,
|
| 2889 |
+
"validation_loss": 0.7316175699234009,
|
| 2890 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2891 |
+
"validation_f1_macro": 0.7231832224960381
|
| 2892 |
+
},
|
| 2893 |
+
{
|
| 2894 |
+
"epoch": 21.0,
|
| 2895 |
+
"training_loss": 0.7254922986030579,
|
| 2896 |
+
"validation_loss": 0.7338428497314453,
|
| 2897 |
+
"validation_accuracy": 0.730593607305936,
|
| 2898 |
+
"validation_f1_macro": 0.7052727011184234
|
| 2899 |
+
},
|
| 2900 |
+
{
|
| 2901 |
+
"epoch": 22.0,
|
| 2902 |
+
"training_loss": 0.7048084808558952,
|
| 2903 |
+
"validation_loss": 0.7339456677436829,
|
| 2904 |
+
"validation_accuracy": 0.7214611872146118,
|
| 2905 |
+
"validation_f1_macro": 0.7166191562713704
|
| 2906 |
+
},
|
| 2907 |
+
{
|
| 2908 |
+
"epoch": 23.0,
|
| 2909 |
+
"training_loss": 0.7217072335685172,
|
| 2910 |
+
"validation_loss": 0.7096080183982849,
|
| 2911 |
+
"validation_accuracy": 0.7351598173515982,
|
| 2912 |
+
"validation_f1_macro": 0.7232759567659875
|
| 2913 |
+
},
|
| 2914 |
+
{
|
| 2915 |
+
"epoch": 24.0,
|
| 2916 |
+
"training_loss": 0.694426145495438,
|
| 2917 |
+
"validation_loss": 0.7198649644851685,
|
| 2918 |
+
"validation_accuracy": 0.730593607305936,
|
| 2919 |
+
"validation_f1_macro": 0.7219951080353464
|
| 2920 |
+
},
|
| 2921 |
+
{
|
| 2922 |
+
"epoch": 25.0,
|
| 2923 |
+
"training_loss": 0.685888970043601,
|
| 2924 |
+
"validation_loss": 0.7141242027282715,
|
| 2925 |
+
"validation_accuracy": 0.726027397260274,
|
| 2926 |
+
"validation_f1_macro": 0.709853949870283
|
| 2927 |
+
},
|
| 2928 |
+
{
|
| 2929 |
+
"epoch": 26.0,
|
| 2930 |
+
"training_loss": 0.6784876305155638,
|
| 2931 |
+
"validation_loss": 0.717924952507019,
|
| 2932 |
+
"validation_accuracy": 0.7168949771689498,
|
| 2933 |
+
"validation_f1_macro": 0.7044832586768071
|
| 2934 |
+
},
|
| 2935 |
+
{
|
| 2936 |
+
"epoch": 27.0,
|
| 2937 |
+
"training_loss": 0.6826280130118858,
|
| 2938 |
+
"validation_loss": 0.7048062682151794,
|
| 2939 |
+
"validation_accuracy": 0.7442922374429224,
|
| 2940 |
+
"validation_f1_macro": 0.7313134228007573
|
| 2941 |
+
},
|
| 2942 |
+
{
|
| 2943 |
+
"epoch": 28.0,
|
| 2944 |
+
"training_loss": 0.6632811921398815,
|
| 2945 |
+
"validation_loss": 0.7309033274650574,
|
| 2946 |
+
"validation_accuracy": 0.726027397260274,
|
| 2947 |
+
"validation_f1_macro": 0.7225617660101258
|
| 2948 |
+
},
|
| 2949 |
+
{
|
| 2950 |
+
"epoch": 29.0,
|
| 2951 |
+
"training_loss": 0.6795863043971178,
|
| 2952 |
+
"validation_loss": 0.6975738406181335,
|
| 2953 |
+
"validation_accuracy": 0.726027397260274,
|
| 2954 |
+
"validation_f1_macro": 0.7100132842068326
|
| 2955 |
+
},
|
| 2956 |
+
{
|
| 2957 |
+
"epoch": 30.0,
|
| 2958 |
+
"training_loss": 0.6437340684053374,
|
| 2959 |
+
"validation_loss": 0.665772020816803,
|
| 2960 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2961 |
+
"validation_f1_macro": 0.7328823093731366
|
| 2962 |
+
},
|
| 2963 |
+
{
|
| 2964 |
+
"epoch": 31.0,
|
| 2965 |
+
"training_loss": 0.7039524542122353,
|
| 2966 |
+
"validation_loss": 0.719477117061615,
|
| 2967 |
+
"validation_accuracy": 0.726027397260274,
|
| 2968 |
+
"validation_f1_macro": 0.7113093026126989
|
| 2969 |
+
},
|
| 2970 |
+
{
|
| 2971 |
+
"epoch": 32.0,
|
| 2972 |
+
"training_loss": 0.6489482645581408,
|
| 2973 |
+
"validation_loss": 0.7060401439666748,
|
| 2974 |
+
"validation_accuracy": 0.730593607305936,
|
| 2975 |
+
"validation_f1_macro": 0.720639788504223
|
| 2976 |
+
},
|
| 2977 |
+
{
|
| 2978 |
+
"epoch": 33.0,
|
| 2979 |
+
"training_loss": 0.6433238772357383,
|
| 2980 |
+
"validation_loss": 0.7341402769088745,
|
| 2981 |
+
"validation_accuracy": 0.7123287671232876,
|
| 2982 |
+
"validation_f1_macro": 0.6899070486620005
|
| 2983 |
+
},
|
| 2984 |
+
{
|
| 2985 |
+
"epoch": 34.0,
|
| 2986 |
+
"training_loss": 0.6565981808958984,
|
| 2987 |
+
"validation_loss": 0.6739374399185181,
|
| 2988 |
+
"validation_accuracy": 0.7625570776255708,
|
| 2989 |
+
"validation_f1_macro": 0.7401719424176123
|
| 2990 |
+
},
|
| 2991 |
+
{
|
| 2992 |
+
"epoch": 35.0,
|
| 2993 |
+
"training_loss": 0.6548550739520933,
|
| 2994 |
+
"validation_loss": 0.7086837291717529,
|
| 2995 |
+
"validation_accuracy": 0.726027397260274,
|
| 2996 |
+
"validation_f1_macro": 0.7100132842068326
|
| 2997 |
+
},
|
| 2998 |
+
{
|
| 2999 |
+
"epoch": 36.0,
|
| 3000 |
+
"training_loss": 0.602200011291155,
|
| 3001 |
+
"validation_loss": 0.6941585540771484,
|
| 3002 |
+
"validation_accuracy": 0.7351598173515982,
|
| 3003 |
+
"validation_f1_macro": 0.7234462506071674
|
| 3004 |
+
},
|
| 3005 |
+
{
|
| 3006 |
+
"epoch": 37.0,
|
| 3007 |
+
"training_loss": 0.63544079007172,
|
| 3008 |
+
"validation_loss": 0.7004677653312683,
|
| 3009 |
+
"validation_accuracy": 0.730593607305936,
|
| 3010 |
+
"validation_f1_macro": 0.720639788504223
|
| 3011 |
+
},
|
| 3012 |
+
{
|
| 3013 |
+
"epoch": 38.0,
|
| 3014 |
+
"training_loss": 0.6624184563392546,
|
| 3015 |
+
"validation_loss": 0.7010037899017334,
|
| 3016 |
+
"validation_accuracy": 0.726027397260274,
|
| 3017 |
+
"validation_f1_macro": 0.717861527690879
|
| 3018 |
+
},
|
| 3019 |
+
{
|
| 3020 |
+
"epoch": 39.0,
|
| 3021 |
+
"training_loss": 0.5985031287844588,
|
| 3022 |
+
"validation_loss": 0.6666479110717773,
|
| 3023 |
+
"validation_accuracy": 0.7488584474885844,
|
| 3024 |
+
"validation_f1_macro": 0.7315324401710119
|
| 3025 |
+
},
|
| 3026 |
+
{
|
| 3027 |
+
"epoch": 40.0,
|
| 3028 |
+
"training_loss": 0.6056617698291453,
|
| 3029 |
+
"validation_loss": 0.6940096020698547,
|
| 3030 |
+
"validation_accuracy": 0.7488584474885844,
|
| 3031 |
+
"validation_f1_macro": 0.7360844329718171
|
| 3032 |
+
},
|
| 3033 |
+
{
|
| 3034 |
+
"epoch": 41.0,
|
| 3035 |
+
"training_loss": 0.6359976275665004,
|
| 3036 |
+
"validation_loss": 0.6597247123718262,
|
| 3037 |
+
"validation_accuracy": 0.7579908675799086,
|
| 3038 |
+
"validation_f1_macro": 0.7372566114501599
|
| 3039 |
+
},
|
| 3040 |
+
{
|
| 3041 |
+
"epoch": 42.0,
|
| 3042 |
+
"training_loss": 0.6047317712772183,
|
| 3043 |
+
"validation_loss": 0.6979882717132568,
|
| 3044 |
+
"validation_accuracy": 0.730593607305936,
|
| 3045 |
+
"validation_f1_macro": 0.7124974170733906
|
| 3046 |
+
},
|
| 3047 |
+
{
|
| 3048 |
+
"epoch": 43.0,
|
| 3049 |
+
"training_loss": 0.6072182982433133,
|
| 3050 |
+
"validation_loss": 0.7281728386878967,
|
| 3051 |
+
"validation_accuracy": 0.7214611872146118,
|
| 3052 |
+
"validation_f1_macro": 0.7046568261714561
|
| 3053 |
+
},
|
| 3054 |
+
{
|
| 3055 |
+
"epoch": 44.0,
|
| 3056 |
+
"training_loss": 0.5998183230801326,
|
| 3057 |
+
"validation_loss": 0.6768959760665894,
|
| 3058 |
+
"validation_accuracy": 0.730593607305936,
|
| 3059 |
+
"validation_f1_macro": 0.7169811762776586
|
| 3060 |
+
},
|
| 3061 |
+
{
|
| 3062 |
+
"epoch": 45.0,
|
| 3063 |
+
"training_loss": 0.6171028475935866,
|
| 3064 |
+
"validation_loss": 0.6866343021392822,
|
| 3065 |
+
"validation_accuracy": 0.730593607305936,
|
| 3066 |
+
"validation_f1_macro": 0.7085102123329972
|
| 3067 |
+
},
|
| 3068 |
+
{
|
| 3069 |
+
"epoch": 46.0,
|
| 3070 |
+
"training_loss": 0.5848244028847392,
|
| 3071 |
+
"validation_loss": 0.678470253944397,
|
| 3072 |
+
"validation_accuracy": 0.7351598173515982,
|
| 3073 |
+
"validation_f1_macro": 0.7195757575757575
|
| 3074 |
+
},
|
| 3075 |
+
{
|
| 3076 |
+
"epoch": 47.0,
|
| 3077 |
+
"training_loss": 0.6237764242218762,
|
| 3078 |
+
"validation_loss": 0.684725821018219,
|
| 3079 |
+
"validation_accuracy": 0.7442922374429224,
|
| 3080 |
+
"validation_f1_macro": 0.7301780448040185
|
| 3081 |
+
},
|
| 3082 |
+
{
|
| 3083 |
+
"epoch": 48.0,
|
| 3084 |
+
"training_loss": 0.5977335670372335,
|
| 3085 |
+
"validation_loss": 0.6758159399032593,
|
| 3086 |
+
"validation_accuracy": 0.730593607305936,
|
| 3087 |
+
"validation_f1_macro": 0.70888995215311
|
| 3088 |
+
},
|
| 3089 |
+
{
|
| 3090 |
+
"epoch": 49.0,
|
| 3091 |
+
"training_loss": 0.6079468349131142,
|
| 3092 |
+
"validation_loss": 0.6623165607452393,
|
| 3093 |
+
"validation_accuracy": 0.7488584474885844,
|
| 3094 |
+
"validation_f1_macro": 0.7466358704586553
|
| 3095 |
+
},
|
| 3096 |
+
{
|
| 3097 |
+
"epoch": 50.0,
|
| 3098 |
+
"training_loss": 0.6073242571295762,
|
| 3099 |
+
"validation_loss": 0.7163891792297363,
|
| 3100 |
+
"validation_accuracy": 0.7214611872146118,
|
| 3101 |
+
"validation_f1_macro": 0.7070384085443462
|
| 3102 |
+
}
|
| 3103 |
+
]
|
| 3104 |
+
}
|
| 3105 |
+
]
|
diagnostics/2026-10-16-brca-training-collapse/results/epochs_50.log
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
limit=50 seed=0 done: best=49/50 acc=0.763 f1m=0.724
|
| 2 |
+
limit=50 seed=1 done: best=50/50 acc=0.772 f1m=0.744
|
| 3 |
+
limit=50 seed=2 done: best=50/50 acc=0.790 f1m=0.761
|
| 4 |
+
limit=50 seed=3 done: best=47/50 acc=0.731 f1m=0.714
|
| 5 |
+
limit=50 seed=7 done: best=32/44 acc=0.772 f1m=0.752
|
| 6 |
+
limit=50 seed=42 done: best=38/50 acc=0.767 f1m=0.747
|
| 7 |
+
limit=50 seed=123 done: best=37/49 acc=0.763 f1m=0.740
|
| 8 |
+
limit=50 seed=2024 done: best=41/50 acc=0.758 f1m=0.737
|
| 9 |
+
limit=50 ALL DONE
|
diagnostics/2026-10-16-brca-training-collapse/results/paper_config_sgd.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
paper: SGD lr=0.01 wd=0.01 200ep acc=0.498 f1_macro=0.133 f1_w=0.331 epochs=17 pred=[0, 0, 0, 219, 0] prob std=0.0000
|
| 2 |
+
paper, no early stop acc=0.498 f1_macro=0.133 f1_w=0.331 epochs=200 pred=[0, 0, 0, 219, 0] prob std=0.0000
|
| 3 |
+
|
| 4 |
+
[exited with code 0]
|
diagnostics/2026-10-16-brca-training-collapse/results/seed_runs.txt
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
weight_decay=0.000 seed=0 accuracy=0.763 f1_macro=0.724 f1_weighted=0.769 epochs=50 classes_predicted=5 prob_std=0.265 recall_0.0=0.793 recall_1.0=0.818 recall_2.0=0.545 recall_3.0=0.807 recall_4.0=0.622
|
| 2 |
+
weight_decay=0.000 seed=1 accuracy=0.772 f1_macro=0.744 f1_weighted=0.781 epochs=50 classes_predicted=5 prob_std=0.266 recall_0.0=0.828 recall_1.0=0.848 recall_2.0=0.727 recall_3.0=0.789 recall_4.0=0.622
|
| 3 |
+
weight_decay=0.000 seed=2 accuracy=0.790 f1_macro=0.761 f1_weighted=0.802 epochs=50 classes_predicted=5 prob_std=0.278 recall_0.0=0.862 recall_1.0=0.788 recall_2.0=0.909 recall_3.0=0.798 recall_4.0=0.676
|
| 4 |
+
weight_decay=0.000 seed=3 accuracy=0.731 f1_macro=0.714 f1_weighted=0.739 epochs=50 classes_predicted=5 prob_std=0.271 recall_0.0=0.793 recall_1.0=0.818 recall_2.0=0.545 recall_3.0=0.743 recall_4.0=0.622
|
| 5 |
+
weight_decay=0.000 seed=7 accuracy=0.772 f1_macro=0.752 f1_weighted=0.783 epochs=44 classes_predicted=5 prob_std=0.259 recall_0.0=0.862 recall_1.0=0.788 recall_2.0=0.636 recall_3.0=0.761 recall_4.0=0.757
|
| 6 |
+
weight_decay=0.000 seed=42 accuracy=0.767 f1_macro=0.747 f1_weighted=0.774 epochs=50 classes_predicted=5 prob_std=0.270 recall_0.0=0.759 recall_1.0=0.939 recall_2.0=0.909 recall_3.0=0.771 recall_4.0=0.568
|
| 7 |
+
weight_decay=0.000 seed=123 accuracy=0.763 f1_macro=0.740 f1_weighted=0.773 epochs=49 classes_predicted=5 prob_std=0.267 recall_0.0=0.897 recall_1.0=0.879 recall_2.0=0.727 recall_3.0=0.743 recall_4.0=0.622
|
| 8 |
+
weight_decay=0.000 seed=2024 accuracy=0.758 f1_macro=0.737 f1_weighted=0.770 epochs=50 classes_predicted=5 prob_std=0.276 recall_0.0=0.759 recall_1.0=0.818 recall_2.0=0.727 recall_3.0=0.780 recall_4.0=0.649
|
| 9 |
+
weight_decay=0.010 seed=0 accuracy=0.498 f1_macro=0.133 f1_weighted=0.331 epochs=13 classes_predicted=1 prob_std=0.000 recall_0.0=0.000 recall_1.0=0.000 recall_2.0=0.000 recall_3.0=1.000 recall_4.0=0.000
|
| 10 |
+
weight_decay=0.010 seed=1 accuracy=0.498 f1_macro=0.133 f1_weighted=0.331 epochs=15 classes_predicted=1 prob_std=0.000 recall_0.0=0.000 recall_1.0=0.000 recall_2.0=0.000 recall_3.0=1.000 recall_4.0=0.000
|
| 11 |
+
weight_decay=0.010 seed=2 accuracy=0.626 f1_macro=0.539 f1_weighted=0.611 epochs=50 classes_predicted=5 prob_std=0.142 recall_0.0=0.103 recall_1.0=0.879 recall_2.0=0.636 recall_3.0=0.817 recall_4.0=0.243
|
| 12 |
+
weight_decay=0.010 seed=3 accuracy=0.498 f1_macro=0.133 f1_weighted=0.331 epochs=23 classes_predicted=1 prob_std=0.000 recall_0.0=0.000 recall_1.0=0.000 recall_2.0=0.000 recall_3.0=1.000 recall_4.0=0.000
|
| 13 |
+
weight_decay=0.010 seed=7 accuracy=0.498 f1_macro=0.133 f1_weighted=0.331 epochs=22 classes_predicted=1 prob_std=0.000 recall_0.0=0.000 recall_1.0=0.000 recall_2.0=0.000 recall_3.0=1.000 recall_4.0=0.000
|
| 14 |
+
weight_decay=0.010 seed=42 accuracy=0.498 f1_macro=0.133 f1_weighted=0.331 epochs=31 classes_predicted=1 prob_std=0.000 recall_0.0=0.000 recall_1.0=0.000 recall_2.0=0.000 recall_3.0=1.000 recall_4.0=0.000
|
| 15 |
+
weight_decay=0.010 seed=123 accuracy=0.498 f1_macro=0.133 f1_weighted=0.331 epochs=17 classes_predicted=1 prob_std=0.000 recall_0.0=0.000 recall_1.0=0.000 recall_2.0=0.000 recall_3.0=1.000 recall_4.0=0.000
|
| 16 |
+
weight_decay=0.010 seed=2024 accuracy=0.658 f1_macro=0.480 f1_weighted=0.565 epochs=50 classes_predicted=4 prob_std=0.134 recall_0.0=0.000 recall_1.0=0.848 recall_2.0=0.545 recall_3.0=0.982 recall_4.0=0.081
|
| 17 |
+
|
| 18 |
+
SUMMARY (mean ± std over seeds)
|
| 19 |
+
weight_decay 0.0001 0.0100
|
| 20 |
+
accuracy mean 0.764 0.534
|
| 21 |
+
std 0.017 0.067
|
| 22 |
+
min 0.731 0.498
|
| 23 |
+
max 0.790 0.658
|
| 24 |
+
f1_macro mean 0.740 0.227
|
| 25 |
+
std 0.015 0.175
|
| 26 |
+
min 0.714 0.133
|
| 27 |
+
max 0.761 0.539
|
| 28 |
+
f1_weighted mean 0.774 0.395
|
| 29 |
+
std 0.018 0.120
|
| 30 |
+
min 0.739 0.331
|
| 31 |
+
max 0.802 0.611
|
| 32 |
+
epochs mean 49.125 27.625
|
| 33 |
+
std 2.100 14.889
|
| 34 |
+
min 44.000 13.000
|
| 35 |
+
max 50.000 50.000
|
| 36 |
+
classes_predicted mean 5.000 1.875
|
| 37 |
+
std 0.000 1.642
|
| 38 |
+
min 5.000 1.000
|
| 39 |
+
max 5.000 5.000
|
| 40 |
+
recall_0.0 mean 0.819 0.013
|
| 41 |
+
std 0.051 0.037
|
| 42 |
+
min 0.759 0.000
|
| 43 |
+
max 0.897 0.103
|
| 44 |
+
recall_1.0 mean 0.837 0.216
|
| 45 |
+
std 0.051 0.400
|
| 46 |
+
min 0.788 0.000
|
| 47 |
+
max 0.939 0.879
|
| 48 |
+
recall_2.0 mean 0.716 0.148
|
| 49 |
+
std 0.141 0.275
|
| 50 |
+
min 0.545 0.000
|
| 51 |
+
max 0.909 0.636
|
| 52 |
+
recall_3.0 mean 0.774 0.975
|
| 53 |
+
std 0.024 0.064
|
| 54 |
+
min 0.743 0.817
|
| 55 |
+
max 0.807 1.000
|
| 56 |
+
recall_4.0 mean 0.642 0.041
|
| 57 |
+
std 0.055 0.087
|
| 58 |
+
min 0.568 0.000
|
| 59 |
+
max 0.757 0.243
|
| 60 |
+
|
| 61 |
+
collapsed runs (1 class predicted): [[0.01, 0.0], [0.01, 1.0], [0.01, 3.0], [0.01, 7.0], [0.01, 42.0], [0.01, 123.0]]
|
| 62 |
+
|
| 63 |
+
[exited with code 0]
|
diagnostics/2026-10-16-brca-training-collapse/results/weight_decay_sweep.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
app default (Adam, wd=0.01) acc=0.498 f1_macro=0.133 epochs= 31 pred counts=[0, 0, 0, 219, 0] prob std across samples=0.0000
|
| 2 |
+
wd=0 acc=0.749 f1_macro=0.741 epochs= 44 pred counts=[46, 29, 15, 91, 38] prob std across samples=0.2643
|
| 3 |
+
wd=1e-4 acc=0.767 f1_macro=0.747 epochs= 50 pred counts=[46, 32, 16, 96, 29] prob std across samples=0.2704
|
| 4 |
+
wd=0, no class weighting acc=0.772 f1_macro=0.692 epochs= 50 pred counts=[31, 33, 5, 112, 38] prob std across samples=0.2582
|
| 5 |
+
wd=0.01, lr=0.01 acc=0.498 f1_macro=0.133 epochs= 21 pred counts=[0, 0, 0, 219, 0] prob std across samples=0.0000
|
| 6 |
+
|
| 7 |
+
[exited with code 0]
|
diagnostics/2026-10-16-brca-training-collapse/scripts/diagnose.py
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Read-only diagnostics for a BioLM-NET training run. Does not modify project code;
|
| 2 |
+
it wraps library functions from the outside to observe what they do."""
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
import pickle
|
| 6 |
+
import sys
|
| 7 |
+
from pathlib import Path
|
| 8 |
+
|
| 9 |
+
import numpy as np
|
| 10 |
+
import pandas as pd
|
| 11 |
+
import torch
|
| 12 |
+
|
| 13 |
+
OUT = Path(__file__).parent
|
| 14 |
+
DATASET = sys.argv[1] if len(sys.argv) > 1 else "BRCA"
|
| 15 |
+
CLASS_WEIGHTING = (sys.argv[2] if len(sys.argv) > 2 else "1") == "1"
|
| 16 |
+
EPOCHS = int(sys.argv[3]) if len(sys.argv) > 3 else 50
|
| 17 |
+
|
| 18 |
+
import app # noqa: E402
|
| 19 |
+
import biolmnet.training as training # noqa: E402
|
| 20 |
+
from biolmnet.data import read_csv, upstream_example_sources # noqa: E402
|
| 21 |
+
|
| 22 |
+
pd.set_option("display.width", 200)
|
| 23 |
+
np.set_printoptions(precision=3, suppress=True, linewidth=160)
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def section(title):
|
| 27 |
+
print(f"\n{'=' * 8} {title} {'=' * 8}")
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
# ---------- raw files ----------
|
| 31 |
+
section(f"RAW FILES ({DATASET})")
|
| 32 |
+
for key, url in upstream_example_sources(DATASET).items():
|
| 33 |
+
frame = read_csv(url)
|
| 34 |
+
print(f"{key:14s} shape={frame.shape} first cols={list(frame.columns[:3])}")
|
| 35 |
+
if key == "labels":
|
| 36 |
+
print(" raw label counts:", frame.iloc[:, 0].value_counts().to_dict())
|
| 37 |
+
|
| 38 |
+
# ---------- workspace ----------
|
| 39 |
+
cache = OUT / f"workspace_{DATASET}.pkl"
|
| 40 |
+
if cache.exists():
|
| 41 |
+
workspace = pickle.loads(cache.read_bytes())
|
| 42 |
+
else:
|
| 43 |
+
result = app.prepare_workspace(
|
| 44 |
+
"BioLM-NET examples", DATASET, "", None, None, None, None, None, None, None,
|
| 45 |
+
True, "Auto — bulk or single-cell based on source", progress=lambda *a, **k: None,
|
| 46 |
+
)
|
| 47 |
+
workspace = result[0]
|
| 48 |
+
if workspace is None:
|
| 49 |
+
print(result[1]); sys.exit(1)
|
| 50 |
+
cache.write_bytes(pickle.dumps(workspace))
|
| 51 |
+
|
| 52 |
+
section("WORKSPACE")
|
| 53 |
+
print("warnings:", workspace.warnings)
|
| 54 |
+
print("samples:", len(workspace.labels), " classes:", workspace.label_names)
|
| 55 |
+
print("full class counts:", dict(zip(workspace.label_names, np.bincount(workspace.labels).tolist())))
|
| 56 |
+
for name, values in (("gene", workspace.gene_expression), ("dna", workspace.dna_methylation)):
|
| 57 |
+
print(f"{name}: shape={values.shape} min={values.min():.3g} max={values.max():.3g} "
|
| 58 |
+
f"mean={values.mean():.3g} zero-var cols={(values.std(0) < 1e-8).sum()}")
|
| 59 |
+
|
| 60 |
+
section("MASKS")
|
| 61 |
+
for name, branch in (("gene", workspace.gene_branch), ("dna", workspace.dna_branch)):
|
| 62 |
+
m = branch.biological_mask
|
| 63 |
+
p = branch.pathway_mask
|
| 64 |
+
print(f"{name}: bio mask {m.shape} density={(m > 0).mean():.4%} nnz={(m > 0).sum():,} "
|
| 65 |
+
f"PDI={branch.pdi_edges} PPI={branch.ppi_edges}")
|
| 66 |
+
print(f" inputs with 0 outgoing edges: {(m.sum(1) == 0).sum()}/{m.shape[0]} "
|
| 67 |
+
f"hidden genes in-degree median={np.median((m > 0).sum(0)):.0f} max={(m > 0).sum(0).max()}")
|
| 68 |
+
print(f" nonzero mask values: min={m[m > 0].min():.3f} median={np.median(m[m > 0]):.3f} max={m.max():.3f}")
|
| 69 |
+
print(f" pathway mask {p.shape}: hidden genes in no pathway={(p.sum(1) == 0).sum()}/{p.shape[0]} "
|
| 70 |
+
f"genes/pathway median={np.median(p.sum(0)):.0f}")
|
| 71 |
+
|
| 72 |
+
# ---------- instrumented training ----------
|
| 73 |
+
hp = training.Hyperparameters(epochs=EPOCHS, class_weighting=CLASS_WEIGHTING)
|
| 74 |
+
section(f"TRAINING {hp}")
|
| 75 |
+
train_index, validation_index = training.split_train_validation(workspace.labels, hp.validation_fraction, hp.seed)
|
| 76 |
+
names = workspace.label_names
|
| 77 |
+
print("training class counts: ", dict(zip(names, np.bincount(workspace.labels[train_index], minlength=len(names)).tolist())))
|
| 78 |
+
print("validation class counts:", dict(zip(names, np.bincount(workspace.labels[validation_index], minlength=len(names)).tolist())))
|
| 79 |
+
|
| 80 |
+
captured = {"criterion_weights": [], "evals": [], "loss_calls": 0}
|
| 81 |
+
orig_ce = training.nn.CrossEntropyLoss
|
| 82 |
+
|
| 83 |
+
|
| 84 |
+
class SpyCE(orig_ce):
|
| 85 |
+
def forward(self, logits, target):
|
| 86 |
+
captured["loss_calls"] += 1
|
| 87 |
+
captured["seen_weight"] = None if self.weight is None else self.weight.detach().cpu().numpy()
|
| 88 |
+
return super().forward(logits, target)
|
| 89 |
+
|
| 90 |
+
|
| 91 |
+
def make_spy(*args, **kwargs):
|
| 92 |
+
loss = SpyCE(*args, **kwargs)
|
| 93 |
+
captured["criterion_weights"].append(None if loss.weight is None else loss.weight.cpu().numpy())
|
| 94 |
+
return loss
|
| 95 |
+
|
| 96 |
+
|
| 97 |
+
training.nn.CrossEntropyLoss = make_spy
|
| 98 |
+
orig_eval = training._evaluate
|
| 99 |
+
|
| 100 |
+
|
| 101 |
+
def spy_eval(model, gene, dna, labels, device):
|
| 102 |
+
out = orig_eval(model, gene, dna, labels, device)
|
| 103 |
+
captured["evals"].append((out[1], out[2]))
|
| 104 |
+
return out
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
training._evaluate = spy_eval
|
| 108 |
+
orig_make = training._make_model
|
| 109 |
+
|
| 110 |
+
|
| 111 |
+
def spy_make(*a, **k):
|
| 112 |
+
model = orig_make(*a, **k)
|
| 113 |
+
captured["initial_state"] = {k2: v.detach().clone() for k2, v in model.state_dict().items()}
|
| 114 |
+
return model
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
training._make_model = spy_make
|
| 118 |
+
|
| 119 |
+
result = training.train(workspace, hp)
|
| 120 |
+
bundle = result.bundle
|
| 121 |
+
|
| 122 |
+
section("CLASS WEIGHTS")
|
| 123 |
+
print("weights passed to CrossEntropyLoss:", captured["criterion_weights"])
|
| 124 |
+
print("weight attribute seen inside loss.forward:", captured.get("seen_weight"))
|
| 125 |
+
print("loss.forward calls:", captured["loss_calls"])
|
| 126 |
+
|
| 127 |
+
section("HISTORY")
|
| 128 |
+
print(pd.DataFrame(bundle.history).to_string(index=False))
|
| 129 |
+
|
| 130 |
+
section("PER-EPOCH VALIDATION PREDICTION COUNTS")
|
| 131 |
+
for i, (probs, preds) in enumerate(captured["evals"][:-1]):
|
| 132 |
+
counts = np.bincount(preds, minlength=len(names))
|
| 133 |
+
print(f"epoch {i + 1:3d}: counts={counts.tolist()} mean max-prob={probs.max(1).mean():.3f}")
|
| 134 |
+
|
| 135 |
+
section("FINAL (best checkpoint) VALIDATION")
|
| 136 |
+
probs, preds = captured["evals"][-1]
|
| 137 |
+
y_val = workspace.labels[validation_index]
|
| 138 |
+
print("prediction counts:", dict(zip(names, np.bincount(preds, minlength=len(names)).tolist())))
|
| 139 |
+
print("average predicted probability per class:", dict(zip(names, probs.mean(0).round(3).tolist())))
|
| 140 |
+
print("training class prior:", dict(zip(names, (np.bincount(workspace.labels[train_index], minlength=len(names)) / len(train_index)).round(3).tolist())))
|
| 141 |
+
print("std of each class prob across samples:", probs.std(0).round(4).tolist())
|
| 142 |
+
print("max-prob: min/median/max =", np.percentile(probs.max(1), [0, 50, 100]).round(3).tolist())
|
| 143 |
+
sorted_p = np.sort(probs, 1)
|
| 144 |
+
print("margin top1-top2: median =", np.median(sorted_p[:, -1] - sorted_p[:, -2]).round(4))
|
| 145 |
+
print("first 8 validation rows (prob vectors):\n", probs[:8])
|
| 146 |
+
print("metrics:", {k: v for k, v in bundle.metrics.items() if k != "device"})
|
| 147 |
+
print("confusion:\n", result.confusion)
|
| 148 |
+
|
| 149 |
+
section("LOGITS / ACTIVATIONS (best checkpoint, validation rows)")
|
| 150 |
+
model = bundle.model.eval()
|
| 151 |
+
gene = torch.from_numpy(((workspace.gene_expression[validation_index] - bundle.gene_mean) / bundle.gene_scale).astype(np.float32))
|
| 152 |
+
dna = torch.from_numpy(((workspace.dna_methylation[validation_index] - bundle.dna_mean) / bundle.dna_scale).astype(np.float32))
|
| 153 |
+
with torch.no_grad():
|
| 154 |
+
stats = {}
|
| 155 |
+
for name, branch, x in (("gene", model.gene_branch, gene), ("dna", model.dna_branch, dna)):
|
| 156 |
+
pre = branch.biological(x)
|
| 157 |
+
hidden = torch.relu(pre)
|
| 158 |
+
pathways = branch.pathway_attention(hidden)
|
| 159 |
+
proj = torch.sigmoid(branch.projection(pathways))
|
| 160 |
+
dead = (hidden.max(0).values == 0).float().mean().item()
|
| 161 |
+
print(f"{name}: bio pre-act mean={pre.mean():.3g} std={pre.std():.3g} dead ReLU units={dead:.1%} "
|
| 162 |
+
f"pathway std across samples={pathways.std(0).mean():.3g} "
|
| 163 |
+
f"sigmoid saturated(<.02|>.98)={((proj < .02) | (proj > .98)).float().mean():.1%} "
|
| 164 |
+
f"proj std across samples={proj.std(0).mean():.3g}")
|
| 165 |
+
stats[name] = proj
|
| 166 |
+
fused = torch.tanh(model.fusion(torch.cat([stats["gene"], stats["dna"]], 1)))
|
| 167 |
+
logits = model.output(fused)
|
| 168 |
+
print(f"fusion tanh saturated(|x|>.98)={(fused.abs() > .98).float().mean():.1%} fused std across samples={fused.std(0).mean():.3g}")
|
| 169 |
+
print("logits mean per class:", logits.mean(0).numpy(), " logits std across samples per class:", logits.std(0).numpy())
|
| 170 |
+
|
| 171 |
+
section("PARAMETER CHANGE FROM INIT")
|
| 172 |
+
for key, value in bundle.model.state_dict().items():
|
| 173 |
+
init = captured["initial_state"].get(key)
|
| 174 |
+
if init is None or not value.is_floating_point() or key.endswith("mask") or key.endswith("embeddings"):
|
| 175 |
+
continue
|
| 176 |
+
delta = (value - init.cpu()).norm() / (init.norm() + 1e-12)
|
| 177 |
+
print(f"{key:45s} rel change={delta:.4f}")
|
diagnostics/2026-10-16-brca-training-collapse/scripts/epochs.py
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Diagnostic only: BRCA, weight_decay=1e-4, one epoch limit across 8 seeds.
|
| 2 |
+
Usage: epochs.py <epoch_limit>. Writes epochs_<limit>.json next to this file.
|
| 3 |
+
Project code is used unchanged; only Hyperparameters fields are overridden."""
|
| 4 |
+
import json
|
| 5 |
+
import pickle
|
| 6 |
+
import sys
|
| 7 |
+
from dataclasses import asdict, replace
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
import numpy as np
|
| 11 |
+
from sklearn.metrics import recall_score
|
| 12 |
+
|
| 13 |
+
import biolmnet.training as training
|
| 14 |
+
|
| 15 |
+
HERE = Path(__file__).parent
|
| 16 |
+
LIMIT = int(sys.argv[1])
|
| 17 |
+
SEEDS = [0, 1, 2, 3, 7, 42, 123, 2024]
|
| 18 |
+
TOLERANCE = 1e-5 # mirrors train(): improvement must exceed 1e-5
|
| 19 |
+
|
| 20 |
+
workspace = pickle.loads((HERE / "workspace_BRCA.pkl").read_bytes())
|
| 21 |
+
names = workspace.label_names
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def replay(history, patience_limit):
|
| 25 |
+
"""Re-run train()'s checkpoint/early-stop bookkeeping on the recorded history."""
|
| 26 |
+
best_loss, best_epoch, patience, stopped = float("inf"), None, 0, False
|
| 27 |
+
for row in history:
|
| 28 |
+
if row["validation_loss"] < best_loss - TOLERANCE:
|
| 29 |
+
best_loss, best_epoch, patience = row["validation_loss"], int(row["epoch"]), 0
|
| 30 |
+
else:
|
| 31 |
+
patience += 1
|
| 32 |
+
if patience >= patience_limit:
|
| 33 |
+
stopped = True
|
| 34 |
+
break
|
| 35 |
+
return best_epoch, stopped
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
runs = []
|
| 39 |
+
for seed in SEEDS:
|
| 40 |
+
hp = replace(
|
| 41 |
+
training.Hyperparameters(),
|
| 42 |
+
epochs=LIMIT, weight_decay=1e-4, seed=seed,
|
| 43 |
+
optimizer="Adam", learning_rate=0.001,
|
| 44 |
+
)
|
| 45 |
+
result = training.train(workspace, hp)
|
| 46 |
+
bundle = result.bundle
|
| 47 |
+
history = bundle.history
|
| 48 |
+
best_epoch, early_stopped = replay(history, hp.early_stopping_patience)
|
| 49 |
+
best_row = history[best_epoch - 1]
|
| 50 |
+
vp = result.validation_predictions
|
| 51 |
+
recalls = recall_score(vp["observed"], vp["predicted"], labels=names, average=None, zero_division=0)
|
| 52 |
+
counts = vp["predicted"].value_counts().reindex(names, fill_value=0).astype(int).tolist()
|
| 53 |
+
m = bundle.metrics
|
| 54 |
+
# Sanity: the restored checkpoint's re-evaluated loss must match the best history row.
|
| 55 |
+
assert abs(m["validation_loss"] - best_row["validation_loss"]) < 1e-4, (seed, m["validation_loss"], best_row)
|
| 56 |
+
run = {
|
| 57 |
+
"limit": LIMIT, "seed": seed, "hyperparameters": asdict(hp),
|
| 58 |
+
"epochs_completed": m["epochs_completed"], "best_epoch": best_epoch,
|
| 59 |
+
"early_stopped": early_stopped, "hit_max": m["epochs_completed"] == LIMIT and not early_stopped,
|
| 60 |
+
"train_loss_at_best": best_row["training_loss"], "val_loss_at_best": best_row["validation_loss"],
|
| 61 |
+
"accuracy": m["accuracy"], "f1_macro": m["f1_macro"], "f1_weighted": m["f1_weighted"],
|
| 62 |
+
"recall": dict(zip(names, map(float, recalls))), "pred_counts": dict(zip(names, counts)),
|
| 63 |
+
"collapsed": int((np.array(counts) > 0).sum()) == 1,
|
| 64 |
+
"history": history,
|
| 65 |
+
}
|
| 66 |
+
runs.append(run)
|
| 67 |
+
print(f"limit={LIMIT} seed={seed} done: best={best_epoch}/{m['epochs_completed']} "
|
| 68 |
+
f"acc={m['accuracy']:.3f} f1m={m['f1_macro']:.3f}", flush=True)
|
| 69 |
+
|
| 70 |
+
(HERE / f"epochs_{LIMIT}.json").write_text(json.dumps(runs, indent=1))
|
| 71 |
+
print(f"limit={LIMIT} ALL DONE", flush=True)
|
diagnostics/2026-10-16-brca-training-collapse/scripts/epochs_summary.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Summarise epochs_{50,100,200}.json produced by epochs.py."""
|
| 2 |
+
import json
|
| 3 |
+
from pathlib import Path
|
| 4 |
+
|
| 5 |
+
import numpy as np
|
| 6 |
+
import pandas as pd
|
| 7 |
+
|
| 8 |
+
HERE = Path(__file__).parent
|
| 9 |
+
LIMITS = [50, 100, 200]
|
| 10 |
+
data = {limit: json.loads((HERE / f"epochs_{limit}.json").read_text()) for limit in LIMITS}
|
| 11 |
+
names = list(data[50][0]["recall"])
|
| 12 |
+
pd.set_option("display.width", 250)
|
| 13 |
+
pd.set_option("display.max_columns", 40)
|
| 14 |
+
|
| 15 |
+
print("=" * 20, "PER RUN")
|
| 16 |
+
rows = []
|
| 17 |
+
for limit in LIMITS:
|
| 18 |
+
for r in data[limit]:
|
| 19 |
+
h = pd.DataFrame(r["history"])
|
| 20 |
+
best = r["best_epoch"]
|
| 21 |
+
after = h[h.epoch > best]
|
| 22 |
+
rows.append({
|
| 23 |
+
"limit": limit, "seed": r["seed"], "done": r["epochs_completed"], "best": best,
|
| 24 |
+
"early_stop": r["early_stopped"], "hit_max": r["hit_max"],
|
| 25 |
+
"trL@best": r["train_loss_at_best"], "vaL@best": r["val_loss_at_best"],
|
| 26 |
+
"acc": r["accuracy"], "f1_mac": r["f1_macro"], "f1_w": r["f1_weighted"],
|
| 27 |
+
**{f"rec_{n}": r["recall"][n] for n in names},
|
| 28 |
+
"pred_counts": "/".join(str(r["pred_counts"][n]) for n in names),
|
| 29 |
+
"collapsed": r["collapsed"],
|
| 30 |
+
# overfitting signals after the best checkpoint
|
| 31 |
+
"trL_drop_after_best": (r["train_loss_at_best"] - h.training_loss.iloc[-1]) if len(after) else 0.0,
|
| 32 |
+
"vaL_rise_after_best": (h.validation_loss.iloc[-1] - r["val_loss_at_best"]) if len(after) else 0.0,
|
| 33 |
+
"vaL_max_after_best": (after.validation_loss.max() - r["val_loss_at_best"]) if len(after) else 0.0,
|
| 34 |
+
"f1_last_epoch": h.validation_f1_macro.iloc[-1],
|
| 35 |
+
})
|
| 36 |
+
runs = pd.DataFrame(rows)
|
| 37 |
+
print(runs.round(3).to_string(index=False))
|
| 38 |
+
runs.to_csv(HERE / "epochs_runs.csv", index=False)
|
| 39 |
+
|
| 40 |
+
print("\n" + "=" * 20, "SUMMARY PER EPOCH LIMIT (8 seeds)")
|
| 41 |
+
summary = []
|
| 42 |
+
for limit, g in runs.groupby("limit"):
|
| 43 |
+
summary.append({
|
| 44 |
+
"limit": limit,
|
| 45 |
+
"acc": f"{g.acc.mean():.3f} ± {g.acc.std():.3f}",
|
| 46 |
+
"f1_macro": f"{g.f1_mac.mean():.3f} ± {g.f1_mac.std():.3f}",
|
| 47 |
+
"f1_weighted": f"{g.f1_w.mean():.3f} ± {g.f1_w.std():.3f}",
|
| 48 |
+
"f1_macro min/max": f"{g.f1_mac.min():.3f} / {g.f1_mac.max():.3f}",
|
| 49 |
+
"mean best epoch": f"{g.best.mean():.1f}",
|
| 50 |
+
"best epoch range": f"{g.best.min()}–{g.best.max()}",
|
| 51 |
+
"hit max": int(g.hit_max.sum()), "early stopped": int(g.early_stop.sum()),
|
| 52 |
+
"collapsed": int(g.collapsed.sum()),
|
| 53 |
+
**{f"recall {n}": f"{g[f'rec_{n}'].mean():.3f}" for n in names},
|
| 54 |
+
})
|
| 55 |
+
print(pd.DataFrame(summary).set_index("limit").T.to_string())
|
| 56 |
+
|
| 57 |
+
print("\n" + "=" * 20, "PAIRED CHANGE vs 50 EPOCHS (same seed)")
|
| 58 |
+
base = runs[runs.limit == 50].set_index("seed")
|
| 59 |
+
for limit in (100, 200):
|
| 60 |
+
other = runs[runs.limit == limit].set_index("seed")
|
| 61 |
+
for metric in ("acc", "f1_mac", "f1_w"):
|
| 62 |
+
diff = other[metric] - base[metric]
|
| 63 |
+
print(f"{limit:3d} vs 50 {metric:7s} mean Δ={diff.mean():+.4f} std={diff.std():.4f} "
|
| 64 |
+
f"better/equal/worse = {(diff > 1e-9).sum()}/{(diff.abs() <= 1e-9).sum()}/{(diff < -1e-9).sum()} "
|
| 65 |
+
f"per-seed={diff.round(3).tolist()}")
|
| 66 |
+
other = runs[runs.limit == 200].set_index("seed"); mid = runs[runs.limit == 100].set_index("seed")
|
| 67 |
+
diff = other.f1_mac - mid.f1_mac
|
| 68 |
+
print(f"200 vs 100 f1_mac mean Δ={diff.mean():+.4f} better/equal/worse = "
|
| 69 |
+
f"{(diff > 1e-9).sum()}/{(diff.abs() <= 1e-9).sum()}/{(diff < -1e-9).sum()}")
|
| 70 |
+
|
| 71 |
+
print("\n" + "=" * 20, "OVERFITTING SIGNALS (after the best checkpoint)")
|
| 72 |
+
for limit, g in runs.groupby("limit"):
|
| 73 |
+
trained_past = g[g.done > g.best]
|
| 74 |
+
print(f"limit {limit}: runs that trained past best={len(trained_past)} "
|
| 75 |
+
f"mean epochs after best={(g.done - g.best).mean():.1f} "
|
| 76 |
+
f"mean train-loss drop after best={trained_past.trL_drop_after_best.mean():.3f} "
|
| 77 |
+
f"mean val-loss rise (final-best)={trained_past.vaL_rise_after_best.mean():.3f} "
|
| 78 |
+
f"runs where train↓ and val↑ after best="
|
| 79 |
+
f"{int(((trained_past.trL_drop_after_best > 0) & (trained_past.vaL_rise_after_best > 0)).sum())}")
|
| 80 |
+
|
| 81 |
+
print("\n" + "=" * 20, "MEAN LOSS CURVES (200-epoch runs; mean over seeds still running at that epoch)")
|
| 82 |
+
curves = pd.concat([pd.DataFrame(r["history"]).assign(seed=r["seed"]) for r in data[200]])
|
| 83 |
+
checkpoints = [1, 5, 10, 20, 30, 40, 50, 60, 80, 100, 125, 150, 175, 200]
|
| 84 |
+
table = curves[curves.epoch.isin(checkpoints)].groupby("epoch").agg(
|
| 85 |
+
runs=("seed", "count"), train_loss=("training_loss", "mean"),
|
| 86 |
+
val_loss=("validation_loss", "mean"), val_acc=("validation_accuracy", "mean"),
|
| 87 |
+
val_f1_macro=("validation_f1_macro", "mean"))
|
| 88 |
+
print(table.round(3).to_string())
|
| 89 |
+
|
| 90 |
+
print("\n" + "=" * 20, "DETERMINISM: shared epochs identical across limits for the same seed?")
|
| 91 |
+
for seed in [r["seed"] for r in data[50]]:
|
| 92 |
+
hs = {L: pd.DataFrame(next(r for r in data[L] if r["seed"] == seed)["history"]) for L in LIMITS}
|
| 93 |
+
n = min(len(h) for h in hs.values())
|
| 94 |
+
same = all(np.allclose(hs[L].validation_loss.iloc[:n], hs[50].validation_loss.iloc[:n], atol=1e-6) for L in LIMITS)
|
| 95 |
+
print(f"seed {seed}: first {n} epochs identical across 50/100/200 = {same}")
|
diagnostics/2026-10-16-brca-training-collapse/scripts/seeds.py
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Seed-stability check on BRCA: weight_decay=1e-4 vs the current default 0.01.
|
| 2 |
+
Each seed changes the stratified split, weight init and batch order together.
|
| 3 |
+
Uses project code as-is; only Hyperparameters are overridden."""
|
| 4 |
+
import pickle
|
| 5 |
+
from dataclasses import replace
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
import numpy as np
|
| 9 |
+
import pandas as pd
|
| 10 |
+
from sklearn.metrics import recall_score
|
| 11 |
+
|
| 12 |
+
import biolmnet.training as training
|
| 13 |
+
|
| 14 |
+
workspace = pickle.loads((Path(__file__).parent / "workspace_BRCA.pkl").read_bytes())
|
| 15 |
+
names = workspace.label_names
|
| 16 |
+
seeds = [0, 1, 2, 3, 7, 42, 123, 2024]
|
| 17 |
+
rows = []
|
| 18 |
+
for weight_decay in (1e-4, 0.01):
|
| 19 |
+
for seed in seeds:
|
| 20 |
+
hp = replace(training.Hyperparameters(), weight_decay=weight_decay, seed=seed)
|
| 21 |
+
result = training.train(workspace, hp)
|
| 22 |
+
m = result.bundle.metrics
|
| 23 |
+
vp = result.validation_predictions
|
| 24 |
+
probs = vp[[f"P({n})" for n in names]].to_numpy()
|
| 25 |
+
recalls = recall_score(vp["observed"], vp["predicted"], labels=names, average=None, zero_division=0)
|
| 26 |
+
row = {
|
| 27 |
+
"weight_decay": weight_decay, "seed": seed,
|
| 28 |
+
"accuracy": m["accuracy"], "f1_macro": m["f1_macro"], "f1_weighted": m["f1_weighted"],
|
| 29 |
+
"epochs": m["epochs_completed"],
|
| 30 |
+
"classes_predicted": int(vp["predicted"].nunique()),
|
| 31 |
+
"prob_std": float(probs.std(0).mean()),
|
| 32 |
+
**{f"recall_{n}": r for n, r in zip(names, recalls)},
|
| 33 |
+
}
|
| 34 |
+
rows.append(row)
|
| 35 |
+
print(" ".join(f"{k}={v:.3f}" if isinstance(v, float) else f"{k}={v}" for k, v in row.items()), flush=True)
|
| 36 |
+
|
| 37 |
+
frame = pd.DataFrame(rows)
|
| 38 |
+
frame.to_csv(Path(__file__).parent / "seed_runs.csv", index=False)
|
| 39 |
+
print("\nSUMMARY (mean ± std over seeds)")
|
| 40 |
+
metrics = ["accuracy", "f1_macro", "f1_weighted", "epochs", "classes_predicted"] + [f"recall_{n}" for n in names]
|
| 41 |
+
summary = frame.groupby("weight_decay")[metrics].agg(["mean", "std", "min", "max"]).T
|
| 42 |
+
pd.set_option("display.width", 200)
|
| 43 |
+
print(summary.round(3).to_string())
|
| 44 |
+
print("\ncollapsed runs (1 class predicted):", frame[frame.classes_predicted == 1][["weight_decay", "seed"]].values.tolist())
|
diagnostics/2026-10-16-brca-training-collapse/scripts/sweep.py
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Train BRCA under a few optimizer settings and report whether the model collapses."""
|
| 2 |
+
import pickle
|
| 3 |
+
import sys
|
| 4 |
+
from dataclasses import replace
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
import numpy as np
|
| 8 |
+
|
| 9 |
+
import biolmnet.training as training
|
| 10 |
+
|
| 11 |
+
workspace = pickle.loads((Path(__file__).parent / "workspace_BRCA.pkl").read_bytes())
|
| 12 |
+
base = training.Hyperparameters(epochs=int(sys.argv[1]) if len(sys.argv) > 1 else 50)
|
| 13 |
+
configs = {
|
| 14 |
+
"app default (Adam, wd=0.01)": base,
|
| 15 |
+
"wd=0": replace(base, weight_decay=0.0),
|
| 16 |
+
"wd=1e-4": replace(base, weight_decay=1e-4),
|
| 17 |
+
"wd=0, no class weighting": replace(base, weight_decay=0.0, class_weighting=False),
|
| 18 |
+
"wd=0.01, lr=0.01": replace(base, learning_rate=0.01),
|
| 19 |
+
}
|
| 20 |
+
for name, hp in configs.items():
|
| 21 |
+
result = training.train(workspace, hp)
|
| 22 |
+
vp = result.validation_predictions
|
| 23 |
+
probs = vp[[c for c in vp if c.startswith("P(")]].to_numpy()
|
| 24 |
+
m = result.bundle.metrics
|
| 25 |
+
counts = vp["predicted"].value_counts().reindex(workspace.label_names, fill_value=0).tolist()
|
| 26 |
+
print(f"{name:30s} acc={m['accuracy']:.3f} f1_macro={m['f1_macro']:.3f} epochs={m['epochs_completed']:3d} "
|
| 27 |
+
f"pred counts={counts} prob std across samples={probs.std(0).mean():.4f}", flush=True)
|
diagnostics/2026-10-16-brca-training-collapse/upstream/BioLMNET.ipynb
ADDED
|
@@ -0,0 +1,947 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": null,
|
| 6 |
+
"id": "634f46b7-f788-499d-b014-7c28905eeff6",
|
| 7 |
+
"metadata": {},
|
| 8 |
+
"outputs": [],
|
| 9 |
+
"source": [
|
| 10 |
+
"import os\n",
|
| 11 |
+
"os.environ['PYTHONHASHSEED'] = '0'\n",
|
| 12 |
+
"os.environ['TF_DETERMINISTIC_OPS'] = '1'\n",
|
| 13 |
+
"os.environ['CUDA_VISIBLE_DEVICES'] = ''\n",
|
| 14 |
+
"import random\n",
|
| 15 |
+
"import numpy as np\n",
|
| 16 |
+
"import pandas as pd\n",
|
| 17 |
+
"import itertools\n",
|
| 18 |
+
"from sklearn.preprocessing import StandardScaler, LabelEncoder\n",
|
| 19 |
+
"from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score\n",
|
| 20 |
+
"from sklearn.model_selection import train_test_split, StratifiedKFold\n",
|
| 21 |
+
"import matplotlib.pyplot as plt\n",
|
| 22 |
+
"import tensorflow as tf\n",
|
| 23 |
+
"from pathlib import Path\n",
|
| 24 |
+
"from tensorflow.keras import layers, Model\n",
|
| 25 |
+
"from tensorflow.keras.layers import Lambda, Dense, Dropout, Input, concatenate, Flatten, BatchNormalization, Activation\n",
|
| 26 |
+
"from tensorflow.keras import backend as K, regularizers, initializers\n",
|
| 27 |
+
"from tensorflow.keras.initializers import LecunUniform, GlorotUniform\n",
|
| 28 |
+
"from tensorflow.keras.regularizers import l2\n",
|
| 29 |
+
"from joblib import Parallel, delayed\n",
|
| 30 |
+
"from tqdm import tqdm\n",
|
| 31 |
+
"from tqdm_joblib import tqdm_joblib\n",
|
| 32 |
+
"from huggingface_hub import hf_hub_download\n",
|
| 33 |
+
"tf.config.threading.set_intra_op_parallelism_threads(1)\n",
|
| 34 |
+
"tf.config.threading.set_inter_op_parallelism_threads(1)\n",
|
| 35 |
+
"tf.random.set_seed(42)\n"
|
| 36 |
+
]
|
| 37 |
+
},
|
| 38 |
+
{
|
| 39 |
+
"cell_type": "code",
|
| 40 |
+
"execution_count": null,
|
| 41 |
+
"id": "535e884e-58a5-434e-95df-0735956321b5",
|
| 42 |
+
"metadata": {},
|
| 43 |
+
"outputs": [],
|
| 44 |
+
"source": [
|
| 45 |
+
"from huggingface_hub import hf_hub_download\n",
|
| 46 |
+
"\n",
|
| 47 |
+
"FNAME = \"embedding_associations_cell_type_tissue_drug_pathway_openai_large.parquet\" \n",
|
| 48 |
+
"parquet_path = hf_hub_download(\n",
|
| 49 |
+
" repo_id = \"honicky/genept-composable-embeddings\",\n",
|
| 50 |
+
" filename = FNAME,\n",
|
| 51 |
+
" repo_type = \"model\"\n",
|
| 52 |
+
")\n",
|
| 53 |
+
"emb = pd.read_parquet(parquet_path)"
|
| 54 |
+
]
|
| 55 |
+
},
|
| 56 |
+
{
|
| 57 |
+
"cell_type": "code",
|
| 58 |
+
"execution_count": null,
|
| 59 |
+
"id": "1a4d2523-d9a0-466f-bc58-8c815370e9e2",
|
| 60 |
+
"metadata": {},
|
| 61 |
+
"outputs": [],
|
| 62 |
+
"source": [
|
| 63 |
+
"df_gene = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"Gene_Expression.csv\")\n",
|
| 64 |
+
"df_dna = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"DNA_Methylation.csv\")\n",
|
| 65 |
+
" \n",
|
| 66 |
+
"true_label = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"label.csv\")\n",
|
| 67 |
+
"\n",
|
| 68 |
+
"scaler = StandardScaler()\n",
|
| 69 |
+
"le = LabelEncoder()\n",
|
| 70 |
+
"le.fit(true_label)\n",
|
| 71 |
+
"y = le.transform(true_label)\n",
|
| 72 |
+
"\n",
|
| 73 |
+
"ge_genes = list(df_gene.columns)\n",
|
| 74 |
+
"\n",
|
| 75 |
+
"df_pdi = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"PDI\"/ \"PDI.csv\",sep=',')\n",
|
| 76 |
+
"df_ge_pdi = df_pdi[df_pdi.Target.isin(ge_genes)]\n",
|
| 77 |
+
"unique_tfs = df_ge_pdi['TF'].unique()\n",
|
| 78 |
+
"unique_targets = df_ge_pdi['Target'].unique()\n",
|
| 79 |
+
"\n",
|
| 80 |
+
"dna_genes =list(df_dna.columns) \n",
|
| 81 |
+
"df_dna_pdi = df_pdi[df_pdi.Target.isin(dna_genes)]\n",
|
| 82 |
+
"\n",
|
| 83 |
+
"dna_unique_tfs = df_dna_pdi['TF'].unique()\n",
|
| 84 |
+
"dna_unique_targets = df_dna_pdi['Target'].unique()\n",
|
| 85 |
+
"\n",
|
| 86 |
+
"df_ppi = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"PPI\"/ \"PPI.csv\",sep=',')\n",
|
| 87 |
+
"df_ppi = df_ppi.drop(['Unnamed: 0'], axis =1)\n",
|
| 88 |
+
"df_ppi['combined_score'] = df_ppi['combined_score'] /1000\n",
|
| 89 |
+
"threshold = df_ppi['combined_score'].quantile(0.9)\n",
|
| 90 |
+
"df_ppi = df_ppi[df_ppi['combined_score'] >= threshold]\n",
|
| 91 |
+
"df_ge_ppi = df_ppi[df_ppi['protein1'].isin(ge_genes) | df_ppi['protein2'].isin(ge_genes)]\n",
|
| 92 |
+
"unique_protein1 = df_ge_ppi['protein1'].unique()\n",
|
| 93 |
+
"unique_protein2 = df_ge_ppi['protein2'].unique()\n",
|
| 94 |
+
"\n",
|
| 95 |
+
"df_dna_ppi = df_ppi[df_ppi['protein1'].isin(dna_genes) | df_ppi['protein2'].isin(dna_genes)]\n",
|
| 96 |
+
"dna_unique_protein1 = df_dna_ppi['protein1'].unique()\n",
|
| 97 |
+
"dna_unique_protein2 = df_dna_ppi['protein2'].unique()\n",
|
| 98 |
+
"\n",
|
| 99 |
+
"ge_pdi_ppi_genes = list(set(unique_targets) | set(unique_protein2))\n",
|
| 100 |
+
"dna_pdi_ppi_genes = list(set(dna_unique_targets) | set(dna_unique_protein2))"
|
| 101 |
+
]
|
| 102 |
+
},
|
| 103 |
+
{
|
| 104 |
+
"cell_type": "code",
|
| 105 |
+
"execution_count": null,
|
| 106 |
+
"id": "e868db94-f1d2-413a-b36f-028cb0d7499d",
|
| 107 |
+
"metadata": {},
|
| 108 |
+
"outputs": [],
|
| 109 |
+
"source": [
|
| 110 |
+
"genept_gene_emb = emb.loc[emb.index.isin(ge_pdi_ppi_genes)]\n",
|
| 111 |
+
"ge_pdi_ppi_genept = genept_gene_emb.index"
|
| 112 |
+
]
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"cell_type": "code",
|
| 116 |
+
"execution_count": null,
|
| 117 |
+
"id": "dfd04c7c-6119-4f60-836e-43d2c2060299",
|
| 118 |
+
"metadata": {},
|
| 119 |
+
"outputs": [],
|
| 120 |
+
"source": [
|
| 121 |
+
"genept_dna_emb = emb.loc[emb.index.isin(dna_pdi_ppi_genes)]\n",
|
| 122 |
+
"dna_pdi_ppi_genept = genept_dna_emb.index"
|
| 123 |
+
]
|
| 124 |
+
},
|
| 125 |
+
{
|
| 126 |
+
"cell_type": "code",
|
| 127 |
+
"execution_count": null,
|
| 128 |
+
"id": "537876a2-01e5-4a8f-92df-621469614756",
|
| 129 |
+
"metadata": {},
|
| 130 |
+
"outputs": [],
|
| 131 |
+
"source": [
|
| 132 |
+
"def create_ge_mask_matrix (extra_neurons):\n",
|
| 133 |
+
" de_gene_to_idx = {gene: i for i, gene in enumerate(ge_genes)}\n",
|
| 134 |
+
" target_to_idx = {target: j for j, target in enumerate(unique_targets)}\n",
|
| 135 |
+
" protein2_to_idx = {protein2: k for k, protein2 in enumerate(unique_protein2)}\n",
|
| 136 |
+
"\n",
|
| 137 |
+
" pdi_mask_matrix = np.zeros((len(ge_genes), len(unique_targets)), dtype=int)\n",
|
| 138 |
+
"\n",
|
| 139 |
+
" for _, row in df_ge_pdi.iterrows():\n",
|
| 140 |
+
" tfa = row[\"TF\"]\n",
|
| 141 |
+
" target = row[\"Target\"]\n",
|
| 142 |
+
" if tfa in de_gene_to_idx and target in target_to_idx:\n",
|
| 143 |
+
" tf_idx = de_gene_to_idx[tfa]\n",
|
| 144 |
+
" target_idx = target_to_idx[target]\n",
|
| 145 |
+
" pdi_mask_matrix[tf_idx, target_idx] = 1\n",
|
| 146 |
+
" \n",
|
| 147 |
+
" ppi_mask_matrix = np.zeros((len(ge_genes), len(unique_protein2)))\n",
|
| 148 |
+
"\n",
|
| 149 |
+
" for _, row in df_ge_ppi.iterrows():\n",
|
| 150 |
+
" protein1 = row[\"protein1\"]\n",
|
| 151 |
+
" protein2 = row[\"protein2\"]\n",
|
| 152 |
+
" combined_score = row[\"combined_score\"]\n",
|
| 153 |
+
"\n",
|
| 154 |
+
" if protein1 in de_gene_to_idx and protein2 in protein2_to_idx:\n",
|
| 155 |
+
" protein1_idx = de_gene_to_idx[protein1]\n",
|
| 156 |
+
" protein2_idx = protein2_to_idx[protein2]\n",
|
| 157 |
+
" ppi_mask_matrix[protein1_idx, protein2_idx] = combined_score \n",
|
| 158 |
+
" \n",
|
| 159 |
+
" pdi_mask_df= pd.DataFrame(pdi_mask_matrix)\n",
|
| 160 |
+
" ppi_mask_df= pd.DataFrame(ppi_mask_matrix)\n",
|
| 161 |
+
" pdi_mask_df.columns = unique_targets\n",
|
| 162 |
+
" ppi_mask_df.columns = unique_protein2\n",
|
| 163 |
+
" pdi_ppi_mask_df = pd.concat([pdi_mask_df, ppi_mask_df], axis=1)\n",
|
| 164 |
+
" pdi_ppi_mask_df = pdi_ppi_mask_df.loc[:, ~pdi_ppi_mask_df.columns.duplicated(keep='last')]\n",
|
| 165 |
+
" col_mask = pdi_ppi_mask_df.columns.isin(ge_pdi_ppi_genept)\n",
|
| 166 |
+
" sub_pdi_ppi_mask_df = pdi_ppi_mask_df.loc[:, col_mask]\n",
|
| 167 |
+
" \n",
|
| 168 |
+
" extra_columns = np.ones((len(ge_genes), extra_neurons), dtype=int)\n",
|
| 169 |
+
" adjusted_mask_matrix = np.hstack([sub_pdi_ppi_mask_df, extra_columns])\n",
|
| 170 |
+
" new_mask_matrix = tf.constant(adjusted_mask_matrix, dtype=tf.float32)\n",
|
| 171 |
+
" \n",
|
| 172 |
+
" return new_mask_matrix\n",
|
| 173 |
+
"\n",
|
| 174 |
+
"def create_dna_mask_matrix (extra_neurons):\n",
|
| 175 |
+
" de_gene_to_idx = {gene: i for i, gene in enumerate(dna_genes)}\n",
|
| 176 |
+
" target_to_idx = {target: j for j, target in enumerate(dna_unique_targets)}\n",
|
| 177 |
+
" protein2_to_idx = {protein2: k for k, protein2 in enumerate(dna_unique_protein2)}\n",
|
| 178 |
+
"\n",
|
| 179 |
+
"\n",
|
| 180 |
+
" pdi_mask_matrix = np.zeros((len(dna_genes), len(dna_unique_targets)), dtype=int)\n",
|
| 181 |
+
"\n",
|
| 182 |
+
"\n",
|
| 183 |
+
" for _, row in df_dna_pdi.iterrows():\n",
|
| 184 |
+
" tfa = row[\"TF\"]\n",
|
| 185 |
+
" target = row[\"Target\"]\n",
|
| 186 |
+
" if tfa in de_gene_to_idx and target in target_to_idx:\n",
|
| 187 |
+
" tf_idx = de_gene_to_idx[tfa]\n",
|
| 188 |
+
" target_idx = target_to_idx[target]\n",
|
| 189 |
+
" pdi_mask_matrix[tf_idx, target_idx] = 1\n",
|
| 190 |
+
" \n",
|
| 191 |
+
" ppi_mask_matrix = np.zeros((len(dna_genes), len(dna_unique_protein2)))\n",
|
| 192 |
+
"\n",
|
| 193 |
+
" for _, row in df_dna_ppi.iterrows():\n",
|
| 194 |
+
" protein1 = row[\"protein1\"]\n",
|
| 195 |
+
" protein2 = row[\"protein2\"]\n",
|
| 196 |
+
" combined_score = row[\"combined_score\"]\n",
|
| 197 |
+
"\n",
|
| 198 |
+
" if protein1 in de_gene_to_idx and protein2 in protein2_to_idx:\n",
|
| 199 |
+
" protein1_idx = de_gene_to_idx[protein1]\n",
|
| 200 |
+
" protein2_idx = protein2_to_idx[protein2]\n",
|
| 201 |
+
" ppi_mask_matrix[protein1_idx, protein2_idx] = combined_score \n",
|
| 202 |
+
" \n",
|
| 203 |
+
" pdi_mask_df= pd.DataFrame(pdi_mask_matrix)\n",
|
| 204 |
+
" ppi_mask_df= pd.DataFrame(ppi_mask_matrix)\n",
|
| 205 |
+
" pdi_mask_df.columns = dna_unique_targets\n",
|
| 206 |
+
" ppi_mask_df.columns = dna_unique_protein2\n",
|
| 207 |
+
" pdi_ppi_mask_df = pd.concat([pdi_mask_df, ppi_mask_df], axis=1)\n",
|
| 208 |
+
" pdi_ppi_mask_df = pdi_ppi_mask_df.loc[:, ~pdi_ppi_mask_df.columns.duplicated(keep='last')]\n",
|
| 209 |
+
" col_mask = pdi_ppi_mask_df.columns.isin(dna_pdi_ppi_genept)\n",
|
| 210 |
+
" sub_pdi_ppi_mask_df = pdi_ppi_mask_df.loc[:, col_mask]\n",
|
| 211 |
+
"\n",
|
| 212 |
+
" \n",
|
| 213 |
+
" extra_columns = np.ones((len(dna_genes), extra_neurons), dtype=int)\n",
|
| 214 |
+
" adjusted_mask_matrix = np.hstack([sub_pdi_ppi_mask_df, extra_columns])\n",
|
| 215 |
+
" new_mask_matrix = tf.constant(adjusted_mask_matrix, dtype=tf.float32)\n",
|
| 216 |
+
" \n",
|
| 217 |
+
" return new_mask_matrix"
|
| 218 |
+
]
|
| 219 |
+
},
|
| 220 |
+
{
|
| 221 |
+
"cell_type": "code",
|
| 222 |
+
"execution_count": null,
|
| 223 |
+
"id": "e5161905-ef7c-4943-aa4d-46a2dc84f498",
|
| 224 |
+
"metadata": {},
|
| 225 |
+
"outputs": [],
|
| 226 |
+
"source": [
|
| 227 |
+
"ge_target_to_kegg = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"ge_target_to_KEGG_significant.csv\",sep=',')\n",
|
| 228 |
+
"dna_target_to_kegg = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"dna_target_to_KEGG_significant.csv\",sep=',')"
|
| 229 |
+
]
|
| 230 |
+
},
|
| 231 |
+
{
|
| 232 |
+
"cell_type": "code",
|
| 233 |
+
"execution_count": null,
|
| 234 |
+
"id": "235fc5c0-0c09-47c7-aa1a-36d708372be1",
|
| 235 |
+
"metadata": {},
|
| 236 |
+
"outputs": [],
|
| 237 |
+
"source": [
|
| 238 |
+
"def create_ge_pathway_mask_matrix ():\n",
|
| 239 |
+
" genes = ge_pdi_ppi_genept\n",
|
| 240 |
+
" pathways = ge_target_to_kegg[\"PathwayID\"].unique().tolist()\n",
|
| 241 |
+
"\n",
|
| 242 |
+
" gene_to_idx = {gene: i for i, gene in enumerate(genes)}\n",
|
| 243 |
+
" pathway_to_idx = {pw: j for j, pw in enumerate(pathways)}\n",
|
| 244 |
+
"\n",
|
| 245 |
+
" mask_matrix = np.zeros((len(genes), len(pathways)), dtype=int)\n",
|
| 246 |
+
"\n",
|
| 247 |
+
" for _, row in ge_target_to_kegg.iterrows():\n",
|
| 248 |
+
" gene = row[\"SYMBOL\"]\n",
|
| 249 |
+
" pw = row[\"PathwayID\"]\n",
|
| 250 |
+
" if gene in gene_to_idx and pw in pathway_to_idx:\n",
|
| 251 |
+
" i = gene_to_idx[gene]\n",
|
| 252 |
+
" j = pathway_to_idx[pw]\n",
|
| 253 |
+
" mask_matrix[i, j] = 1\n",
|
| 254 |
+
" mask_df = pd.DataFrame(mask_matrix, index=genes, columns=pathways)\n",
|
| 255 |
+
" return mask_df\n",
|
| 256 |
+
"\n",
|
| 257 |
+
"def create_dna_pathway_mask_matrix ():\n",
|
| 258 |
+
" genes = dna_pdi_ppi_genept\n",
|
| 259 |
+
" pathways = dna_target_to_kegg[\"PathwayID\"].unique().tolist()\n",
|
| 260 |
+
"\n",
|
| 261 |
+
" gene_to_idx = {gene: i for i, gene in enumerate(genes)}\n",
|
| 262 |
+
" pathway_to_idx = {pw: j for j, pw in enumerate(pathways)}\n",
|
| 263 |
+
"\n",
|
| 264 |
+
" mask_matrix = np.zeros((len(genes), len(pathways)), dtype=int)\n",
|
| 265 |
+
"\n",
|
| 266 |
+
" for _, row in dna_target_to_kegg.iterrows():\n",
|
| 267 |
+
" gene = row[\"SYMBOL\"]\n",
|
| 268 |
+
" pw = row[\"PathwayID\"]\n",
|
| 269 |
+
" if gene in gene_to_idx and pw in pathway_to_idx:\n",
|
| 270 |
+
" i = gene_to_idx[gene]\n",
|
| 271 |
+
" j = pathway_to_idx[pw]\n",
|
| 272 |
+
" mask_matrix[i, j] = 1\n",
|
| 273 |
+
" mask_df = pd.DataFrame(mask_matrix, index=genes, columns=pathways)\n",
|
| 274 |
+
" return mask_df\n",
|
| 275 |
+
" \n",
|
| 276 |
+
"mask_gene_pathway = create_ge_pathway_mask_matrix ()\n",
|
| 277 |
+
"mask_dna_pathway = create_dna_pathway_mask_matrix()"
|
| 278 |
+
]
|
| 279 |
+
},
|
| 280 |
+
{
|
| 281 |
+
"cell_type": "code",
|
| 282 |
+
"execution_count": null,
|
| 283 |
+
"id": "dbfe572a-d773-4306-94a1-69ab748f924c",
|
| 284 |
+
"metadata": {},
|
| 285 |
+
"outputs": [],
|
| 286 |
+
"source": [
|
| 287 |
+
"class MaskedLayer(layers.Layer):\n",
|
| 288 |
+
" def __init__(self, mask_matrix, **kwargs):\n",
|
| 289 |
+
" super().__init__(**kwargs)\n",
|
| 290 |
+
" self.mask_matrix = K.constant(mask_matrix, dtype='float32')\n",
|
| 291 |
+
"\n",
|
| 292 |
+
" def call(self, inputs):\n",
|
| 293 |
+
" return K.dot(inputs, self.mask_matrix)\n",
|
| 294 |
+
"\n",
|
| 295 |
+
"\n",
|
| 296 |
+
"class AttentionPathwayLayer(layers.Layer):\n",
|
| 297 |
+
" def __init__(self, genept_embs, pathway_mask, init_seed=42, **kwargs):\n",
|
| 298 |
+
" super().__init__(**kwargs)\n",
|
| 299 |
+
"\n",
|
| 300 |
+
" genept_np = genept_embs.values if hasattr(genept_embs, \"values\") else np.asarray(genept_embs)\n",
|
| 301 |
+
" n_genes, D_embed = genept_np.shape\n",
|
| 302 |
+
"\n",
|
| 303 |
+
" pw_np = pathway_mask.values if hasattr(pathway_mask, \"values\") else np.asarray(pathway_mask)\n",
|
| 304 |
+
" n_pathways = pw_np.shape[1]\n",
|
| 305 |
+
"\n",
|
| 306 |
+
" self.G = K.constant(genept_np, dtype=\"float32\")\n",
|
| 307 |
+
" self.P = K.constant(pw_np, dtype=\"float32\")\n",
|
| 308 |
+
"\n",
|
| 309 |
+
" glorot = initializers.GlorotUniform(seed=init_seed)\n",
|
| 310 |
+
" self.W = self.add_weight(\n",
|
| 311 |
+
" shape=(n_pathways, D_embed),\n",
|
| 312 |
+
" initializer=glorot,\n",
|
| 313 |
+
" trainable=True,\n",
|
| 314 |
+
" name=\"W_query\"\n",
|
| 315 |
+
" )\n",
|
| 316 |
+
"\n",
|
| 317 |
+
" def call(self, x):\n",
|
| 318 |
+
" G_T = K.transpose(self.G) \n",
|
| 319 |
+
" S = K.dot(self.W, G_T) \n",
|
| 320 |
+
" S_T = K.transpose(S) \n",
|
| 321 |
+
" S_masked = S_T * self.P \n",
|
| 322 |
+
" alpha = K.softmax(S_masked, axis=0) \n",
|
| 323 |
+
" x_sq = K.squeeze(x, axis=-1) \n",
|
| 324 |
+
" out_mat = K.dot(x_sq, alpha) \n",
|
| 325 |
+
" return K.expand_dims(out_mat, axis=-1) \n",
|
| 326 |
+
"\n",
|
| 327 |
+
" def compute_output_shape(self, input_shape):\n",
|
| 328 |
+
" batch_size, n_genes, _ = input_shape\n",
|
| 329 |
+
" n_pathways = K.int_shape(self.P)[1]\n",
|
| 330 |
+
" return (batch_size, n_pathways, 1)\n",
|
| 331 |
+
" \n",
|
| 332 |
+
" def get_attention(self):\n",
|
| 333 |
+
" G_T = K.transpose(self.G) \n",
|
| 334 |
+
" S = K.dot(self.W, G_T) \n",
|
| 335 |
+
" S_T = K.transpose(S) \n",
|
| 336 |
+
" S_masked = S_T * self.P \n",
|
| 337 |
+
" return K.softmax(S_masked, axis=0) \n",
|
| 338 |
+
"\n",
|
| 339 |
+
"\n",
|
| 340 |
+
"def create_model(\n",
|
| 341 |
+
" num_ex_neuron,\n",
|
| 342 |
+
" layer_one,\n",
|
| 343 |
+
" activation_function_one,\n",
|
| 344 |
+
" activation_function_two,\n",
|
| 345 |
+
" activation_function_three,\n",
|
| 346 |
+
" dropout_p,\n",
|
| 347 |
+
" learning_rate,\n",
|
| 348 |
+
" l2_reg,\n",
|
| 349 |
+
" optimizer_choice,\n",
|
| 350 |
+
" genept_gene_emb,\n",
|
| 351 |
+
" mask_gene_pathway,\n",
|
| 352 |
+
" genept_dna_emb,\n",
|
| 353 |
+
" mask_dna_pathway\n",
|
| 354 |
+
"):\n",
|
| 355 |
+
"\n",
|
| 356 |
+
" new_ge_mask_matrix = create_ge_mask_matrix(num_ex_neuron)\n",
|
| 357 |
+
" new_dna_mask_matrix = create_dna_mask_matrix(num_ex_neuron)\n",
|
| 358 |
+
" \n",
|
| 359 |
+
" inputA = Input(shape=(df_gene.shape[1],), name=\"gene_input\")\n",
|
| 360 |
+
" x = layers.Dense(\n",
|
| 361 |
+
" new_ge_mask_matrix.shape[0],\n",
|
| 362 |
+
" activation=activation_function_one,\n",
|
| 363 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 364 |
+
" kernel_initializer=initializers.LecunUniform(42)\n",
|
| 365 |
+
" )(inputA)\n",
|
| 366 |
+
" x = MaskedLayer(new_ge_mask_matrix)(x)\n",
|
| 367 |
+
" x = Dropout(dropout_p)(x)\n",
|
| 368 |
+
" x_feat = Lambda(lambda t: K.expand_dims(t, -1), name=\"gene_add_dim\")(x)\n",
|
| 369 |
+
"\n",
|
| 370 |
+
" gene_path_layer = AttentionPathwayLayer(\n",
|
| 371 |
+
" genept_embs = genept_gene_emb,\n",
|
| 372 |
+
" pathway_mask = mask_gene_pathway,\n",
|
| 373 |
+
" name = \"gene_path_attn\"\n",
|
| 374 |
+
" )\n",
|
| 375 |
+
" x_path = gene_path_layer(x_feat)\n",
|
| 376 |
+
" x_path = Flatten()(x_path)\n",
|
| 377 |
+
"\n",
|
| 378 |
+
" x_proj = layers.Dense(\n",
|
| 379 |
+
" layer_one,\n",
|
| 380 |
+
" activation=activation_function_two,\n",
|
| 381 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 382 |
+
" kernel_initializer=initializers.LecunUniform(42),\n",
|
| 383 |
+
" name=\"gene_proj\"\n",
|
| 384 |
+
" )(x_path)\n",
|
| 385 |
+
"\n",
|
| 386 |
+
" inputB = Input(shape=(df_dna.shape[1],), name=\"dna_input\")\n",
|
| 387 |
+
" y = layers.Dense(\n",
|
| 388 |
+
" new_dna_mask_matrix.shape[0],\n",
|
| 389 |
+
" activation=activation_function_one,\n",
|
| 390 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 391 |
+
" kernel_initializer=initializers.LecunUniform(42)\n",
|
| 392 |
+
" )(inputB)\n",
|
| 393 |
+
" y = MaskedLayer(new_dna_mask_matrix)(y)\n",
|
| 394 |
+
" y = Dropout(dropout_p)(y)\n",
|
| 395 |
+
" y_feat = Lambda(lambda t: K.expand_dims(t, -1), name=\"dna_add_dim\")(y)\n",
|
| 396 |
+
"\n",
|
| 397 |
+
" dna_path_layer = AttentionPathwayLayer(\n",
|
| 398 |
+
" genept_embs = genept_dna_emb,\n",
|
| 399 |
+
" pathway_mask = mask_dna_pathway,\n",
|
| 400 |
+
" name = \"dna_path_attn\"\n",
|
| 401 |
+
" )\n",
|
| 402 |
+
" y_path = dna_path_layer(y_feat)\n",
|
| 403 |
+
" y_path = Flatten()(y_path)\n",
|
| 404 |
+
"\n",
|
| 405 |
+
" y_proj = layers.Dense(\n",
|
| 406 |
+
" layer_one,\n",
|
| 407 |
+
" activation=activation_function_two,\n",
|
| 408 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 409 |
+
" kernel_initializer=initializers.LecunUniform(42),\n",
|
| 410 |
+
" name=\"dna_proj\"\n",
|
| 411 |
+
" )(y_path)\n",
|
| 412 |
+
"\n",
|
| 413 |
+
" merged = concatenate([x_proj, y_proj], name=\"merge_xy\")\n",
|
| 414 |
+
" h = layers.Dense(\n",
|
| 415 |
+
" 12,\n",
|
| 416 |
+
" activation=activation_function_three,\n",
|
| 417 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 418 |
+
" kernel_initializer=initializers.GlorotUniform(42),\n",
|
| 419 |
+
" name=\"fusion_dense\"\n",
|
| 420 |
+
" )(merged)\n",
|
| 421 |
+
" h = Dropout(dropout_p, name=\"drop_fusion\")(h)\n",
|
| 422 |
+
" out = layers.Dense(\n",
|
| 423 |
+
" 4,\n",
|
| 424 |
+
" activation=\"softmax\",\n",
|
| 425 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 426 |
+
" kernel_initializer=initializers.GlorotUniform(42),\n",
|
| 427 |
+
" name=\"output\"\n",
|
| 428 |
+
" )(h)\n",
|
| 429 |
+
"\n",
|
| 430 |
+
" model = Model(inputs=[inputA, inputB], outputs=out, name=\"PathwayModel\")\n",
|
| 431 |
+
"\n",
|
| 432 |
+
" if optimizer_choice == 'adam':\n",
|
| 433 |
+
" optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)\n",
|
| 434 |
+
" elif optimizer_choice == 'sgd':\n",
|
| 435 |
+
" optimizer = tf.keras.optimizers.SGD(learning_rate=learning_rate)\n",
|
| 436 |
+
" model.compile(\n",
|
| 437 |
+
" optimizer=optimizer,\n",
|
| 438 |
+
" loss='sparse_categorical_crossentropy',\n",
|
| 439 |
+
" metrics=['accuracy']\n",
|
| 440 |
+
" )\n",
|
| 441 |
+
" return model"
|
| 442 |
+
]
|
| 443 |
+
},
|
| 444 |
+
{
|
| 445 |
+
"cell_type": "code",
|
| 446 |
+
"execution_count": null,
|
| 447 |
+
"id": "be89b57c-5f26-4b58-be38-7d4c797d4c6d",
|
| 448 |
+
"metadata": {},
|
| 449 |
+
"outputs": [],
|
| 450 |
+
"source": [
|
| 451 |
+
"def evaluate_model_cv(X_train, X_val, y_train, y_val, params):\n",
|
| 452 |
+
" model = create_model(\n",
|
| 453 |
+
" num_ex_neuron=params['num_ex_neuron'],\n",
|
| 454 |
+
" layer_one=params['layer_one'],\n",
|
| 455 |
+
" activation_function_one=params['activation_function_one'],\n",
|
| 456 |
+
" activation_function_two=params['activation_function_two'],\n",
|
| 457 |
+
" activation_function_three=params['activation_function_three'],\n",
|
| 458 |
+
" dropout_p=params['dropout_p'],\n",
|
| 459 |
+
" learning_rate=params['learning_rate'],\n",
|
| 460 |
+
" l2_reg=params['l2_reg'],\n",
|
| 461 |
+
" optimizer_choice=params['optimizer'],\n",
|
| 462 |
+
" genept_gene_emb = genept_gene_emb,\n",
|
| 463 |
+
" mask_gene_pathway = mask_gene_pathway,\n",
|
| 464 |
+
" genept_dna_emb = genept_dna_emb,\n",
|
| 465 |
+
" mask_dna_pathway = mask_dna_pathway\n",
|
| 466 |
+
" )\n",
|
| 467 |
+
" \n",
|
| 468 |
+
" history = model.fit(\n",
|
| 469 |
+
" X_train, y_train,\n",
|
| 470 |
+
" validation_data=(X_val, y_val),\n",
|
| 471 |
+
" epochs=params['epoch'],\n",
|
| 472 |
+
" batch_size=params['batch_size'],\n",
|
| 473 |
+
" shuffle = False,\n",
|
| 474 |
+
" verbose=0\n",
|
| 475 |
+
" )\n",
|
| 476 |
+
" \n",
|
| 477 |
+
" y_pred = model.predict(X_val).argmax(1)\n",
|
| 478 |
+
" \n",
|
| 479 |
+
"\n",
|
| 480 |
+
" f1_weighted = f1_score(y_val, y_pred, average='weighted')\n",
|
| 481 |
+
" f1_macro = f1_score(y_val, y_pred, average='macro')\n",
|
| 482 |
+
" f1_micro = f1_score(y_val, y_pred, average='micro')\n",
|
| 483 |
+
"\n",
|
| 484 |
+
" precision_weighted = precision_score(y_val, y_pred, average='weighted')\n",
|
| 485 |
+
" precision_macro = precision_score(y_val, y_pred, average='macro')\n",
|
| 486 |
+
" precision_micro = precision_score(y_val, y_pred, average='micro')\n",
|
| 487 |
+
" \n",
|
| 488 |
+
"\n",
|
| 489 |
+
" recall_weighted = recall_score(y_val, y_pred, average='weighted')\n",
|
| 490 |
+
" recall_macro = recall_score(y_val, y_pred, average='macro')\n",
|
| 491 |
+
" recall_micro = recall_score(y_val, y_pred, average='micro')\n",
|
| 492 |
+
" \n",
|
| 493 |
+
"\n",
|
| 494 |
+
" accuracy = accuracy_score(y_val, y_pred)\n",
|
| 495 |
+
"\n",
|
| 496 |
+
" return {\n",
|
| 497 |
+
" 'history': history.history,\n",
|
| 498 |
+
" 'f1_weighted': f1_weighted,\n",
|
| 499 |
+
" 'f1_macro': f1_macro,\n",
|
| 500 |
+
" 'f1_micro': f1_micro,\n",
|
| 501 |
+
" 'precision_weighted': precision_weighted,\n",
|
| 502 |
+
" 'precision_macro': precision_macro,\n",
|
| 503 |
+
" 'precision_micro': precision_micro,\n",
|
| 504 |
+
" 'recall_weighted': recall_weighted,\n",
|
| 505 |
+
" 'recall_macro': recall_macro,\n",
|
| 506 |
+
" 'recall_micro': recall_micro,\n",
|
| 507 |
+
" 'accuracy': accuracy\n",
|
| 508 |
+
" }\n",
|
| 509 |
+
"\n",
|
| 510 |
+
"def evaluate_combination(param_combination,X_gene_train,X_dna_train,y_train,n_splits=5):\n",
|
| 511 |
+
" skf = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=42)\n",
|
| 512 |
+
" \n",
|
| 513 |
+
" f1_weighted_list = []\n",
|
| 514 |
+
" f1_macro_list = []\n",
|
| 515 |
+
" f1_micro_list = []\n",
|
| 516 |
+
" \n",
|
| 517 |
+
" precision_weighted_list = []\n",
|
| 518 |
+
" precision_macro_list = []\n",
|
| 519 |
+
" precision_micro_list = []\n",
|
| 520 |
+
" \n",
|
| 521 |
+
" recall_weighted_list = []\n",
|
| 522 |
+
" recall_macro_list = []\n",
|
| 523 |
+
" recall_micro_list = []\n",
|
| 524 |
+
" \n",
|
| 525 |
+
" accuracy_list = []\n",
|
| 526 |
+
" all_histories = []\n",
|
| 527 |
+
" \n",
|
| 528 |
+
" for train_idx, val_idx in skf.split(X_gene_train, y_train):\n",
|
| 529 |
+
" Xg_tr, Xg_val = X_gene_train[train_idx], X_gene_train[val_idx]\n",
|
| 530 |
+
" Xd_tr, Xd_val = X_dna_train[train_idx], X_dna_train[val_idx]\n",
|
| 531 |
+
" y_tr, y_val = y_train[train_idx], y_train[val_idx]\n",
|
| 532 |
+
" \n",
|
| 533 |
+
" scores = evaluate_model_cv([Xg_tr, Xd_tr], [Xg_val, Xd_val], y_tr, y_val, param_combination)\n",
|
| 534 |
+
" \n",
|
| 535 |
+
" history_dict = scores.pop('history')\n",
|
| 536 |
+
" all_histories.append(history_dict)\n",
|
| 537 |
+
" \n",
|
| 538 |
+
" f1_weighted_list.append(scores['f1_weighted'])\n",
|
| 539 |
+
" f1_macro_list.append(scores['f1_macro'])\n",
|
| 540 |
+
" f1_micro_list.append(scores['f1_micro'])\n",
|
| 541 |
+
" \n",
|
| 542 |
+
" precision_weighted_list.append(scores['precision_weighted'])\n",
|
| 543 |
+
" precision_macro_list.append(scores['precision_macro'])\n",
|
| 544 |
+
" precision_micro_list.append(scores['precision_micro'])\n",
|
| 545 |
+
" \n",
|
| 546 |
+
" recall_weighted_list.append(scores['recall_weighted'])\n",
|
| 547 |
+
" recall_macro_list.append(scores['recall_macro'])\n",
|
| 548 |
+
" recall_micro_list.append(scores['recall_micro'])\n",
|
| 549 |
+
" \n",
|
| 550 |
+
" accuracy_list.append(scores['accuracy'])\n",
|
| 551 |
+
" \n",
|
| 552 |
+
" results = {\n",
|
| 553 |
+
" 'f1_weighted_mean': np.mean(f1_weighted_list),\n",
|
| 554 |
+
" 'f1_weighted_std': np.std(f1_weighted_list),\n",
|
| 555 |
+
" 'f1_macro_mean': np.mean(f1_macro_list),\n",
|
| 556 |
+
" 'f1_macro_std': np.std(f1_macro_list),\n",
|
| 557 |
+
" 'f1_micro_mean': np.mean(f1_micro_list),\n",
|
| 558 |
+
" 'f1_micro_std': np.std(f1_micro_list),\n",
|
| 559 |
+
" 'precision_weighted_mean': np.mean(precision_weighted_list),\n",
|
| 560 |
+
" 'precision_weighted_std': np.std(precision_weighted_list),\n",
|
| 561 |
+
" 'precision_macro_mean': np.mean(precision_macro_list),\n",
|
| 562 |
+
" 'precision_macro_std': np.std(precision_macro_list),\n",
|
| 563 |
+
" 'precision_micro_mean': np.mean(precision_micro_list),\n",
|
| 564 |
+
" 'precision_micro_std': np.std(precision_micro_list),\n",
|
| 565 |
+
" 'recall_weighted_mean': np.mean(recall_weighted_list),\n",
|
| 566 |
+
" 'recall_weighted_std': np.std(recall_weighted_list),\n",
|
| 567 |
+
" 'recall_macro_mean': np.mean(recall_macro_list),\n",
|
| 568 |
+
" 'recall_macro_std': np.std(recall_macro_list),\n",
|
| 569 |
+
" 'recall_micro_mean': np.mean(recall_micro_list),\n",
|
| 570 |
+
" 'recall_micro_std': np.std(recall_micro_list),\n",
|
| 571 |
+
" 'accuracy_mean': np.mean(accuracy_list),\n",
|
| 572 |
+
" 'accuracy_std': np.std(accuracy_list)\n",
|
| 573 |
+
" }\n",
|
| 574 |
+
" \n",
|
| 575 |
+
" return param_combination, results, all_histories\n",
|
| 576 |
+
"\n",
|
| 577 |
+
"\n",
|
| 578 |
+
"params_grid = {\n",
|
| 579 |
+
" 'num_ex_neuron': [0],\n",
|
| 580 |
+
" 'layer_one': [64],\n",
|
| 581 |
+
" 'activation_function_one': ['relu'],\n",
|
| 582 |
+
" 'activation_function_two': ['sigmoid'],\n",
|
| 583 |
+
" 'activation_function_three': ['tanh'],\n",
|
| 584 |
+
" 'dropout_p': [0.3],\n",
|
| 585 |
+
" 'learning_rate': [0.01],\n",
|
| 586 |
+
" 'l2_reg': [0.01],\n",
|
| 587 |
+
" 'epoch': [200],\n",
|
| 588 |
+
" 'batch_size':[16],\n",
|
| 589 |
+
" 'optimizer': ['sgd']\n",
|
| 590 |
+
" }\n",
|
| 591 |
+
"\n",
|
| 592 |
+
"param_combinations = list(itertools.product(\n",
|
| 593 |
+
" params_grid['num_ex_neuron'],\n",
|
| 594 |
+
" params_grid['layer_one'],\n",
|
| 595 |
+
" params_grid['activation_function_one'],\n",
|
| 596 |
+
" params_grid['activation_function_two'],\n",
|
| 597 |
+
" params_grid['activation_function_three'],\n",
|
| 598 |
+
" params_grid['dropout_p'],\n",
|
| 599 |
+
" params_grid['learning_rate'],\n",
|
| 600 |
+
" params_grid['l2_reg'],\n",
|
| 601 |
+
" params_grid['epoch'],\n",
|
| 602 |
+
" params_grid['batch_size'],\n",
|
| 603 |
+
" params_grid['optimizer']\n",
|
| 604 |
+
" \n",
|
| 605 |
+
"))\n",
|
| 606 |
+
"\n",
|
| 607 |
+
"\n",
|
| 608 |
+
"param_dicts = []\n",
|
| 609 |
+
"for comb in param_combinations:\n",
|
| 610 |
+
" param_dicts.append({\n",
|
| 611 |
+
" 'num_ex_neuron': comb[0],\n",
|
| 612 |
+
" 'layer_one': comb[1],\n",
|
| 613 |
+
" 'activation_function_one': comb[2],\n",
|
| 614 |
+
" 'activation_function_two': comb[3],\n",
|
| 615 |
+
" 'activation_function_three': comb[4],\n",
|
| 616 |
+
" 'dropout_p': comb[5],\n",
|
| 617 |
+
" 'learning_rate': comb[6],\n",
|
| 618 |
+
" 'l2_reg': comb[7],\n",
|
| 619 |
+
" 'epoch': comb[8],\n",
|
| 620 |
+
" 'batch_size': comb[9],\n",
|
| 621 |
+
" 'optimizer': comb[10]\n",
|
| 622 |
+
" })\n",
|
| 623 |
+
"\n",
|
| 624 |
+
"\n",
|
| 625 |
+
"X_gene_train, X_gene_test, X_dna_train, X_dna_test, y_train, y_test = train_test_split(df_gene, df_dna, y, test_size=0.2, stratify=y, random_state=42)\n",
|
| 626 |
+
"scaler = StandardScaler()\n",
|
| 627 |
+
"X_gene_train=(np.array(X_gene_train).astype(np.float32))\n",
|
| 628 |
+
"scaler.fit(X_gene_train)\n",
|
| 629 |
+
"X_gene_train=scaler.transform(X_gene_train)\n",
|
| 630 |
+
"\n",
|
| 631 |
+
"X_gene_test=(np.array(X_gene_test).astype(np.float32))\n",
|
| 632 |
+
"scaler.fit(X_gene_test)\n",
|
| 633 |
+
"X_gene_test=scaler.transform(X_gene_test)\n",
|
| 634 |
+
"\n",
|
| 635 |
+
"X_dna_train=(np.array(X_dna_train).astype(np.float32))\n",
|
| 636 |
+
"scaler.fit(X_dna_train)\n",
|
| 637 |
+
"X_dna_train=scaler.transform(X_dna_train)\n",
|
| 638 |
+
"\n",
|
| 639 |
+
"X_dna_test=(np.array(X_dna_test).astype(np.float32))\n",
|
| 640 |
+
"scaler.fit(X_dna_test)\n",
|
| 641 |
+
"X_dna_test=scaler.transform(X_dna_test)\n",
|
| 642 |
+
"\n",
|
| 643 |
+
"with tqdm_joblib(\n",
|
| 644 |
+
" tqdm(desc=\"Evaluating hyperparameter combinations\",\n",
|
| 645 |
+
" total=len(param_dicts))\n",
|
| 646 |
+
" ) as progress_bar:\n",
|
| 647 |
+
" results = Parallel(n_jobs=-1)(\n",
|
| 648 |
+
" delayed(evaluate_combination)(\n",
|
| 649 |
+
" param, X_gene_train, X_dna_train, y_train, n_splits=5\n",
|
| 650 |
+
" )\n",
|
| 651 |
+
" for param in param_dicts\n",
|
| 652 |
+
" )\n",
|
| 653 |
+
"\n",
|
| 654 |
+
"results_list = []\n",
|
| 655 |
+
"histories_dict = {}\n",
|
| 656 |
+
"best_param_weighted = None\n",
|
| 657 |
+
"best_weighted_scores = None\n",
|
| 658 |
+
"best_avg_f1_weighted = -np.inf\n",
|
| 659 |
+
"\n",
|
| 660 |
+
"best_param_macro = None\n",
|
| 661 |
+
"best_macro_scores = None\n",
|
| 662 |
+
"best_avg_f1_macro = -np.inf\n",
|
| 663 |
+
"\n",
|
| 664 |
+
"best_param_micro = None\n",
|
| 665 |
+
"best_micro_scores = None\n",
|
| 666 |
+
"best_avg_f1_micro = -np.inf\n",
|
| 667 |
+
"\n",
|
| 668 |
+
"for param_dict, scores_dict, histories in results:\n",
|
| 669 |
+
" key = str(param_dict)\n",
|
| 670 |
+
" histories_dict[key] = histories\n",
|
| 671 |
+
"\n",
|
| 672 |
+
" row = {}\n",
|
| 673 |
+
" row.update(param_dict)\n",
|
| 674 |
+
" row.update(scores_dict)\n",
|
| 675 |
+
" results_list.append(row)\n",
|
| 676 |
+
"\n",
|
| 677 |
+
" if scores_dict['f1_weighted_mean'] > best_avg_f1_weighted:\n",
|
| 678 |
+
" best_avg_f1_weighted = scores_dict['f1_weighted_mean']\n",
|
| 679 |
+
" best_param_weighted = param_dict\n",
|
| 680 |
+
" best_weighted_scores = scores_dict\n",
|
| 681 |
+
"\n",
|
| 682 |
+
" if scores_dict['f1_macro_mean'] > best_avg_f1_macro:\n",
|
| 683 |
+
" best_avg_f1_macro = scores_dict['f1_macro_mean']\n",
|
| 684 |
+
" best_param_macro = param_dict\n",
|
| 685 |
+
" best_macro_scores = scores_dict\n",
|
| 686 |
+
"\n",
|
| 687 |
+
" if scores_dict['f1_micro_mean'] > best_avg_f1_micro:\n",
|
| 688 |
+
" best_avg_f1_micro = scores_dict['f1_micro_mean']\n",
|
| 689 |
+
" best_param_micro = param_dict\n",
|
| 690 |
+
" best_micro_scores = scores_dict\n",
|
| 691 |
+
"\n",
|
| 692 |
+
"results_df = pd.DataFrame(results_list)\n",
|
| 693 |
+
"best_key = str(best_param_macro)\n",
|
| 694 |
+
"best_histories = histories_dict[best_key] \n",
|
| 695 |
+
"\n",
|
| 696 |
+
"\n",
|
| 697 |
+
"hyperparam_cols = list(param_dict.keys())\n",
|
| 698 |
+
"\n",
|
| 699 |
+
"\n",
|
| 700 |
+
"weighted_cols = hyperparam_cols + ['f1_weighted_mean', 'f1_weighted_std',\n",
|
| 701 |
+
" 'precision_weighted_mean', 'precision_weighted_std',\n",
|
| 702 |
+
" 'recall_weighted_mean', 'recall_weighted_std',\n",
|
| 703 |
+
" 'accuracy_mean', 'accuracy_std']\n",
|
| 704 |
+
"results_df_weighted = results_df[weighted_cols]\n",
|
| 705 |
+
"\n",
|
| 706 |
+
"macro_cols = hyperparam_cols + ['f1_macro_mean', 'f1_macro_std',\n",
|
| 707 |
+
" 'precision_macro_mean', 'precision_macro_std',\n",
|
| 708 |
+
" 'recall_macro_mean', 'recall_macro_std',\n",
|
| 709 |
+
" 'accuracy_mean', 'accuracy_std']\n",
|
| 710 |
+
"results_df_macro = results_df[macro_cols]\n",
|
| 711 |
+
"\n",
|
| 712 |
+
"micro_cols = hyperparam_cols + ['f1_micro_mean', 'f1_micro_std',\n",
|
| 713 |
+
" 'precision_micro_mean', 'precision_micro_std',\n",
|
| 714 |
+
" 'recall_micro_mean', 'recall_micro_std',\n",
|
| 715 |
+
" 'accuracy_mean', 'accuracy_std']\n",
|
| 716 |
+
"results_df_micro = results_df[micro_cols]"
|
| 717 |
+
]
|
| 718 |
+
},
|
| 719 |
+
{
|
| 720 |
+
"cell_type": "code",
|
| 721 |
+
"execution_count": null,
|
| 722 |
+
"id": "2576c647-0fa9-44ff-b26b-b152a8f96389",
|
| 723 |
+
"metadata": {},
|
| 724 |
+
"outputs": [],
|
| 725 |
+
"source": [
|
| 726 |
+
"def create_model_test(\n",
|
| 727 |
+
" num_ex_neuron,\n",
|
| 728 |
+
" layer_one,\n",
|
| 729 |
+
" activation_function_one,\n",
|
| 730 |
+
" activation_function_two,\n",
|
| 731 |
+
" activation_function_three,\n",
|
| 732 |
+
" dropout_p,\n",
|
| 733 |
+
" learning_rate,\n",
|
| 734 |
+
" l2_reg,\n",
|
| 735 |
+
" optimizer_choice\n",
|
| 736 |
+
"):\n",
|
| 737 |
+
"\n",
|
| 738 |
+
" new_ge_mask_matrix = create_ge_mask_matrix(num_ex_neuron) \n",
|
| 739 |
+
" new_dna_mask_matrix = create_dna_mask_matrix(num_ex_neuron) \n",
|
| 740 |
+
"\n",
|
| 741 |
+
" inputA = Input(shape=(df_gene.shape[1],), name=\"gene_input\") \n",
|
| 742 |
+
" inputB = Input(shape=(df_dna.shape[1],), name=\"dna_input\") \n",
|
| 743 |
+
"\n",
|
| 744 |
+
" x1 = layers.Dense(\n",
|
| 745 |
+
" new_ge_mask_matrix.shape[0], \n",
|
| 746 |
+
" kernel_initializer=LecunUniform(seed=42),\n",
|
| 747 |
+
" activation=activation_function_one,\n",
|
| 748 |
+
" kernel_regularizer=l2(l2_reg)\n",
|
| 749 |
+
" )(inputA) \n",
|
| 750 |
+
"\n",
|
| 751 |
+
"\n",
|
| 752 |
+
" x1_masked = MaskedLayer(new_ge_mask_matrix)(x1) \n",
|
| 753 |
+
" x1_masked = Dropout(dropout_p)(x1_masked) \n",
|
| 754 |
+
"\n",
|
| 755 |
+
" x1_feat = layers.Lambda(lambda t: K.expand_dims(t, -1), name=\"gene_add_dim\")(x1_masked)\n",
|
| 756 |
+
"\n",
|
| 757 |
+
" gene_path_layer = AttentionPathwayLayer(\n",
|
| 758 |
+
" genept_embs = genept_gene_emb, \n",
|
| 759 |
+
" pathway_mask = mask_gene_pathway, \n",
|
| 760 |
+
" name = \"gene_path_attn\"\n",
|
| 761 |
+
" )\n",
|
| 762 |
+
" x1_path = gene_path_layer(x1_feat) \n",
|
| 763 |
+
"\n",
|
| 764 |
+
" x1_path = Flatten(name=\"gene_flat_path\")(x1_path) \n",
|
| 765 |
+
"\n",
|
| 766 |
+
" x1_proj = layers.Dense(\n",
|
| 767 |
+
" layer_one,\n",
|
| 768 |
+
" kernel_initializer=LecunUniform(seed=42),\n",
|
| 769 |
+
" activation=activation_function_two,\n",
|
| 770 |
+
" kernel_regularizer=l2(l2_reg),\n",
|
| 771 |
+
" name=\"gene_proj\"\n",
|
| 772 |
+
" )(x1_path) \n",
|
| 773 |
+
"\n",
|
| 774 |
+
" y1 = layers.Dense(\n",
|
| 775 |
+
" new_dna_mask_matrix.shape[0], \n",
|
| 776 |
+
" kernel_initializer=LecunUniform(seed=42),\n",
|
| 777 |
+
" activation=activation_function_one,\n",
|
| 778 |
+
" kernel_regularizer=l2(l2_reg)\n",
|
| 779 |
+
" )(inputB) \n",
|
| 780 |
+
"\n",
|
| 781 |
+
" y1_masked = MaskedLayer(new_dna_mask_matrix)(y1) \n",
|
| 782 |
+
" y1_masked = Dropout(dropout_p)(y1_masked) \n",
|
| 783 |
+
"\n",
|
| 784 |
+
" y1_feat = layers.Lambda(lambda t: K.expand_dims(t, -1), name=\"dna_add_dim\")(y1_masked)\n",
|
| 785 |
+
"\n",
|
| 786 |
+
" dna_path_layer = AttentionPathwayLayer(\n",
|
| 787 |
+
" genept_embs = genept_dna_emb, \n",
|
| 788 |
+
" pathway_mask = mask_dna_pathway, \n",
|
| 789 |
+
" name = \"dna_path_attn\"\n",
|
| 790 |
+
" )\n",
|
| 791 |
+
" y1_path = dna_path_layer(y1_feat) \n",
|
| 792 |
+
" y1_path = Flatten(name=\"dna_flat_path\")(y1_path) \n",
|
| 793 |
+
"\n",
|
| 794 |
+
" y1_proj = layers.Dense(\n",
|
| 795 |
+
" layer_one,\n",
|
| 796 |
+
" kernel_initializer=LecunUniform(seed=42),\n",
|
| 797 |
+
" activation=activation_function_two,\n",
|
| 798 |
+
" kernel_regularizer=l2(l2_reg),\n",
|
| 799 |
+
" name=\"dna_proj\"\n",
|
| 800 |
+
" )(y1_path) \n",
|
| 801 |
+
"\n",
|
| 802 |
+
" merged = concatenate([x1_proj, y1_proj], name=\"merge_xy\") \n",
|
| 803 |
+
"\n",
|
| 804 |
+
" h = layers.Dense(\n",
|
| 805 |
+
" 12,\n",
|
| 806 |
+
" activation=activation_function_three,\n",
|
| 807 |
+
" kernel_initializer=GlorotUniform(seed=42),\n",
|
| 808 |
+
" kernel_regularizer=l2(l2_reg),\n",
|
| 809 |
+
" name=\"fusion_dense\"\n",
|
| 810 |
+
" )(merged) \n",
|
| 811 |
+
" h = Dropout(dropout_p, name=\"drop_fusion\")(h) \n",
|
| 812 |
+
"\n",
|
| 813 |
+
" outputs = layers.Dense(\n",
|
| 814 |
+
" 4,\n",
|
| 815 |
+
" activation=\"softmax\",\n",
|
| 816 |
+
" kernel_initializer=GlorotUniform(seed=42),\n",
|
| 817 |
+
" kernel_regularizer=l2(l2_reg),\n",
|
| 818 |
+
" name=\"output\"\n",
|
| 819 |
+
" )(h) \n",
|
| 820 |
+
"\n",
|
| 821 |
+
" model = Model(inputs=[inputA, inputB], outputs=outputs, name=\"PathwayModel_Test\")\n",
|
| 822 |
+
"\n",
|
| 823 |
+
" if optimizer_choice == 'adam':\n",
|
| 824 |
+
" optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)\n",
|
| 825 |
+
" else:\n",
|
| 826 |
+
" optimizer = tf.keras.optimizers.SGD(learning_rate=learning_rate)\n",
|
| 827 |
+
"\n",
|
| 828 |
+
" model.compile(\n",
|
| 829 |
+
" optimizer=optimizer,\n",
|
| 830 |
+
" loss='sparse_categorical_crossentropy',\n",
|
| 831 |
+
" metrics=['accuracy']\n",
|
| 832 |
+
" )\n",
|
| 833 |
+
" return model"
|
| 834 |
+
]
|
| 835 |
+
},
|
| 836 |
+
{
|
| 837 |
+
"cell_type": "code",
|
| 838 |
+
"execution_count": null,
|
| 839 |
+
"id": "fcda02d6-b3bd-4028-ba48-b0095d80245a",
|
| 840 |
+
"metadata": {},
|
| 841 |
+
"outputs": [],
|
| 842 |
+
"source": [
|
| 843 |
+
"def evaluate_test_model(best_param, avg_type, save_csv_path=None):\n",
|
| 844 |
+
" \n",
|
| 845 |
+
" per_run_results = []\n",
|
| 846 |
+
"\n",
|
| 847 |
+
" for run_i in range(1,11):\n",
|
| 848 |
+
" \n",
|
| 849 |
+
" model = create_model_test(\n",
|
| 850 |
+
" num_ex_neuron = best_param['num_ex_neuron'],\n",
|
| 851 |
+
" layer_one = best_param['layer_one'],\n",
|
| 852 |
+
" activation_function_one = best_param['activation_function_one'],\n",
|
| 853 |
+
" activation_function_two = best_param['activation_function_two'],\n",
|
| 854 |
+
" activation_function_three = best_param['activation_function_three'],\n",
|
| 855 |
+
" dropout_p = best_param['dropout_p'],\n",
|
| 856 |
+
" learning_rate = best_param['learning_rate'],\n",
|
| 857 |
+
" l2_reg = best_param['l2_reg'],\n",
|
| 858 |
+
" optimizer_choice = best_param['optimizer']\n",
|
| 859 |
+
" )\n",
|
| 860 |
+
" model.fit(\n",
|
| 861 |
+
" [X_gene_train, X_dna_train],\n",
|
| 862 |
+
" y_train,\n",
|
| 863 |
+
" epochs=best_param['epoch'],\n",
|
| 864 |
+
" batch_size=best_param['batch_size'],\n",
|
| 865 |
+
" shuffle=False,\n",
|
| 866 |
+
" verbose=0\n",
|
| 867 |
+
" )\n",
|
| 868 |
+
" y_pred = model.predict([X_gene_test, X_dna_test]).argmax(axis=1)\n",
|
| 869 |
+
"\n",
|
| 870 |
+
" f1_val = f1_score(y_test, y_pred, average=avg_type)\n",
|
| 871 |
+
" precision_v = precision_score(y_test, y_pred, average=avg_type)\n",
|
| 872 |
+
" recall_v = recall_score(y_test, y_pred, average=avg_type)\n",
|
| 873 |
+
" acc_v = accuracy_score(y_test, y_pred)\n",
|
| 874 |
+
"\n",
|
| 875 |
+
" per_run_results.append({\n",
|
| 876 |
+
" 'run_idx': run_i,\n",
|
| 877 |
+
" f'f1_{avg_type}': f1_val,\n",
|
| 878 |
+
" f'precision_{avg_type}': precision_v,\n",
|
| 879 |
+
" f'recall_{avg_type}': recall_v,\n",
|
| 880 |
+
" 'accuracy': acc_v\n",
|
| 881 |
+
" })\n",
|
| 882 |
+
"\n",
|
| 883 |
+
" df_runs = pd.DataFrame(per_run_results)\n",
|
| 884 |
+
" summary = {\n",
|
| 885 |
+
" f'f1_{avg_type}_mean': df_runs[f'f1_{avg_type}'].mean(),\n",
|
| 886 |
+
" f'f1_{avg_type}_std': df_runs[f'f1_{avg_type}'].std(),\n",
|
| 887 |
+
" f'precision_{avg_type}_mean': df_runs[f'precision_{avg_type}'].mean(),\n",
|
| 888 |
+
" f'precision_{avg_type}_std': df_runs[f'precision_{avg_type}'].std(),\n",
|
| 889 |
+
" f'recall_{avg_type}_mean': df_runs[f'recall_{avg_type}'].mean(),\n",
|
| 890 |
+
" f'recall_{avg_type}_std': df_runs[f'recall_{avg_type}'].std(),\n",
|
| 891 |
+
" 'accuracy_mean': df_runs['accuracy'].mean(),\n",
|
| 892 |
+
" 'accuracy_std': df_runs['accuracy'].std()\n",
|
| 893 |
+
" }\n",
|
| 894 |
+
"\n",
|
| 895 |
+
" df_runs[f'f1_{avg_type}_std'] = pd.NA\n",
|
| 896 |
+
" df_runs[f'precision_{avg_type}_std'] = pd.NA\n",
|
| 897 |
+
" df_runs[f'recall_{avg_type}_std'] = pd.NA\n",
|
| 898 |
+
" df_runs['accuracy_std'] = pd.NA\n",
|
| 899 |
+
"\n",
|
| 900 |
+
" summary_row = {\n",
|
| 901 |
+
" 'run_idx': 'mean',\n",
|
| 902 |
+
" f'f1_{avg_type}': summary[f'f1_{avg_type}_mean'],\n",
|
| 903 |
+
" f'f1_{avg_type}_std': summary[f'f1_{avg_type}_std'],\n",
|
| 904 |
+
" f'precision_{avg_type}': summary[f'precision_{avg_type}_mean'],\n",
|
| 905 |
+
" f'precision_{avg_type}_std': summary[f'precision_{avg_type}_std'],\n",
|
| 906 |
+
" f'recall_{avg_type}': summary[f'recall_{avg_type}_mean'],\n",
|
| 907 |
+
" f'recall_{avg_type}_std': summary[f'recall_{avg_type}_std'],\n",
|
| 908 |
+
" 'accuracy': summary['accuracy_mean'],\n",
|
| 909 |
+
" 'accuracy_std': summary['accuracy_std']\n",
|
| 910 |
+
" }\n",
|
| 911 |
+
" df_summary = pd.DataFrame([summary_row])\n",
|
| 912 |
+
"\n",
|
| 913 |
+
" df_runs = pd.concat([df_runs, df_summary], ignore_index=True)\n",
|
| 914 |
+
"\n",
|
| 915 |
+
" if save_csv_path is not None:\n",
|
| 916 |
+
" df_runs.to_csv(save_csv_path, index=False)\n",
|
| 917 |
+
"\n",
|
| 918 |
+
" return summary, df_runs\n",
|
| 919 |
+
"\n",
|
| 920 |
+
"summary_macro, df_macro_runs = evaluate_test_model(\n",
|
| 921 |
+
" best_param_macro,\n",
|
| 922 |
+
" avg_type=\"macro\")"
|
| 923 |
+
]
|
| 924 |
+
}
|
| 925 |
+
],
|
| 926 |
+
"metadata": {
|
| 927 |
+
"kernelspec": {
|
| 928 |
+
"display_name": "colo2",
|
| 929 |
+
"language": "python",
|
| 930 |
+
"name": "colo2"
|
| 931 |
+
},
|
| 932 |
+
"language_info": {
|
| 933 |
+
"codemirror_mode": {
|
| 934 |
+
"name": "ipython",
|
| 935 |
+
"version": 3
|
| 936 |
+
},
|
| 937 |
+
"file_extension": ".py",
|
| 938 |
+
"mimetype": "text/x-python",
|
| 939 |
+
"name": "python",
|
| 940 |
+
"nbconvert_exporter": "python",
|
| 941 |
+
"pygments_lexer": "ipython3",
|
| 942 |
+
"version": "3.9.13"
|
| 943 |
+
}
|
| 944 |
+
},
|
| 945 |
+
"nbformat": 4,
|
| 946 |
+
"nbformat_minor": 5
|
| 947 |
+
}
|
diagnostics/2026-10-16-brca-training-collapse/upstream/BioLMNET_Weighted_Loss.ipynb
ADDED
|
@@ -0,0 +1,940 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"cells": [
|
| 3 |
+
{
|
| 4 |
+
"cell_type": "code",
|
| 5 |
+
"execution_count": null,
|
| 6 |
+
"id": "634f46b7-f788-499d-b014-7c28905eeff6",
|
| 7 |
+
"metadata": {},
|
| 8 |
+
"outputs": [],
|
| 9 |
+
"source": [
|
| 10 |
+
"import os\n",
|
| 11 |
+
"os.environ['PYTHONHASHSEED'] = '0'\n",
|
| 12 |
+
"os.environ['TF_DETERMINISTIC_OPS'] = '1'\n",
|
| 13 |
+
"os.environ['CUDA_VISIBLE_DEVICES'] = ''\n",
|
| 14 |
+
"import random\n",
|
| 15 |
+
"import numpy as np\n",
|
| 16 |
+
"import pandas as pd\n",
|
| 17 |
+
"import re\n",
|
| 18 |
+
"import glob\n",
|
| 19 |
+
"from collections import defaultdict\n",
|
| 20 |
+
"from sklearn.preprocessing import StandardScaler, LabelEncoder\n",
|
| 21 |
+
"from sklearn.metrics import accuracy_score, f1_score, precision_score, recall_score\n",
|
| 22 |
+
"from sklearn.model_selection import train_test_split, StratifiedKFold\n",
|
| 23 |
+
"import matplotlib.pyplot as plt\n",
|
| 24 |
+
"import tensorflow as tf\n",
|
| 25 |
+
"from tensorflow.keras import layers, Model\n",
|
| 26 |
+
"from tensorflow.keras.layers import Dense, Dropout, Input, concatenate\n",
|
| 27 |
+
"import itertools\n",
|
| 28 |
+
"from joblib import Parallel, delayed\n",
|
| 29 |
+
"from tqdm import tqdm\n",
|
| 30 |
+
"from tqdm_joblib import tqdm_joblib\n",
|
| 31 |
+
"from sklearn.utils.class_weight import compute_class_weight\n",
|
| 32 |
+
"tf.config.threading.set_intra_op_parallelism_threads(1)\n",
|
| 33 |
+
"tf.config.threading.set_inter_op_parallelism_threads(1)\n",
|
| 34 |
+
"tf.random.set_seed(42)"
|
| 35 |
+
]
|
| 36 |
+
},
|
| 37 |
+
{
|
| 38 |
+
"cell_type": "code",
|
| 39 |
+
"execution_count": null,
|
| 40 |
+
"id": "535e884e-58a5-434e-95df-0735956321b5",
|
| 41 |
+
"metadata": {},
|
| 42 |
+
"outputs": [],
|
| 43 |
+
"source": [
|
| 44 |
+
"from huggingface_hub import hf_hub_download\n",
|
| 45 |
+
"import pandas as pd\n",
|
| 46 |
+
"\n",
|
| 47 |
+
"FNAME = \"embedding_associations_cell_type_tissue_drug_pathway_openai_large.parquet\" \n",
|
| 48 |
+
"\n",
|
| 49 |
+
"parquet_path = hf_hub_download(\n",
|
| 50 |
+
" repo_id = \"honicky/genept-composable-embeddings\",\n",
|
| 51 |
+
" filename = FNAME,\n",
|
| 52 |
+
" repo_type = \"model\"\n",
|
| 53 |
+
")\n",
|
| 54 |
+
"emb = pd.read_parquet(parquet_path)"
|
| 55 |
+
]
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"cell_type": "code",
|
| 59 |
+
"execution_count": null,
|
| 60 |
+
"id": "1a4d2523-d9a0-466f-bc58-8c815370e9e2",
|
| 61 |
+
"metadata": {},
|
| 62 |
+
"outputs": [],
|
| 63 |
+
"source": [
|
| 64 |
+
"df_gene = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"Gene_Expression.csv\")\n",
|
| 65 |
+
"df_dna = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"DNA_Methylation.csv\")\n",
|
| 66 |
+
" \n",
|
| 67 |
+
"true_label = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"label.csv\")\n",
|
| 68 |
+
"\n",
|
| 69 |
+
"scaler = StandardScaler()\n",
|
| 70 |
+
"le = LabelEncoder()\n",
|
| 71 |
+
"le.fit(true_label)\n",
|
| 72 |
+
"y = le.transform(true_label)\n",
|
| 73 |
+
"\n",
|
| 74 |
+
"ge_genes = list(df_gene.columns)\n",
|
| 75 |
+
"\n",
|
| 76 |
+
"df_pdi = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"PDI\"/ \"PDI.csv\",sep=',')\n",
|
| 77 |
+
"df_ge_pdi = df_pdi[df_pdi.Target.isin(ge_genes)]\n",
|
| 78 |
+
"unique_tfs = df_ge_pdi['TF'].unique()\n",
|
| 79 |
+
"unique_targets = df_ge_pdi['Target'].unique()\n",
|
| 80 |
+
"\n",
|
| 81 |
+
"dna_genes =list(df_dna.columns) \n",
|
| 82 |
+
"df_dna_pdi = df_pdi[df_pdi.Target.isin(dna_genes)]\n",
|
| 83 |
+
"\n",
|
| 84 |
+
"dna_unique_tfs = df_dna_pdi['TF'].unique()\n",
|
| 85 |
+
"dna_unique_targets = df_dna_pdi['Target'].unique()\n",
|
| 86 |
+
"\n",
|
| 87 |
+
"df_ppi = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"PPI\"/ \"PPI.csv\",sep=',')\n",
|
| 88 |
+
"df_ppi = df_ppi.drop(['Unnamed: 0'], axis =1)\n",
|
| 89 |
+
"df_ppi['combined_score'] = df_ppi['combined_score'] /1000\n",
|
| 90 |
+
"threshold = df_ppi['combined_score'].quantile(0.9)\n",
|
| 91 |
+
"df_ppi = df_ppi[df_ppi['combined_score'] >= threshold]\n",
|
| 92 |
+
"df_ge_ppi = df_ppi[df_ppi['protein1'].isin(ge_genes) | df_ppi['protein2'].isin(ge_genes)]\n",
|
| 93 |
+
"unique_protein1 = df_ge_ppi['protein1'].unique()\n",
|
| 94 |
+
"unique_protein2 = df_ge_ppi['protein2'].unique()\n",
|
| 95 |
+
"\n",
|
| 96 |
+
"df_dna_ppi = df_ppi[df_ppi['protein1'].isin(dna_genes) | df_ppi['protein2'].isin(dna_genes)]\n",
|
| 97 |
+
"dna_unique_protein1 = df_dna_ppi['protein1'].unique()\n",
|
| 98 |
+
"dna_unique_protein2 = df_dna_ppi['protein2'].unique()\n",
|
| 99 |
+
"\n",
|
| 100 |
+
"ge_pdi_ppi_genes = list(set(unique_targets) | set(unique_protein2))\n",
|
| 101 |
+
"dna_pdi_ppi_genes = list(set(dna_unique_targets) | set(dna_unique_protein2))"
|
| 102 |
+
]
|
| 103 |
+
},
|
| 104 |
+
{
|
| 105 |
+
"cell_type": "code",
|
| 106 |
+
"execution_count": null,
|
| 107 |
+
"id": "e868db94-f1d2-413a-b36f-028cb0d7499d",
|
| 108 |
+
"metadata": {},
|
| 109 |
+
"outputs": [],
|
| 110 |
+
"source": [
|
| 111 |
+
"genept_gene_emb = emb.loc[emb.index.isin(ge_pdi_ppi_genes)]\n",
|
| 112 |
+
"ge_pdi_ppi_genept = genept_gene_emb.index"
|
| 113 |
+
]
|
| 114 |
+
},
|
| 115 |
+
{
|
| 116 |
+
"cell_type": "code",
|
| 117 |
+
"execution_count": null,
|
| 118 |
+
"id": "dfd04c7c-6119-4f60-836e-43d2c2060299",
|
| 119 |
+
"metadata": {},
|
| 120 |
+
"outputs": [],
|
| 121 |
+
"source": [
|
| 122 |
+
"genept_dna_emb = emb.loc[emb.index.isin(dna_pdi_ppi_genes)]\n",
|
| 123 |
+
"dna_pdi_ppi_genept = genept_dna_emb.index"
|
| 124 |
+
]
|
| 125 |
+
},
|
| 126 |
+
{
|
| 127 |
+
"cell_type": "code",
|
| 128 |
+
"execution_count": null,
|
| 129 |
+
"id": "537876a2-01e5-4a8f-92df-621469614756",
|
| 130 |
+
"metadata": {},
|
| 131 |
+
"outputs": [],
|
| 132 |
+
"source": [
|
| 133 |
+
"def create_ge_mask_matrix (extra_neurons):\n",
|
| 134 |
+
" de_gene_to_idx = {gene: i for i, gene in enumerate(ge_genes)}\n",
|
| 135 |
+
" target_to_idx = {target: j for j, target in enumerate(unique_targets)}\n",
|
| 136 |
+
" protein2_to_idx = {protein2: k for k, protein2 in enumerate(unique_protein2)}\n",
|
| 137 |
+
"\n",
|
| 138 |
+
" pdi_mask_matrix = np.zeros((len(ge_genes), len(unique_targets)), dtype=int)\n",
|
| 139 |
+
"\n",
|
| 140 |
+
" for _, row in df_ge_pdi.iterrows():\n",
|
| 141 |
+
" tfa = row[\"TF\"]\n",
|
| 142 |
+
" target = row[\"Target\"]\n",
|
| 143 |
+
" if tfa in de_gene_to_idx and target in target_to_idx:\n",
|
| 144 |
+
" tf_idx = de_gene_to_idx[tfa]\n",
|
| 145 |
+
" target_idx = target_to_idx[target]\n",
|
| 146 |
+
" pdi_mask_matrix[tf_idx, target_idx] = 1\n",
|
| 147 |
+
" \n",
|
| 148 |
+
" ppi_mask_matrix = np.zeros((len(ge_genes), len(unique_protein2)))\n",
|
| 149 |
+
"\n",
|
| 150 |
+
" for _, row in df_ge_ppi.iterrows():\n",
|
| 151 |
+
" protein1 = row[\"protein1\"]\n",
|
| 152 |
+
" protein2 = row[\"protein2\"]\n",
|
| 153 |
+
" combined_score = row[\"combined_score\"]\n",
|
| 154 |
+
"\n",
|
| 155 |
+
" if protein1 in de_gene_to_idx and protein2 in protein2_to_idx:\n",
|
| 156 |
+
" protein1_idx = de_gene_to_idx[protein1]\n",
|
| 157 |
+
" protein2_idx = protein2_to_idx[protein2]\n",
|
| 158 |
+
" ppi_mask_matrix[protein1_idx, protein2_idx] = combined_score \n",
|
| 159 |
+
" \n",
|
| 160 |
+
" pdi_mask_df= pd.DataFrame(pdi_mask_matrix)\n",
|
| 161 |
+
" ppi_mask_df= pd.DataFrame(ppi_mask_matrix)\n",
|
| 162 |
+
" pdi_mask_df.columns = unique_targets\n",
|
| 163 |
+
" ppi_mask_df.columns = unique_protein2\n",
|
| 164 |
+
" pdi_ppi_mask_df = pd.concat([pdi_mask_df, ppi_mask_df], axis=1)\n",
|
| 165 |
+
" pdi_ppi_mask_df = pdi_ppi_mask_df.loc[:, ~pdi_ppi_mask_df.columns.duplicated(keep='last')]\n",
|
| 166 |
+
" col_mask = pdi_ppi_mask_df.columns.isin(ge_pdi_ppi_genept)\n",
|
| 167 |
+
" sub_pdi_ppi_mask_df = pdi_ppi_mask_df.loc[:, col_mask]\n",
|
| 168 |
+
" \n",
|
| 169 |
+
" extra_columns = np.ones((len(ge_genes), extra_neurons), dtype=int)\n",
|
| 170 |
+
" adjusted_mask_matrix = np.hstack([sub_pdi_ppi_mask_df, extra_columns])\n",
|
| 171 |
+
" new_mask_matrix = tf.constant(adjusted_mask_matrix, dtype=tf.float32)\n",
|
| 172 |
+
" \n",
|
| 173 |
+
" return new_mask_matrix\n",
|
| 174 |
+
"\n",
|
| 175 |
+
"def create_dna_mask_matrix (extra_neurons):\n",
|
| 176 |
+
" de_gene_to_idx = {gene: i for i, gene in enumerate(dna_genes)}\n",
|
| 177 |
+
" target_to_idx = {target: j for j, target in enumerate(dna_unique_targets)}\n",
|
| 178 |
+
" protein2_to_idx = {protein2: k for k, protein2 in enumerate(dna_unique_protein2)}\n",
|
| 179 |
+
"\n",
|
| 180 |
+
"\n",
|
| 181 |
+
" pdi_mask_matrix = np.zeros((len(dna_genes), len(dna_unique_targets)), dtype=int)\n",
|
| 182 |
+
"\n",
|
| 183 |
+
"\n",
|
| 184 |
+
" for _, row in df_dna_pdi.iterrows():\n",
|
| 185 |
+
" tfa = row[\"TF\"]\n",
|
| 186 |
+
" target = row[\"Target\"]\n",
|
| 187 |
+
" if tfa in de_gene_to_idx and target in target_to_idx:\n",
|
| 188 |
+
" tf_idx = de_gene_to_idx[tfa]\n",
|
| 189 |
+
" target_idx = target_to_idx[target]\n",
|
| 190 |
+
" pdi_mask_matrix[tf_idx, target_idx] = 1\n",
|
| 191 |
+
" \n",
|
| 192 |
+
" ppi_mask_matrix = np.zeros((len(dna_genes), len(dna_unique_protein2)))\n",
|
| 193 |
+
"\n",
|
| 194 |
+
" for _, row in df_dna_ppi.iterrows():\n",
|
| 195 |
+
" protein1 = row[\"protein1\"]\n",
|
| 196 |
+
" protein2 = row[\"protein2\"]\n",
|
| 197 |
+
" combined_score = row[\"combined_score\"]\n",
|
| 198 |
+
"\n",
|
| 199 |
+
" if protein1 in de_gene_to_idx and protein2 in protein2_to_idx:\n",
|
| 200 |
+
" protein1_idx = de_gene_to_idx[protein1]\n",
|
| 201 |
+
" protein2_idx = protein2_to_idx[protein2]\n",
|
| 202 |
+
" ppi_mask_matrix[protein1_idx, protein2_idx] = combined_score \n",
|
| 203 |
+
" \n",
|
| 204 |
+
" pdi_mask_df= pd.DataFrame(pdi_mask_matrix)\n",
|
| 205 |
+
" ppi_mask_df= pd.DataFrame(ppi_mask_matrix)\n",
|
| 206 |
+
" pdi_mask_df.columns = dna_unique_targets\n",
|
| 207 |
+
" ppi_mask_df.columns = dna_unique_protein2\n",
|
| 208 |
+
" pdi_ppi_mask_df = pd.concat([pdi_mask_df, ppi_mask_df], axis=1)\n",
|
| 209 |
+
" pdi_ppi_mask_df = pdi_ppi_mask_df.loc[:, ~pdi_ppi_mask_df.columns.duplicated(keep='last')]\n",
|
| 210 |
+
" col_mask = pdi_ppi_mask_df.columns.isin(dna_pdi_ppi_genept)\n",
|
| 211 |
+
" sub_pdi_ppi_mask_df = pdi_ppi_mask_df.loc[:, col_mask]\n",
|
| 212 |
+
"\n",
|
| 213 |
+
" \n",
|
| 214 |
+
" extra_columns = np.ones((len(dna_genes), extra_neurons), dtype=int)\n",
|
| 215 |
+
" adjusted_mask_matrix = np.hstack([sub_pdi_ppi_mask_df, extra_columns])\n",
|
| 216 |
+
" new_mask_matrix = tf.constant(adjusted_mask_matrix, dtype=tf.float32)\n",
|
| 217 |
+
" \n",
|
| 218 |
+
" return new_mask_matrix"
|
| 219 |
+
]
|
| 220 |
+
},
|
| 221 |
+
{
|
| 222 |
+
"cell_type": "code",
|
| 223 |
+
"execution_count": null,
|
| 224 |
+
"id": "e5161905-ef7c-4943-aa4d-46a2dc84f498",
|
| 225 |
+
"metadata": {},
|
| 226 |
+
"outputs": [],
|
| 227 |
+
"source": [
|
| 228 |
+
"ge_target_to_kegg = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"ge_target_to_KEGG_significant.csv\",sep=',')\n",
|
| 229 |
+
"dna_target_to_kegg = pd.read_csv(Path(__file__).parent / \"Dataset\"/\"scTrioseq2\"/ \"dna_target_to_KEGG_significant.csv\",sep=',')"
|
| 230 |
+
]
|
| 231 |
+
},
|
| 232 |
+
{
|
| 233 |
+
"cell_type": "code",
|
| 234 |
+
"execution_count": null,
|
| 235 |
+
"id": "235fc5c0-0c09-47c7-aa1a-36d708372be1",
|
| 236 |
+
"metadata": {},
|
| 237 |
+
"outputs": [],
|
| 238 |
+
"source": [
|
| 239 |
+
"def create_ge_pathway_mask_matrix ():\n",
|
| 240 |
+
" genes = ge_pdi_ppi_genept\n",
|
| 241 |
+
" pathways = ge_target_to_kegg[\"PathwayID\"].unique().tolist()\n",
|
| 242 |
+
"\n",
|
| 243 |
+
" gene_to_idx = {gene: i for i, gene in enumerate(genes)}\n",
|
| 244 |
+
" pathway_to_idx = {pw: j for j, pw in enumerate(pathways)}\n",
|
| 245 |
+
"\n",
|
| 246 |
+
" mask_matrix = np.zeros((len(genes), len(pathways)), dtype=int)\n",
|
| 247 |
+
"\n",
|
| 248 |
+
" for _, row in ge_target_to_kegg.iterrows():\n",
|
| 249 |
+
" gene = row[\"SYMBOL\"]\n",
|
| 250 |
+
" pw = row[\"PathwayID\"]\n",
|
| 251 |
+
" if gene in gene_to_idx and pw in pathway_to_idx:\n",
|
| 252 |
+
" i = gene_to_idx[gene]\n",
|
| 253 |
+
" j = pathway_to_idx[pw]\n",
|
| 254 |
+
" mask_matrix[i, j] = 1\n",
|
| 255 |
+
" mask_df = pd.DataFrame(mask_matrix, index=genes, columns=pathways)\n",
|
| 256 |
+
" return mask_df\n",
|
| 257 |
+
"\n",
|
| 258 |
+
"def create_dna_pathway_mask_matrix ():\n",
|
| 259 |
+
" genes = dna_pdi_ppi_genept\n",
|
| 260 |
+
" pathways = dna_target_to_kegg[\"PathwayID\"].unique().tolist()\n",
|
| 261 |
+
"\n",
|
| 262 |
+
" gene_to_idx = {gene: i for i, gene in enumerate(genes)}\n",
|
| 263 |
+
" pathway_to_idx = {pw: j for j, pw in enumerate(pathways)}\n",
|
| 264 |
+
"\n",
|
| 265 |
+
" mask_matrix = np.zeros((len(genes), len(pathways)), dtype=int)\n",
|
| 266 |
+
"\n",
|
| 267 |
+
" for _, row in dna_target_to_kegg.iterrows():\n",
|
| 268 |
+
" gene = row[\"SYMBOL\"]\n",
|
| 269 |
+
" pw = row[\"PathwayID\"]\n",
|
| 270 |
+
" if gene in gene_to_idx and pw in pathway_to_idx:\n",
|
| 271 |
+
" i = gene_to_idx[gene]\n",
|
| 272 |
+
" j = pathway_to_idx[pw]\n",
|
| 273 |
+
" mask_matrix[i, j] = 1\n",
|
| 274 |
+
" mask_df = pd.DataFrame(mask_matrix, index=genes, columns=pathways)\n",
|
| 275 |
+
" return mask_df\n",
|
| 276 |
+
" \n",
|
| 277 |
+
"mask_gene_pathway = create_ge_pathway_mask_matrix ()\n",
|
| 278 |
+
"mask_dna_pathway = create_dna_pathway_mask_matrix()"
|
| 279 |
+
]
|
| 280 |
+
},
|
| 281 |
+
{
|
| 282 |
+
"cell_type": "code",
|
| 283 |
+
"execution_count": null,
|
| 284 |
+
"id": "dbfe572a-d773-4306-94a1-69ab748f924c",
|
| 285 |
+
"metadata": {},
|
| 286 |
+
"outputs": [],
|
| 287 |
+
"source": [
|
| 288 |
+
"class MaskedLayer(layers.Layer):\n",
|
| 289 |
+
" def __init__(self, mask_matrix, **kwargs):\n",
|
| 290 |
+
" super().__init__(**kwargs)\n",
|
| 291 |
+
" self.mask_matrix = K.constant(mask_matrix, dtype='float32')\n",
|
| 292 |
+
"\n",
|
| 293 |
+
" def call(self, inputs):\n",
|
| 294 |
+
" return K.dot(inputs, self.mask_matrix)\n",
|
| 295 |
+
"\n",
|
| 296 |
+
"\n",
|
| 297 |
+
"class AttentionPathwayLayer(layers.Layer):\n",
|
| 298 |
+
" def __init__(self, genept_embs, pathway_mask, init_seed=42, **kwargs):\n",
|
| 299 |
+
" super().__init__(**kwargs)\n",
|
| 300 |
+
"\n",
|
| 301 |
+
" genept_np = genept_embs.values if hasattr(genept_embs, \"values\") else np.asarray(genept_embs)\n",
|
| 302 |
+
" n_genes, D_embed = genept_np.shape\n",
|
| 303 |
+
"\n",
|
| 304 |
+
" pw_np = pathway_mask.values if hasattr(pathway_mask, \"values\") else np.asarray(pathway_mask)\n",
|
| 305 |
+
" n_pathways = pw_np.shape[1]\n",
|
| 306 |
+
"\n",
|
| 307 |
+
" self.G = K.constant(genept_np, dtype=\"float32\")\n",
|
| 308 |
+
" self.P = K.constant(pw_np, dtype=\"float32\")\n",
|
| 309 |
+
"\n",
|
| 310 |
+
" glorot = initializers.GlorotUniform(seed=init_seed)\n",
|
| 311 |
+
" self.W = self.add_weight(\n",
|
| 312 |
+
" shape=(n_pathways, D_embed),\n",
|
| 313 |
+
" initializer=glorot,\n",
|
| 314 |
+
" trainable=True,\n",
|
| 315 |
+
" name=\"W_query\"\n",
|
| 316 |
+
" )\n",
|
| 317 |
+
"\n",
|
| 318 |
+
" def call(self, x):\n",
|
| 319 |
+
" G_T = K.transpose(self.G) \n",
|
| 320 |
+
" S = K.dot(self.W, G_T) \n",
|
| 321 |
+
" S_T = K.transpose(S) \n",
|
| 322 |
+
" S_masked = S_T * self.P \n",
|
| 323 |
+
" alpha = K.softmax(S_masked, axis=0) \n",
|
| 324 |
+
" x_sq = K.squeeze(x, axis=-1) \n",
|
| 325 |
+
" out_mat = K.dot(x_sq, alpha) \n",
|
| 326 |
+
" return K.expand_dims(out_mat, axis=-1) \n",
|
| 327 |
+
"\n",
|
| 328 |
+
" def compute_output_shape(self, input_shape):\n",
|
| 329 |
+
" batch_size, n_genes, _ = input_shape\n",
|
| 330 |
+
" n_pathways = K.int_shape(self.P)[1]\n",
|
| 331 |
+
" return (batch_size, n_pathways, 1)\n",
|
| 332 |
+
" \n",
|
| 333 |
+
" def get_attention(self):\n",
|
| 334 |
+
" G_T = K.transpose(self.G) \n",
|
| 335 |
+
" S = K.dot(self.W, G_T) \n",
|
| 336 |
+
" S_T = K.transpose(S) \n",
|
| 337 |
+
" S_masked = S_T * self.P \n",
|
| 338 |
+
" return K.softmax(S_masked, axis=0) \n",
|
| 339 |
+
"\n",
|
| 340 |
+
"\n",
|
| 341 |
+
"def create_model(\n",
|
| 342 |
+
" num_ex_neuron,\n",
|
| 343 |
+
" layer_one,\n",
|
| 344 |
+
" activation_function_one,\n",
|
| 345 |
+
" activation_function_two,\n",
|
| 346 |
+
" activation_function_three,\n",
|
| 347 |
+
" dropout_p,\n",
|
| 348 |
+
" learning_rate,\n",
|
| 349 |
+
" l2_reg,\n",
|
| 350 |
+
" optimizer_choice,\n",
|
| 351 |
+
" genept_gene_emb,\n",
|
| 352 |
+
" mask_gene_pathway,\n",
|
| 353 |
+
" genept_dna_emb,\n",
|
| 354 |
+
" mask_dna_pathway\n",
|
| 355 |
+
"):\n",
|
| 356 |
+
"\n",
|
| 357 |
+
" new_ge_mask_matrix = create_ge_mask_matrix(num_ex_neuron)\n",
|
| 358 |
+
" new_dna_mask_matrix = create_dna_mask_matrix(num_ex_neuron)\n",
|
| 359 |
+
" \n",
|
| 360 |
+
" inputA = Input(shape=(df_gene.shape[1],), name=\"gene_input\")\n",
|
| 361 |
+
" x = layers.Dense(\n",
|
| 362 |
+
" new_ge_mask_matrix.shape[0],\n",
|
| 363 |
+
" activation=activation_function_one,\n",
|
| 364 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 365 |
+
" kernel_initializer=initializers.LecunUniform(42)\n",
|
| 366 |
+
" )(inputA)\n",
|
| 367 |
+
" x = MaskedLayer(new_ge_mask_matrix)(x)\n",
|
| 368 |
+
" x = Dropout(dropout_p)(x)\n",
|
| 369 |
+
" x_feat = Lambda(lambda t: K.expand_dims(t, -1), name=\"gene_add_dim\")(x)\n",
|
| 370 |
+
"\n",
|
| 371 |
+
" gene_path_layer = AttentionPathwayLayer(\n",
|
| 372 |
+
" genept_embs = genept_gene_emb,\n",
|
| 373 |
+
" pathway_mask = mask_gene_pathway,\n",
|
| 374 |
+
" name = \"gene_path_attn\"\n",
|
| 375 |
+
" )\n",
|
| 376 |
+
" x_path = gene_path_layer(x_feat)\n",
|
| 377 |
+
" x_path = Flatten()(x_path)\n",
|
| 378 |
+
"\n",
|
| 379 |
+
" x_proj = layers.Dense(\n",
|
| 380 |
+
" layer_one,\n",
|
| 381 |
+
" activation=activation_function_two,\n",
|
| 382 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 383 |
+
" kernel_initializer=initializers.LecunUniform(42),\n",
|
| 384 |
+
" name=\"gene_proj\"\n",
|
| 385 |
+
" )(x_path)\n",
|
| 386 |
+
"\n",
|
| 387 |
+
" inputB = Input(shape=(df_dna.shape[1],), name=\"dna_input\")\n",
|
| 388 |
+
" y = layers.Dense(\n",
|
| 389 |
+
" new_dna_mask_matrix.shape[0],\n",
|
| 390 |
+
" activation=activation_function_one,\n",
|
| 391 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 392 |
+
" kernel_initializer=initializers.LecunUniform(42)\n",
|
| 393 |
+
" )(inputB)\n",
|
| 394 |
+
" y = MaskedLayer(new_dna_mask_matrix)(y)\n",
|
| 395 |
+
" y = Dropout(dropout_p)(y)\n",
|
| 396 |
+
" y_feat = Lambda(lambda t: K.expand_dims(t, -1), name=\"dna_add_dim\")(y)\n",
|
| 397 |
+
"\n",
|
| 398 |
+
" dna_path_layer = AttentionPathwayLayer(\n",
|
| 399 |
+
" genept_embs = genept_dna_emb,\n",
|
| 400 |
+
" pathway_mask = mask_dna_pathway,\n",
|
| 401 |
+
" name = \"dna_path_attn\"\n",
|
| 402 |
+
" )\n",
|
| 403 |
+
" y_path = dna_path_layer(y_feat)\n",
|
| 404 |
+
" y_path = Flatten()(y_path)\n",
|
| 405 |
+
"\n",
|
| 406 |
+
" y_proj = layers.Dense(\n",
|
| 407 |
+
" layer_one,\n",
|
| 408 |
+
" activation=activation_function_two,\n",
|
| 409 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 410 |
+
" kernel_initializer=initializers.LecunUniform(42),\n",
|
| 411 |
+
" name=\"dna_proj\"\n",
|
| 412 |
+
" )(y_path)\n",
|
| 413 |
+
"\n",
|
| 414 |
+
" merged = concatenate([x_proj, y_proj], name=\"merge_xy\")\n",
|
| 415 |
+
" h = layers.Dense(\n",
|
| 416 |
+
" 12,\n",
|
| 417 |
+
" activation=activation_function_three,\n",
|
| 418 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 419 |
+
" kernel_initializer=initializers.GlorotUniform(42),\n",
|
| 420 |
+
" name=\"fusion_dense\"\n",
|
| 421 |
+
" )(merged)\n",
|
| 422 |
+
" h = Dropout(dropout_p, name=\"drop_fusion\")(h)\n",
|
| 423 |
+
" out = layers.Dense(\n",
|
| 424 |
+
" 4,\n",
|
| 425 |
+
" activation=\"softmax\",\n",
|
| 426 |
+
" kernel_regularizer=regularizers.l2(l2_reg),\n",
|
| 427 |
+
" kernel_initializer=initializers.GlorotUniform(42),\n",
|
| 428 |
+
" name=\"output\"\n",
|
| 429 |
+
" )(h)\n",
|
| 430 |
+
"\n",
|
| 431 |
+
" model = Model(inputs=[inputA, inputB], outputs=out, name=\"PathwayModel\")\n",
|
| 432 |
+
"\n",
|
| 433 |
+
" if optimizer_choice == 'adam':\n",
|
| 434 |
+
" optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)\n",
|
| 435 |
+
" elif optimizer_choice == 'sgd':\n",
|
| 436 |
+
" optimizer = tf.keras.optimizers.SGD(learning_rate=learning_rate)\n",
|
| 437 |
+
" model.compile(\n",
|
| 438 |
+
" optimizer=optimizer,\n",
|
| 439 |
+
" loss='sparse_categorical_crossentropy',\n",
|
| 440 |
+
" metrics=['accuracy']\n",
|
| 441 |
+
" )\n",
|
| 442 |
+
" return model"
|
| 443 |
+
]
|
| 444 |
+
},
|
| 445 |
+
{
|
| 446 |
+
"cell_type": "code",
|
| 447 |
+
"execution_count": null,
|
| 448 |
+
"id": "be89b57c-5f26-4b58-be38-7d4c797d4c6d",
|
| 449 |
+
"metadata": {},
|
| 450 |
+
"outputs": [],
|
| 451 |
+
"source": [
|
| 452 |
+
"def evaluate_model_cv(X_train, X_val, y_train, y_val, params):\n",
|
| 453 |
+
" model = create_model(\n",
|
| 454 |
+
" params['num_ex_neuron'], params['layer_one'],\n",
|
| 455 |
+
" params['activation_function_one'], params['activation_function_two'], params['activation_function_three'],\n",
|
| 456 |
+
" params['dropout_p'], params['learning_rate'], params['l2_reg'], params['optimizer'],\n",
|
| 457 |
+
" genept_gene_emb, mask_gene_pathway, genept_dna_emb, mask_dna_pathway\n",
|
| 458 |
+
" )\n",
|
| 459 |
+
"\n",
|
| 460 |
+
" classes = np.unique(y_train)\n",
|
| 461 |
+
" weights = compute_class_weight('balanced', classes=classes, y=y_train)\n",
|
| 462 |
+
" class_weight = dict(zip(classes, weights))\n",
|
| 463 |
+
"\n",
|
| 464 |
+
" history = model.fit(\n",
|
| 465 |
+
" X_train, y_train,\n",
|
| 466 |
+
" validation_data=(X_val, y_val),\n",
|
| 467 |
+
" epochs=params['epoch'], batch_size=params['batch_size'],\n",
|
| 468 |
+
" shuffle=False, verbose=0,\n",
|
| 469 |
+
" class_weight=class_weight\n",
|
| 470 |
+
" )\n",
|
| 471 |
+
"\n",
|
| 472 |
+
" y_pred = model.predict(X_val).argmax(1)\n",
|
| 473 |
+
" return {\n",
|
| 474 |
+
" 'history': history.history,\n",
|
| 475 |
+
" 'f1_weighted': f1_score(y_val, y_pred, average='weighted'),\n",
|
| 476 |
+
" 'f1_macro': f1_score(y_val, y_pred, average='macro'),\n",
|
| 477 |
+
" 'f1_micro': f1_score(y_val, y_pred, average='micro'),\n",
|
| 478 |
+
" 'precision_weighted': precision_score(y_val, y_pred, average='weighted'),\n",
|
| 479 |
+
" 'precision_macro': precision_score(y_val, y_pred, average='macro'),\n",
|
| 480 |
+
" 'precision_micro': precision_score(y_val, y_pred, average='micro'),\n",
|
| 481 |
+
" 'recall_weighted': recall_score(y_val, y_pred, average='weighted'),\n",
|
| 482 |
+
" 'recall_macro': recall_score(y_val, y_pred, average='macro'),\n",
|
| 483 |
+
" 'recall_micro': recall_score(y_val, y_pred, average='micro'),\n",
|
| 484 |
+
" 'accuracy': accuracy_score(y_val, y_pred)\n",
|
| 485 |
+
" }\n",
|
| 486 |
+
"\n",
|
| 487 |
+
"def evaluate_combination(param_combination,X_gene_train,X_dna_train,y_train,n_splits=5):\n",
|
| 488 |
+
" skf = StratifiedKFold(n_splits=n_splits, shuffle=True, random_state=42)\n",
|
| 489 |
+
" \n",
|
| 490 |
+
" f1_weighted_list = []\n",
|
| 491 |
+
" f1_macro_list = []\n",
|
| 492 |
+
" f1_micro_list = []\n",
|
| 493 |
+
" \n",
|
| 494 |
+
" precision_weighted_list = []\n",
|
| 495 |
+
" precision_macro_list = []\n",
|
| 496 |
+
" precision_micro_list = []\n",
|
| 497 |
+
" \n",
|
| 498 |
+
" recall_weighted_list = []\n",
|
| 499 |
+
" recall_macro_list = []\n",
|
| 500 |
+
" recall_micro_list = []\n",
|
| 501 |
+
" \n",
|
| 502 |
+
" accuracy_list = []\n",
|
| 503 |
+
" all_histories = []\n",
|
| 504 |
+
" \n",
|
| 505 |
+
" for train_idx, val_idx in skf.split(X_gene_train, y_train):\n",
|
| 506 |
+
" Xg_tr, Xg_val = X_gene_train[train_idx], X_gene_train[val_idx]\n",
|
| 507 |
+
" Xd_tr, Xd_val = X_dna_train[train_idx], X_dna_train[val_idx]\n",
|
| 508 |
+
" y_tr, y_val = y_train[train_idx], y_train[val_idx]\n",
|
| 509 |
+
" \n",
|
| 510 |
+
" scores = evaluate_model_cv([Xg_tr, Xd_tr], [Xg_val, Xd_val], y_tr, y_val, param_combination)\n",
|
| 511 |
+
" \n",
|
| 512 |
+
" history_dict = scores.pop('history')\n",
|
| 513 |
+
" all_histories.append(history_dict)\n",
|
| 514 |
+
" \n",
|
| 515 |
+
" # Append each metric.\n",
|
| 516 |
+
" f1_weighted_list.append(scores['f1_weighted'])\n",
|
| 517 |
+
" f1_macro_list.append(scores['f1_macro'])\n",
|
| 518 |
+
" f1_micro_list.append(scores['f1_micro'])\n",
|
| 519 |
+
" \n",
|
| 520 |
+
" precision_weighted_list.append(scores['precision_weighted'])\n",
|
| 521 |
+
" precision_macro_list.append(scores['precision_macro'])\n",
|
| 522 |
+
" precision_micro_list.append(scores['precision_micro'])\n",
|
| 523 |
+
" \n",
|
| 524 |
+
" recall_weighted_list.append(scores['recall_weighted'])\n",
|
| 525 |
+
" recall_macro_list.append(scores['recall_macro'])\n",
|
| 526 |
+
" recall_micro_list.append(scores['recall_micro'])\n",
|
| 527 |
+
" \n",
|
| 528 |
+
" accuracy_list.append(scores['accuracy'])\n",
|
| 529 |
+
" \n",
|
| 530 |
+
" results = {\n",
|
| 531 |
+
" 'f1_weighted_mean': np.mean(f1_weighted_list),\n",
|
| 532 |
+
" 'f1_weighted_std': np.std(f1_weighted_list),\n",
|
| 533 |
+
" 'f1_macro_mean': np.mean(f1_macro_list),\n",
|
| 534 |
+
" 'f1_macro_std': np.std(f1_macro_list),\n",
|
| 535 |
+
" 'f1_micro_mean': np.mean(f1_micro_list),\n",
|
| 536 |
+
" 'f1_micro_std': np.std(f1_micro_list),\n",
|
| 537 |
+
" 'precision_weighted_mean': np.mean(precision_weighted_list),\n",
|
| 538 |
+
" 'precision_weighted_std': np.std(precision_weighted_list),\n",
|
| 539 |
+
" 'precision_macro_mean': np.mean(precision_macro_list),\n",
|
| 540 |
+
" 'precision_macro_std': np.std(precision_macro_list),\n",
|
| 541 |
+
" 'precision_micro_mean': np.mean(precision_micro_list),\n",
|
| 542 |
+
" 'precision_micro_std': np.std(precision_micro_list),\n",
|
| 543 |
+
" 'recall_weighted_mean': np.mean(recall_weighted_list),\n",
|
| 544 |
+
" 'recall_weighted_std': np.std(recall_weighted_list),\n",
|
| 545 |
+
" 'recall_macro_mean': np.mean(recall_macro_list),\n",
|
| 546 |
+
" 'recall_macro_std': np.std(recall_macro_list),\n",
|
| 547 |
+
" 'recall_micro_mean': np.mean(recall_micro_list),\n",
|
| 548 |
+
" 'recall_micro_std': np.std(recall_micro_list),\n",
|
| 549 |
+
" 'accuracy_mean': np.mean(accuracy_list),\n",
|
| 550 |
+
" 'accuracy_std': np.std(accuracy_list)\n",
|
| 551 |
+
" }\n",
|
| 552 |
+
" \n",
|
| 553 |
+
" return param_combination, results, all_histories\n",
|
| 554 |
+
"\n",
|
| 555 |
+
"params_grid = {\n",
|
| 556 |
+
" 'num_ex_neuron': [0],\n",
|
| 557 |
+
" 'layer_one': [64],\n",
|
| 558 |
+
" 'activation_function_one': ['relu'],\n",
|
| 559 |
+
" 'activation_function_two': ['sigmoid'],\n",
|
| 560 |
+
" 'activation_function_three': ['tanh'],\n",
|
| 561 |
+
" 'dropout_p': [0.3],\n",
|
| 562 |
+
" 'learning_rate': [0.01],\n",
|
| 563 |
+
" 'l2_reg': [0.01],\n",
|
| 564 |
+
" 'epoch': [200],\n",
|
| 565 |
+
" 'batch_size':[16],\n",
|
| 566 |
+
" 'optimizer': ['sgd']\n",
|
| 567 |
+
" }\n",
|
| 568 |
+
"\n",
|
| 569 |
+
"\n",
|
| 570 |
+
"param_combinations = list(itertools.product(\n",
|
| 571 |
+
" params_grid['num_ex_neuron'],\n",
|
| 572 |
+
" params_grid['layer_one'],\n",
|
| 573 |
+
" params_grid['activation_function_one'],\n",
|
| 574 |
+
" params_grid['activation_function_two'],\n",
|
| 575 |
+
" params_grid['activation_function_three'],\n",
|
| 576 |
+
" params_grid['dropout_p'],\n",
|
| 577 |
+
" params_grid['learning_rate'],\n",
|
| 578 |
+
" params_grid['l2_reg'],\n",
|
| 579 |
+
" params_grid['epoch'],\n",
|
| 580 |
+
" params_grid['batch_size'],\n",
|
| 581 |
+
" params_grid['optimizer']\n",
|
| 582 |
+
" \n",
|
| 583 |
+
"))\n",
|
| 584 |
+
"\n",
|
| 585 |
+
"\n",
|
| 586 |
+
"param_dicts = []\n",
|
| 587 |
+
"for comb in param_combinations:\n",
|
| 588 |
+
" param_dicts.append({\n",
|
| 589 |
+
" 'num_ex_neuron': comb[0],\n",
|
| 590 |
+
" 'layer_one': comb[1],\n",
|
| 591 |
+
" 'activation_function_one': comb[2],\n",
|
| 592 |
+
" 'activation_function_two': comb[3],\n",
|
| 593 |
+
" 'activation_function_three': comb[4],\n",
|
| 594 |
+
" 'dropout_p': comb[5],\n",
|
| 595 |
+
" 'learning_rate': comb[6],\n",
|
| 596 |
+
" 'l2_reg': comb[7],\n",
|
| 597 |
+
" 'epoch': comb[8],\n",
|
| 598 |
+
" 'batch_size': comb[9],\n",
|
| 599 |
+
" 'optimizer': comb[10]\n",
|
| 600 |
+
" })\n",
|
| 601 |
+
"\n",
|
| 602 |
+
"\n",
|
| 603 |
+
"X_gene_train, X_gene_test, X_dna_train, X_dna_test, y_train, y_test = train_test_split(df_gene, df_dna, y, test_size=0.2, stratify=y, random_state=42)\n",
|
| 604 |
+
"scaler = StandardScaler()\n",
|
| 605 |
+
"X_gene_train=(np.array(X_gene_train).astype(np.float32))\n",
|
| 606 |
+
"scaler.fit(X_gene_train)\n",
|
| 607 |
+
"X_gene_train=scaler.transform(X_gene_train)\n",
|
| 608 |
+
"\n",
|
| 609 |
+
"X_gene_test=(np.array(X_gene_test).astype(np.float32))\n",
|
| 610 |
+
"scaler.fit(X_gene_test)\n",
|
| 611 |
+
"X_gene_test=scaler.transform(X_gene_test)\n",
|
| 612 |
+
"\n",
|
| 613 |
+
"X_dna_train=(np.array(X_dna_train).astype(np.float32))\n",
|
| 614 |
+
"scaler.fit(X_dna_train)\n",
|
| 615 |
+
"X_dna_train=scaler.transform(X_dna_train)\n",
|
| 616 |
+
"\n",
|
| 617 |
+
"X_dna_test=(np.array(X_dna_test).astype(np.float32))\n",
|
| 618 |
+
"scaler.fit(X_dna_test)\n",
|
| 619 |
+
"X_dna_test=scaler.transform(X_dna_test)\n",
|
| 620 |
+
"\n",
|
| 621 |
+
"\n",
|
| 622 |
+
"with tqdm_joblib(\n",
|
| 623 |
+
" tqdm(desc=\"Evaluating hyperparameter combinations\",\n",
|
| 624 |
+
" total=len(param_dicts))\n",
|
| 625 |
+
" ) as progress_bar:\n",
|
| 626 |
+
" results = Parallel(n_jobs=-1)(\n",
|
| 627 |
+
" delayed(evaluate_combination)(\n",
|
| 628 |
+
" param, X_gene_train, X_dna_train, y_train, n_splits=5\n",
|
| 629 |
+
" )\n",
|
| 630 |
+
" for param in param_dicts\n",
|
| 631 |
+
" )\n",
|
| 632 |
+
"\n",
|
| 633 |
+
"results_list = []\n",
|
| 634 |
+
"histories_dict = {}\n",
|
| 635 |
+
"best_param_weighted = None\n",
|
| 636 |
+
"best_weighted_scores = None\n",
|
| 637 |
+
"best_avg_f1_weighted = -np.inf\n",
|
| 638 |
+
"\n",
|
| 639 |
+
"best_param_macro = None\n",
|
| 640 |
+
"best_macro_scores = None\n",
|
| 641 |
+
"best_avg_f1_macro = -np.inf\n",
|
| 642 |
+
"\n",
|
| 643 |
+
"best_param_micro = None\n",
|
| 644 |
+
"best_micro_scores = None\n",
|
| 645 |
+
"best_avg_f1_micro = -np.inf\n",
|
| 646 |
+
"\n",
|
| 647 |
+
"for param_dict, scores_dict, histories in results:\n",
|
| 648 |
+
" key = str(param_dict)\n",
|
| 649 |
+
" histories_dict[key] = histories\n",
|
| 650 |
+
"\n",
|
| 651 |
+
" row = {}\n",
|
| 652 |
+
" row.update(param_dict)\n",
|
| 653 |
+
" row.update(scores_dict)\n",
|
| 654 |
+
" results_list.append(row)\n",
|
| 655 |
+
"\n",
|
| 656 |
+
" if scores_dict['f1_weighted_mean'] > best_avg_f1_weighted:\n",
|
| 657 |
+
" best_avg_f1_weighted = scores_dict['f1_weighted_mean']\n",
|
| 658 |
+
" best_param_weighted = param_dict\n",
|
| 659 |
+
" best_weighted_scores = scores_dict\n",
|
| 660 |
+
"\n",
|
| 661 |
+
" if scores_dict['f1_macro_mean'] > best_avg_f1_macro:\n",
|
| 662 |
+
" best_avg_f1_macro = scores_dict['f1_macro_mean']\n",
|
| 663 |
+
" best_param_macro = param_dict\n",
|
| 664 |
+
" best_macro_scores = scores_dict\n",
|
| 665 |
+
"\n",
|
| 666 |
+
" if scores_dict['f1_micro_mean'] > best_avg_f1_micro:\n",
|
| 667 |
+
" best_avg_f1_micro = scores_dict['f1_micro_mean']\n",
|
| 668 |
+
" best_param_micro = param_dict\n",
|
| 669 |
+
" best_micro_scores = scores_dict\n",
|
| 670 |
+
"\n",
|
| 671 |
+
"results_df = pd.DataFrame(results_list)\n",
|
| 672 |
+
"best_key = str(best_param_macro)\n",
|
| 673 |
+
"best_histories = histories_dict[best_key] \n",
|
| 674 |
+
"\n",
|
| 675 |
+
"\n",
|
| 676 |
+
"hyperparam_cols = list(param_dict.keys())\n",
|
| 677 |
+
"\n",
|
| 678 |
+
"\n",
|
| 679 |
+
"weighted_cols = hyperparam_cols + ['f1_weighted_mean', 'f1_weighted_std',\n",
|
| 680 |
+
" 'precision_weighted_mean', 'precision_weighted_std',\n",
|
| 681 |
+
" 'recall_weighted_mean', 'recall_weighted_std',\n",
|
| 682 |
+
" 'accuracy_mean', 'accuracy_std']\n",
|
| 683 |
+
"results_df_weighted = results_df[weighted_cols]\n",
|
| 684 |
+
"\n",
|
| 685 |
+
"macro_cols = hyperparam_cols + ['f1_macro_mean', 'f1_macro_std',\n",
|
| 686 |
+
" 'precision_macro_mean', 'precision_macro_std',\n",
|
| 687 |
+
" 'recall_macro_mean', 'recall_macro_std',\n",
|
| 688 |
+
" 'accuracy_mean', 'accuracy_std']\n",
|
| 689 |
+
"results_df_macro = results_df[macro_cols]\n",
|
| 690 |
+
"\n",
|
| 691 |
+
"micro_cols = hyperparam_cols + ['f1_micro_mean', 'f1_micro_std',\n",
|
| 692 |
+
" 'precision_micro_mean', 'precision_micro_std',\n",
|
| 693 |
+
" 'recall_micro_mean', 'recall_micro_std',\n",
|
| 694 |
+
" 'accuracy_mean', 'accuracy_std']\n",
|
| 695 |
+
"results_df_micro = results_df[micro_cols]"
|
| 696 |
+
]
|
| 697 |
+
},
|
| 698 |
+
{
|
| 699 |
+
"cell_type": "code",
|
| 700 |
+
"execution_count": null,
|
| 701 |
+
"id": "2576c647-0fa9-44ff-b26b-b152a8f96389",
|
| 702 |
+
"metadata": {},
|
| 703 |
+
"outputs": [],
|
| 704 |
+
"source": [
|
| 705 |
+
"def create_model_test(\n",
|
| 706 |
+
" num_ex_neuron,\n",
|
| 707 |
+
" layer_one,\n",
|
| 708 |
+
" activation_function_one,\n",
|
| 709 |
+
" activation_function_two,\n",
|
| 710 |
+
" activation_function_three,\n",
|
| 711 |
+
" dropout_p,\n",
|
| 712 |
+
" learning_rate,\n",
|
| 713 |
+
" l2_reg,\n",
|
| 714 |
+
" optimizer_choice\n",
|
| 715 |
+
"):\n",
|
| 716 |
+
"\n",
|
| 717 |
+
" new_ge_mask_matrix = create_ge_mask_matrix(num_ex_neuron) \n",
|
| 718 |
+
" new_dna_mask_matrix = create_dna_mask_matrix(num_ex_neuron) \n",
|
| 719 |
+
"\n",
|
| 720 |
+
" inputA = Input(shape=(df_gene.shape[1],), name=\"gene_input\") \n",
|
| 721 |
+
" inputB = Input(shape=(df_dna.shape[1],), name=\"dna_input\") \n",
|
| 722 |
+
"\n",
|
| 723 |
+
" x1 = layers.Dense(\n",
|
| 724 |
+
" new_ge_mask_matrix.shape[0], \n",
|
| 725 |
+
" kernel_initializer=LecunUniform(seed=42),\n",
|
| 726 |
+
" activation=activation_function_one,\n",
|
| 727 |
+
" kernel_regularizer=l2(l2_reg)\n",
|
| 728 |
+
" )(inputA) \n",
|
| 729 |
+
"\n",
|
| 730 |
+
"\n",
|
| 731 |
+
" x1_masked = MaskedLayer(new_ge_mask_matrix)(x1) \n",
|
| 732 |
+
" x1_masked = Dropout(dropout_p)(x1_masked) \n",
|
| 733 |
+
"\n",
|
| 734 |
+
" x1_feat = layers.Lambda(lambda t: K.expand_dims(t, -1), name=\"gene_add_dim\")(x1_masked)\n",
|
| 735 |
+
"\n",
|
| 736 |
+
" gene_path_layer = AttentionPathwayLayer(\n",
|
| 737 |
+
" genept_embs = genept_gene_emb, \n",
|
| 738 |
+
" pathway_mask = mask_gene_pathway, \n",
|
| 739 |
+
" name = \"gene_path_attn\"\n",
|
| 740 |
+
" )\n",
|
| 741 |
+
" x1_path = gene_path_layer(x1_feat) \n",
|
| 742 |
+
"\n",
|
| 743 |
+
" x1_path = Flatten(name=\"gene_flat_path\")(x1_path) \n",
|
| 744 |
+
"\n",
|
| 745 |
+
" x1_proj = layers.Dense(\n",
|
| 746 |
+
" layer_one,\n",
|
| 747 |
+
" kernel_initializer=LecunUniform(seed=42),\n",
|
| 748 |
+
" activation=activation_function_two,\n",
|
| 749 |
+
" kernel_regularizer=l2(l2_reg),\n",
|
| 750 |
+
" name=\"gene_proj\"\n",
|
| 751 |
+
" )(x1_path) \n",
|
| 752 |
+
"\n",
|
| 753 |
+
" y1 = layers.Dense(\n",
|
| 754 |
+
" new_dna_mask_matrix.shape[0], \n",
|
| 755 |
+
" kernel_initializer=LecunUniform(seed=42),\n",
|
| 756 |
+
" activation=activation_function_one,\n",
|
| 757 |
+
" kernel_regularizer=l2(l2_reg)\n",
|
| 758 |
+
" )(inputB) \n",
|
| 759 |
+
"\n",
|
| 760 |
+
" y1_masked = MaskedLayer(new_dna_mask_matrix)(y1) \n",
|
| 761 |
+
" y1_masked = Dropout(dropout_p)(y1_masked) \n",
|
| 762 |
+
"\n",
|
| 763 |
+
" y1_feat = layers.Lambda(lambda t: K.expand_dims(t, -1), name=\"dna_add_dim\")(y1_masked)\n",
|
| 764 |
+
"\n",
|
| 765 |
+
" dna_path_layer = AttentionPathwayLayer(\n",
|
| 766 |
+
" genept_embs = genept_dna_emb, \n",
|
| 767 |
+
" pathway_mask = mask_dna_pathway, \n",
|
| 768 |
+
" name = \"dna_path_attn\"\n",
|
| 769 |
+
" )\n",
|
| 770 |
+
" y1_path = dna_path_layer(y1_feat) \n",
|
| 771 |
+
" y1_path = Flatten(name=\"dna_flat_path\")(y1_path) \n",
|
| 772 |
+
"\n",
|
| 773 |
+
" y1_proj = layers.Dense(\n",
|
| 774 |
+
" layer_one,\n",
|
| 775 |
+
" kernel_initializer=LecunUniform(seed=42),\n",
|
| 776 |
+
" activation=activation_function_two,\n",
|
| 777 |
+
" kernel_regularizer=l2(l2_reg),\n",
|
| 778 |
+
" name=\"dna_proj\"\n",
|
| 779 |
+
" )(y1_path) \n",
|
| 780 |
+
"\n",
|
| 781 |
+
" merged = concatenate([x1_proj, y1_proj], name=\"merge_xy\") \n",
|
| 782 |
+
"\n",
|
| 783 |
+
" h = layers.Dense(\n",
|
| 784 |
+
" 12,\n",
|
| 785 |
+
" activation=activation_function_three,\n",
|
| 786 |
+
" kernel_initializer=GlorotUniform(seed=42),\n",
|
| 787 |
+
" kernel_regularizer=l2(l2_reg),\n",
|
| 788 |
+
" name=\"fusion_dense\"\n",
|
| 789 |
+
" )(merged) \n",
|
| 790 |
+
" h = Dropout(dropout_p, name=\"drop_fusion\")(h) \n",
|
| 791 |
+
"\n",
|
| 792 |
+
" outputs = layers.Dense(\n",
|
| 793 |
+
" 4,\n",
|
| 794 |
+
" activation=\"softmax\",\n",
|
| 795 |
+
" kernel_initializer=GlorotUniform(seed=42),\n",
|
| 796 |
+
" kernel_regularizer=l2(l2_reg),\n",
|
| 797 |
+
" name=\"output\"\n",
|
| 798 |
+
" )(h) \n",
|
| 799 |
+
"\n",
|
| 800 |
+
" model = Model(inputs=[inputA, inputB], outputs=outputs, name=\"PathwayModel_Test\")\n",
|
| 801 |
+
"\n",
|
| 802 |
+
" if optimizer_choice == 'adam':\n",
|
| 803 |
+
" optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)\n",
|
| 804 |
+
" else:\n",
|
| 805 |
+
" optimizer = tf.keras.optimizers.SGD(learning_rate=learning_rate)\n",
|
| 806 |
+
"\n",
|
| 807 |
+
" model.compile(\n",
|
| 808 |
+
" optimizer=optimizer,\n",
|
| 809 |
+
" loss='sparse_categorical_crossentropy',\n",
|
| 810 |
+
" metrics=['accuracy']\n",
|
| 811 |
+
" )\n",
|
| 812 |
+
" return model"
|
| 813 |
+
]
|
| 814 |
+
},
|
| 815 |
+
{
|
| 816 |
+
"cell_type": "code",
|
| 817 |
+
"execution_count": null,
|
| 818 |
+
"id": "fcda02d6-b3bd-4028-ba48-b0095d80245a",
|
| 819 |
+
"metadata": {},
|
| 820 |
+
"outputs": [],
|
| 821 |
+
"source": [
|
| 822 |
+
"def _run_once(run_i,\n",
|
| 823 |
+
" best_param,\n",
|
| 824 |
+
" class_weight,\n",
|
| 825 |
+
" avg_type,\n",
|
| 826 |
+
" X_gene_train, X_dna_train, y_train,\n",
|
| 827 |
+
" X_gene_test, X_dna_test, y_test,\n",
|
| 828 |
+
" genept_gene_emb, mask_gene_pathway,\n",
|
| 829 |
+
" genept_dna_emb, mask_dna_pathway):\n",
|
| 830 |
+
" model = create_model(\n",
|
| 831 |
+
" best_param['num_ex_neuron'],\n",
|
| 832 |
+
" best_param['layer_one'],\n",
|
| 833 |
+
" best_param['activation_function_one'],\n",
|
| 834 |
+
" best_param['activation_function_two'],\n",
|
| 835 |
+
" best_param['activation_function_three'],\n",
|
| 836 |
+
" best_param['dropout_p'],\n",
|
| 837 |
+
" best_param['learning_rate'],\n",
|
| 838 |
+
" best_param['l2_reg'],\n",
|
| 839 |
+
" best_param['optimizer'],\n",
|
| 840 |
+
" genept_gene_emb, mask_gene_pathway,\n",
|
| 841 |
+
" genept_dna_emb, mask_dna_pathway\n",
|
| 842 |
+
" )\n",
|
| 843 |
+
"\n",
|
| 844 |
+
" model.fit(\n",
|
| 845 |
+
" [X_gene_train, X_dna_train], y_train,\n",
|
| 846 |
+
" epochs=best_param['epoch'],\n",
|
| 847 |
+
" batch_size=best_param['batch_size'],\n",
|
| 848 |
+
" shuffle=False,\n",
|
| 849 |
+
" verbose=0,\n",
|
| 850 |
+
" class_weight=class_weight\n",
|
| 851 |
+
" )\n",
|
| 852 |
+
" \n",
|
| 853 |
+
" y_pred = model.predict([X_gene_test, X_dna_test]).argmax(axis=1)\n",
|
| 854 |
+
" return {\n",
|
| 855 |
+
" 'run_idx': run_i,\n",
|
| 856 |
+
" f'f1_{avg_type}': f1_score(y_test, y_pred, average=avg_type),\n",
|
| 857 |
+
" f'precision_{avg_type}': precision_score(y_test, y_pred, average=avg_type),\n",
|
| 858 |
+
" f'recall_{avg_type}': recall_score(y_test, y_pred, average=avg_type),\n",
|
| 859 |
+
" 'accuracy': accuracy_score(y_test, y_pred)\n",
|
| 860 |
+
" }\n",
|
| 861 |
+
"\n",
|
| 862 |
+
"def evaluate_test_model(best_param, avg_type, n_runs=10, save_csv_path=None):\n",
|
| 863 |
+
" \n",
|
| 864 |
+
" classes = np.unique(y_train)\n",
|
| 865 |
+
" weights = compute_class_weight('balanced', classes=classes, y=y_train)\n",
|
| 866 |
+
" class_weight = dict(zip(classes, weights))\n",
|
| 867 |
+
"\n",
|
| 868 |
+
" per_run_results = Parallel(\n",
|
| 869 |
+
" n_jobs=n_runs,\n",
|
| 870 |
+
" backend='multiprocessing'\n",
|
| 871 |
+
" )(\n",
|
| 872 |
+
" delayed(_run_once)(\n",
|
| 873 |
+
" run_i,\n",
|
| 874 |
+
" best_param,\n",
|
| 875 |
+
" class_weight,\n",
|
| 876 |
+
" avg_type,\n",
|
| 877 |
+
" X_gene_train, X_dna_train, y_train,\n",
|
| 878 |
+
" X_gene_test, X_dna_test, y_test,\n",
|
| 879 |
+
" genept_gene_emb, mask_gene_pathway,\n",
|
| 880 |
+
" genept_dna_emb, mask_dna_pathway\n",
|
| 881 |
+
" )\n",
|
| 882 |
+
" for run_i in range(1, n_runs+1)\n",
|
| 883 |
+
" )\n",
|
| 884 |
+
"\n",
|
| 885 |
+
" df_runs = pd.DataFrame(per_run_results)\n",
|
| 886 |
+
" \n",
|
| 887 |
+
" summary = {\n",
|
| 888 |
+
" f'f1_{avg_type}_mean': df_runs[f'f1_{avg_type}'].mean(),\n",
|
| 889 |
+
" f'f1_{avg_type}_std': df_runs[f'f1_{avg_type}'].std(),\n",
|
| 890 |
+
" f'precision_{avg_type}_mean': df_runs[f'precision_{avg_type}'].mean(),\n",
|
| 891 |
+
" f'precision_{avg_type}_std': df_runs[f'precision_{avg_type}'].std(),\n",
|
| 892 |
+
" f'recall_{avg_type}_mean': df_runs[f'recall_{avg_type}'].mean(),\n",
|
| 893 |
+
" f'recall_{avg_type}_std': df_runs[f'recall_{avg_type}'].std(),\n",
|
| 894 |
+
" 'accuracy_mean': df_runs['accuracy'].mean(),\n",
|
| 895 |
+
" 'accuracy_std': df_runs['accuracy'].std()\n",
|
| 896 |
+
" }\n",
|
| 897 |
+
"\n",
|
| 898 |
+
" if save_csv_path:\n",
|
| 899 |
+
" df_runs.to_csv(save_csv_path, index=False)\n",
|
| 900 |
+
"\n",
|
| 901 |
+
" return summary, df_runs\n",
|
| 902 |
+
"\n",
|
| 903 |
+
"\n",
|
| 904 |
+
"summary_macro, df_macro_runs = evaluate_test_model(\n",
|
| 905 |
+
" best_param_macro,\n",
|
| 906 |
+
" avg_type=\"macro\"\n",
|
| 907 |
+
")\n",
|
| 908 |
+
"summary_weighted, df_weighted_runs = evaluate_test_model(\n",
|
| 909 |
+
" best_param_weighted,\n",
|
| 910 |
+
" avg_type=\"weighted\"\n",
|
| 911 |
+
")\n",
|
| 912 |
+
"summary_micro, df_micro_runs = evaluate_test_model(\n",
|
| 913 |
+
" best_param_micro,\n",
|
| 914 |
+
" avg_type=\"micro\"\n",
|
| 915 |
+
")\n"
|
| 916 |
+
]
|
| 917 |
+
}
|
| 918 |
+
],
|
| 919 |
+
"metadata": {
|
| 920 |
+
"kernelspec": {
|
| 921 |
+
"display_name": "colo2",
|
| 922 |
+
"language": "python",
|
| 923 |
+
"name": "colo2"
|
| 924 |
+
},
|
| 925 |
+
"language_info": {
|
| 926 |
+
"codemirror_mode": {
|
| 927 |
+
"name": "ipython",
|
| 928 |
+
"version": 3
|
| 929 |
+
},
|
| 930 |
+
"file_extension": ".py",
|
| 931 |
+
"mimetype": "text/x-python",
|
| 932 |
+
"name": "python",
|
| 933 |
+
"nbconvert_exporter": "python",
|
| 934 |
+
"pygments_lexer": "ipython3",
|
| 935 |
+
"version": "3.9.18"
|
| 936 |
+
}
|
| 937 |
+
},
|
| 938 |
+
"nbformat": 4,
|
| 939 |
+
"nbformat_minor": 5
|
| 940 |
+
}
|
diagnostics/2026-10-30-lab-hyperparameter-grid/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Lab hyperparameter grid on BRCA (2026-10-30)
|
| 2 |
+
|
| 3 |
+
These runs test the hyperparameter grid Jubair Rifat suggested on 2026-10-17 (lr 0.01, L2 0.01, dropout 0.3, 200 epochs, SGD with momentum 0.03 or Adam, layer_one 64/128, batch 16/32, activations relu/sigmoid/tanh, single-cell GenePT file). The Workbench's own `train()` was used unchanged.
|
| 4 |
+
|
| 5 |
+
## Result
|
| 6 |
+
|
| 7 |
+
- Of 216 configurations, 185 collapsed to a single class.
|
| 8 |
+
- All 108 SGD configurations failed (106 collapsed), and none with a sigmoid activation worked.
|
| 9 |
+
- The 5 best configurations were re-run on 8 seeds. Configuration **D** (Adam, batch 32, projection 64, tanh/relu/tanh) was the most stable, with macro F1 0.749 ± 0.018 and no collapses. It is now the Workbench default.
|
| 10 |
+
- `num_ex_neuron` (extra hidden neurons) isn't supported by the Workbench and was fixed at 0.
|
| 11 |
+
- Only BRCA has been tested.
|
| 12 |
+
|
| 13 |
+
## Files
|
| 14 |
+
|
| 15 |
+
- `scripts/build_workspaces.py <cache_dir>`: builds the BRCA workspace with the bulk and single-cell GenePT files.
|
| 16 |
+
- `scripts/grid.py <workspace.pkl> <out.jsonl> <shard> <n_shards>`: runs the grid; it is resumable.
|
| 17 |
+
- `scripts/grid_summary.py <grid.jsonl>`: summarises a grid run.
|
| 18 |
+
- `scripts/seed_check.py <workspace.pkl> <out.jsonl> <shard> <n_shards>`: runs the 8-seed check of the top configurations against the 2026-10-16 baseline.
|
| 19 |
+
- `results/grid_singlecell_seed42.jsonl` and `results/grid_summary.txt`: grid results, seed 42.
|
| 20 |
+
- `results/seed_check_singlecell.jsonl` and `results/seed_check_summary.txt`: 8-seed results.
|
| 21 |
+
|
| 22 |
+
Run the scripts from the repository root with `PYTHONPATH=$PWD .venv/bin/python ...`.
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_shard0.log
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[0] 0 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 2 |
+
[0] 4 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 3 |
+
[0] 8 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 4 |
+
[0] 12 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 5 |
+
[0] 16 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 6 |
+
[0] 20 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 7 |
+
[0] 24 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 8 |
+
[0] 28 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 9 |
+
[0] 32 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 10 |
+
[0] 36 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 11 |
+
[0] 40 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 12 |
+
[0] 44 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 13 |
+
[0] 48 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 14 |
+
[0] 52 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 15 |
+
[0] 56 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 16 |
+
[0] 60 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 17 |
+
[0] 64 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 18 |
+
[0] 68 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 19 |
+
[0] 72 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 20 |
+
[0] 76 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 21 |
+
[0] 80 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 22 |
+
[0] 84 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 23 |
+
[0] 88 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 24 |
+
[0] 92 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 25 |
+
[0] 96 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 26 |
+
[0] 100 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 27 |
+
[0] 104 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 28 |
+
[0] 108 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 29 |
+
[0] 112 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 30 |
+
[0] 116 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 31 |
+
[0] 120 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 32 |
+
[0] 124 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 33 |
+
[0] 128 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 34 |
+
[0] 132 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 35 |
+
[0] 136 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 36 |
+
[0] 140 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 37 |
+
[0] 144 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 38 |
+
[0] 148 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 39 |
+
[0] 152 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 40 |
+
[0] 156 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 41 |
+
[0] 160 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 42 |
+
[0] 164 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 43 |
+
[0] 168 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 44 |
+
[0] 172 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 45 |
+
[0] 176 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 46 |
+
[0] 180 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 47 |
+
[0] 184 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 48 |
+
[0] 188 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 49 |
+
[0] 192 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 50 |
+
[0] 196 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 51 |
+
[0] 200 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 52 |
+
[0] 204 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 53 |
+
[0] 208 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 54 |
+
[0] 212 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 55 |
+
SHARD 0 DONE
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_shard1.log
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[1] 1 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.403 classes=4
|
| 2 |
+
[1] 5 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 3 |
+
[1] 9 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.442 classes=3
|
| 4 |
+
[1] 13 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 5 |
+
[1] 17 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 6 |
+
[1] 21 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 7 |
+
[1] 25 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.690 classes=5
|
| 8 |
+
[1] 29 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 9 |
+
[1] 33 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.657 classes=5
|
| 10 |
+
[1] 37 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 11 |
+
[1] 41 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 12 |
+
[1] 45 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 13 |
+
[1] 49 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 14 |
+
[1] 53 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 15 |
+
[1] 57 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 16 |
+
[1] 61 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 17 |
+
[1] 65 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 18 |
+
[1] 69 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 19 |
+
[1] 73 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.723 classes=5
|
| 20 |
+
[1] 77 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.545 classes=4
|
| 21 |
+
[1] 81 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.741 classes=5
|
| 22 |
+
[1] 85 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 23 |
+
[1] 89 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 24 |
+
[1] 93 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 25 |
+
[1] 97 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.733 classes=5
|
| 26 |
+
[1] 101 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.411 classes=3
|
| 27 |
+
[1] 105 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.752 classes=5
|
| 28 |
+
[1] 109 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 29 |
+
[1] 113 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 30 |
+
[1] 117 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.789 classes=5
|
| 31 |
+
[1] 121 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 32 |
+
[1] 125 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 33 |
+
[1] 129 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 34 |
+
[1] 133 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 35 |
+
[1] 137 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 36 |
+
[1] 141 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.701 classes=5
|
| 37 |
+
[1] 145 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 38 |
+
[1] 149 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 39 |
+
[1] 153 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 40 |
+
[1] 157 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 41 |
+
[1] 161 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 42 |
+
[1] 165 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 43 |
+
[1] 169 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 44 |
+
[1] 173 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 45 |
+
[1] 177 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 46 |
+
[1] 181 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.728 classes=5
|
| 47 |
+
[1] 185 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 48 |
+
[1] 189 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.727 classes=5
|
| 49 |
+
[1] 193 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 50 |
+
[1] 197 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 51 |
+
[1] 201 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 52 |
+
[1] 205 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.712 classes=5
|
| 53 |
+
[1] 209 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.400 classes=3
|
| 54 |
+
[1] 213 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 16, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.733 classes=5
|
| 55 |
+
SHARD 1 DONE
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_shard2.log
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[2] 2 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 2 |
+
[2] 6 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 3 |
+
[2] 10 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 4 |
+
[2] 14 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 5 |
+
[2] 18 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 6 |
+
[2] 22 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 7 |
+
[2] 26 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 8 |
+
[2] 30 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 9 |
+
[2] 34 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 10 |
+
[2] 38 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 11 |
+
[2] 42 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 12 |
+
[2] 46 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 13 |
+
[2] 50 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 14 |
+
[2] 54 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 15 |
+
[2] 58 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 16 |
+
[2] 62 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 17 |
+
[2] 66 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 18 |
+
[2] 70 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 19 |
+
[2] 74 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 20 |
+
[2] 78 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 21 |
+
[2] 82 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 22 |
+
[2] 86 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 23 |
+
[2] 90 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 24 |
+
[2] 94 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 25 |
+
[2] 98 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 26 |
+
[2] 102 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 27 |
+
[2] 106 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.047 classes=1
|
| 28 |
+
[2] 110 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 29 |
+
[2] 114 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 30 |
+
[2] 118 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 31 |
+
[2] 122 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 32 |
+
[2] 126 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 33 |
+
[2] 130 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 34 |
+
[2] 134 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 35 |
+
[2] 138 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 36 |
+
[2] 142 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 37 |
+
[2] 146 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 38 |
+
[2] 150 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 39 |
+
[2] 154 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 40 |
+
[2] 158 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 41 |
+
[2] 162 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 42 |
+
[2] 166 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 43 |
+
[2] 170 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 44 |
+
[2] 174 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 45 |
+
[2] 178 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 46 |
+
[2] 182 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=2
|
| 47 |
+
[2] 186 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 48 |
+
[2] 190 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 49 |
+
[2] 194 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 50 |
+
[2] 198 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 51 |
+
[2] 202 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 52 |
+
[2] 206 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=2
|
| 53 |
+
[2] 210 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.133 classes=1
|
| 54 |
+
[2] 214 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'SGD', 'seed': 42} -> f1m=0.058 classes=1
|
| 55 |
+
SHARD 2 DONE
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_shard3.log
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[3] 3 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 2 |
+
[3] 7 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 3 |
+
[3] 11 {'projection_dim': 64, 'act1': 'relu', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.737 classes=5
|
| 4 |
+
[3] 15 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 5 |
+
[3] 19 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.052 classes=1
|
| 6 |
+
[3] 23 {'projection_dim': 64, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 7 |
+
[3] 27 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 8 |
+
[3] 31 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 9 |
+
[3] 35 {'projection_dim': 64, 'act1': 'relu', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.713 classes=5
|
| 10 |
+
[3] 39 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.052 classes=1
|
| 11 |
+
[3] 43 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 12 |
+
[3] 47 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 13 |
+
[3] 51 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 14 |
+
[3] 55 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 15 |
+
[3] 59 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.052 classes=1
|
| 16 |
+
[3] 63 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 17 |
+
[3] 67 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 18 |
+
[3] 71 {'projection_dim': 64, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 19 |
+
[3] 75 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 20 |
+
[3] 79 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 21 |
+
[3] 83 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.778 classes=5
|
| 22 |
+
[3] 87 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 23 |
+
[3] 91 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.052 classes=1
|
| 24 |
+
[3] 95 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 25 |
+
[3] 99 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.789 classes=5
|
| 26 |
+
[3] 103 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 27 |
+
[3] 107 {'projection_dim': 64, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.757 classes=5
|
| 28 |
+
[3] 111 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 29 |
+
[3] 115 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.047 classes=1
|
| 30 |
+
[3] 119 {'projection_dim': 128, 'act1': 'relu', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.756 classes=5
|
| 31 |
+
[3] 123 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 32 |
+
[3] 127 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 33 |
+
[3] 131 {'projection_dim': 128, 'act1': 'relu', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 34 |
+
[3] 135 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 35 |
+
[3] 139 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.047 classes=1
|
| 36 |
+
[3] 143 {'projection_dim': 128, 'act1': 'relu', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.691 classes=5
|
| 37 |
+
[3] 147 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 38 |
+
[3] 151 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 39 |
+
[3] 155 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.052 classes=1
|
| 40 |
+
[3] 159 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 41 |
+
[3] 163 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 42 |
+
[3] 167 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.058 classes=1
|
| 43 |
+
[3] 171 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 44 |
+
[3] 175 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.058 classes=1
|
| 45 |
+
[3] 179 {'projection_dim': 128, 'act1': 'sigmoid', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 46 |
+
[3] 183 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.789 classes=5
|
| 47 |
+
[3] 187 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.047 classes=1
|
| 48 |
+
[3] 191 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'relu', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.773 classes=5
|
| 49 |
+
[3] 195 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 50 |
+
[3] 199 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.133 classes=1
|
| 51 |
+
[3] 203 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'sigmoid', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.058 classes=1
|
| 52 |
+
[3] 207 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'relu', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.725 classes=5
|
| 53 |
+
[3] 211 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'sigmoid', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.444 classes=3
|
| 54 |
+
[3] 215 {'projection_dim': 128, 'act1': 'tanh', 'act2': 'tanh', 'act3': 'tanh', 'batch_size': 32, 'optimizer': 'Adam', 'seed': 42} -> f1m=0.696 classes=5
|
| 55 |
+
SHARD 3 DONE
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_singlecell_seed42.jsonl
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/grid_summary.txt
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
configs: 216 collapsed (1 class): 185 all 5 classes predicted: 23 macro F1 >= 0.70: 19
|
| 2 |
+
|
| 3 |
+
TOP 20 by macro F1
|
| 4 |
+
optimizer batch_size projection_dim acts acc f1_macro f1_w min_recall best epochs pred
|
| 5 |
+
Adam 32 64 tanh/tanh/relu 0.795 0.789 0.803 0.622 47 59 52/29/13/93/32
|
| 6 |
+
Adam 16 128 relu/relu/tanh 0.781 0.789 0.790 0.676 42 54 48/30/12/90/39
|
| 7 |
+
Adam 32 128 tanh/relu/relu 0.799 0.789 0.804 0.568 44 56 52/30/11/97/29
|
| 8 |
+
Adam 32 64 tanh/relu/tanh 0.776 0.778 0.785 0.649 56 68 48/31/10/93/37
|
| 9 |
+
Adam 32 128 tanh/relu/tanh 0.781 0.773 0.793 0.730 26 38 49/28/14/88/40
|
| 10 |
+
Adam 32 64 tanh/tanh/tanh 0.776 0.757 0.789 0.703 28 40 51/27/17/88/36
|
| 11 |
+
Adam 32 128 relu/relu/tanh 0.781 0.756 0.786 0.568 24 36 43/29/10/104/33
|
| 12 |
+
Adam 16 64 tanh/tanh/tanh 0.763 0.752 0.768 0.486 8 20 51/29/11/101/27
|
| 13 |
+
Adam 16 64 tanh/relu/tanh 0.758 0.741 0.768 0.595 8 20 50/27/13/96/33
|
| 14 |
+
Adam 32 64 relu/relu/tanh 0.763 0.737 0.773 0.622 24 36 48/29/9/96/37
|
| 15 |
+
Adam 16 64 tanh/tanh/relu 0.749 0.733 0.753 0.459 10 22 50/29/15/100/25
|
| 16 |
+
Adam 16 128 tanh/tanh/tanh 0.753 0.733 0.759 0.541 24 36 44/31/13/100/31
|
| 17 |
+
Adam 16 128 tanh/relu/relu 0.763 0.728 0.760 0.378 13 25 49/29/16/108/17
|
| 18 |
+
Adam 16 128 tanh/relu/tanh 0.767 0.727 0.770 0.486 24 36 52/32/10/104/21
|
| 19 |
+
Adam 32 128 tanh/tanh/relu 0.753 0.725 0.763 0.545 19 31 55/33/9/79/43
|
| 20 |
+
Adam 16 64 tanh/relu/relu 0.749 0.723 0.757 0.568 22 34 44/27/18/98/32
|
| 21 |
+
Adam 32 64 relu/tanh/tanh 0.744 0.713 0.754 0.621 24 36 40/26/12/101/40
|
| 22 |
+
Adam 16 128 tanh/tanh/relu 0.740 0.712 0.737 0.351 11 23 50/30/16/103/20
|
| 23 |
+
Adam 16 128 relu/tanh/tanh 0.731 0.701 0.734 0.486 38 50 38/29/11/110/31
|
| 24 |
+
Adam 32 128 tanh/tanh/tanh 0.726 0.696 0.725 0.351 10 22 53/29/17/100/20
|
| 25 |
+
|
| 26 |
+
BY optimizer
|
| 27 |
+
n f1_mean f1_max collapsed working
|
| 28 |
+
optimizer
|
| 29 |
+
Adam 108 0.270 0.789 79 19
|
| 30 |
+
SGD 108 0.112 0.133 106 0
|
| 31 |
+
|
| 32 |
+
BY batch_size
|
| 33 |
+
n f1_mean f1_max collapsed working
|
| 34 |
+
batch_size
|
| 35 |
+
16 108 0.211 0.789 91 10
|
| 36 |
+
32 108 0.171 0.789 94 9
|
| 37 |
+
|
| 38 |
+
BY projection_dim
|
| 39 |
+
n f1_mean f1_max collapsed working
|
| 40 |
+
projection_dim
|
| 41 |
+
64 108 0.189 0.789 93 9
|
| 42 |
+
128 108 0.192 0.789 92 10
|
| 43 |
+
|
| 44 |
+
BY act1
|
| 45 |
+
n f1_mean f1_max collapsed working
|
| 46 |
+
act1
|
| 47 |
+
relu 72 0.190 0.789 62 5
|
| 48 |
+
sigmoid 72 0.121 0.133 72 0
|
| 49 |
+
tanh 72 0.262 0.789 51 14
|
| 50 |
+
|
| 51 |
+
BY act2
|
| 52 |
+
n f1_mean f1_max collapsed working
|
| 53 |
+
act2
|
| 54 |
+
relu 72 0.216 0.789 58 10
|
| 55 |
+
sigmoid 72 0.118 0.133 72 0
|
| 56 |
+
tanh 72 0.238 0.789 55 9
|
| 57 |
+
|
| 58 |
+
BY act3
|
| 59 |
+
n f1_mean f1_max collapsed working
|
| 60 |
+
act3
|
| 61 |
+
relu 72 0.186 0.789 61 7
|
| 62 |
+
sigmoid 72 0.144 0.545 68 0
|
| 63 |
+
tanh 72 0.242 0.789 56 12
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_check_singlecell.jsonl
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{"config": "A b32 p64 tanh/tanh/relu", "seed": 3, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 3, "biological_activation": "tanh", "projection_activation": "tanh", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.684931506849315, "f1_macro": 0.6444813586786613, "f1_weighted": 0.6749256063279981, "epochs_completed": 19, "best_epoch": 7, "pred_counts": [44, 28, 6, 122, 19], "collapsed": false, "recall": [0.6896551724137931, 0.8181818181818182, 0.5454545454545454, 0.8073394495412844, 0.24324324324324326]}
|
| 2 |
+
{"config": "A b32 p64 tanh/tanh/relu", "seed": 1, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 1, "biological_activation": "tanh", "projection_activation": "tanh", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.726027397260274, "f1_macro": 0.7144281742354031, "f1_weighted": 0.7332409934786565, "epochs_completed": 25, "best_epoch": 13, "pred_counts": [54, 32, 9, 86, 38], "collapsed": false, "recall": [0.9310344827586207, 0.8787878787878788, 0.6363636363636364, 0.6880733944954128, 0.5675675675675675]}
|
| 3 |
+
{"config": "A b32 p64 tanh/tanh/relu", "seed": 2, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2, "biological_activation": "tanh", "projection_activation": "tanh", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7397260273972602, "f1_macro": 0.7138206206911931, "f1_weighted": 0.7466811668840856, "epochs_completed": 28, "best_epoch": 16, "pred_counts": [54, 26, 20, 93, 26], "collapsed": false, "recall": [0.896551724137931, 0.7878787878787878, 1.0, 0.7522935779816514, 0.4594594594594595]}
|
| 4 |
+
{"config": "A b32 p64 tanh/tanh/relu", "seed": 0, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 0, "biological_activation": "tanh", "projection_activation": "tanh", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7488584474885844, "f1_macro": 0.7236842897667166, "f1_weighted": 0.7535285657158763, "epochs_completed": 40, "best_epoch": 28, "pred_counts": [48, 28, 9, 105, 29], "collapsed": false, "recall": [0.8275862068965517, 0.8181818181818182, 0.6363636363636364, 0.7889908256880734, 0.5405405405405406]}
|
| 5 |
+
{"config": "A b32 p64 tanh/tanh/relu", "seed": 2024, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2024, "biological_activation": "tanh", "projection_activation": "tanh", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7808219178082192, "f1_macro": 0.7541439764590951, "f1_weighted": 0.7898422552519037, "epochs_completed": 43, "best_epoch": 31, "pred_counts": [49, 29, 12, 97, 32], "collapsed": false, "recall": [0.8275862068965517, 0.8181818181818182, 0.8181818181818182, 0.8165137614678899, 0.5945945945945946]}
|
| 6 |
+
{"config": "A b32 p64 tanh/tanh/relu", "seed": 123, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 123, "biological_activation": "tanh", "projection_activation": "tanh", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7534246575342466, "f1_macro": 0.7359501479955786, "f1_weighted": 0.7626088247020677, "epochs_completed": 49, "best_epoch": 37, "pred_counts": [51, 29, 12, 90, 37], "collapsed": false, "recall": [0.896551724137931, 0.8787878787878788, 0.7272727272727273, 0.7339449541284404, 0.5945945945945946]}
|
| 7 |
+
{"config": "A b32 p64 tanh/tanh/relu", "seed": 7, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 7, "biological_activation": "tanh", "projection_activation": "tanh", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7671232876712328, "f1_macro": 0.7406338069110205, "f1_weighted": 0.7784375791314946, "epochs_completed": 45, "best_epoch": 33, "pred_counts": [50, 24, 14, 96, 35], "collapsed": false, "recall": [0.8275862068965517, 0.7272727272727273, 0.8181818181818182, 0.7889908256880734, 0.6756756756756757]}
|
| 8 |
+
{"config": "A b32 p64 tanh/tanh/relu", "seed": 42, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 42, "biological_activation": "tanh", "projection_activation": "tanh", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7945205479452054, "f1_macro": 0.78874693921005, "f1_weighted": 0.8026041446389447, "epochs_completed": 59, "best_epoch": 47, "pred_counts": [52, 29, 13, 93, 32], "collapsed": false, "recall": [0.9310344827586207, 0.8787878787878788, 0.9090909090909091, 0.7798165137614679, 0.6216216216216216]}
|
| 9 |
+
{"config": "B b16 p128 relu/relu/tanh", "seed": 3, "hyperparameters": {"epochs": 200, "batch_size": 16, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 3, "biological_activation": "relu", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7168949771689498, "f1_macro": 0.6634952144629563, "f1_weighted": 0.7175294877460144, "epochs_completed": 48, "best_epoch": 36, "pred_counts": [49, 30, 4, 108, 28], "collapsed": false, "recall": [0.7931034482758621, 0.8181818181818182, 0.36363636363636365, 0.7798165137614679, 0.4864864864864865]}
|
| 10 |
+
{"config": "B b16 p128 relu/relu/tanh", "seed": 2, "hyperparameters": {"epochs": 200, "batch_size": 16, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2, "biological_activation": "relu", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.730593607305936, "f1_macro": 0.6682730017572305, "f1_weighted": 0.7194362526214491, "epochs_completed": 38, "best_epoch": 26, "pred_counts": [54, 27, 14, 110, 14], "collapsed": false, "recall": [0.896551724137931, 0.8181818181818182, 0.7272727272727273, 0.8256880733944955, 0.24324324324324326]}
|
| 11 |
+
{"config": "B b16 p128 relu/relu/tanh", "seed": 0, "hyperparameters": {"epochs": 200, "batch_size": 16, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 0, "biological_activation": "relu", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7488584474885844, "f1_macro": 0.7283944490396104, "f1_weighted": 0.7570745621268528, "epochs_completed": 39, "best_epoch": 27, "pred_counts": [52, 29, 9, 101, 28], "collapsed": false, "recall": [0.8275862068965517, 0.8484848484848485, 0.6363636363636364, 0.7706422018348624, 0.5675675675675675]}
|
| 12 |
+
{"config": "B b16 p128 relu/relu/tanh", "seed": 1, "hyperparameters": {"epochs": 200, "batch_size": 16, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 1, "biological_activation": "relu", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7625570776255708, "f1_macro": 0.7017018823470437, "f1_weighted": 0.7589129909059207, "epochs_completed": 49, "best_epoch": 37, "pred_counts": [41, 29, 15, 116, 18], "collapsed": false, "recall": [0.7241379310344828, 0.8484848484848485, 0.7272727272727273, 0.8715596330275229, 0.40540540540540543]}
|
| 13 |
+
{"config": "B b16 p128 relu/relu/tanh", "seed": 2024, "hyperparameters": {"epochs": 200, "batch_size": 16, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2024, "biological_activation": "relu", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7534246575342466, "f1_macro": 0.7013460186286767, "f1_weighted": 0.7603570398639725, "epochs_completed": 35, "best_epoch": 23, "pred_counts": [45, 29, 12, 99, 34], "collapsed": false, "recall": [0.7931034482758621, 0.7878787878787878, 0.6363636363636364, 0.8073394495412844, 0.5675675675675675]}
|
| 14 |
+
{"config": "B b16 p128 relu/relu/tanh", "seed": 7, "hyperparameters": {"epochs": 200, "batch_size": 16, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 7, "biological_activation": "relu", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7808219178082192, "f1_macro": 0.751011131155479, "f1_weighted": 0.7887772320889953, "epochs_completed": 29, "best_epoch": 17, "pred_counts": [50, 28, 8, 105, 28], "collapsed": false, "recall": [0.8275862068965517, 0.7878787878787878, 0.6363636363636364, 0.8348623853211009, 0.6216216216216216]}
|
| 15 |
+
{"config": "B b16 p128 relu/relu/tanh", "seed": 123, "hyperparameters": {"epochs": 200, "batch_size": 16, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 123, "biological_activation": "relu", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7534246575342466, "f1_macro": 0.7071455263854697, "f1_weighted": 0.7550850295543412, "epochs_completed": 34, "best_epoch": 22, "pred_counts": [52, 31, 12, 100, 24], "collapsed": false, "recall": [0.896551724137931, 0.9090909090909091, 0.6363636363636364, 0.7889908256880734, 0.43243243243243246]}
|
| 16 |
+
{"config": "C b32 p128 tanh/relu/relu", "seed": 2, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.4977168949771689, "f1_macro": 0.1329268292682927, "f1_weighted": 0.3307996436128745, "epochs_completed": 23, "best_epoch": 11, "pred_counts": [0, 0, 0, 219, 0], "collapsed": true, "recall": [0.0, 0.0, 0.0, 1.0, 0.0]}
|
| 17 |
+
{"config": "C b32 p128 tanh/relu/relu", "seed": 3, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 3, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7397260273972602, "f1_macro": 0.7148184407361271, "f1_weighted": 0.7493292901128092, "epochs_completed": 42, "best_epoch": 30, "pred_counts": [48, 29, 7, 94, 41], "collapsed": false, "recall": [0.7931034482758621, 0.8181818181818182, 0.5454545454545454, 0.7431192660550459, 0.6756756756756757]}
|
| 18 |
+
{"config": "C b32 p128 tanh/relu/relu", "seed": 0, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 0, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.776255707762557, "f1_macro": 0.7578915715890517, "f1_weighted": 0.7873287183808084, "epochs_completed": 58, "best_epoch": 46, "pred_counts": [54, 29, 9, 91, 36], "collapsed": false, "recall": [0.896551724137931, 0.8484848484848485, 0.6363636363636364, 0.7522935779816514, 0.7297297297297297]}
|
| 19 |
+
{"config": "B b16 p128 relu/relu/tanh", "seed": 42, "hyperparameters": {"epochs": 200, "batch_size": 16, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 42, "biological_activation": "relu", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7808219178082192, "f1_macro": 0.788652381544761, "f1_weighted": 0.7895010559630641, "epochs_completed": 54, "best_epoch": 42, "pred_counts": [48, 30, 12, 90, 39], "collapsed": false, "recall": [0.8620689655172413, 0.9090909090909091, 0.9090909090909091, 0.7431192660550459, 0.6756756756756757]}
|
| 20 |
+
{"config": "C b32 p128 tanh/relu/relu", "seed": 123, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 123, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7853881278538812, "f1_macro": 0.7597321666231736, "f1_weighted": 0.7932886529725107, "epochs_completed": 51, "best_epoch": 39, "pred_counts": [48, 29, 15, 97, 30], "collapsed": false, "recall": [0.8620689655172413, 0.8787878787878788, 0.8181818181818182, 0.7889908256880734, 0.6216216216216216]}
|
| 21 |
+
{"config": "C b32 p128 tanh/relu/relu", "seed": 2024, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2024, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7945205479452054, "f1_macro": 0.7775926070493133, "f1_weighted": 0.8037755930922895, "epochs_completed": 46, "best_epoch": 34, "pred_counts": [45, 29, 10, 100, 35], "collapsed": false, "recall": [0.7586206896551724, 0.8181818181818182, 0.8181818181818182, 0.8348623853211009, 0.6756756756756757]}
|
| 22 |
+
{"config": "C b32 p128 tanh/relu/relu", "seed": 7, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 7, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7168949771689498, "f1_macro": 0.6666606642657062, "f1_weighted": 0.7075349317809315, "epochs_completed": 65, "best_epoch": 53, "pred_counts": [56, 27, 9, 115, 12], "collapsed": false, "recall": [0.8620689655172413, 0.7575757575757576, 0.6363636363636364, 0.8256880733944955, 0.2702702702702703]}
|
| 23 |
+
{"config": "C b32 p128 tanh/relu/relu", "seed": 1, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 1, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.8127853881278538, "f1_macro": 0.8004969316657136, "f1_weighted": 0.8177554227696595, "epochs_completed": 65, "best_epoch": 53, "pred_counts": [50, 31, 9, 98, 31], "collapsed": false, "recall": [0.9655172413793104, 0.9090909090909091, 0.7272727272727273, 0.8073394495412844, 0.6486486486486487]}
|
| 24 |
+
{"config": "D b32 p64 tanh/relu/tanh", "seed": 2, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7899543378995434, "f1_macro": 0.7647661601172038, "f1_weighted": 0.7982709673173486, "epochs_completed": 58, "best_epoch": 46, "pred_counts": [51, 29, 16, 95, 28], "collapsed": false, "recall": [0.896551724137931, 0.8484848484848485, 0.9090909090909091, 0.7981651376146789, 0.5945945945945946]}
|
| 25 |
+
{"config": "D b32 p64 tanh/relu/tanh", "seed": 3, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 3, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7579908675799086, "f1_macro": 0.7450983463384329, "f1_weighted": 0.7676536929640603, "epochs_completed": 59, "best_epoch": 47, "pred_counts": [44, 27, 7, 100, 41], "collapsed": false, "recall": [0.7241379310344828, 0.7878787878787878, 0.6363636363636364, 0.7798165137614679, 0.7297297297297297]}
|
| 26 |
+
{"config": "D b32 p64 tanh/relu/tanh", "seed": 0, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 0, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7579908675799086, "f1_macro": 0.7305752281147861, "f1_weighted": 0.7672308198023153, "epochs_completed": 40, "best_epoch": 28, "pred_counts": [46, 28, 10, 98, 37], "collapsed": false, "recall": [0.7586206896551724, 0.8181818181818182, 0.6363636363636364, 0.7706422018348624, 0.7027027027027027]}
|
| 27 |
+
{"config": "D b32 p64 tanh/relu/tanh", "seed": 2024, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2024, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7534246575342466, "f1_macro": 0.738332484131178, "f1_weighted": 0.7656099462973935, "epochs_completed": 42, "best_epoch": 30, "pred_counts": [52, 28, 10, 93, 36], "collapsed": false, "recall": [0.8275862068965517, 0.8181818181818182, 0.7272727272727273, 0.7614678899082569, 0.6216216216216216]}
|
| 28 |
+
{"config": "C b32 p128 tanh/relu/relu", "seed": 42, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 42, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "relu", "sgd_momentum": 0.0}, "accuracy": 0.7990867579908676, "f1_macro": 0.7885889251585044, "f1_weighted": 0.8040701819868671, "epochs_completed": 56, "best_epoch": 44, "pred_counts": [52, 30, 11, 97, 29], "collapsed": false, "recall": [0.9655172413793104, 0.9090909090909091, 0.8181818181818182, 0.7981651376146789, 0.5675675675675675]}
|
| 29 |
+
{"config": "D b32 p64 tanh/relu/tanh", "seed": 123, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 123, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7808219178082192, "f1_macro": 0.7359225592888959, "f1_weighted": 0.791296097847027, "epochs_completed": 55, "best_epoch": 43, "pred_counts": [55, 33, 10, 93, 28], "collapsed": false, "recall": [0.896551724137931, 0.9090909090909091, 0.5454545454545454, 0.7798165137614679, 0.6486486486486487]}
|
| 30 |
+
{"config": "D b32 p64 tanh/relu/tanh", "seed": 7, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 7, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7534246575342466, "f1_macro": 0.7357654892283638, "f1_weighted": 0.765273263266187, "epochs_completed": 44, "best_epoch": 32, "pred_counts": [50, 24, 13, 96, 36], "collapsed": false, "recall": [0.7931034482758621, 0.7272727272727273, 0.8181818181818182, 0.7706422018348624, 0.6756756756756757]}
|
| 31 |
+
{"config": "E b32 p128 tanh/relu/tanh", "seed": 2, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7808219178082192, "f1_macro": 0.7595667299177735, "f1_weighted": 0.7904695167211089, "epochs_completed": 32, "best_epoch": 20, "pred_counts": [51, 29, 13, 95, 31], "collapsed": false, "recall": [0.8620689655172413, 0.8484848484848485, 0.8181818181818182, 0.7889908256880734, 0.6216216216216216]}
|
| 32 |
+
{"config": "E b32 p128 tanh/relu/tanh", "seed": 3, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 3, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7123287671232876, "f1_macro": 0.7019184281569603, "f1_weighted": 0.7172640652092707, "epochs_completed": 47, "best_epoch": 35, "pred_counts": [48, 27, 7, 109, 28], "collapsed": false, "recall": [0.7586206896551724, 0.7878787878787878, 0.6363636363636364, 0.7706422018348624, 0.4594594594594595]}
|
| 33 |
+
{"config": "D b32 p64 tanh/relu/tanh", "seed": 1, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 1, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7808219178082192, "f1_macro": 0.7666271513372672, "f1_weighted": 0.7841213035584601, "epochs_completed": 46, "best_epoch": 34, "pred_counts": [53, 32, 9, 101, 24], "collapsed": false, "recall": [0.9310344827586207, 0.9090909090909091, 0.7272727272727273, 0.7981651376146789, 0.5135135135135135]}
|
| 34 |
+
{"config": "E b32 p128 tanh/relu/tanh", "seed": 123, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 123, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7671232876712328, "f1_macro": 0.7396749831626857, "f1_weighted": 0.7699385457307235, "epochs_completed": 34, "best_epoch": 22, "pred_counts": [52, 29, 14, 102, 22], "collapsed": false, "recall": [0.896551724137931, 0.8787878787878788, 0.8181818181818182, 0.7981651376146789, 0.4594594594594595]}
|
| 35 |
+
{"config": "E b32 p128 tanh/relu/tanh", "seed": 0, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 0, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7579908675799086, "f1_macro": 0.743470919668342, "f1_weighted": 0.7665191757209968, "epochs_completed": 57, "best_epoch": 45, "pred_counts": [48, 29, 8, 100, 34], "collapsed": false, "recall": [0.7931034482758621, 0.8484848484848485, 0.6363636363636364, 0.7706422018348624, 0.6486486486486487]}
|
| 36 |
+
{"config": "E b32 p128 tanh/relu/tanh", "seed": 2024, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2024, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7990867579908676, "f1_macro": 0.7616315451274192, "f1_weighted": 0.8058428826086493, "epochs_completed": 35, "best_epoch": 23, "pred_counts": [45, 29, 10, 106, 29], "collapsed": false, "recall": [0.7586206896551724, 0.8181818181818182, 0.7272727272727273, 0.8715596330275229, 0.6216216216216216]}
|
| 37 |
+
{"config": "E b32 p128 tanh/relu/tanh", "seed": 7, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 7, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7534246575342466, "f1_macro": 0.7446451031909788, "f1_weighted": 0.7653821355518723, "epochs_completed": 33, "best_epoch": 21, "pred_counts": [51, 25, 12, 93, 38], "collapsed": false, "recall": [0.8275862068965517, 0.7575757575757576, 0.8181818181818182, 0.7522935779816514, 0.6756756756756757]}
|
| 38 |
+
{"config": "D b32 p64 tanh/relu/tanh", "seed": 42, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 42, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.776255707762557, "f1_macro": 0.7776900614771901, "f1_weighted": 0.7854714654440004, "epochs_completed": 68, "best_epoch": 56, "pred_counts": [48, 31, 10, 93, 37], "collapsed": false, "recall": [0.8275862068965517, 0.9090909090909091, 0.8181818181818182, 0.7614678899082569, 0.6486486486486487]}
|
| 39 |
+
{"config": "E b32 p128 tanh/relu/tanh", "seed": 1, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 1, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7671232876712328, "f1_macro": 0.7387577790490057, "f1_weighted": 0.7727522475446735, "epochs_completed": 34, "best_epoch": 22, "pred_counts": [53, 34, 7, 92, 33], "collapsed": false, "recall": [0.9310344827586207, 0.9090909090909091, 0.5454545454545454, 0.7522935779816514, 0.6216216216216216]}
|
| 40 |
+
{"config": "E b32 p128 tanh/relu/tanh", "seed": 42, "hyperparameters": {"epochs": 200, "batch_size": 32, "learning_rate": 0.01, "weight_decay": 0.01, "dropout": 0.3, "projection_dim": 128, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 42, "biological_activation": "tanh", "projection_activation": "relu", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7808219178082192, "f1_macro": 0.7734406826426466, "f1_weighted": 0.7928328973182098, "epochs_completed": 38, "best_epoch": 26, "pred_counts": [49, 28, 14, 88, 40], "collapsed": false, "recall": [0.8275862068965517, 0.8484848484848485, 0.9090909090909091, 0.7522935779816514, 0.7297297297297297]}
|
| 41 |
+
{"config": "BASE lr1e-3 wd1e-4 relu/sigmoid/tanh", "seed": 0, "hyperparameters": {"epochs": 100, "batch_size": 16, "learning_rate": 0.001, "weight_decay": 0.0001, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 0, "biological_activation": "relu", "projection_activation": "sigmoid", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7625570776255708, "f1_macro": 0.7241977003359705, "f1_weighted": 0.7688921750314536, "epochs_completed": 61, "best_epoch": 49, "pred_counts": [47, 28, 8, 105, 31], "collapsed": false, "recall": [0.7931034482758621, 0.8181818181818182, 0.5454545454545454, 0.8073394495412844, 0.6216216216216216]}
|
| 42 |
+
{"config": "BASE lr1e-3 wd1e-4 relu/sigmoid/tanh", "seed": 2, "hyperparameters": {"epochs": 100, "batch_size": 16, "learning_rate": 0.001, "weight_decay": 0.0001, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2, "biological_activation": "relu", "projection_activation": "sigmoid", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.8082191780821918, "f1_macro": 0.792199067264165, "f1_weighted": 0.8205970478829074, "epochs_completed": 81, "best_epoch": 69, "pred_counts": [53, 29, 14, 91, 32], "collapsed": false, "recall": [0.896551724137931, 0.8484848484848485, 0.9090909090909091, 0.7981651376146789, 0.7027027027027027]}
|
| 43 |
+
{"config": "BASE lr1e-3 wd1e-4 relu/sigmoid/tanh", "seed": 3, "hyperparameters": {"epochs": 100, "batch_size": 16, "learning_rate": 0.001, "weight_decay": 0.0001, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 3, "biological_activation": "relu", "projection_activation": "sigmoid", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7397260273972602, "f1_macro": 0.7190529426628272, "f1_weighted": 0.7474937309171131, "epochs_completed": 83, "best_epoch": 71, "pred_counts": [45, 28, 6, 102, 38], "collapsed": false, "recall": [0.7586206896551724, 0.8181818181818182, 0.5454545454545454, 0.7706422018348624, 0.6216216216216216]}
|
| 44 |
+
{"config": "BASE lr1e-3 wd1e-4 relu/sigmoid/tanh", "seed": 7, "hyperparameters": {"epochs": 100, "batch_size": 16, "learning_rate": 0.001, "weight_decay": 0.0001, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 7, "biological_activation": "relu", "projection_activation": "sigmoid", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.771689497716895, "f1_macro": 0.7524499679210638, "f1_weighted": 0.7826279144428353, "epochs_completed": 44, "best_epoch": 32, "pred_counts": [51, 28, 8, 91, 41], "collapsed": false, "recall": [0.8620689655172413, 0.7878787878787878, 0.6363636363636364, 0.7614678899082569, 0.7567567567567568]}
|
| 45 |
+
{"config": "BASE lr1e-3 wd1e-4 relu/sigmoid/tanh", "seed": 1, "hyperparameters": {"epochs": 100, "batch_size": 16, "learning_rate": 0.001, "weight_decay": 0.0001, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 1, "biological_activation": "relu", "projection_activation": "sigmoid", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7808219178082192, "f1_macro": 0.7513846597558472, "f1_weighted": 0.7897822474196114, "epochs_completed": 62, "best_epoch": 50, "pred_counts": [49, 30, 12, 98, 30], "collapsed": false, "recall": [0.8275862068965517, 0.8484848484848485, 0.7272727272727273, 0.7981651376146789, 0.6486486486486487]}
|
| 46 |
+
{"config": "BASE lr1e-3 wd1e-4 relu/sigmoid/tanh", "seed": 123, "hyperparameters": {"epochs": 100, "batch_size": 16, "learning_rate": 0.001, "weight_decay": 0.0001, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 123, "biological_activation": "relu", "projection_activation": "sigmoid", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7625570776255708, "f1_macro": 0.7396509109600558, "f1_weighted": 0.773059563038045, "epochs_completed": 49, "best_epoch": 37, "pred_counts": [53, 29, 13, 90, 34], "collapsed": false, "recall": [0.896551724137931, 0.8787878787878788, 0.7272727272727273, 0.7431192660550459, 0.6216216216216216]}
|
| 47 |
+
{"config": "BASE lr1e-3 wd1e-4 relu/sigmoid/tanh", "seed": 2024, "hyperparameters": {"epochs": 100, "batch_size": 16, "learning_rate": 0.001, "weight_decay": 0.0001, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 2024, "biological_activation": "relu", "projection_activation": "sigmoid", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7579908675799086, "f1_macro": 0.7372566114501599, "f1_weighted": 0.7695326473497044, "epochs_completed": 53, "best_epoch": 41, "pred_counts": [48, 29, 10, 95, 37], "collapsed": false, "recall": [0.7586206896551724, 0.8181818181818182, 0.7272727272727273, 0.7798165137614679, 0.6486486486486487]}
|
| 48 |
+
{"config": "BASE lr1e-3 wd1e-4 relu/sigmoid/tanh", "seed": 42, "hyperparameters": {"epochs": 100, "batch_size": 16, "learning_rate": 0.001, "weight_decay": 0.0001, "dropout": 0.3, "projection_dim": 64, "fusion_dim": 12, "validation_fraction": 0.25, "optimizer": "Adam", "class_weighting": true, "early_stopping_patience": 12, "seed": 42, "biological_activation": "relu", "projection_activation": "sigmoid", "fusion_activation": "tanh", "sgd_momentum": 0.0}, "accuracy": 0.7671232876712328, "f1_macro": 0.7474258785478297, "f1_weighted": 0.7740214080920172, "epochs_completed": 50, "best_epoch": 38, "pred_counts": [46, 32, 16, 96, 29], "collapsed": false, "recall": [0.7586206896551724, 0.9393939393939394, 0.9090909090909091, 0.7706422018348624, 0.5675675675675675]}
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_check_summary.txt
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
acc f1_macro f1_w f1m min/max collapsed min recall (mean) best epoch max epochs run recall c0 recall c1 recall c2 recall c3 recall c4
|
| 2 |
+
config
|
| 3 |
+
D b32 p64 tanh/relu/tanh 0.769 ± 0.015 0.749 ± 0.018 0.778 ± 0.013 0.731 / 0.778 0 0.609 39.5 68 0.83 0.84 0.73 0.78 0.64
|
| 4 |
+
BASE lr1e-3 wd1e-4 relu/sigmoid/tanh 0.769 ± 0.020 0.745 ± 0.022 0.778 ± 0.021 0.719 / 0.792 0 0.615 48.4 83 0.82 0.84 0.72 0.78 0.65
|
| 5 |
+
E b32 p128 tanh/relu/tanh 0.765 ± 0.026 0.745 ± 0.021 0.773 ± 0.027 0.702 / 0.773 0 0.594 26.8 57 0.83 0.84 0.74 0.78 0.60
|
| 6 |
+
A b32 p64 tanh/tanh/relu 0.749 ± 0.034 0.727 ± 0.041 0.755 ± 0.040 0.644 / 0.789 0 0.537 26.5 59 0.85 0.83 0.76 0.77 0.54
|
| 7 |
+
B b16 p128 relu/relu/tanh 0.753 ± 0.022 0.714 ± 0.042 0.756 ± 0.027 0.663 / 0.789 0 0.485 28.8 54 0.83 0.84 0.66 0.80 0.50
|
| 8 |
+
C b32 p128 tanh/relu/relu 0.740 ± 0.103 0.675 ± 0.223 0.724 ± 0.163 0.133 / 0.800 1 0.496 38.8 65 0.76 0.74 0.62 0.82 0.52
|
| 9 |
+
|
| 10 |
+
A b32 p64 tanh/tanh/relu vs BASE (same seed): mean Δ macro F1 -0.018, better on 2/8 seeds, per-seed [-0.001, -0.037, -0.078, -0.075, -0.012, 0.041, -0.004, 0.017]
|
| 11 |
+
B b16 p128 relu/relu/tanh vs BASE (same seed): mean Δ macro F1 -0.032, better on 2/8 seeds, per-seed [0.004, -0.05, -0.124, -0.056, -0.001, 0.041, -0.033, -0.036]
|
| 12 |
+
C b32 p128 tanh/relu/relu vs BASE (same seed): mean Δ macro F1 -0.071, better on 5/8 seeds, per-seed [0.034, 0.049, -0.659, -0.004, -0.086, 0.041, 0.02, 0.04]
|
| 13 |
+
D b32 p64 tanh/relu/tanh vs BASE (same seed): mean Δ macro F1 +0.004, better on 5/8 seeds, per-seed [0.006, 0.015, -0.027, 0.026, -0.017, 0.03, -0.004, 0.001]
|
| 14 |
+
E b32 p128 tanh/relu/tanh vs BASE (same seed): mean Δ macro F1 -0.000, better on 4/8 seeds, per-seed [0.019, -0.013, -0.033, -0.017, -0.008, 0.026, 0.0, 0.024]
|
| 15 |
+
|
| 16 |
+
config A b32 p64 tanh/tanh/relu B b16 p128 relu/relu/tanh BASE lr1e-3 wd1e-4 relu/sigmoid/tanh C b32 p128 tanh/relu/relu D b32 p64 tanh/relu/tanh E b32 p128 tanh/relu/tanh
|
| 17 |
+
seed
|
| 18 |
+
0 0.724 0.728 0.724 0.758 0.731 0.743
|
| 19 |
+
1 0.714 0.702 0.751 0.800 0.767 0.739
|
| 20 |
+
2 0.714 0.668 0.792 0.133 0.765 0.760
|
| 21 |
+
3 0.644 0.663 0.719 0.715 0.745 0.702
|
| 22 |
+
7 0.741 0.751 0.752 0.667 0.736 0.745
|
| 23 |
+
42 0.789 0.789 0.747 0.789 0.778 0.773
|
| 24 |
+
123 0.736 0.707 0.740 0.760 0.736 0.740
|
| 25 |
+
2024 0.754 0.701 0.737 0.778 0.738 0.762
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_shard0.log
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[0] A b32 p64 tanh/tanh/relu seed=0 f1m=0.724 collapsed=False
|
| 2 |
+
[0] A b32 p64 tanh/tanh/relu seed=7 f1m=0.741 collapsed=False
|
| 3 |
+
[0] B b16 p128 relu/relu/tanh seed=0 f1m=0.728 collapsed=False
|
| 4 |
+
[0] B b16 p128 relu/relu/tanh seed=7 f1m=0.751 collapsed=False
|
| 5 |
+
[0] C b32 p128 tanh/relu/relu seed=0 f1m=0.758 collapsed=False
|
| 6 |
+
[0] C b32 p128 tanh/relu/relu seed=7 f1m=0.667 collapsed=False
|
| 7 |
+
[0] D b32 p64 tanh/relu/tanh seed=0 f1m=0.731 collapsed=False
|
| 8 |
+
[0] D b32 p64 tanh/relu/tanh seed=7 f1m=0.736 collapsed=False
|
| 9 |
+
[0] E b32 p128 tanh/relu/tanh seed=0 f1m=0.743 collapsed=False
|
| 10 |
+
[0] E b32 p128 tanh/relu/tanh seed=7 f1m=0.745 collapsed=False
|
| 11 |
+
[0] BASE lr1e-3 wd1e-4 relu/sigmoid/tanh seed=0 f1m=0.724 collapsed=False
|
| 12 |
+
[0] BASE lr1e-3 wd1e-4 relu/sigmoid/tanh seed=7 f1m=0.752 collapsed=False
|
| 13 |
+
SHARD 0 DONE
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_shard1.log
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[1] A b32 p64 tanh/tanh/relu seed=1 f1m=0.714 collapsed=False
|
| 2 |
+
[1] A b32 p64 tanh/tanh/relu seed=42 f1m=0.789 collapsed=False
|
| 3 |
+
[1] B b16 p128 relu/relu/tanh seed=1 f1m=0.702 collapsed=False
|
| 4 |
+
[1] B b16 p128 relu/relu/tanh seed=42 f1m=0.789 collapsed=False
|
| 5 |
+
[1] C b32 p128 tanh/relu/relu seed=1 f1m=0.800 collapsed=False
|
| 6 |
+
[1] C b32 p128 tanh/relu/relu seed=42 f1m=0.789 collapsed=False
|
| 7 |
+
[1] D b32 p64 tanh/relu/tanh seed=1 f1m=0.767 collapsed=False
|
| 8 |
+
[1] D b32 p64 tanh/relu/tanh seed=42 f1m=0.778 collapsed=False
|
| 9 |
+
[1] E b32 p128 tanh/relu/tanh seed=1 f1m=0.739 collapsed=False
|
| 10 |
+
[1] E b32 p128 tanh/relu/tanh seed=42 f1m=0.773 collapsed=False
|
| 11 |
+
[1] BASE lr1e-3 wd1e-4 relu/sigmoid/tanh seed=1 f1m=0.751 collapsed=False
|
| 12 |
+
[1] BASE lr1e-3 wd1e-4 relu/sigmoid/tanh seed=42 f1m=0.747 collapsed=False
|
| 13 |
+
SHARD 1 DONE
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_shard2.log
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[2] A b32 p64 tanh/tanh/relu seed=2 f1m=0.714 collapsed=False
|
| 2 |
+
[2] A b32 p64 tanh/tanh/relu seed=123 f1m=0.736 collapsed=False
|
| 3 |
+
[2] B b16 p128 relu/relu/tanh seed=2 f1m=0.668 collapsed=False
|
| 4 |
+
[2] B b16 p128 relu/relu/tanh seed=123 f1m=0.707 collapsed=False
|
| 5 |
+
[2] C b32 p128 tanh/relu/relu seed=2 f1m=0.133 collapsed=True
|
| 6 |
+
[2] C b32 p128 tanh/relu/relu seed=123 f1m=0.760 collapsed=False
|
| 7 |
+
[2] D b32 p64 tanh/relu/tanh seed=2 f1m=0.765 collapsed=False
|
| 8 |
+
[2] D b32 p64 tanh/relu/tanh seed=123 f1m=0.736 collapsed=False
|
| 9 |
+
[2] E b32 p128 tanh/relu/tanh seed=2 f1m=0.760 collapsed=False
|
| 10 |
+
[2] E b32 p128 tanh/relu/tanh seed=123 f1m=0.740 collapsed=False
|
| 11 |
+
[2] BASE lr1e-3 wd1e-4 relu/sigmoid/tanh seed=2 f1m=0.792 collapsed=False
|
| 12 |
+
[2] BASE lr1e-3 wd1e-4 relu/sigmoid/tanh seed=123 f1m=0.740 collapsed=False
|
| 13 |
+
SHARD 2 DONE
|
diagnostics/2026-10-30-lab-hyperparameter-grid/results/seed_shard3.log
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[3] A b32 p64 tanh/tanh/relu seed=3 f1m=0.644 collapsed=False
|
| 2 |
+
[3] A b32 p64 tanh/tanh/relu seed=2024 f1m=0.754 collapsed=False
|
| 3 |
+
[3] B b16 p128 relu/relu/tanh seed=3 f1m=0.663 collapsed=False
|
| 4 |
+
[3] B b16 p128 relu/relu/tanh seed=2024 f1m=0.701 collapsed=False
|
| 5 |
+
[3] C b32 p128 tanh/relu/relu seed=3 f1m=0.715 collapsed=False
|
| 6 |
+
[3] C b32 p128 tanh/relu/relu seed=2024 f1m=0.778 collapsed=False
|
| 7 |
+
[3] D b32 p64 tanh/relu/tanh seed=3 f1m=0.745 collapsed=False
|
| 8 |
+
[3] D b32 p64 tanh/relu/tanh seed=2024 f1m=0.738 collapsed=False
|
| 9 |
+
[3] E b32 p128 tanh/relu/tanh seed=3 f1m=0.702 collapsed=False
|
| 10 |
+
[3] E b32 p128 tanh/relu/tanh seed=2024 f1m=0.762 collapsed=False
|
| 11 |
+
[3] BASE lr1e-3 wd1e-4 relu/sigmoid/tanh seed=3 f1m=0.719 collapsed=False
|
| 12 |
+
[3] BASE lr1e-3 wd1e-4 relu/sigmoid/tanh seed=2024 f1m=0.737 collapsed=False
|
| 13 |
+
SHARD 3 DONE
|
diagnostics/2026-10-30-lab-hyperparameter-grid/scripts/build_workspaces.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Build and cache the BRCA workspace with both GenePT files, using the app's own prepare step.
|
| 2 |
+
Usage: build_workspaces.py <cache_dir>"""
|
| 3 |
+
import pickle
|
| 4 |
+
import sys
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
import numpy as np
|
| 8 |
+
|
| 9 |
+
import app
|
| 10 |
+
|
| 11 |
+
CACHE = Path(sys.argv[1])
|
| 12 |
+
CACHE.mkdir(parents=True, exist_ok=True)
|
| 13 |
+
OPTIONS = {
|
| 14 |
+
"bulk": "Bulk · large-3 context",
|
| 15 |
+
"singlecell": "Single-cell · cell type, tissue, drug & pathway",
|
| 16 |
+
}
|
| 17 |
+
for key, option in OPTIONS.items():
|
| 18 |
+
result = app.prepare_workspace(
|
| 19 |
+
"BioLM-NET examples", "BRCA", "", None, None, None, None, None, None, None,
|
| 20 |
+
True, option, progress=lambda *a, **k: None,
|
| 21 |
+
)
|
| 22 |
+
workspace = result[0]
|
| 23 |
+
if workspace is None:
|
| 24 |
+
sys.exit(f"{key}: {result[1]}")
|
| 25 |
+
(CACHE / f"workspace_BRCA_{key}.pkl").write_bytes(pickle.dumps(workspace))
|
| 26 |
+
for name, branch in (("gene", workspace.gene_branch), ("dna", workspace.dna_branch)):
|
| 27 |
+
m = branch.biological_mask
|
| 28 |
+
print(f"{key:10s} {name}: inputs={m.shape[0]} hidden genes={m.shape[1]} edges={(m > 0).sum()} "
|
| 29 |
+
f"median in-degree={np.median((m > 0).sum(0)):.0f} pathways={len(branch.pathways)} "
|
| 30 |
+
f"GenePT dim={branch.embeddings.shape[1]}", flush=True)
|
diagnostics/2026-10-30-lab-hyperparameter-grid/scripts/grid.py
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Jubair's hyperparameter grid (email of 2026-10-17) on BRCA, using the Workbench's train() unchanged.
|
| 2 |
+
|
| 3 |
+
Usage: grid.py <workspace.pkl> <out.jsonl> <shard> <n_shards> [seed]
|
| 4 |
+
Resumable: configs already in <out.jsonl> are skipped.
|
| 5 |
+
|
| 6 |
+
Grid as sent, mapped onto Workbench Hyperparameters:
|
| 7 |
+
layer_one -> projection_dim; activation_function_one/two/three -> biological/projection/fusion activation;
|
| 8 |
+
l2_reg -> weight_decay; epoch -> epochs (early stopping, patience 12, still applies);
|
| 9 |
+
SGD gets momentum 0.03 as instructed. num_ex_neuron is not supported by the Workbench (fixed at 0).
|
| 10 |
+
"""
|
| 11 |
+
import itertools
|
| 12 |
+
import json
|
| 13 |
+
import sys
|
| 14 |
+
from dataclasses import asdict, replace
|
| 15 |
+
from pathlib import Path
|
| 16 |
+
|
| 17 |
+
import numpy as np
|
| 18 |
+
import pickle
|
| 19 |
+
import torch
|
| 20 |
+
from sklearn.metrics import recall_score
|
| 21 |
+
|
| 22 |
+
import biolmnet.training as training
|
| 23 |
+
|
| 24 |
+
WORKSPACE, OUT, SHARD, SHARDS = Path(sys.argv[1]), Path(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4])
|
| 25 |
+
SEED = int(sys.argv[5]) if len(sys.argv) > 5 else 42
|
| 26 |
+
torch.set_num_threads(2)
|
| 27 |
+
|
| 28 |
+
ACT = ["relu", "sigmoid", "tanh"]
|
| 29 |
+
GRID = list(itertools.product([64, 128], ACT, ACT, ACT, [16, 32], ["SGD", "Adam"]))
|
| 30 |
+
|
| 31 |
+
workspace = pickle.loads(WORKSPACE.read_bytes())
|
| 32 |
+
names = workspace.label_names
|
| 33 |
+
done = set()
|
| 34 |
+
if OUT.exists():
|
| 35 |
+
done = {json.dumps(json.loads(line)["key"]) for line in OUT.read_text().splitlines() if line.strip()}
|
| 36 |
+
|
| 37 |
+
for index, (proj, a1, a2, a3, batch, opt) in enumerate(GRID):
|
| 38 |
+
if index % SHARDS != SHARD:
|
| 39 |
+
continue
|
| 40 |
+
key = {"projection_dim": proj, "act1": a1, "act2": a2, "act3": a3, "batch_size": batch, "optimizer": opt, "seed": SEED}
|
| 41 |
+
if json.dumps(key) in done:
|
| 42 |
+
continue
|
| 43 |
+
hp = replace(
|
| 44 |
+
training.Hyperparameters(),
|
| 45 |
+
epochs=200, batch_size=batch, learning_rate=0.01, weight_decay=0.01, dropout=0.3,
|
| 46 |
+
projection_dim=proj, optimizer=opt, sgd_momentum=0.03 if opt == "SGD" else 0.0,
|
| 47 |
+
biological_activation=a1, projection_activation=a2, fusion_activation=a3, seed=SEED,
|
| 48 |
+
)
|
| 49 |
+
try:
|
| 50 |
+
result = training.train(workspace, hp)
|
| 51 |
+
except Exception as exc: # record and keep going
|
| 52 |
+
row = {"key": key, "error": repr(exc)}
|
| 53 |
+
else:
|
| 54 |
+
m = result.bundle.metrics
|
| 55 |
+
vp = result.validation_predictions
|
| 56 |
+
counts = vp["predicted"].value_counts().reindex(names, fill_value=0).astype(int).tolist()
|
| 57 |
+
history = result.bundle.history
|
| 58 |
+
best_epoch = int(min(history, key=lambda h: h["validation_loss"])["epoch"])
|
| 59 |
+
row = {
|
| 60 |
+
"key": key, "hyperparameters": asdict(hp),
|
| 61 |
+
"accuracy": m["accuracy"], "f1_macro": m["f1_macro"], "f1_weighted": m["f1_weighted"],
|
| 62 |
+
"epochs_completed": m["epochs_completed"], "best_epoch": best_epoch,
|
| 63 |
+
"pred_counts": counts, "classes_predicted": int((np.array(counts) > 0).sum()),
|
| 64 |
+
"recall": recall_score(vp["observed"], vp["predicted"], labels=names, average=None, zero_division=0).tolist(),
|
| 65 |
+
"final_train_loss": history[-1]["training_loss"], "best_val_loss": m["validation_loss"],
|
| 66 |
+
}
|
| 67 |
+
with OUT.open("a") as handle:
|
| 68 |
+
handle.write(json.dumps(row) + "\n")
|
| 69 |
+
print(f"[{SHARD}] {index} {key} -> " + (row.get("error") or f"f1m={row['f1_macro']:.3f} classes={row['classes_predicted']}"), flush=True)
|
| 70 |
+
print(f"SHARD {SHARD} DONE", flush=True)
|
diagnostics/2026-10-30-lab-hyperparameter-grid/scripts/grid_summary.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Summarise grid.py output. Usage: grid_summary.py <grid.jsonl>"""
|
| 2 |
+
import json
|
| 3 |
+
import sys
|
| 4 |
+
|
| 5 |
+
import pandas as pd
|
| 6 |
+
|
| 7 |
+
rows = []
|
| 8 |
+
for line in open(sys.argv[1]):
|
| 9 |
+
r = json.loads(line)
|
| 10 |
+
if "error" in r:
|
| 11 |
+
print("ERROR", r["key"], r["error"])
|
| 12 |
+
continue
|
| 13 |
+
rows.append({**r["key"], "acc": r["accuracy"], "f1_macro": r["f1_macro"], "f1_w": r["f1_weighted"],
|
| 14 |
+
"epochs": r["epochs_completed"], "best": r["best_epoch"], "classes": r["classes_predicted"],
|
| 15 |
+
"collapsed": r["classes_predicted"] == 1, "pred": "/".join(map(str, r["pred_counts"])),
|
| 16 |
+
"min_recall": min(r["recall"])})
|
| 17 |
+
df = pd.DataFrame(rows)
|
| 18 |
+
df["acts"] = df.act1 + "/" + df.act2 + "/" + df.act3
|
| 19 |
+
pd.set_option("display.width", 220)
|
| 20 |
+
pd.set_option("display.max_rows", 300)
|
| 21 |
+
|
| 22 |
+
print(f"configs: {len(df)} collapsed (1 class): {df.collapsed.sum()} "
|
| 23 |
+
f"all 5 classes predicted: {(df.classes == 5).sum()} macro F1 >= 0.70: {(df.f1_macro >= 0.70).sum()}")
|
| 24 |
+
print("\nTOP 20 by macro F1")
|
| 25 |
+
print(df.sort_values("f1_macro", ascending=False).head(20)[
|
| 26 |
+
["optimizer", "batch_size", "projection_dim", "acts", "acc", "f1_macro", "f1_w", "min_recall", "best", "epochs", "pred"]
|
| 27 |
+
].round(3).to_string(index=False))
|
| 28 |
+
for factor in ["optimizer", "batch_size", "projection_dim", "act1", "act2", "act3"]:
|
| 29 |
+
g = df.groupby(factor).agg(n=("f1_macro", "size"), f1_mean=("f1_macro", "mean"), f1_max=("f1_macro", "max"),
|
| 30 |
+
collapsed=("collapsed", "sum"), working=("f1_macro", lambda s: int((s >= 0.70).sum())))
|
| 31 |
+
print(f"\nBY {factor}\n" + g.round(3).to_string())
|
diagnostics/2026-10-30-lab-hyperparameter-grid/scripts/seed_check.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Re-run the best grid configurations (plus the 2026-10-16 stable baseline) across 8 seeds.
|
| 2 |
+
Usage: seed_check.py <workspace.pkl> <out.jsonl> <shard> <n_shards>
|
| 3 |
+
Resumable: (config, seed) pairs already in <out.jsonl> are skipped."""
|
| 4 |
+
import json
|
| 5 |
+
import pickle
|
| 6 |
+
import sys
|
| 7 |
+
from dataclasses import asdict, replace
|
| 8 |
+
from pathlib import Path
|
| 9 |
+
|
| 10 |
+
import numpy as np
|
| 11 |
+
import torch
|
| 12 |
+
from sklearn.metrics import recall_score
|
| 13 |
+
|
| 14 |
+
import biolmnet.training as training
|
| 15 |
+
|
| 16 |
+
WORKSPACE, OUT, SHARD, SHARDS = Path(sys.argv[1]), Path(sys.argv[2]), int(sys.argv[3]), int(sys.argv[4])
|
| 17 |
+
torch.set_num_threads(2)
|
| 18 |
+
SEEDS = [0, 1, 2, 3, 7, 42, 123, 2024]
|
| 19 |
+
|
| 20 |
+
GRID_BASE = dict(epochs=200, learning_rate=0.01, weight_decay=0.01, dropout=0.3, optimizer="Adam")
|
| 21 |
+
CONFIGS = {
|
| 22 |
+
"A b32 p64 tanh/tanh/relu": dict(GRID_BASE, batch_size=32, projection_dim=64,
|
| 23 |
+
biological_activation="tanh", projection_activation="tanh", fusion_activation="relu"),
|
| 24 |
+
"B b16 p128 relu/relu/tanh": dict(GRID_BASE, batch_size=16, projection_dim=128,
|
| 25 |
+
biological_activation="relu", projection_activation="relu", fusion_activation="tanh"),
|
| 26 |
+
"C b32 p128 tanh/relu/relu": dict(GRID_BASE, batch_size=32, projection_dim=128,
|
| 27 |
+
biological_activation="tanh", projection_activation="relu", fusion_activation="relu"),
|
| 28 |
+
"D b32 p64 tanh/relu/tanh": dict(GRID_BASE, batch_size=32, projection_dim=64,
|
| 29 |
+
biological_activation="tanh", projection_activation="relu", fusion_activation="tanh"),
|
| 30 |
+
"E b32 p128 tanh/relu/tanh": dict(GRID_BASE, batch_size=32, projection_dim=128,
|
| 31 |
+
biological_activation="tanh", projection_activation="relu", fusion_activation="tanh"),
|
| 32 |
+
# 2026-10-16 stable setting: Adam lr 1e-3, weight_decay 1e-4, published activations, 100-epoch limit.
|
| 33 |
+
"BASE lr1e-3 wd1e-4 relu/sigmoid/tanh": dict(epochs=100, weight_decay=1e-4),
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
workspace = pickle.loads(WORKSPACE.read_bytes())
|
| 37 |
+
names = workspace.label_names
|
| 38 |
+
done = set()
|
| 39 |
+
if OUT.exists():
|
| 40 |
+
done = {(r["config"], r["seed"]) for r in map(json.loads, OUT.read_text().splitlines()) if r}
|
| 41 |
+
|
| 42 |
+
jobs = [(c, s) for c in CONFIGS for s in SEEDS]
|
| 43 |
+
for index, (config, seed) in enumerate(jobs):
|
| 44 |
+
if index % SHARDS != SHARD or (config, seed) in done:
|
| 45 |
+
continue
|
| 46 |
+
hp = replace(training.Hyperparameters(), seed=seed, **CONFIGS[config])
|
| 47 |
+
result = training.train(workspace, hp)
|
| 48 |
+
m = result.bundle.metrics
|
| 49 |
+
vp = result.validation_predictions
|
| 50 |
+
counts = vp["predicted"].value_counts().reindex(names, fill_value=0).astype(int).tolist()
|
| 51 |
+
row = {
|
| 52 |
+
"config": config, "seed": seed, "hyperparameters": asdict(hp),
|
| 53 |
+
"accuracy": m["accuracy"], "f1_macro": m["f1_macro"], "f1_weighted": m["f1_weighted"],
|
| 54 |
+
"epochs_completed": m["epochs_completed"],
|
| 55 |
+
"best_epoch": int(min(result.bundle.history, key=lambda h: h["validation_loss"])["epoch"]),
|
| 56 |
+
"pred_counts": counts, "collapsed": int((np.array(counts) > 0).sum()) == 1,
|
| 57 |
+
"recall": recall_score(vp["observed"], vp["predicted"], labels=names, average=None, zero_division=0).tolist(),
|
| 58 |
+
}
|
| 59 |
+
with OUT.open("a") as handle:
|
| 60 |
+
handle.write(json.dumps(row) + "\n")
|
| 61 |
+
print(f"[{SHARD}] {config} seed={seed} f1m={row['f1_macro']:.3f} collapsed={row['collapsed']}", flush=True)
|
| 62 |
+
print(f"SHARD {SHARD} DONE", flush=True)
|
tests/test_core.py
CHANGED
|
@@ -1,9 +1,11 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import pickle
|
|
|
|
| 4 |
|
| 5 |
import numpy as np
|
| 6 |
import pandas as pd
|
|
|
|
| 7 |
import torch
|
| 8 |
|
| 9 |
from biolmnet.artifacts import load_bundle, save_bundle
|
|
@@ -15,7 +17,13 @@ from biolmnet.data import (
|
|
| 15 |
deterministic_gene_embeddings,
|
| 16 |
)
|
| 17 |
from biolmnet.model import BioMaskedLinear, BioLMNet
|
| 18 |
-
from biolmnet.training import
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
|
| 21 |
def test_biological_mask_uses_pdi_and_undirected_ppi() -> None:
|
|
@@ -232,3 +240,217 @@ def test_zerogpu_duration_estimator_is_bounded_and_scales() -> None:
|
|
| 232 |
long = estimate_training_duration(common[0], 200, *common[1:])
|
| 233 |
assert 30 <= short <= 300
|
| 234 |
assert short <= long <= 300
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
import pickle
|
| 4 |
+
from dataclasses import replace
|
| 5 |
|
| 6 |
import numpy as np
|
| 7 |
import pandas as pd
|
| 8 |
+
import pytest
|
| 9 |
import torch
|
| 10 |
|
| 11 |
from biolmnet.artifacts import load_bundle, save_bundle
|
|
|
|
| 17 |
deterministic_gene_embeddings,
|
| 18 |
)
|
| 19 |
from biolmnet.model import BioMaskedLinear, BioLMNet
|
| 20 |
+
from biolmnet.training import (
|
| 21 |
+
DEFAULT_VALIDATION_FRACTION,
|
| 22 |
+
Hyperparameters,
|
| 23 |
+
predict,
|
| 24 |
+
split_train_validation,
|
| 25 |
+
train,
|
| 26 |
+
)
|
| 27 |
|
| 28 |
|
| 29 |
def test_biological_mask_uses_pdi_and_undirected_ppi() -> None:
|
|
|
|
| 240 |
long = estimate_training_duration(common[0], 200, *common[1:])
|
| 241 |
assert 30 <= short <= 300
|
| 242 |
assert short <= long <= 300
|
| 243 |
+
|
| 244 |
+
|
| 245 |
+
_FAST = Hyperparameters(
|
| 246 |
+
epochs=3,
|
| 247 |
+
batch_size=8,
|
| 248 |
+
projection_dim=4,
|
| 249 |
+
fusion_dim=3,
|
| 250 |
+
dropout=0.0,
|
| 251 |
+
early_stopping_patience=3,
|
| 252 |
+
)
|
| 253 |
+
|
| 254 |
+
|
| 255 |
+
def test_default_split_is_75_training_25_validation() -> None:
|
| 256 |
+
assert DEFAULT_VALIDATION_FRACTION == 0.25
|
| 257 |
+
assert Hyperparameters().validation_fraction == 0.25
|
| 258 |
+
labels = np.repeat(np.array([0, 1]), 50)
|
| 259 |
+
train_index, validation_index = split_train_validation(
|
| 260 |
+
labels, Hyperparameters().validation_fraction, Hyperparameters().seed
|
| 261 |
+
)
|
| 262 |
+
assert len(train_index) == 75
|
| 263 |
+
assert len(validation_index) == 25
|
| 264 |
+
|
| 265 |
+
|
| 266 |
+
def test_split_partitions_every_sample_exactly_once() -> None:
|
| 267 |
+
labels = np.repeat(np.array([0, 1, 2]), [40, 25, 18])
|
| 268 |
+
train_index, validation_index = split_train_validation(labels, 0.25, 42)
|
| 269 |
+
assert len(train_index) + len(validation_index) == len(labels)
|
| 270 |
+
assert set(train_index).isdisjoint(validation_index)
|
| 271 |
+
assert sorted(np.concatenate([train_index, validation_index])) == list(range(len(labels)))
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
def test_split_preserves_class_proportions() -> None:
|
| 275 |
+
labels = np.repeat(np.array([0, 1, 2]), [120, 60, 20]) # 60 / 30 / 10
|
| 276 |
+
train_index, validation_index = split_train_validation(labels, 0.25, 42)
|
| 277 |
+
expected = np.array([0.6, 0.3, 0.1])
|
| 278 |
+
for partition in (train_index, validation_index):
|
| 279 |
+
observed = np.bincount(labels[partition], minlength=3) / len(partition)
|
| 280 |
+
np.testing.assert_allclose(observed, expected, atol=0.02)
|
| 281 |
+
|
| 282 |
+
|
| 283 |
+
def test_split_is_reproducible_for_a_fixed_seed() -> None:
|
| 284 |
+
labels = np.repeat(np.array([0, 1]), [30, 34])
|
| 285 |
+
first = split_train_validation(labels, 0.25, 42)
|
| 286 |
+
second = split_train_validation(labels, 0.25, 42)
|
| 287 |
+
other_seed = split_train_validation(labels, 0.25, 7)
|
| 288 |
+
np.testing.assert_array_equal(first[0], second[0])
|
| 289 |
+
np.testing.assert_array_equal(first[1], second[1])
|
| 290 |
+
assert set(first[1]) != set(other_seed[1])
|
| 291 |
+
|
| 292 |
+
|
| 293 |
+
def test_split_rejects_partitions_too_small_to_stratify() -> None:
|
| 294 |
+
with pytest.raises(ValueError, match="at least two samples"):
|
| 295 |
+
split_train_validation(np.array([0, 0, 0, 1]), 0.25, 42)
|
| 296 |
+
# 4 classes x 2 samples: 25% leaves 2 validation samples for 4 classes.
|
| 297 |
+
with pytest.raises(ValueError, match="one sample per class"):
|
| 298 |
+
split_train_validation(np.repeat(np.arange(4), 2), 0.25, 42)
|
| 299 |
+
|
| 300 |
+
|
| 301 |
+
def test_training_uses_paired_rows_and_train_only_scaler() -> None:
|
| 302 |
+
workspace = _tiny_workspace()
|
| 303 |
+
hyperparameters = replace(_FAST, validation_fraction=0.25)
|
| 304 |
+
train_index, validation_index = split_train_validation(
|
| 305 |
+
workspace.labels, hyperparameters.validation_fraction, hyperparameters.seed
|
| 306 |
+
)
|
| 307 |
+
# Shift only the validation rows: a scaler fitted on all samples would move.
|
| 308 |
+
workspace.gene_expression[validation_index] += 100.0
|
| 309 |
+
workspace.dna_methylation[validation_index] -= 100.0
|
| 310 |
+
|
| 311 |
+
result = train(workspace, hyperparameters)
|
| 312 |
+
bundle = result.bundle
|
| 313 |
+
|
| 314 |
+
assert bundle.metrics["training_samples"] == 36
|
| 315 |
+
assert bundle.metrics["validation_samples"] == 12
|
| 316 |
+
np.testing.assert_array_equal(
|
| 317 |
+
result.validation_predictions["sample_row"].to_numpy(), validation_index
|
| 318 |
+
)
|
| 319 |
+
expected_labels = [workspace.label_names[value] for value in workspace.labels[validation_index]]
|
| 320 |
+
assert result.validation_predictions["observed"].tolist() == expected_labels
|
| 321 |
+
|
| 322 |
+
# Both omics scalers come from the same training rows only.
|
| 323 |
+
np.testing.assert_allclose(
|
| 324 |
+
bundle.gene_mean, workspace.gene_expression[train_index].mean(axis=0), rtol=1e-5
|
| 325 |
+
)
|
| 326 |
+
np.testing.assert_allclose(
|
| 327 |
+
bundle.gene_scale, workspace.gene_expression[train_index].std(axis=0), rtol=1e-5
|
| 328 |
+
)
|
| 329 |
+
np.testing.assert_allclose(
|
| 330 |
+
bundle.dna_mean, workspace.dna_methylation[train_index].mean(axis=0), rtol=1e-5
|
| 331 |
+
)
|
| 332 |
+
np.testing.assert_allclose(
|
| 333 |
+
bundle.dna_scale, workspace.dna_methylation[train_index].std(axis=0), rtol=1e-5
|
| 334 |
+
)
|
| 335 |
+
|
| 336 |
+
# Validation rows are transformed with that training-fitted scaler: the
|
| 337 |
+
# stored validation probabilities match predict(), which uses the bundle's scaler.
|
| 338 |
+
rescored = predict(
|
| 339 |
+
pd.DataFrame(workspace.gene_expression[validation_index], columns=bundle.gene_features),
|
| 340 |
+
pd.DataFrame(workspace.dna_methylation[validation_index], columns=bundle.dna_features),
|
| 341 |
+
bundle,
|
| 342 |
+
)
|
| 343 |
+
probability_columns = [f"P({label})" for label in workspace.label_names]
|
| 344 |
+
np.testing.assert_allclose(
|
| 345 |
+
result.validation_predictions[probability_columns].to_numpy(),
|
| 346 |
+
rescored[probability_columns].to_numpy(),
|
| 347 |
+
atol=1e-5,
|
| 348 |
+
)
|
| 349 |
+
|
| 350 |
+
|
| 351 |
+
def test_class_weights_use_training_labels_only(monkeypatch) -> None:
|
| 352 |
+
import biolmnet.training as training
|
| 353 |
+
|
| 354 |
+
captured = {}
|
| 355 |
+
original = training.nn.CrossEntropyLoss
|
| 356 |
+
|
| 357 |
+
def spy(*args, weight=None, **kwargs):
|
| 358 |
+
captured["weight"] = None if weight is None else weight.cpu().numpy()
|
| 359 |
+
return original(*args, weight=weight, **kwargs)
|
| 360 |
+
|
| 361 |
+
monkeypatch.setattr(training.nn, "CrossEntropyLoss", spy)
|
| 362 |
+
workspace = _tiny_workspace() # 24 control / 24 case: all-sample weights are [1, 1].
|
| 363 |
+
# Force a lopsided split so training-only weights clearly differ from all-sample ones.
|
| 364 |
+
train_index = np.concatenate([np.arange(0, 22), np.arange(24, 30)])
|
| 365 |
+
validation_index = np.setdiff1d(np.arange(48), train_index)
|
| 366 |
+
monkeypatch.setattr(
|
| 367 |
+
training, "split_train_validation", lambda *args: (train_index, validation_index)
|
| 368 |
+
)
|
| 369 |
+
train(workspace, _FAST)
|
| 370 |
+
|
| 371 |
+
counts = np.bincount(workspace.labels[train_index], minlength=2).astype(np.float32)
|
| 372 |
+
assert counts.tolist() == [22.0, 6.0]
|
| 373 |
+
np.testing.assert_allclose(captured["weight"], len(train_index) / (2 * counts), rtol=1e-6)
|
| 374 |
+
|
| 375 |
+
|
| 376 |
+
def test_results_page_receives_training_history_plot() -> None:
|
| 377 |
+
from app import refresh_results
|
| 378 |
+
|
| 379 |
+
assert refresh_results(None, {})[-1] is None
|
| 380 |
+
|
| 381 |
+
result = train(_tiny_workspace(), _FAST)
|
| 382 |
+
figure = refresh_results(result.bundle, {})[-1]
|
| 383 |
+
traces = {trace.name: trace for trace in figure.data}
|
| 384 |
+
assert set(traces) == {"Training", "Validation"}
|
| 385 |
+
history = result.bundle.history
|
| 386 |
+
assert list(traces["Training"].y) == [row["training_loss"] for row in history]
|
| 387 |
+
assert list(traces["Validation"].y) == [row["validation_loss"] for row in history]
|
| 388 |
+
|
| 389 |
+
# Artifacts saved without history still render the rest of the page.
|
| 390 |
+
result.bundle.history = []
|
| 391 |
+
assert refresh_results(result.bundle, {})[-1] is None
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
def test_activation_choices_reach_model_config_and_artifact(tmp_path) -> None:
|
| 395 |
+
hyperparameters = replace(
|
| 396 |
+
_FAST,
|
| 397 |
+
biological_activation="tanh",
|
| 398 |
+
projection_activation="relu",
|
| 399 |
+
fusion_activation="sigmoid",
|
| 400 |
+
)
|
| 401 |
+
result = train(_tiny_workspace(), hyperparameters)
|
| 402 |
+
branch = result.bundle.model.gene_branch
|
| 403 |
+
assert isinstance(branch.biological_activation, torch.nn.Tanh)
|
| 404 |
+
assert isinstance(branch.projection_activation, torch.nn.ReLU)
|
| 405 |
+
assert isinstance(result.bundle.model.fusion_activation, torch.nn.Sigmoid)
|
| 406 |
+
assert result.bundle.config["architecture"]["biological_activation"] == "tanh"
|
| 407 |
+
|
| 408 |
+
restored = load_bundle(save_bundle(result.bundle, tmp_path / "model.zip"))
|
| 409 |
+
assert isinstance(restored.model.gene_branch.biological_activation, torch.nn.Tanh)
|
| 410 |
+
assert isinstance(restored.model.fusion_activation, torch.nn.Sigmoid)
|
| 411 |
+
|
| 412 |
+
|
| 413 |
+
def test_defaults_follow_lab_grid_configuration() -> None:
|
| 414 |
+
defaults = Hyperparameters()
|
| 415 |
+
assert (defaults.optimizer, defaults.learning_rate, defaults.weight_decay) == ("Adam", 0.01, 0.01)
|
| 416 |
+
assert (defaults.batch_size, defaults.projection_dim, defaults.dropout, defaults.epochs) == (32, 64, 0.3, 200)
|
| 417 |
+
assert (defaults.biological_activation, defaults.projection_activation, defaults.fusion_activation) == (
|
| 418 |
+
"tanh",
|
| 419 |
+
"relu",
|
| 420 |
+
"tanh",
|
| 421 |
+
)
|
| 422 |
+
assert defaults.sgd_momentum == 0.03
|
| 423 |
+
|
| 424 |
+
|
| 425 |
+
def test_auto_genept_uses_lab_recommended_single_cell_file() -> None:
|
| 426 |
+
from app import GENEPT_OPTIONS, _resolve_embedding_file
|
| 427 |
+
|
| 428 |
+
auto = next(label for label, value in GENEPT_OPTIONS.items() if value == "auto")
|
| 429 |
+
for dataset in ("BRCA", "COAD", "GBM", "scTrioseq2"):
|
| 430 |
+
assert _resolve_embedding_file(auto, "BioLM-NET examples", dataset) == (
|
| 431 |
+
"embedding_associations_cell_type_tissue_drug_pathway_openai_large.parquet"
|
| 432 |
+
)
|
| 433 |
+
|
| 434 |
+
|
| 435 |
+
def test_sgd_momentum_reaches_optimizer(monkeypatch) -> None:
|
| 436 |
+
import biolmnet.training as training
|
| 437 |
+
|
| 438 |
+
captured = {}
|
| 439 |
+
original = training.torch.optim.SGD
|
| 440 |
+
|
| 441 |
+
def spy(params, **kwargs):
|
| 442 |
+
captured.update(kwargs)
|
| 443 |
+
return original(params, **kwargs)
|
| 444 |
+
|
| 445 |
+
monkeypatch.setattr(training.torch.optim, "SGD", spy)
|
| 446 |
+
train(_tiny_workspace(), replace(_FAST, optimizer="SGD", learning_rate=0.01, sgd_momentum=0.03))
|
| 447 |
+
assert captured["momentum"] == 0.03
|
| 448 |
+
|
| 449 |
+
|
| 450 |
+
@pytest.mark.parametrize(
|
| 451 |
+
"field, value",
|
| 452 |
+
[("biological_activation", "softmax"), ("fusion_activation", "gelu"), ("sgd_momentum", 1.0)],
|
| 453 |
+
)
|
| 454 |
+
def test_invalid_activation_or_momentum_is_rejected(field, value) -> None:
|
| 455 |
+
with pytest.raises(ValueError):
|
| 456 |
+
replace(Hyperparameters(), **{field: value}).validate()
|