Ga naar hoofdinhoud

Een introductie tot Q-learning: een tutorial voor beginners

Leer over het populairste modelvrije reinforcement learning-algoritme met een Python-tutorial.
Bijgewerkt 1 jun 2026  · 11 min lezen

Q Learning Header

Reinforcement learning (RL) is het deel van het machinelearning-ecosysteem waarin de agent leert door met de omgeving te interageren om de optimale strategie te vinden voor het bereiken van de doelen. Het is heel anders dan gesuperviseerde machinelearning-algoritmen, waarbij we data moeten inladen en verwerken. Reinforcement learning heeft geen data nodig. In plaats daarvan leert het van de omgeving en het beloningssysteem om betere beslissingen te nemen.

In het Mario-videospel bijvoorbeeld, als een personage een willekeurige actie uitvoert (bijv. naar links bewegen), kan het op basis van die actie een beloning ontvangen. Nadat de actie is uitgevoerd, bevindt de agent (Mario) zich in een nieuwe toestand en herhaalt het proces zich totdat het gamepersonage het einde van het level bereikt of sterft. 

Deze episode wordt meerdere keren herhaald totdat Mario leert de omgeving te navigeren door de beloningen te maximaliseren. 

Reinforcement Learning

Afbeelding door de auteur

We kunnen reinforcement learning opdelen in vijf eenvoudige stappen:

  1. De agent bevindt zich in toestand nul in een omgeving.
  2. Hij onderneemt een actie op basis van een specifieke strategie.
  3. Hij ontvangt een beloning of straf op basis van die actie.
  4. Door te leren van eerdere zetten en de strategie te optimaliseren. 
  5. Het proces herhaalt zich totdat een optimale strategie is gevonden. 

Leer meer door onze tutorial te lezen, een Introductie tot Reinforcement Learning. Je ontdekt meer over hoe reinforcement learning werkt met codevoorbeelden. 

In deze tutorial leren we over Q-learning en begrijpen we waarom we Deep Q-learning nodig hebben. Bovendien leren we Q-learning-algoritmen vanaf nul te maken en te trainen met Numpy en OpenAI Gym.

Let op: als je nieuw bent met machine learning, raden we je aan onze carrièreroute Machine Learning Scientist met Python te volgen om Reinforcement learning en Q-learning beter te begrijpen. 

Wat is Q-learning?

Q-learning is een modelvrij, waardegestuurd, off-policy algoritme dat de beste reeks acties vindt op basis van de huidige toestand van de agent. De “Q” staat voor quality (kwaliteit). Kwaliteit geeft aan hoe waardevol de actie is voor het maximaliseren van toekomstige beloningen.  

Modelgebaseerde algoritmen gebruiken transitie- en beloningsfuncties om het optimale beleid te schatten en het model te creëren. Daarentegen leren modelloze algoritmen de gevolgen van hun acties via ervaring, zonder transitie- en beloningsfunctie. 

De waardegestuurde methode traint de waardefunctie om te leren welke toestand waardevoller is en actie te ondernemen. Anderzijds trainen beleidsgestuurde methoden het beleid rechtstreeks om te leren welke actie in een gegeven toestand moet worden genomen.

Bij off-policy evalueert en werkt het algoritme een beleid bij dat verschilt van het beleid dat is gebruikt om een actie te nemen. Omgekeerd evalueert en verbetert het on-policy algoritme hetzelfde beleid dat is gebruikt om een actie te nemen.  

Belangrijke terminologie in Q-learning

Voordat we ingaan op hoe Q-learning werkt, moeten we een paar nuttige termen leren om de basis van Q-learning te begrijpen. 

  • Toestanden (s): de huidige positie van de agent in de omgeving. 
  • Actie (a): een stap die de agent in een bepaalde toestand neemt. 
  • Beloningen: voor elke actie ontvangt de agent een beloning en een straf. 
  • Episodes: het einde van het level, waar agenten geen nieuwe actie meer kunnen ondernemen. Dit gebeurt wanneer de agent het doel heeft bereikt of heeft gefaald. 
  • Q(St+1, a): verwachte optimale Q-waarde van het uitvoeren van de actie in een bepaalde toestand. 
  • Q(St, At): dit is de huidige schatting van Q(St+1, a).
  • Q-tabel: de agent onderhoudt de Q-tabel met sets van toestanden en acties.
  • Temporal Differences (TD): gebruikt om de verwachte waarde van Q(St+1, a) te schatten door de huidige toestand en actie en de vorige toestand en actie te gebruiken. 

Hoe werkt Q-learning?

We leren in detail hoe Q-learning werkt aan de hand van het voorbeeld van een bevroren meer. In deze omgeving moet de agent het bevroren meer oversteken van start naar doel, zonder in de gaten te vallen. De beste strategie is om het doel te bereiken via het kortste pad. 

Q-Learning Visualization

Gif door de auteur

Q-tabel

De agent gebruikt een Q-tabel om de best mogelijke actie te nemen op basis van de verwachte beloning voor elke toestand in de omgeving. Simpel gezegd: een Q-tabel is een datastructuur met sets van acties en toestanden, en we gebruiken het Q-learning-algoritme om de waarden in de tabel bij te werken. 

Q-functie

De Q-functie gebruikt de Bellman-vergelijking en neemt toestand (s) en actie (a) als invoer. De vergelijking vereenvoudigt de berekening van toestandswaarden en toestand-actie-waarden. Bellman Equation

Afbeelding van freecodecamp.org

Q-learning-algoritme

Q-Learning Process

Afbeelding door de auteur

Q-tabel initialiseren

We initialiseren eerst de Q-tabel. We bouwen de tabel met kolommen op basis van het aantal acties en rijen op basis van het aantal toestanden.

In ons voorbeeld kan het personage omhoog, omlaag, links en rechts bewegen. We hebben vier mogelijke acties en vier toestanden (start, inactief, verkeerd pad en einde). Je kunt het verkeerde pad ook zien als in het gat vallen. We initialiseren de Q-tabel met waarden op 0. 

Q-Table 1

Afbeelding door de auteur

Kies een actie

De tweede stap is vrij eenvoudig. Aan het begin kiest de agent om een willekeurige actie te nemen (omlaag of rechts), en bij de tweede run gebruikt hij een bijgewerkte Q-tabel om de actie te kiezen. 

Voer een actie uit

Het kiezen en uitvoeren van een actie zal meerdere keren worden herhaald totdat de trainingslus stopt. De eerste actie en toestand worden geselecteerd met behulp van de Q-tabel. In ons geval zijn alle waarden in de Q-tabel nul. 

Vervolgens beweegt de agent omlaag en werkt hij de Q-tabel bij met behulp van de Bellman-vergelijking. Bij elke zet werken we de waarden in de Q-tabel bij en gebruiken we die ook om het beste handelingsverloop te bepalen. 

In het begin staat de agent in exploratiemodus en kiest hij een willekeurige actie om de omgeving te verkennen. De Epsilon-greedy-strategie is een eenvoudige methode om exploratie en exploitatie in balans te brengen. Epsilon staat voor de kans om te kiezen voor exploreren en exploiteren wanneer de kans om te exploreren kleiner wordt. 

Aan het begin is de epsilon-waarde hoger, wat betekent dat de agent in exploratiemodus is. Terwijl de omgeving wordt verkend, daalt epsilon en begint de agent de omgeving te exploiteren. Tijdens de exploratie wordt de agent met elke iteratie zekerder in het schatten van Q-waarden

Q-Table 2

Afbeelding door de auteur

In het voorbeeld van het bevroren meer kent de agent de omgeving niet, dus neemt hij om te beginnen een willekeurige actie (omlaag bewegen). Zoals we in de bovenstaande afbeelding kunnen zien, is de Q-tabel bijgewerkt met behulp van de Bellman-vergelijking.

Beloningen meten

Nadat de actie is uitgevoerd, meten we de uitkomst en de beloning. 

  • De beloning voor het bereiken van het doel is +1
  • De beloning voor het nemen van het verkeerde pad (in het gat vallen) is 0
  • De beloning voor inactief zijn of bewegen op het bevroren meer is ook 0. 

Q-tabel bijwerken

We werken de functie Q(St, At) bij met behulp van de vergelijking. Deze gebruikt de geschatte Q-waarden van de vorige episode, het leerpercentage en de Temporal Differences-fout. De Temporal Differences-fout wordt berekend met de directe beloning, de verdisconteerde maximale verwachte toekomstige beloning en de eerdere geschatte Q-waarde. 

Het proces wordt meerdere keren herhaald totdat de Q-tabel is bijgewerkt en de Q-waardefunctie is gemaximaliseerd. 

Q-learning equation

Afbeelding door de auteur | Vergelijkingsvisuals van Thomas Simonini

In het begin verkent de agent de omgeving om de Q-tabel bij te werken. En wanneer de Q-tabel klaar is, begint de agent te exploiteren en betere beslissingen te nemen. Q-Table 3

Afbeelding door de auteur

In het geval van een bevroren meer leert de agent het kortste pad te nemen om het doel te bereiken en te vermijden in de gaten te springen. 

Q-learning Python-tutorial 

In deze sectie bouwen we ons Q-learning-model vanaf nul met de Gym-omgeving, Pygame en Numpy. De Python-tutorial is een aangepaste versie van het Notebook van Thomas Simonini. Het omvat het initialiseren van de omgeving en de Q-tabel, het definiëren van het greedy-beleid, het instellen van hyperparameters, het maken en uitvoeren van de trainingslus en evaluatie, en het visualiseren van de resultaten.   

Als je problemen ondervindt bij het maken en uitvoeren van je trainingslus, kun je de codebron met de output bekijken.   

Aan de slag

Stel een virtueel display in

We installeren eerst alle dependencies om een replayvideo (gif) te genereren. We hebben een virtueel scherm (pyvirtualdisplay) nodig om de omgeving te renderen en de frames op te nemen. 

Let op: met %%capture onderdrukken we de output van de Jupyter-cel. 

%%capture
!pip install pyglet==1.5.1
!apt install python-opengl
!apt install ffmpeg
!apt install xvfb
!pip3 install pyvirtualdisplay

# Virtual display
from pyvirtualdisplay import Display

virtual_display = Display(visible=0, size=(1400, 900))
virtual_display.start()

Dependencies installeren

We installeren nu dependencies die ons helpen de trainingslus te maken, uit te voeren en te evalueren. 

  • gym: gebruikt om de FrozenLake-v1-omgeving te initialiseren.
  • pygame: gebruikt voor de FrozenLake-v1-UI.
  • numPy: gebruikt voor het maken en beheren van de Q-tabel.
%%capture
!pip install gym==0.24
!pip install pygame
!pip install numpy

!pip install imageio imageio_ffmpeg

Importeer de pakketten

We importeren nu de vereiste libraries. 

  • Imageio wordt gebruikt voor het maken van de animatie. 
  • tqdm wordt gebruikt voor voortgangsbalken. 
import numpy as np
import gym
import random
import imageio
from tqdm.notebook import trange

Frozen Lake Gym-omgeving 

We gaan een niet-gladde 4x4-omgeving maken met behulp van de Frozen Lake gym-bibliotheek

  • Er zijn twee rasterversies, “4x4” en “8x8”.
  • Als is_slippery=True, kan de agent niet in de bedoelde richting bewegen vanwege de gladheid van het bevroren meer. 

Na het initialiseren van de omgeving doen we een omgevingsanalyse. 

env = gym.make("FrozenLake-v1",map_name="4x4",is_slippery=False)

print("Observation Space", env.observation_space)
print("Sample observation", env.observation_space.sample()) # display a random observation

Er zijn 16 unieke ruimtes in de omgeving die op willekeurige posities worden weergegeven. 

Observation Space Discrete(16)
Sample observation 15

Laten we het aantal acties ontdekken en de willekeurige actie weergeven. 

De actie-ruimte:

  • 0: naar links bewegen
  • 1: omlaag bewegen
  • 2: naar rechts bewegen
  • 3: omhoog bewegen

Beloningsfunctie:

  • Doel bereiken: +1
  • In het gat vallen: 0
  • Op het bevroren meer blijven: 0
print("Action Space Shape", env.action_space.n)
print("Action Space Sample", env.action_space.sample())
Action Space Shape 4
Action Space Sample 1

Maak en initialiseer de Q-tabel

De Q-tabel heeft kolommen als acties en rijen als toestanden. We kunnen OpenAI Gym gebruiken om de actieruimte en toestandsruimte te vinden. We gebruiken deze informatie vervolgens om de Q-tabel te maken. 

state_space = env.observation_space.n
print("There are ", state_space, " possible states")

action_space = env.action_space.n
print("There are ", action_space, " possible actions")
There are  16  possible states
There are  4  possible actions

Voor het initialiseren van de Q-tabel maken we een Numpy-array van state_space en action space. We maken een 16 x 4-array. 

def initialize_q_table(state_space, action_space):
  Qtable = np.zeros((state_space, action_space))
  return Qtable

Qtable_frozenlake = initialize_q_table(state_space, action_space)

Epsilon-greedy-beleid

In de vorige sectie hebben we geleerd over de epsilon-greedy-strategie die de afweging tussen exploratie en exploitatie beheert. Met een kans van 1 - ɛ doen we exploitatie, en met de kans ɛ doen we exploratie. 

In de epsilon_greedy_policy zullen we:

  1. Het willekeurige getal tussen 0 en 1 genereren.
  2. Als het willekeurige getal groter is dan epsilon, doen we exploitatie. Dat betekent dat de agent de actie neemt met de hoogste waarde gegeven een toestand.
  3. Anders doen we exploratie (willekeurige actie nemen). 
def epsilon_greedy_policy(Qtable, state, epsilon):
  random_int = random.uniform(0,1)
  if random_int > epsilon:
    action = np.argmax(Qtable[state])
  else:
    action = env.action_space.sample()
  return action

Definieer het greedy-beleid

Zoals we nu weten is Q-learning een off-policy algoritme, wat betekent dat het beleid voor het nemen van actie en het bijwerken van de functie verschillend is. 

In dit voorbeeld is het Epsilon-greedy-beleid het handelingsbeleid en het Greedy-beleid het bijwerkbeleid. 

Het Greedy-beleid zal ook het uiteindelijke beleid zijn wanneer de agent is getraind. Het wordt gebruikt om de hoogste toestand- en actiewaarde uit de Q-tabel te selecteren.

def greedy_policy(Qtable, state):
  action = np.argmax(Qtable[state])
  return action

Modelhyperparameters

Deze hyperparameters worden gebruikt in de trainingslus, en het fine-tunen ervan levert je betere resultaten op. 

De agent moet genoeg toestandsruimte verkennen om een goede waarde-benadering te leren; we hebben een progressieve afname van epsilon nodig. Als de afname te sterk is, kan de agent vastlopen omdat hij niet genoeg toestandsruimte heeft verkend.

  • Er zijn 10.000 trainings- en 100 evaluatie-episodes.
  • Het leerpercentage is 0,7.
  • We gebruiken "FrozenLake-v1" als omgeving met 99 maximale stappen per episode.
  • De gamma (kortingsfactor) is 0,95.
  • eval_seed: evaluatie-seed voor de omgeving.
  • De epsilon-kans voor exploratie aan het begin is 1,0, en de minimale kans is 0,05.
  • De exponentiële afname voor de epsilon-kans is 0,0005.
# Training parameters
n_training_episodes = 10000
learning_rate = 0.7        

# Evaluation parameters
n_eval_episodes = 100      

# Environment parameters
env_id = "FrozenLake-v1"   
max_steps = 99             
gamma = 0.95               
eval_seed = []             

# Exploration parameters
max_epsilon = 1.0           
min_epsilon = 0.05           
decay_rate = 0.0005           

Modeltraining 

In de trainingslus zullen we:

  1. Een lus maken voor trainingsepisodes.
  2. We verlagen eerst epsilon. We hebben met elke episode minder exploratie en meer exploitatie nodig. 
  3. De omgeving resetten.
  4. Een geneste lus maken voor het maximum aantal stappen.
  5. De actie kiezen met behulp van het epsilon-greedy-beleid. 
  6. Actie (At) ondernemen en de verwachte beloning (Rt+1) en toestand (St+1) observeren.
  7. De actie (a) nemen en de resulterende toestand (s') en beloning (r) observeren.
  8. De Q-functie bijwerken met behulp van de formule. 
  9. Als done= True, de episode beëindigen en de lus breken.
  10. Tot slot de huidige toestand wijzigen naar de nieuwe toestand. 
  11. Na het afronden van alle trainingsepisodes retourneert de functie de bijgewerkte Q-tabel. 
def train(n_training_episodes, min_epsilon, max_epsilon, decay_rate, env, max_steps, Qtable):
  for episode in trange(n_training_episodes):
 
    epsilon = min_epsilon + (max_epsilon - min_epsilon)*np.exp(-decay_rate*episode)
    # Reset the environment
    state = env.reset()
    step = 0
    done = False

    # repeat
    for step in range(max_steps):
   
      action = epsilon_greedy_policy(Qtable, state, epsilon)

   
      new_state, reward, done, info = env.step(action)

   
      Qtable[state][action] = Qtable[state][action] + learning_rate * (reward + gamma * np.max(Qtable[new_state]) - Qtable[state][action])

      # If done, finish the episode
      if done:
        break
     
      # Our state is the new state
      state = new_state
  return Qtable

Het kostte ons 3 seconden om 10.000 trainingsepisodes te voltooien. 

Qtable_frozenlake = train(n_training_episodes, min_epsilon, max_epsilon, decay_rate, env, max_steps, Qtable_frozenlake)

Training Episodes Outcome

Zoals we zien, heeft de getrainde Q-tabel waarden, en de agent zal deze waarden nu gebruiken om door de omgeving te navigeren en het doel te bereiken.  

Qtable_frozenlake
array([[0.73509189, 0.77378094, 0.77378094, 0.73509189],
      [0.73509189, 0.        , 0.81450625, 0.77378094],
      [0.77378094, 0.857375  , 0.77378094, 0.81450625],
      [0.81450625, 0.        , 0.77378094, 0.77378094],
      [0.77378094, 0.81450625, 0.        , 0.73509189],
      [0.        , 0.        , 0.        , 0.        ],
      [0.        , 0.9025    , 0.        , 0.81450625],
      [0.        , 0.        , 0.        , 0.        ],
      [0.81450625, 0.        , 0.857375  , 0.77378094],
      [0.81450625, 0.9025    , 0.9025    , 0.        ],
      [0.857375  , 0.95      , 0.        , 0.857375  ],
      [0.        , 0.        , 0.        , 0.        ],
      [0.        , 0.        , 0.        , 0.        ],
      [0.        , 0.9025    , 0.95      , 0.857375  ],
      [0.9025    , 0.95      , 1.        , 0.9025    ],
      [0.        , 0.        , 0.        , 0.        ]])

Evaluatie

De evaluate_agent draait voor n_eval_episodes episodes en retourneert het gemiddelde en de standaarddeviatie van de beloning. 

  1. In de lus controleren we eerst of er een evaluatie-seed is. Zo niet, dan resetten we de omgeving zonder seed. 
  2. De geneste lus draait tot max_steps.
  3. De agent neemt de actie die de maximale verwachte toekomstige beloning heeft in een gegeven toestand met behulp van de Q-tabel. 
  4. Bereken de beloning.
  5. Verander de toestand.
  6. Als done (agent valt in het gat of doel is bereikt), breek de lus.
  7. Resultaten toevoegen.
  8. Uiteindelijk gebruiken we deze resultaten om het gemiddelde en de standaarddeviatie te berekenen. 
def evaluate_agent(env, max_steps, n_eval_episodes, Q, seed):

  episode_rewards = []
  for episode in range(n_eval_episodes):
    if seed:
      state = env.reset(seed=seed[episode])
    else:
      state = env.reset()
    step = 0
    done = False
    total_rewards_ep = 0
   
    for step in range(max_steps):
      # Take the action (index) that have the maximum reward
      action = np.argmax(Q[state][:])
      new_state, reward, done, info = env.step(action)
      total_rewards_ep += reward
       
      if done:
        break
      state = new_state
    episode_rewards.append(total_rewards_ep)
  mean_reward = np.mean(episode_rewards)
  std_reward = np.std(episode_rewards)

  return mean_reward, std_reward

Zoals je ziet hebben we de perfecte score met nul standaarddeviatie. Dat betekent dat onze agent in alle 100 episodes het doel heeft bereikt. 

# Evaluate our Agent
mean_reward, std_reward = evaluate_agent(env, max_steps, n_eval_episodes, Qtable_frozenlake, eval_seed)
print(f"Mean_reward={mean_reward:.2f} +/- {std_reward:.2f}")
Mean_reward=1.00 +/- 0.00

Resultaat visualiseren

Tot nu toe hebben we met cijfers gewerkt, en om de demo te geven moeten we een geanimeerde gif maken van de agent vanaf de start tot hij het doel bereikt. 

  1. We maken eerst de toestand door de omgeving te resetten met een willekeurig geheel getal 0-500. 
  2. Render de omgeving met rdb_array om een afbeeldingsarray te maken. 
  3. Voeg vervolgens de img toe aan de images-array. 
  4. In de lus zetten we de stap met behulp van de Q-tabel en renderen we bij elke stap de afbeelding. 
  5. Uiteindelijk gebruiken we deze array en imageio om een gif te maken van één frame per seconde. 
def record_video(env, Qtable, out_directory, fps=1):
  images = [] 
  done = False
  state = env.reset(seed=random.randint(0,500))
  img = env.render(mode='rgb_array')
  images.append(img)
  while not done:
    # Take the action (index) that have the maximum expected future reward given that state
    action = np.argmax(Qtable[state][:])
    state, reward, done, info = env.step(action) # We directly put next_state = state for recording logic
    img = env.render(mode='rgb_array')
    images.append(img)
  imageio.mimsave(out_directory, [np.array(img) for i, img in enumerate(images)], fps=fps)

Als je in een Jupyter-notebook werkt, kun je de gif weergeven met de Image-functie van IPython.display

video_path="/content/replay.gif"
video_fps=1
record_video(env, Qtable_frozenlake, video_path, video_fps)

from IPython.display import Image
Image('./replay.gif')

Je kunt deze resultaten nu delen met je collega’s en studiegenoten of posten op sociale media.

Veelgestelde vragen over Q-learning

Wat is het nadeel van Q-learning?

Het leerproces in Q-learning is kostbaar voor de agent, vooral in de eerste stappen. Waarom is dat? Om tot een optimaal beleid te convergeren, wordt elk toestand- en actiepaar vaak bezocht.

Waarom heet Q-learning zo?

In Q-learning staat ‘Q’ voor quality (kwaliteit). Het geeft aan hoe nuttig een bepaalde actie is bij het behalen van toekomstige beloningen, wat wordt gebruikt om een kaartsysteem van toestand en actie te creëren om verwachte beloningen te maximaliseren.

Waarom is Q-learning off-policy?

In Q-learning verschilt het bijgewerkte beleid van het gedrags- (actie)beleid, en daarom wordt het een off-policy algoritme genoemd.

Convergeert Q-learning altijd?

Ja. Tijdens het trainen convergeert het algoritme altijd naar het optimale beleid.

Waarom hebben we deep Q-learning nodig?

Q-learning is een eenvoudig algoritme dat is ontworpen voor een kleinere en discrete omgeving. In het geval van een grotere omgeving hebben we een enorm grote Q-tabel van toestanden en acties nodig, die veel geheugen en rekenkracht kost om te trainen. Deep Q-learning daarentegen vervangt de Q-tabel door een neuraal netwerk om grote omgevingen aan te kunnen die continue acties en toestanden omvatten.

Onderwerpen

Courses over machine learning

Cursus

Machine Learning-workflows ontwerpen in Python

4 Hr
12.6K
Leer pijpleidingen bouwen die lang meegaan.
Bekijk detailsRight Arrow
Begin met de cursus
Meer zienRight Arrow
Gerelateerd

blog

AI vanaf nul leren in 2026: een complete gids van de experts

Ontdek alles wat je moet weten om in 2026 AI te leren, van tips om te beginnen tot handige resources en inzichten van industrie-experts.
Adel Nehme's photo

Adel Nehme

15 min

Meer zienMeer zien