Skip to content

Datamasters-it/qlearning-demo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 

Repository files navigation

Q-Learning con p5.js

Un progetto di reinforcement learning che dimostra come un agente impara a raggiungere un obiettivo usando l'algoritmo Q-learning.

Caratteristiche

  • Ambiente: Griglia 10x10 con agente, obiettivo e ostacoli
  • Algoritmo: Q-learning con Q-table
  • Visualizzazione: Interfaccia grafica in tempo reale
  • Controlli: Pulsanti per training e inferenza
  • Statistiche: Monitoraggio del progresso dell'apprendimento

Come usare

  1. Apri index.html nel browser
  2. Clicca "Inizia Training" per far imparare l'agente
  3. Attendi che il training sia completato (1000 episodi)
  4. Clicca "Mostra Inferenza" per vedere l'agente applicare la conoscenza appresa
  5. Usa "Reset" per ricominciare da capo

Elementi dell'ambiente

  • 🔴 Agente (cerchio rosso): Deve imparare a raggiungere l'obiettivo
  • 🟢 Obiettivo (cerchio verde): Da raggiungere per ottenere ricompensa (+100)
  • Ostacoli (cerchi neri): Da evitare (penalità -10)
  • Spazio libero: Movimento consentito (penalità -1 per step)

Parametri Q-learning

  • Learning Rate: 0.1
  • Discount Factor: 0.95
  • Epsilon iniziale: 1.0 (esplorazione al 100%)
  • Epsilon finale: 0.01 (esplorazione all'1%)
  • Epsilon Decay: 0.995
  • Max Episodi: 1000
  • Max Steps per episodio: 100

Funzionamento

Step per implementare Q-Learning

1. 🏗️ Definizione dell'Ambiente

  • Stati: Posizioni (x,y) nella griglia 10×10 = 100 stati possibili
  • Azioni: 4 movimenti possibili (su, giù, sinistra, destra)
  • Spazio di osservazione: Posizione corrente dell'agente
  • Dinamiche: Regole di movimento e collisioni

2. 🎯 Sistema di Ricompense

  • Obiettivo raggiunto: +100 punti (rinforzo positivo forte)
  • Ostacoli/Muri: -10 punti (penalità per errori)
  • Ogni passo: -1 punto (incoraggia efficienza)
  • Bilanciamento: Ricompense progettate per guidare l'apprendimento

3. 📊 Inizializzazione Q-Table

  • Dimensioni: 100 stati × 4 azioni = 400 valori Q
  • Valori iniziali: Tutti inizializzati a 0
  • Struttura: qTable[stato][azione] = valore_Q

4. 🎲 Strategia di Esplorazione (ε-greedy)

4. 🎲 Strategia di Esplorazione (ε-greedy)

  • Epsilon iniziale: 1.0 (100% esplorazione casuale)
  • Epsilon finale: 0.01 (1% esplorazione, 99% exploitation)
  • Decay: 0.995 per episodio (riduzione graduale)
  • Bilanciamento: Esplorazione → Exploitation nel tempo

🚀 INIZIO DELL'ADDESTRAMENTO

5. ⚖️ Equazione di Bellman

Q(s,a) = Q(s,a) + α × [r + γ × max(Q(s',a')) - Q(s,a)]
  • α (Learning Rate): 0.1 - velocità di apprendimento
  • γ (Discount Factor): 0.95 - importanza del futuro

6. 🔄 CICLO DI TRAINING DETTAGLIATO

📋 LIVELLO EPISODIO (ripetuto 1000 volte)

🔴 INIZIO EPISODIO N:

  1. resetAgent() - Agente torna a posizione (0,0)
  2. clearPathTrail() - Pulisce la traccia visiva
  3. stepCount = 0 - Reset contatore passi
  4. addToPathTrail(0,0) - Segna posizione iniziale

⚡ LIVELLO STEP (ripetuto fino a max 100 step per episodio)

STEP 1 - OSSERVAZIONE:

let currentState = getStateString(agentPos.x, agentPos.y); // es: "3,7"

STEP 2 - SCELTA AZIONE (ε-greedy):

if (Math.random() < epsilon) {
    // ESPLORAZIONE: azione casuale
    action = Math.floor(Math.random() * 4);
} else {
    // EXPLOITATION: migliore azione conosciuta
    let qValues = qTable[currentState]; // [0.2, -0.5, 1.3, 0.8]
    action = indexOfMax(qValues); // sceglie azione con Q-value più alto
}

STEP 3 - ESECUZIONE AZIONE:

let newX = agentPos.x + actions[action].x; // nuova coordinata X
let newY = agentPos.y + actions[action].y; // nuova coordinata Y

// Controlla validità movimento
if (isValidPosition(newX, newY)) {
    agentPos.x = newX;
    agentPos.y = newY;
    addToPathTrail(newX, newY); // Aggiorna traccia visiva
}

STEP 4 - CALCOLO RICOMPENSA:

let reward = getReward(agentPos.x, agentPos.y);
// Possibili valori:
// +100 se raggiunge obiettivo (9,9)
// -10 se va su ostacolo o fuori griglia
// -1 per movimento normale (costo del tempo)

STEP 5 - AGGIORNAMENTO Q-TABLE (BELLMAN):

let oldQ = qTable[currentState][action];        // Q-value precedente
let newState = getStateString(agentPos.x, agentPos.y);
let maxNewQ = Math.max(...qTable[newState]);    // Miglior Q-value nel nuovo stato
let newQ = oldQ + 0.1 * (reward + 0.95 * maxNewQ - oldQ); // Bellman!
qTable[currentState][action] = newQ;            // Aggiorna conoscenza

STEP 6 - CONTROLLO FINE EPISODIO:

if (agentPos.x === 9 && agentPos.y === 9) {
    // 🎯 SUCCESSO! Obiettivo raggiunto
    successes++;
    scores.push(stepCount);
    episodeEnded = true;
} else if (stepCount >= 100) {
    // ⏰ TIMEOUT! Troppi passi
    scores.push(-stepCount);
    episodeEnded = true;
}

🔚 FINE EPISODIO:

if (episodeEnded) {
    episodeCount++;
    epsilon = Math.max(0.01, epsilon * 0.995); // Riduce esplorazione
    resetAgent(); // Torna a (0,0) per nuovo episodio
    updateStats(); // Aggiorna statistiche visuali
}

7. 📈 EVOLUZIONE NEL TEMPO

EPISODI 1-100:

  • ε ≈ 0.9 → Esplorazione quasi totale, movimenti casuali
  • Q-table piena di valori quasi zero
  • Successi rari e casuali

EPISODI 100-500:

  • ε ≈ 0.6 → Inizia a usare conoscenza appresa
  • Alcuni Q-values diventano positivi verso l'obiettivo
  • Aumento graduale del tasso di successo

EPISODI 500-1000:

  • ε ≈ 0.1 → Prevalentemente exploitation
  • Q-table converge verso politica ottimale
  • Percorsi sempre più diretti ed efficienti

🎯 DOPO L'ADDESTRAMENTO

🔍 INFERENZA DETTAGLIATA

🎯 OBIETTIVO: Dimostrare la politica ottimale appresa senza più esplorare

📋 SETUP INFERENZA:

epsilon = 0;              // ZERO esplorazione, solo exploitation
isInference = true;       // Modalità inferenza attivata
isPaused = false;         // Reset stato pausa
resetAgent();             // Parte da (0,0)

⚡ CICLO INFERENZA (episodi infiniti fino a stop manuale)

OGNI STEP DI INFERENZA:

STEP 1 - OSSERVAZIONE:

let currentState = getStateString(agentPos.x, agentPos.y); // es: "4,2"

STEP 2 - SCELTA AZIONE (SOLO EXPLOITATION):

// NESSUNA esplorazione casuale!
let qValues = qTable[currentState];     // [0.8, -0.2, 2.3, 1.1]
let maxQ = Math.max(...qValues);        // 2.3
let bestActions = [];
for (let i = 0; i < qValues.length; i++) {
    if (qValues[i] === maxQ) {
        bestActions.push(i);            // [2] (azione "sinistra")
    }
}
action = bestActions[Math.floor(Math.random() * bestActions.length)];

STEP 3 - ESECUZIONE AZIONE:

let newX = agentPos.x + actions[action].x;
let newY = agentPos.y + actions[action].y;

if (isValidPosition(newX, newY)) {
    agentPos.x = newX;
    agentPos.y = newY;
    addToPathTrail(newX, newY);         // Traccia BLU per inferenza
}

STEP 4 - NESSUN APPRENDIMENTO:

// ❌ NON aggiorna Q-table!
// ❌ NON calcola reward per apprendimento!
// ✅ Solo esecuzione della politica appresa

STEP 5 - CONTROLLO OBIETTIVO:

if (agentPos.x === 9 && agentPos.y === 9) {
    // 🎯 SUCCESSO! Attiva celebrazione
    isPaused = true;
    pauseStartTime = millis();
    
    // Mostra messaggio verde: "🎯 OBIETTIVO RAGGIUNTO!"
    // Countdown 3 secondi: "Riavvio in 3... 2... 1..."
    
} else if (stepCount >= 100) {
    // ⏰ TIMEOUT: Reset immediato (non dovrebbe succedere se ben addestrato)
    resetAgent();
}

🎉 GESTIONE SUCCESSO:

function handleInferencePause() {
    if (millis() - pauseStartTime >= 3000) {  // 3 secondi di pausa
        isPaused = false;
        resetAgent();                         // Nuovo tentativo da (0,0)
        // Ciclo infinito: dimostra ripetutamente la soluzione ottimale
    }
}

🎨 VISUALIZZAZIONE INFERENZA:

  • Traccia BLU: Percorso durante inferenza (vs rosso in training)
  • Movimento più lento: frameCount % 10 (vs frameCount % 3 in training)
  • Percorso diretto: Dovrebbe seguire il percorso ottimale appreso
  • Celebrazione: Schermo verde + countdown quando raggiunge obiettivo

🔄 DIFFERENZE TRAINING vs INFERENZA:

Aspetto Training Inferenza
Epsilon 1.0 → 0.01 0.0 (fisso)
Azioni Casuali + Ottime Solo Ottime
Apprendimento ✅ Aggiorna Q-table ❌ Nessun aggiornamento
Traccia 🟥 Rossa 🟦 Blu
Velocità Veloce Più lenta (osservabile)
Reset Automatico Pausa celebrativa
Episodi 1000 fissi Infiniti

🎯 RISULTATI ATTESI:

  • Percorso ottimale: Linea diretta verso obiettivo
  • Consistenza: Stesso percorso ogni volta
  • Efficienza: Minimo numero di passi possibile
  • Successo garantito: 100% tasso di successo (se ben addestrato)

🔬 ANALISI DELLE PERFORMANCE:

Buon addestramento:

  • Percorso diretto e consistente
  • Raggiunge obiettivo in ~18 passi
  • Evita completamente ostacoli

Addestramento insufficiente:

  • Movimenti non ottimali
  • Occasionali "esitazioni"
  • Percorsi più lunghi del necessario

Statistiche monitorate

  • Episodio corrente: Numero di episodi completati
  • Punteggio medio: Media degli ultimi 100 episodi
  • Tasso di successo: Percentuale di episodi che raggiungono l'obiettivo
  • Epsilon: Livello attuale di esplorazione
  • Modalità: Stato corrente (Pronto/Training/Inferenza)

Struttura del codice

sketch.js

Contiene tutta la logica del Q-learning:

  • Gestione dell'ambiente e rendering
  • Implementazione dell'algoritmo Q-learning
  • Controllo dei pulsanti e aggiornamento delle statistiche
  • Logiche di training e inferenza

index.html

Interfaccia utente con:

  • Canvas p5.js per la visualizzazione
  • Pulsanti di controllo
  • Pannello delle statistiche
  • Styling CSS

Come funziona il Q-learning

Il Q-learning è un algoritmo di reinforcement learning che impara una funzione Q(s,a) che rappresenta la "qualità" di eseguire l'azione a nello stato s.

Formula di aggiornamento:

Q(s,a) = Q(s,a) + α × [r + γ × max(Q(s',a')) - Q(s,a)]

Dove:

  • α = learning rate (quanto velocemente si apprende)
  • r = ricompensa immediata
  • γ = discount factor (importanza delle ricompense future)
  • s' = nuovo stato
  • a' = possibili azioni nel nuovo stato

Strategia ε-greedy:

  • Con probabilità ε: scegli azione casuale (esplorazione)
  • Con probabilità 1-ε: scegli migliore azione conosciuta (exploitation)

L'agente inizia con molta esplorazione (ε=1.0) e gradualmente riduce l'esplorazione man mano che impara (ε→0.01).

Personalizzazione

Puoi modificare facilmente:

  • Dimensione della griglia (gridSize)
  • Posizioni di agente, obiettivo e ostacoli
  • Parametri di Q-learning (learning rate, discount factor, ecc.)
  • Ricompense e penalità
  • Velocità di visualizzazione

💡 Consigli per l'implementazione

Progettazione delle Ricompense

  • Ricompensa finale elevata: Incentiva il raggiungimento dell'obiettivo
  • Penalità moderate: Evita comportamenti indesiderati senza bloccare l'esplorazione
  • Costo del tempo: Piccola penalità per step incoraggia efficienza

Tuning dei Parametri

  • Learning Rate (α): 0.1-0.3 per apprendimento stabile
  • Discount Factor (γ): 0.9-0.99 per bilanciare presente/futuro
  • Epsilon Decay: Lento per problemi complessi, veloce per semplici

Monitoraggio della Convergenza

  • Tasso di successo: Percentuale di episodi che raggiungono l'obiettivo
  • Score medio: Efficienza degli episodi recenti
  • Stabilità: Variazioni minime nelle performance

Debug e Ottimizzazione

  • Visualizzazione del percorso: Tracce colorate per capire il comportamento
  • Salvataggio Q-table: Conserva l'addestramento per test multipli
  • Parametri adattivi: Epsilon decay e learning rate variabili

Tecnologie utilizzate

  • p5.js: Libreria per la visualizzazione e l'animazione
  • HTML/CSS/JavaScript: Interfaccia utente e logica
  • Q-learning: Algoritmo di reinforcement learning

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published