Files
Abschluss-Projekt/edit-training.html

643 lines
43 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charset="utf-8" />
<link rel="stylesheet" href="globals.css" />
<link rel="stylesheet" href="styleguide.css" />
<link rel="stylesheet" href="style.css" />
<style>
#projects-list {
display: flex;
flex-wrap: wrap;
gap: 1px;
justify-content: flex-start;
align-items: flex-start;
}
.dataset-card {
flex: 0 0 auto;
}
.setting-row {
margin-bottom: 20px;
display: grid;
grid-template-columns: 1fr;
align-items: start;
background: rgb(234, 247, 250);
color: #009eac;
border-radius: 10px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
padding: 10px 18px;
position: relative;
}
.setting-row-inner {
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
}
.setting-label {
font-weight: bold;
margin-bottom: 0;
margin-right: 18px;
color: #333;
min-width: 140px;
flex-shrink: 0;
}
.setting-row input[type="number"],
.setting-row input[type="text"] {
width: 200px;
min-width: 120px;
max-width: 230px;
margin-right: 18px;
padding: 4px 8px;
font-size: 1em;
border-radius: 6px;
border: 1px solid #009eac;
background: #f8f8f8;
}
.setting-row input[type="number"]:disabled,
.setting-row input[type="text"]:disabled,
.setting-row input[type="checkbox"]:disabled {
background: #d3d3d3 !important;
color: #666 !important;
cursor: not-allowed !important;
border: 1px solid #999 !important;
}
.setting-row input[disabled]::placeholder {
color: #888;
}
.setting-row input[type="checkbox"] {
margin-right: 18px;
transform: scale(1.2);
}
.setting-desc {
font-size: 1em;
color: #009eac;
margin-top: 8px;
margin-bottom: 2px;
background: #eaf7fa;
border-radius: 6px;
padding: 6px 10px;
width: 100%;
position: static;
}
.setting-row {
margin-bottom: 20px;
}
#exp-setup {
max-width: 600px;
margin: 32px auto;
padding: 24px;
background: #f5f5f5;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
#parameters-setup{
max-width: 600px;
margin: 32px auto;
padding: 24px;
background: #f5f5f5;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
}
.config-section {
margin-bottom: 32px;
}
.config-section h3 {
color: #009eac;
margin-bottom: 16px;
font-size: 1.2em;
}
.config-section-foldable {
margin-bottom: 32px;
background: linear-gradient(90deg, #b7f2ff 0%, #eaf7fa 100%);
border-radius: 10px;
padding: 10px 16px;
position: relative;
}
.config-section-foldable h3 {
color: #009eac;
margin-bottom: 16px;
font-size: 1.2em;
}
.config-section-foldable.nested {
background: #d2f0f7;
border-left: 6px solid #009eac;
margin-left: 16px;
box-shadow: 0 2px 8px rgba(0, 158, 172, 0.12);
}
.config-section-foldable.nested h3 {
color: #007080;
}
.config-section-foldable.nested .fold-icon {
color: #007080;
}
.setting-desc-foldable {
background: #eaf7fa;
border-radius: 6px;
margin-top: 8px;
margin-bottom: 2px;
padding: 0;
width: 100%;
position: relative;
grid-column: 1 / -1;
display: block;
}
.setting-desc-header {
display: flex;
align-items: center;
cursor: pointer;
color: #009eac;
font-size: 1em;
font-weight: bold;
padding: 6px 10px;
border-bottom: 1px solid #b2e4ef;
border-radius: 6px 6px 0 0;
background: #eaf7fa;
}
.setting-desc-content {
padding: 6px 10px;
color: #009eac;
background: #eaf7fa;
border-radius: 0 0 6px 6px;
display: none;
}
</style>
</head>
<!-- TODO: Fix Train from Skretch and disable model select if skratch -->
<body onload="pollStatus()">
<div>
<div id="header">
<icon class="header-icon" onclick="window.location.href='/index.html'" , onmouseover=""
style="cursor: pointer;" src="./media/logo.png" alt="Logo"></icon>
<label id="project-title-label"
style="display: block; text-align: left; font-weight: bold; font-size: x-large;">title</label>
<div class="button-row">
<button id="Add Training Project" onclick="window.location.href='/add-project.html'"
class="button-red">Add Training Project</button>
<button id="seed-db-btn" class="button">
Seed Database
<div class="loader" id="loader" style="display: none"></div>
</button>
<button id="settings-btn" onclick="window.openSettingsModal()" class="button" title="Einstellungen" style="padding: 8px 12px; margin-left: 10px;">⚙️</button>
</div>
</div>
<div id="projects-list">
</div>
<script>
document.getElementById('seed-db-btn').addEventListener('click', function () {
const elLoader = document.getElementById("loader")
elLoader.style.display = "inherit"
fetch('/api/seed')
.finally(() => {
// Instead of hiding loader immediately, poll /api/update-status until done
function pollStatus() {
fetch('/api/update-status')
.then(res => res.json())
.then(status => {
if (status && status.running) {
// Still running, poll again after short delay
setTimeout(pollStatus, 5000);
} else {
elLoader.style.display = "none";
}
})
.catch(() => {
elLoader.style.display = "none";
});
}
pollStatus();
})
});
// Show loader if backend is still processing on page load
function pollStatus() {
const elLoader = document.getElementById("loader");
fetch('/api/update-status')
.then(res => res.json())
.then(status => {
if (status && status.running) {
elLoader.style.display = "inherit";
setTimeout(pollStatus, 5000);
} else {
elLoader.style.display = "none";
}
})
.catch(() => {
elLoader.style.display = "none";
});
}
</script>
<script>
const urlParams = new URLSearchParams(window.location.search);
const projectId = urlParams.get('id');
fetch('/api/training-projects')
.then(res => res.json())
.then(projects => {
const project = projects.find(p => p.project_id == projectId || p.id == projectId);
if (project) {
document.getElementById('project-title-label').textContent = '/' + project.title;
}
});
</script>
<div style="display: flex; flex-wrap: wrap; gap: 32px; justify-content: center; align-items: flex-start; margin-top:32px;">
<div id="exp-setup" style="flex: 1 1 420px; min-width: 340px; max-width: 600px; margin:0;">
<h2 style="margin-bottom:18px;color:#009eac;">YOLOX Training Settings</h2>
<form id="settings-form">
<!-- Autogenerated/Keep Variables -->
<!-- <div class="config-section">
<h3>Dataset & Class Settings</h3>
<div class="setting-row"><div class="setting-row-inner"><label class="setting-label" for="num_classes">Num Classes</label><input type="number" id="num_classes" name="num_classes" value="80" min="1" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;">►</span>Description</div><div class="setting-desc-content">Number of object classes to detect in your dataset.<br>Example: 1-100 (COCO has 80)</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Train Ann</span><input type="text" name="train_ann" value="instances_train2017.json" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;">►</span>Description</div><div class="setting-desc-content">Filenames of annotation files (usually in COCO format) for training, validation, and testing respectively.<br>Examples: instances_train2017.json</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Val Ann</span><input type="text" name="val_ann" value="instances_val2017.json" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;">►</span>Description</div><div class="setting-desc-content">Validation annotation file name.</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Test Ann</span><input type="text" name="test_ann" value="instances_test2017.json" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;">►</span>Description</div><div class="setting-desc-content">Test annotation file name.</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Data Dir</span><input type="text" name="data_dir" value="" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;">►</span>Description</div><div class="setting-desc-content">Path to the directory containing your dataset images and annotations.</div></div></div>
</div> -->
<!-- Main Parameters -->
<div class="config-section-foldable">
<h3>Main Parameters</h3>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Exp Name</span><input type="text" name="exp_name" value="custom_exp" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Name to identify this training run/experiment. Used for logging and saving files.</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Max Epoch</span><input type="number" name="max_epoch" value="300" min="1" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Total number of training epochs.<br>Typical: 100-300</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><label class="setting-label" for="depth">Depth</label><input type="number" id="depth" step="any" name="depth" value="1.00" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Controls the depth (number of layers) of the backbone. Higher depth improves accuracy but may slow down training.<br>Typical values: 0.33 (nano), 0.67 (tiny), 1.0 (s, m, l)</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><label class="setting-label" for="width">Width</label><input type="number" id="width" step="any" name="width" value="1.00" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Controls the width (number of channels) in each layer. Wider models capture more detail but use more memory.<br>Typical values: 0.25-1.33</div></div></div>
<!-- Details Foldable -->
<div class="config-section-foldable nested">
<h3 style="cursor:pointer;display:flex;align-items:center;" onclick="toggleFold(this)"><span>Details</span><span class="fold-icon" style="margin-left:8px;font-size:1.2em;"></span></h3>
<div class="foldable-content">
<div class="setting-row"><div class="setting-row-inner"><label class="setting-label" for="act">Activation</label><input type="text" id="act" name="act" value="silu" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Activation function used in the network.<br>Options: silu, relu, leaky_relu</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Warmup Epochs</span><input type="number" name="warmup_epochs" value="5" min="0" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Number of epochs at the beginning with a slowly increasing learning rate.<br>Common: 3-5</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Warmup LR</span><input type="number" step="any" name="warmup_lr" value="0" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Starting learning rate during warmup phase. Usually set to 0.</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Scheduler</span><input type="text" name="scheduler" value="yoloxwarmcos" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Learning rate scheduler.<br>Default: yoloxwarmcos</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">No Aug Epochs</span><input type="number" name="no_aug_epochs" value="15" min="0" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Number of final epochs with no data augmentation to improve final accuracy.<br>Typical: 10-20</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Min LR Ratio</span><input type="number" step="any" name="min_lr_ratio" value="0.05" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Minimum ratio between the final and initial learning rate.<br>Default: 0.05</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">EMA</span><input type="checkbox" name="ema" checked /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Enable Exponential Moving Average of model weights for smoother training results.</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Weight Decay</span><input type="number" step="any" name="weight_decay" value="0.0005" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Regularization term to reduce overfitting.<br>Typical: 0.0001-0.001</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Momentum</span><input type="number" step="any" name="momentum" value="0.9" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Momentum for optimizer.<br>Default: 0.9</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Input Size</span><input type="text" name="input_size" value="640,640" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Size of input images during training, formatted as width,height.<br>Common values: 640,640 or 512,512</div></div></div>
</div>
</div>
<!-- Logs Foldable -->
<div class="config-section-foldable nested">
<h3 style="cursor:pointer;display:flex;align-items:center;" onclick="toggleFold(this)"><span>Logs</span><span class="fold-icon" style="margin-left:8px;font-size:1.2em;"></span></h3>
<div class="foldable-content">
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Print Interval</span><input type="number" name="print_interval" value="10" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">How often to print training logs (in iterations).<br>Example: 10</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Eval Interval</span><input type="number" name="eval_interval" value="10" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">How often to evaluate on validation set (in epochs).<br>Example: 10</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Save History CKPT</span><input type="checkbox" name="save_history_ckpt" checked /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Save model checkpoints periodically for backup or resuming.</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Test Size</span><input type="text" name="test_size" value="640,640" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Input size for evaluation, formatted as width,height.<br>Example: 640,640</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Test Conf</span><input type="number" step="any" name="test_conf" value="0.01" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Confidence score threshold for predictions during evaluation.<br>Typical: 0.01-0.3</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">NMS Thre</span><input type="number" step="any" name="nmsthre" value="0.65" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">IoU threshold for non-maximum suppression (NMS).<br>Typical: 0.5-0.7</div></div></div>
</div>
</div>
<!-- Transformation Settings Foldable -->
<div class="config-section-foldable nested">
<h3 style="cursor:pointer;display:flex;align-items:center;" onclick="toggleFold(this)"><span>Transformation Settings</span><span class="fold-icon" style="margin-left:8px;font-size:1.2em;"></span></h3>
<div class="foldable-content">
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Multiscale Range</span><input type="number" name="multiscale_range" value="5" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Controls how much to vary image sizes during training for robustness.<br>Range: 0-10 (e.g. 5 = ±5 scale levels)</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Enable Mixup</span><input type="checkbox" name="enable_mixup" checked /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Toggle mixup augmentation on or off. Improves generalization.</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Mosaic Prob</span><input type="number" step="any" name="mosaic_prob" value="1.0" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Probability of applying mosaic augmentation, which combines 4 images into 1.<br>Range: 0.0-1.0</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Mixup Prob</span><input type="number" step="any" name="mixup_prob" value="1.0" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Probability of applying mixup augmentation, blending two images and labels.<br>Range: 0.0-1.0</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">HSV Prob</span><input type="number" step="any" name="hsv_prob" value="1.0" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Probability of applying HSV (color) augmentation to images.<br>Range: 0.0-1.0</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Flip Prob</span><input type="number" step="any" name="flip_prob" value="0.5" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Probability of flipping the image horizontally.<br>Default: 0.5</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Degrees</span><input type="number" step="any" name="degrees" value="10.0" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Maximum rotation angle for random rotation.<br>Typical: 0-15°</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Mosaic Scale</span><input type="text" name="mosaic_scale" value="0.1,2" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Scale range for mosaic augmentation, formatted as min,max.<br>Example: 0.1,2.0</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Mixup Scale</span><input type="text" name="mixup_scale" value="0.5,1.5" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Scale range for mixup augmentation.<br>Example: 0.5,1.5</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Translate</span><input type="number" step="any" name="translate" value="0.1" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Maximum translation ratio. A value of 0.1 means 10% shift in image position.<br>Range: 0.0-0.3</div></div></div>
<div class="setting-row"><div class="setting-row-inner"><span class="setting-label">Shear</span><input type="number" step="any" name="shear" value="2.0" /></div><div class="setting-desc-foldable"><div class="setting-desc-header" onclick="toggleDescFold(this)"><span class="desc-fold-icon" style="margin-right:8px;"></span>Description</div><div class="setting-desc-content">Maximum shear angle in degrees for geometric distortion.<br>Typical: 0.0-5.0</div></div></div>
</div>
</div>
</div>
</form>
</div>
<div id="parameters-setup" style="flex: 1 1 420px; min-width: 340px; max-width: 600px; margin:0;">
<!-- Parameters Section -->
<h2 style="margin-bottom:18px;color:#009eac;">Parameters</h2>
<form id="parameters-form">
<div class="config-section-foldable">
<h3>Category: Split</h3>
<div class="setting-row"><div class="setting-row-inner">
<label class="setting-label" for="seed">Seed</label>
<input type="number" id="seed" name="seed" value="" />
</div></div>
<div class="setting-row"><div class="setting-row-inner">
<label class="setting-label" for="train-slider">Train</label>
<input type="range" id="train-slider" name="train" min="0" max="100" value="70" step="1" style="width:120px;">
<span id="train-value">70%</span>
</div></div>
<div class="setting-row"><div class="setting-row-inner">
<label class="setting-label" for="valid-slider">Valid</label>
<input type="range" id="valid-slider" name="valid" min="0" max="100" value="20" step="1" style="width:120px;">
<span id="valid-value">20%</span>
</div></div>
<div class="setting-row"><div class="setting-row-inner">
<label class="setting-label" for="test-slider">Test</label>
<input type="range" id="test-slider" name="test" min="0" max="100" value="10" step="1" style="width:120px;">
<span id="test-value">10%</span>s
</div>
<div class="config-section-foldable" style="margin-top:24px;">
<h3>Model Settings</h3>
<div class="setting-row">
<div class="setting-row-inner">
<label class="setting-label" for="transfer-learning">Transfer Learning</label>
<select id="transfer-learning" name="transfer_learning" onchange="toggleCkptUpload()">
<option value="sketch">Train from sketch</option>
<option value="coco">Train on coco</option>
<option value="custom">Train on custom</option>
</select>
</div></div>
<div class="setting-row" id="select-model-row"><div class="setting-row-inner">
<label class="setting-label" for="select-model">Select Model</label>
<select id="select-model" name="select_model">
<option value="YOLOX-s">YOLOX-s</option>
<option value="YOLOX-m">YOLOX-m</option>
<option value="YOLOX-l">YOLOX-l</option>
<option value="YOLOX-x">YOLOX-x</option>
<option value="YOLOX-Darknet53">YOLOX-Darknet53</option>
<option value="YOLOX-Nano">YOLOX-Nano</option>
<option value="YOLOX-Tiny">YOLOX-Tiny</option>
</select>
</div></div>
<div class="setting-row" id="ckpt-upload-row" style="display:none;">
<div class="setting-row-inner">
<label class="setting-label" for="ckpt-upload">Upload .pth file</label>
<input type="file" id="ckpt-upload" name="ckpt_upload" accept=".pth" />
</div>
</div>
</div>
<button type="submit" class="button" style="margin-top:18px;">Save Parameters</button>
</form>
</div>
</div>
</div>
</div>
<script>
function toggleFold(header) {
const section = header.parentElement;
const content = section.querySelector('.foldable-content');
const icon = header.querySelector('.fold-icon');
if (content.style.display === 'none') {
content.style.display = '';
icon.textContent = '▼';
} else {
content.style.display = 'none';
icon.textContent = '►';
}
}
window.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.config-section-foldable .foldable-content').forEach(function (content) {
const icon = content.parentElement.querySelector('.fold-icon');
if (content.parentElement.classList.contains('nested')) {
content.style.display = 'none';
if (icon) icon.textContent = '►';
} else {
content.style.display = '';
if (icon) icon.textContent = '▼';
}
});
});
</script>
<script>
function toggleDescFold(header) {
const content = header.nextElementSibling;
const icon = header.querySelector('.desc-fold-icon');
if (content.style.display === 'none' || content.style.display === '') {
content.style.display = 'block';
icon.textContent = '▼';
} else {
content.style.display = 'none';
icon.textContent = '►';
}
}
window.addEventListener('DOMContentLoaded', function () {
document.querySelectorAll('.setting-desc-content').forEach(function (content) {
content.style.display = 'none';
});
});
</script>
<script src="js/start-training.js"></script>
<script>
function toggleCkptUpload() {
var select = document.getElementById('transfer-learning');
var row = document.getElementById('ckpt-upload-row');
if (select.value === 'custom') {
row.style.display = '';
} else {
row.style.display = 'none';
}
}
window.addEventListener('DOMContentLoaded', function() {
toggleCkptUpload();
});
</script>
<script>
function syncSplitSliders(changed) {
let train = parseInt(document.getElementById('train-slider').value);
let valid = parseInt(document.getElementById('valid-slider').value);
let test = 100 - train - valid;
// Clamp valid so test is never negative
if (test < 0) {
valid = 100 - train;
document.getElementById('valid-slider').value = valid;
test = 0;
}
document.getElementById('test-slider').value = test;
document.getElementById('train-value').textContent = train + '%';
document.getElementById('valid-value').textContent = valid + '%';
document.getElementById('test-value').textContent = test + '%';
}
document.getElementById('train-slider').addEventListener('input', function() { syncSplitSliders('train'); });
document.getElementById('valid-slider').addEventListener('input', function() { syncSplitSliders('valid'); });
document.getElementById('test-slider').setAttribute('disabled', 'disabled');
window.addEventListener('DOMContentLoaded', function() { syncSplitSliders('train'); });
</script>
<script>
document.getElementById('parameters-form').addEventListener('submit', async function(e) {
e.preventDefault();
// Temporarily enable all disabled fields so they get included
const disabledInputs = [];
document.querySelectorAll('#settings-form input[disabled], #settings-form select[disabled]').forEach(input => {
input.disabled = false;
disabledInputs.push(input);
});
// Collect YOLOX settings from #settings-form
const settingsForm = document.getElementById('settings-form');
const settingsData = {};
Array.from(settingsForm.elements).forEach(el => {
if (el.name && el.type !== 'submit') {
if (el.type === 'checkbox') {
settingsData[el.name] = el.checked;
} else {
settingsData[el.name] = el.value;
}
}
});
// Re-disable the inputs
disabledInputs.forEach(input => {
input.disabled = true;
});
// Collect parameters from #parameters-form
const paramsForm = document.getElementById('parameters-form');
Array.from(paramsForm.elements).forEach(el => {
if (el.name && el.type !== 'submit') {
if (el.type === 'checkbox') {
settingsData[el.name] = el.checked;
} else if (el.type === 'file') {
if (el.files && el.files[0]) {
settingsData[el.name] = el.files[0]; // Will handle below
}
} else {
settingsData[el.name] = el.value;
}
}
});
// Always add test value from slider (even if disabled)
settingsData['test'] = document.getElementById('test-slider').value;
// Handle file upload (ckpt_upload)
const formData = new FormData();
for (const key in settingsData) {
if (settingsData[key] instanceof File) {
formData.append(key, settingsData[key]);
} else {
formData.append(key, settingsData[key]);
}
}
// Add project id if available
const urlParams = new URLSearchParams(window.location.search);
const projectId = urlParams.get('id');
if (projectId) formData.append('project_id', projectId);
// Send to backend
try {
const res = await fetch('/api/yolox-settings', {
method: 'POST',
body: formData
});
if (res.ok) {
const result = await res.json();
alert('Parameters saved!');
window.location.href = '/overview-training.html?id=' + projectId;
} else {
const err = await res.json();
alert('Error saving parameters: ' + err.message);
}
} catch (error) {
alert('Error saving parameters: ' + error.message);
}
});
</script>
<!-- Settings Modal -->
<div id="settings-modal" class="modal" style="display: none;">
<div class="modal-content" style="max-width: 600px; max-height: 90vh; overflow-y: auto;">
<div class="modal-header">
<h2>Einstellungen</h2>
<button class="close-btn" onclick="window.closeSettingsModal()">&times;</button>
</div>
<div class="modal-body">
<!-- Label Studio Settings -->
<div class="settings-section">
<h3>Label Studio</h3>
<div class="form-group">
<label for="labelstudio-url">API URL:</label>
<input type="text" id="labelstudio-url" placeholder="http://192.168.1.19:8080">
</div>
<div class="form-group">
<label for="labelstudio-token">API Token:</label>
<input type="password" id="labelstudio-token" placeholder="API Token">
</div>
<button id="test-labelstudio-btn" class="button">
Verbindung testen
<div class="loader" id="test-ls-loader" style="display: none"></div>
</button>
<div id="labelstudio-status" class="status-message"></div>
</div>
<!-- YOLOX Settings -->
<div class="settings-section">
<h3>YOLOX</h3>
<div class="form-group">
<label for="yolox-path">Installation Path:</label>
<input type="text" id="yolox-path" placeholder="C:/YOLOX">
</div>
<div class="form-group">
<label for="yolox-venv-path">Virtual Environment Path:</label>
<input type="text" id="yolox-venv-path" placeholder="/path/to/venv/bin/activate">
</div>
<div class="form-group">
<label for="yolox-output-path">Output Folder:</label>
<input type="text" id="yolox-output-path" placeholder="./backend">
<small style="display: block; margin-top: 4px; color: #666;">Folder for experiment files and JSON files</small>
</div>
<div class="form-group">
<label for="yolox-data-dir">Data Directory:</label>
<input type="text" id="yolox-data-dir" placeholder="/home/kitraining/To_Annotate/">
<small style="display: block; margin-top: 4px; color: #666;">Path where training images are located</small>
</div>
<button id="test-yolox-btn" class="button">
Pfad überprüfen
<div class="loader" id="test-yolox-loader" style="display: none"></div>
</button>
<div id="yolox-status" class="status-message"></div>
</div>
<!-- Save Button -->
<div class="settings-section">
<button id="save-settings-btn" class="button-red">Einstellungen speichern</button>
<div id="save-status" class="status-message"></div>
</div>
</div>
</div>
</div>
<script src="js/settings.js"></script>
</body></html>