implemented locking in training setup

This commit is contained in:
Philipp
2025-11-28 16:09:14 +01:00
parent 5220ffbe46
commit c43545e137
15 changed files with 962 additions and 74 deletions

View File

@@ -3,6 +3,156 @@ window.addEventListener('DOMContentLoaded', () => {
// Get the form element at the top
const form = document.getElementById('settings-form');
// Base config state
let currentBaseConfig = null;
let baseConfigFields = [];
// Define which fields are protected by base config
const protectedFields = [
'depth', 'width', 'act', 'max_epoch', 'warmup_epochs', 'warmup_lr',
'scheduler', 'no_aug_epochs', 'min_lr_ratio', 'ema', 'weight_decay',
'momentum', 'input_size', 'mosaic_scale', 'test_size', 'enable_mixup',
'mosaic_prob', 'mixup_prob', 'hsv_prob', 'flip_prob', 'degrees',
'translate', 'shear', 'mixup_scale', 'print_interval', 'eval_interval'
];
// Map backend field names to frontend field names
const fieldNameMap = {
'activation': 'act', // Backend uses 'activation', frontend uses 'act'
'nms_thre': 'nmsthre'
};
// Function to load base config for selected model
function loadBaseConfig(modelName) {
if (!modelName) return Promise.resolve(null);
return fetch(`/api/base-config/${modelName}`)
.then(res => {
if (!res.ok) throw new Error('Base config not found');
return res.json();
})
.catch(err => {
console.warn(`Could not load base config for ${modelName}:`, err);
return null;
});
}
// Function to apply base config to form fields
function applyBaseConfig(config, isCocoMode) {
const infoBanner = document.getElementById('base-config-info');
const modelNameSpan = document.getElementById('base-config-model');
if (!config || !isCocoMode) {
// Hide info banner
if (infoBanner) infoBanner.style.display = 'none';
// Remove grey styling and enable all fields
protectedFields.forEach(fieldName => {
const input = form.querySelector(`[name="${fieldName}"]`);
if (input) {
input.disabled = false;
input.style.backgroundColor = '#f8f8f8';
input.style.color = '#333';
input.style.cursor = 'text';
input.title = '';
}
});
baseConfigFields = [];
return;
}
// Show info banner
if (infoBanner) {
infoBanner.style.display = 'block';
const modelName = form.querySelector('[name="select_model"]')?.value || 'selected model';
if (modelNameSpan) modelNameSpan.textContent = modelName;
}
// Apply base config values and grey out fields
baseConfigFields = [];
Object.entries(config).forEach(([key, value]) => {
// Map backend field name to frontend field name if needed
const frontendFieldName = fieldNameMap[key] || key;
if (protectedFields.includes(frontendFieldName)) {
const input = form.querySelector(`[name="${frontendFieldName}"]`);
if (input) {
baseConfigFields.push(frontendFieldName);
// Set value based on type
if (input.type === 'checkbox') {
input.checked = Boolean(value);
} else if (Array.isArray(value)) {
input.value = value.join(',');
} else {
input.value = value;
}
// Grey out and disable
input.disabled = true;
input.style.backgroundColor = '#d3d3d3';
input.style.color = '#666';
input.style.cursor = 'not-allowed';
// Add title tooltip
const modelName = form.querySelector('[name="select_model"]')?.value || 'selected model';
input.title = `Protected by base config for ${modelName}. Switch to "Train from sketch" to customize.`;
}
}
});
console.log(`Applied base config. Protected fields: ${baseConfigFields.join(', ')}`);
}
// Function to update form based on transfer learning mode
function updateTransferLearningMode() {
const transferLearning = document.getElementById('transfer-learning');
const selectModel = document.getElementById('select-model');
const selectModelRow = document.getElementById('select-model-row');
if (!transferLearning || !selectModel) return;
const isCocoMode = transferLearning.value === 'coco';
const isCustomMode = transferLearning.value === 'custom';
const isSketchMode = transferLearning.value === 'sketch';
const modelName = selectModel.value;
// Show/hide select model based on transfer learning mode
if (selectModelRow) {
if (isSketchMode) {
selectModelRow.style.display = 'none';
} else {
selectModelRow.style.display = '';
}
}
if (isCocoMode && modelName) {
// Load and apply base config
loadBaseConfig(modelName).then(config => {
currentBaseConfig = config;
applyBaseConfig(config, true);
});
} else {
// Clear base config
currentBaseConfig = null;
applyBaseConfig(null, false);
}
}
// Listen for changes to transfer learning dropdown
const transferLearningSelect = document.getElementById('transfer-learning');
if (transferLearningSelect) {
transferLearningSelect.addEventListener('change', updateTransferLearningMode);
}
// Listen for changes to model selection
const modelSelect = document.getElementById('select-model');
if (modelSelect) {
modelSelect.addEventListener('change', updateTransferLearningMode);
}
// Initial update on page load
setTimeout(updateTransferLearningMode, 100);
// Auto-set num_classes from training_project classes array
const urlParams = new URLSearchParams(window.location.search);
@@ -43,17 +193,26 @@ window.addEventListener('DOMContentLoaded', () => {
form.addEventListener('submit', function(e) {
console.log("Form submitted");
e.preventDefault();
// Temporarily enable disabled fields so they get included in FormData
const disabledInputs = [];
form.querySelectorAll('input[disabled], select[disabled]').forEach(input => {
input.disabled = false;
disabledInputs.push(input);
});
const formData = new FormData(form);
const settings = {};
let fileToUpload = null;
for (const [key, value] of formData.entries()) {
if (key === 'model_upload' && form.elements[key].files.length > 0) {
fileToUpload = form.elements[key].files[0];
continue;
}
if (key === 'ema' || key === 'enable_mixup') {
if (key === 'ema' || key === 'enable_mixup' || key === 'save_history_ckpt') {
settings[key] = form.elements[key].checked;
} else if (key === 'scale' || key === 'mosaic_scale') {
} else if (key === 'scale' || key === 'mosaic_scale' || key === 'mixup_scale' || key === 'input_size' || key === 'test_size') {
settings[key] = value.split(',').map(v => parseFloat(v.trim()));
} else if (!isNaN(value) && value !== '') {
settings[key] = parseFloat(value);
@@ -61,6 +220,12 @@ window.addEventListener('DOMContentLoaded', () => {
settings[key] = value;
}
}
// Re-disable the inputs
disabledInputs.forEach(input => {
input.disabled = true;
});
// Attach project id from URL
const urlParams = new URLSearchParams(window.location.search);
const projectId = urlParams.get('id');