import React, { useState } from 'react'; import { EpiADRHyperparameters, EpochTrainingMetric, ModelTrainingSummary } from '../types'; import { globalEpiADREngine } from '../utils/epiAdrEngine'; import { SIDER_BENCHMARK_DRUGS } from '../utils/siderDataset'; import { ResponsiveContainer, LineChart, Line, XAxis, YAxis, Tooltip, CartesianGrid, Legend } from 'recharts'; import { Cpu, Play, Square, RotateCcw, Activity, Layers, CheckCircle, BarChart2, ShieldAlert } from 'lucide-react'; interface TrainingPanelProps { useTissueConditioning: boolean; setUseTissueConditioning: (val: boolean) => void; } export const TrainingPanel: React.FC = ({ useTissueConditioning, setUseTissueConditioning }) => { const [hyperparams, setHyperparams] = useState({ useTissueConditioning, crossAttentionHeads: 16, learningRate: 0.001, epochs: 40, batchSize: 16, optimizer: 'adam', posWeight: 2.5, regularizationL2: 0.001, dropoutRate: 0.2, mcDropoutPasses: 30 }); const [isTraining, setIsTraining] = useState(false); const [epochHistory, setEpochHistory] = useState([]); const [trainingSummary, setTrainingSummary] = useState(null); const handleStartTraining = async () => { setIsTraining(true); setEpochHistory([]); setTrainingSummary(null); try { const summary = await globalEpiADREngine.trainEpiADRModel( SIDER_BENCHMARK_DRUGS, { ...hyperparams, useTissueConditioning }, (metric) => { setEpochHistory(prev => [...prev, metric]); } ); setTrainingSummary(summary); } catch (err: any) { console.error("Training error:", err); } finally { setIsTraining(false); } }; const handleStopTraining = () => { globalEpiADREngine.cancelTraining(); setIsTraining(false); }; return (
{/* Training Configuration Grid */}
{/* Left Column: Hyperparameter Controls */}

EpiADR-Net Model Architecture

{/* Mode Switcher */}
Scientific Controlled Baseline

{useTissueConditioning ? 'Fuses SMILES 256-bit fingerprint with GTEx V8 128-dim organ transcriptomic vectors via 16-Head Cross-Attention.' : 'Disables transcriptomic profiles to measure scientific accuracy uplift of human gene expression data.'}

{/* Hyperparameters */}
Epochs {hyperparams.epochs}
setHyperparams({ ...hyperparams, epochs: parseInt(e.target.value) })} className="w-full accent-indigo-500 cursor-pointer h-1.5 bg-slate-800 rounded-lg" />
Learning Rate (η) {hyperparams.learningRate}
Class Imbalance Weight (pos_weight) {hyperparams.posWeight}x
setHyperparams({ ...hyperparams, posWeight: parseFloat(e.target.value) })} className="w-full accent-indigo-500 cursor-pointer h-1.5 bg-slate-800 rounded-lg" />
L2 Weight Regularization {hyperparams.regularizationL2}
setHyperparams({ ...hyperparams, regularizationL2: parseFloat(e.target.value) })} className="w-full accent-indigo-500 cursor-pointer h-1.5 bg-slate-800 rounded-lg" />
{/* Controls */}
{!isTraining ? ( ) : ( )}
{/* Right Column: Live Epoch Loss & AUROC Charts */}

Live Training & Validation Dynamics

{isTraining && ( Optimizing Epoch {epochHistory.length}/{hyperparams.epochs}... )}
{/* Loss Curve */}
Binary Crossentropy Loss
{/* AUROC Curve */}
Validation AUROC Trajectory
{/* Model Training Summary Metrics */} {trainingSummary && (
Validation AUROC {trainingSummary.finalValAUROC.toFixed(3)}
Macro F1 Score {trainingSummary.finalF1Score.toFixed(3)}
Final Loss {trainingSummary.finalValLoss.toFixed(4)}
Training Duration {trainingSummary.trainingTimeMs} ms
)}
); };