643 lines
43 KiB
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('project_id') || urlParams.get('id'); // Support both parameter names
|
|
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()">×</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> |