CTM / templates /index.html
broadfield-dev's picture
Update templates/index.html
3f880eb verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Continuous Thought Machine - MNIST</title>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<div class="container">
<h1>Continuous Thought Machine - MNIST Classifier</h1>
<p>Upload a grayscale image of a handwritten digit (0-9) to classify it using the CTM model, or train a new model.</p>
<h2>Predict</h2>
<form action="/predict" method="post" enctype="multipart/form-data">
<input type="file" name="file" accept="image/*" required>
<button type="submit">Predict</button>
</form>
<h2>Train Model</h2>
{% if training_status.status == 'running' %}
<p>Training in progress: {{ training_status.message }}</p>
<p>Progress: {{ training_status.progress | round(2) }}%</p>
{% elif training_status.status == 'completed' %}
<p>Training completed: {{ training_status.message }}</p>
{% elif training_status.status == 'error' %}
<p class="error">Training failed: {{ training_status.message }}</p>
{% endif %}
<form id="train-form" action="/train" method="post">
<label for="iterations">Iterations (100-5000):</label>
<input type="number" name="iterations" id="iterations" value="1000" min="100" max="5000" required>
<label for="lr">Learning Rate (1e-6 to 1e-2):</label>
<input type="number" name="lr" id="lr" value="0.0001" step="0.00001" min="0.000001" max="0.01" required>
<button type="submit" {% if training_status.status == 'running' %}disabled{% endif %}>Start Training</button>
</form>
{% if error %}
<p class="error">{{ error }}</p>
{% endif %}
{% if prediction is defined %}
<h2>Results</h2>
<p><strong>Predicted Digit:</strong> {{ prediction }}</p>
<p><strong>Certainty:</strong> {{ certainty }}</p>
<h3>CTM Dynamics Visualization</h3>
<img src="{{ url_for('static', filename=gif_path.replace('static/', '')) }}" alt="CTM Dynamics" style="max-width: 100%;">
{% endif %}
</div>
<script>
// Poll training status every 5 seconds
function checkTrainingStatus() {
fetch('/training_status')
.then(response => response.json())
.then(data => {
if (data.status === 'running') {
document.querySelector('#train-form button').disabled = true;
document.querySelector('#train-form').insertAdjacentHTML('beforebegin',
`<p>Training in progress: ${data.message}</p><p>Progress: ${data.progress.toFixed(2)}%</p>`);
setTimeout(checkTrainingStatus, 5000);
} else {
document.querySelector('#train-form button').disabled = false;
if (data.status === 'completed') {
document.querySelector('#train-form').insertAdjacentHTML('beforebegin',
`<p>Training completed: ${data.message}</p>`);
} else if (data.status === 'error') {
document.querySelector('#train-form').insertAdjacentHTML('beforebegin',
`<p class="error">Training failed: ${data.message}</p>`);
}
}
});
}
// Start polling if training is in progress
{% if training_status.status == 'running' %}
checkTrainingStatus();
{% endif %}
// Handle form submission
document.getElementById('train-form').addEventListener('submit', function(e) {
e.preventDefault();
fetch('/train', {
method: 'POST',
body: new FormData(this)
})
.then(response => response.json())
.then(data => {
if (data.error) {
alert(data.error);
} else {
alert(data.message);
checkTrainingStatus();
}
})
.catch(error => alert('Error starting training: ' + error));
});
</script>
</body>
</html>