Ga naar hoofdinhoud

Aan de slag met TorchRL voor Deep Reinforcement Learning

Een beginnersvriendelijke gids voor TorchRL voor deep reinforcement learning — leer RL‑agenten bouwen met PyTorch aan de hand van praktische voorbeelden.
Bijgewerkt 2 okt 2026  · 15 min lezen

Verken met AI

ChatGPTClaudePerplexity

Reinforcement Learning (RL) wordt gebruikt om allerlei complexe problemen op te lossen, van het trainen van zelfrijdende auto’s tot het trainen van large language models (LLM’s) om mensachtige reacties te geven. 

RL‑agenten worden getraind om te reageren op basis van menselijke feedback, met Reinforcement Learning from Human Feedback (RLHF). Hoewel Python‑gebaseerde frameworks zoals Keras en TensorFlow in enterprise‑toepassingen voor deep learning worden gebruikt, zijn de meeste nieuwe projecten tegenwoordig gebaseerd op PyTorch en PyTorch Lightning.

TorchRL is een open‑sourcelibrary voor het bouwen van RL‑oplossingen met PyTorch. In deze tutorial laat ik je zien hoe je TorchRL instelt, de onderliggende componenten begrijpt en het gebruikt om een eenvoudige RL‑agent te bouwen. We bespreken ook hoe je TorchRL inzet om kant‑en‑klare versies van RL‑algoritmen zoals Proximal Policy Optimization (PPO) te implementeren. Tot slot behandelen we de basisprincipes van het loggen en monitoren van RL‑agenten.

Wat is TorchRL en waarom zou je het gebruiken?

RL‑algoritmen zijn vaak complex. Je moet de agent(en) maken, de returns en verliezen berekenen, de forward‑ en backward‑passes definiëren en de prestaties van de agent evalueren. 

TorchRL verpakt veel gangbare RL‑functies in modules die je direct kunt gebruiken. Dit maakt het makkelijker om verschillende algoritmen te implementeren en ermee te experimenteren om praktische problemen op te lossen. Het vereenvoudigt ook het bouwen van nieuwe algoritmen, omdat onderzoekers toegang hebben tot de rest van het RL‑ecosysteem zonder het zelf te hoeven bouwen. 

TorchRL bevat veel vooraf gebouwde modules die RL‑ontwikkeling efficiënter maken. Bijvoorbeeld: 

  • Omgevingen: TorchRL biedt een gestandaardiseerde API om RL‑omgevingen uit verschillende bronnen te importeren en te gebruiken, inclusief Gymnasium, Jumanji, RoboHive, en meer. In veel gevallen is het nodig de output van de omgeving aan te passen aan specifieke trainingsbehoeften. TorchRL bevat modules voor diverse omgevingstransformaties met één enkele functieaanroep met de gewenste parameters. 
  • Datacollectors en replay‑buffers: Veel RL‑trainingsalgoritmen houden in dat je gegevens verzamelt over de interacties van de agent met de omgeving: de actie van de agent, de beloning die hij kreeg en de volgende toestand waarin hij terechtkwam. TorchRL bevat pakketten met de datastructuren om deze informatie te verzamelen en te samplen. 
  • Doelfuncties: De kernmethodologie van een RL‑algoritme zit in de doelfunctie. TorchRL verpakt gangbare RL‑algoritmen zoals DQN (Deep Q Networks), A2C (Advantage Actor‑Critic), PPO en veel meer in vooraf gebouwde modules die je direct kunt aanroepen om de agent te trainen. 

Gezien bovenstaande functionaliteit blijkt TorchRL nuttig om het bouwen van RL‑oplossingen te stroomlijnen en te vereenvoudigen voor uiteenlopende use‑cases, zoals:

  • Robotica: De robot moet leren zich succesvol door een complexe omgeving te bewegen. Hij wordt bestraft voor struikelen of anderszins falen. Met RL‑trainingsmethoden leert hij de juiste acties om bijvoorbeeld een oneffen natuurlijke ondergrond te doorkruisen. 
  • Game‑AI: Computertegenstanders in video‑ en consolegames moeten hun zetten bedenken en aanpassen in reactie op de acties van de menselijke speler. RL, met beloningen en straffen, wordt gebruikt om zulke spelers te trainen om de juiste zetten te kiezen tegen de mens. 
  • Autonome systemen: Zelfrijdende auto’s moeten zelfstandig door een complexe omgeving (zoals verkeer) navigeren en het doel (de bestemming bereiken) zonder ongelukken halen. RL wordt gebruikt om autonome systemen te trainen om het gedrag van een menselijke bestuurder onder uiteenlopende realistische omstandigheden na te bootsen. 

TorchRL instellen

In deze sectie laat ik je zien hoe je TorchRL installeert en ermee start. 

Vereisten

Je hebt enkele afhankelijkheden nodig voordat je TorchRL kunt installeren en gebruiken:

  • PyTorch: TorchRL is gebaseerd op PyTorch, dus dat is een vereiste. 
  • Gymnasium: Je hebt het Gymnasium‑pakket nodig om RL‑omgevingen te importeren. Sinds jan. 2025 is de nieuwste versie van Gymnasium niet compatibel met TorchRL, zoals uitgelegd op deze Git Discussions‑pagina. Installeer daarom de oudere versie 0.29.1. 
  • PyGame: Dit is een Python‑pakket voor videogames.  TorchRL heeft het nodig om game‑achtige RL‑omgevingen, zoals CartPole, te simuleren. 
  • TensorDict: Werken met een dictionary‑achtige datastructuur om de input en output van neurale netwerken op te slaan, maakt het handig om met tensors in TorchRL te werken. TensorDict biedt een tensorcontainer die tensors als key‑valueparen opslaat. 

Installeer de vereiste pakketten:

!pip install torch tensordict  gymnasium==0.29.1 pygame

TorchRL installeren

Installeer TorchRL met pip. Ik raad sterk aan om deze pakketten in een Conda‑omgeving te installeren als je op een pc of server werkt. 

!pip install torchrl

De installatie verifiëren

Test na installatie of TorchRL succesvol is geïnstalleerd. Probeer torchrl te importeren in een Python‑shell (of notebook). Gebruik de methode check_env_specs() om te controleren dat een standaardomgeving (zoals CartPole) overeenkomt met de specificaties van torchrl:

import torchrl 
from torchrl.envs import GymEnv 
from torchrl.envs.utils import check_env_specs

check_env_specs(GymEnv("CartPole-v1"))

De output zou moeten aangeven dat de omgeving succesvol is aangemaakt en werkt met TorchRL. 

[torchrl][INFO] check_env_specs succeeded!

Belangrijke componenten van TorchRL

Voordat je je eerste RL‑agent bouwt, bekijken we de kernbouwstenen van TorchRL.

Omgevingen

TorchRL biedt een uniforme API om met verschillende omgevingen te interfacen. Het doet dit door specifieke functionaliteit van omgevingen te wrappen in een standaardset wrapperclasses en ‑functies. Je geeft de juiste parameters door aan de wrapper, en die mapt je opdracht intern naar de corresponderende functieaanroep van de specifieke omgeving. Concreet:

  • TorchRL zet omgevingsstaten (observaties), acties en beloningen om in PyTorch‑tensorobjecten, die direct gebruikt kunnen worden door de modules die RL‑algoritmen implementeren.
  • Het maakt het mogelijk om pre‑ en postprocessingstappen toe te passen, bijvoorbeeld om inputtensors te normaliseren en schalen of om outputtensors in een specifiek formaat aan te bieden.

Maak bijvoorbeeld een omgeving uit Gymnasium met de module GymEnv:

env = GymEnv("CartPole-v1")

Transformaties

Het is gebruikelijk om de standaardomgeving uit te breiden met extra functies en transformaties die je anders zelf zou moeten implementeren. Zo kun je een step‑countermodule toevoegen in plaats van die teller zelf te coderen. De step‑counter houdt het aantal stappen per episode bij. De module transformedEnv helpt hierbij:

from torchrl.envs import GymEnv, StepCounter, TransformedEnv
env = TransformedEnv(GymEnv("CartPole-v1"), StepCounter())

Op dezelfde manier is het normaliseren van tensors voor bewerking een gangbare preprocesstap. Een normalisatietransformatie met de module ObservationNorm normaliseert de tensors. De documentatie van de functie TransformedEnv bespreekt verschillende soorten transformaties. 

Je kunt ook meerdere transformaties combineren met de parameter compose():

base_env = GymEnv('CartPole-v1', device=device) 

env = TransformedEnv( 
    base_env, 
    Compose(
        ObservationNorm(in_keys=["observation"]), 
        StepCounter()
    )
)

Agenten en policies

In RL bepaalt de agent zijn acties met behulp van de policy en op basis van de geobserveerde toestand van de omgeving. Het doel van de agent is om de cumulatieve beloningen uit de omgeving te maximaliseren. Hij ontvangt beloningen wanneer hij de juiste actie kiest (zoals stoppen voor een rood licht). 

In een zelfrijdende auto bestuurt de agent bijvoorbeeld de auto. Zijn beslissingen (zoals sturen in een bepaalde richting) zijn gebaseerd op zijn observaties van de toestand van de omgeving (zoals verkeer, de positie van de auto, enz.) en zijn policy (zoals voetgangers en andere obstakels vermijden, stoppen bij rood licht, enz.). 

De eenvoudigste policy is om willekeurig een actie te kiezen. De actor kiest dan willekeurig een van de acties uit de ruimte van mogelijke acties. Een willekeurige policy wordt soms gebruikt om een initiële dataset van interacties te genereren voordat het model wordt getraind. 

Gebruik de module RandomPolicy om een willekeurige policy te maken. Deze willekeurige policy accepteert een parameter action_spec die de actieruimte specificeert. In het onderstaande voorbeeld bestaat de actieruimte uit (continue) getallen tussen −1 en +1. De willekeurige policy kiest dus een actie die wordt weergegeven door een willekeurig getal tussen −1 en +1. 

import torchrl 
import torch
from tensordict import TensorDict
from torchrl.data.tensor_specs import Bounded

action_spec = Bounded(-torch.ones(1), torch.ones(1))
actor = torchrl.envs.utils.RandomPolicy(action_spec=action_spec) 
td = actor(TensorDict({}, batch_size=[])) 
print(td.get("action"))

De output zou een tensor moeten zijn, zoals hieronder:

tensor([0.9258])

Controleer dat de policy inderdaad willekeurig is door de actor nogmaals uit te voeren:

td = actor(TensorDict({}, batch_size=[])) 
print(td.get("action"))

Er zou een andere willekeurige tensor moeten worden geprint.

Heb je een opfrisser nodig over RL‑concepten? Bekijk de skill track Reinforcement Learning in Python op DataCamp!

Je eerste RL‑agent bouwen met TorchRL

In deze sectie laat ik zien hoe je een eenvoudige Reinforcement Learning‑agent implementeert met TorchRL. 

Importeer vooraf de vereiste softwarepakketten in Python:

  • time om de tijd te meten die nodig is om de agent te trainen.
  • GymEnv, StepCounter en TransformedEnv om met Gymnasium‑omgevingen te werken.
  • MLP om een eenvoudig MLP‑neuraal netwerk (multi‑layer perceptron) te maken. 
  • EGreedyModule om exploratie en exploitatie in balans te houden.
  • QValueModule en DQNLoss om het Deep Q‑Learning‑algoritme te implementeren.
  • SoftUpdate om het neuraal netwerk te updaten.
  • SyncDataCollector om gegevens te verzamelen uit de interacties van de agent. 
  • ReplayBuffer om de gegevens uit de interacties van de agent op te slaan.
  • Adam voor backpropagatie.
  • matplotlib om de trainingsvoortgang visueel te tonen. 
  • torchrl_logger om de trainingssessie te loggen.
import time
import matplotlib.pyplot as plt
from torchrl.envs import GymEnv, StepCounter, TransformedEnv
from tensordict.nn import TensorDictModule as TensorDict, TensorDictSequential as Seq
from torchrl.modules import EGreedyModule, MLP, QValueModule
from torchrl.objectives import DQNLoss, SoftUpdate
from torchrl.collectors import SyncDataCollector
from torchrl.data import LazyTensorStorage, ReplayBuffer
from torch.optim import Adam
from torchrl._utils import logger as torchrl_logger

Stap 1: Definieer de omgeving

In dit voorbeeld lossen we de CartPole‑omgeving op. Importeer deze omgeving uit Gymnasium, samen met een step‑counter om het aantal trainingsstappen bij te houden:

env = TransformedEnv(GymEnv("CartPole-v1"), StepCounter())

Seed de Python‑ en RL‑omgevingen om vergelijkbare resultaten over trainingssessies heen te reproduceren. 

torch.manual_seed(0)
env = TransformedEnv(GymEnv("CartPole-v1"), StepCounter())
env.set_seed(0)

Definieer de parameters en hyperparameters voor de training: 

  • INIT_RAND_STEPS: Het aantal stappen waarvoor de agent willekeurig handelt voordat de policy wordt gebruikt. Deze initiële stappen verzamelen data om met het trainen van de policy te starten.
  • FRAMES_PER_BATCH: Het aantal datapuntjes (één per interactie of timestep) in een trainingsbatch. 
  • OPTIM_STEPS: Het aantal stappen waarover verliezen worden geaccumuleerd voordat één backward‑pass wordt uitgevoerd. 
  • EPS_0: De beginwaarde van epsilon, de exploratiecoëfficiënt. 
  • BUFFER_LEN: De grootte van de replay‑buffer.
  • ALPHA: De learning rate.
  • TARGET_UPDATE_EPS: De vervalfactor voor het updaten van het targetnetwerk met de soft‑update‑module.
  • REPLAY_BUFFER_SAMPLE: De grootte van de willekeurige sample die in elke trainingsiteratie uit de replay‑buffer wordt getrokken. De replay‑buffer slaat per timestep de resultaten op van de interacties van de agent met de omgeving. 
  • LOG_EVERY: Het aantal stappen waarna de trainingsvoortgang wordt geprint.
  • MLP_SIZE: De grootte van het neuraal netwerk.
INIT_RAND_STEPS = 5000 
FRAMES_PER_BATCH = 100
OPTIM_STEPS = 10
EPS_0 = 0.5
BUFFER_LEN = 100_000
ALPHA = 0.05
TARGET_UPDATE_EPS = 0.95
REPLAY_BUFFER_SAMPLE = 128
LOG_EVERY = 1000
MLP_SIZE = 64

Stap 2: Maak de policy

Definieer een eenvoudig neuraal netwerk om de policy te implementeren: 

  • Definieer de MLP (neuraal netwerk). Gegeven een observatie geeft de MLP de actie‑waarde terug en vervult zo de rol van de Q‑functie. 
  • Definieer een tensordictionary met de module TensorDict op bovenstaande MLP. Deze dictionary mappt de statusobservaties van de omgeving (dictionarykeys) naar de actie‑kanswaarden (dictionaryvalues) die bij die status horen. 
  • Gebruik de QValueModule om de Q‑functie te implementeren. Gegeven een tensor met actie‑waarden retourneert deze de actie die hoort bij de hoogste actie‑waarde. Dit implementeert de greedy‑ (exploitatie)strategie. 
  • Combineer (met de module TensorDictSequential) de tensordictionary van de MLP en de QValueModule om de policy te definiëren. 
value_mlp = MLP(out_features=env.action_spec.shape[-1], num_cells=[MLP_SIZE, MLP_SIZE])
value_net = TensorDict(value_mlp, in_keys=["observation"], out_keys=["action_value"])
policy = Seq(value_net, QValueModule(spec=env.action_spec))
  • Definieer de exploratiefunctie met de EGreedyModule — die neemt de actieruimte van de omgeving, de lengte van de replay‑buffer en de exploratiecoëfficiënt epsilon. Koppel (met de module TensorDictSequential) deze exploratiefunctie aan de hierboven gedefinieerde policy om de definitieve policy te krijgen:
exploration_module = EGreedyModule(
    env.action_spec, annealing_num_steps=BUFFER_LEN, eps_init=EPS_0
)
policy_explore = Seq(policy, exploration_module)

Stap 3: Train de agent

De eerste stap in het trainen van de agent is het verzamelen van de gegevens uit de interacties van de agent met de omgeving. Gebruik de SyncDataCollector om een collector te bouwen die de policy uitvoert en de resultaten van de interacties van de agent verzamelt: 

collector = SyncDataCollector(
    env,
    policy_explore,
    frames_per_batch=FRAMES_PER_BATCH,
    total_frames=-1,
    init_random_frames=INIT_RAND_STEPS,
)

Maak een replay‑buffer om de resultaten van de interacties op te slaan:

rb = ReplayBuffer(storage=LazyTensorStorage(BUFFER_LEN))

Je moet ook trainingsspecifieke modules declareren, zoals de verliesfunctie (voor DQN‑gebaseerde verliesberekening), de optimizer (de traditionele Adam‑algoritme) en de updaterfuncties (om het neuraal netwerk te updaten). Dit alles is gebaseerd op vooraf gedefinieerde TorchRL‑modules:

loss = DQNLoss(value_network=policy, action_space=env.action_spec, delay_value=True)
optim = Adam(loss.parameters(), lr=ALPHA)
updater = SoftUpdate(loss, eps=TARGET_UPDATE_EPS)

Initialiseer de tellers om het totale aantal stappen en episodes, succesvolle stappen per episode en de uitvoeringstijd bij te houden:

total_count = 0
total_episodes = 0
t0 = time.time()
success_steps = []

De training bestaat uit 2 for‑lussen: 

  • De buitenste lus voert de policy uit en voegt de resultaten van de interacties van de agent toe aan de replay‑buffer.
  • De binnenste lus splitst de trainingssamples in batches. Elke batch wordt als volgt verwerkt: 
    • Kies een willekeurige sample uit de replay‑buffer.
    • Bereken de verliezen met de verliesfunctie.
    • Voer de optimizer en updater uit.
    • Update de tellers.

Elke stap bestaat uit het aanroepen van vooraf gebouwde TorchRL‑modules zonder iets from scratch te coderen. De onderstaande code laat zien hoe je deze stappen implementeert:

for i, data in enumerate(collector):
    rb.extend(data)
    max_length = rb[:]["next", "step_count"].max()
    if len(rb) > INIT_RAND_STEPS:
        for _ in range(OPTIM_STEPS):
            sample = rb.sample(REPLAY_BUFFER_SAMPLE)
            loss_vals = loss(sample)
            loss_vals["loss"].backward()
            optim.step()

            optim.zero_grad()
            # Update exploratiefactor
            exploration_module.step(data.numel())

            # Update targetparameters
            updater.step()
            total_count += data.numel()
            total_episodes += data["next", "done"].sum()
    success_steps.append(max_length)

Stap 4: Evalueer de agent

De lus in de vorige sectie traint de policy continu. We moeten criteria instellen om de prestaties te evalueren en beslissen wanneer we de training als succesvol beschouwen. We willen de voortgang ook uitprinten. 

We printen de voortgang van de training periodiek met de TorchRL‑logger:

if total_count > 0 and total_count % LOG_EVERY == 0:
    torchrl_logger.info(f"Successful steps in the last episode: {max_length}, rb length {len(rb)}, Number of episodes: {total_episodes}")

We gebruiken het maximale aantal stappen dat de agent in de laatste episode bereikte om te bepalen of de training succesvol is. De CartPole‑v1‑omgeving begrenst het maximale aantal stappen en de totale beloning per episode op 500. Het is gebruikelijk om een policy als succesvol te beschouwen als die meer dan 475 stappen behaalt:

if max_length > 475:
    print("TRAINING COMPLETE")
    break

Bovenstaande twee codefragmenten moeten aan het einde van de trainingslus (zoals eerder getoond) worden toegevoegd. Onderstaande snippet toont de trainingslus met de code om de agent te evalueren: 

for i, data in enumerate(collector):
    # Write data in replay buffer
    rb.extend(data)
    max_length = rb[:]["next", "step_count"].max()
    if len(rb) > INIT_RAND_STEPS:
        for _ in range(OPTIM_STEPS):
            sample = rb.sample(REPLAY_BUFFER_SAMPLE)
            loss_vals = loss(sample)
            loss_vals["loss"].backward()
            optim.step()

            optim.zero_grad()
            # Update exploratiefactor
            exploration_module.step(data.numel())

            # Update target params
            updater.step()
            total_count += data.numel()
            total_episodes += data["next", "done"].sum()
    success_steps.append(max_length)

    if total_count > 0 and total_count % LOG_EVERY == 0:
        torchrl_logger.info(f"Successful steps in the last episode: {max_length}, rb length {len(rb)}, Number of episodes: {total_episodes}")

    if max_length > 475:
        print("TRAINING COMPLETE")
        break

Print tot slot na de training en evaluatie de totale trainingstijd en plot de trainingsvoortgang:

t1 = time.time()

torchrl_logger.info(
    f"solved after {total_count} steps, {total_episodes} episodes and in {t1-t0}s."
)

def plot_steps():
    plt.plot(success_steps)
    plt.title('Successful steps over training episodes')
    plt.xlabel('Training episodes')
    plt.ylabel('Steps')
    plt.show()

plot_steps()

Je kunt de volledige code om DQN te implementeren met TorchRL in deze DataLab‑workbook vinden en uitvoeren. 

In deze sectie hebben we een RL‑agent gebouwd en getraind met het eenvoudige DQN‑algoritme. In de volgende sectie verkennen we hoe je vooraf gebouwde TorchRL‑modules gebruikt om een complexer algoritme zoals PPO te implementeren. 

Voorgebouwde algoritmen in TorchRL verkennen

Zoals eerder vermeld, wordt TorchRL geleverd met een aantal vooraf gebouwde algoritmen. Laten we ernaar kijken en zien hoe ze werken.

Ondersteunde algoritmen

TorchRL bevat vooraf gebouwde modules voor veel gangbare Deep Reinforcement Learning‑algoritmen, zoals: 

  • Deep Q Networks (DQN)
  • Deep Deterministic Policy Gradient (DDPG)
  • Soft Actor‑Critic (SAC)
  • Randomized Ensembled Double Q‑learning (REDQ)
  • CrossQ
  • Implicit Q‑learning (IQL)
  • Conservative/Continuous Q‑learning (CQL)
  • Generative Adversarial Imitation Learning (GAIL)
  • Decision Transformer (DT)
  • Twin‑Delayed DDPG (TD3) 
  • Actor‑Advantage Critic (A2C)
  • Proximal Policy Optimization (PPO)
  • REINFORCE
  • en meer 

Dit maakt het efficiënt om met verschillende typen algoritmen te experimenteren en de prestaties van elk te bestuderen voor het oplossen van een bepaald probleem. 

Voorbeeld: PPO in TorchRL

Proximal Policy Optimization gebruikt een geknipte surrogaatdoelfunctie voor een soepel trainingsproces dat exploratie en exploitatie in balans houdt. 

In deze sectie laat ik zien hoe je de vooraf gebouwde PPO‑module in TorchRL gebruikt. Net als bij de eerdere implementatie importeer je de vereiste modules. Naast de modules (zoals ReplayBuffer, SyncDataCollector, enz.) die voor de vorige implementatie nodig waren, heb je voor PPO nog enkele extra pakketten nodig:

  • ProbabilisticActor, om een actie stochastisch te kiezen. Een actie stochastisch kiezen (in plaats van altijd de policy te volgen en de beloning te maximaliseren) bevordert exploratie van de omgeving en het ontdekken van optimalere paden tijdens training.
  • OneHotCategorical, om een one‑hot‑codering te genereren van de tensor die de logkansen van de acties weergeeft. 
  • ValueOperator, om een TorchRL‑module te bouwen op basis van het neuraal netwerk dat de waardefunctie implementeert.
  • GAE, om de generalized advantage estimate te implementeren. PPO gebruikt een advantage‑functie als proxy voor de waardefunctie. De valuemodule (hierboven) is een input voor de GAE. 
  • ClipPPOLoss, om de geknipte doelfunctie voor PPO te bouwen. 
import torch
from torch import nn

from torchrl.envs import Compose, ObservationNorm, DoubleToFloat, StepCounter, TransformedEnv
from torchrl.envs.libs.gym import GymEnv
from torchrl.envs.utils import check_env_specs
from torchrl.modules import ProbabilisticActor, OneHotCategorical, ValueOperator
from torchrl.collectors import SyncDataCollector
from torchrl.data.replay_buffers import ReplayBuffer
from torchrl.data.replay_buffers.storages import LazyTensorStorage
from torchrl.data.replay_buffers.samplers import SamplerWithoutReplacement
from torchrl.objectives.value import GAE
from torchrl.objectives import ClipPPOLoss
from tensordict.nn import TensorDictModule

Declareer de parameters en hyperparameters voor de training:

  • FRAMES_PER_BATCH: Het aantal frames (timesteps) in elke batch data die voortkomt uit de interacties van de agent met de omgeving. 
  • SUB_BATCH_SIZE: Het aantal timesteps in elke subbatch. In PPO‑training wordt elke batch verdeeld in subbatches. 
  • TOTAL_FRAMES: Het totale aantal timesteps waarover je de training laat lopen. 
  • GAMMA: De discontovoet om de waarde van toekomstige beloningen te verdisconteren.
  • CLIP_EPSILON: Dit definieert de trust region waarbinnen de policy in opeenvolgende iteraties mag veranderen. Dit wordt geïmplementeerd door de geüpdatete policy te clippen zodat de verhouding tussen nieuwe en oude kansen binnen een bepaalde limiet valt. 
  • ALPHA: De learning rate.
  • ENTROPY_EPS: Deze hyperparameter stuurt de verhouding tussen exploratie en exploitatie. 
  • OPTIM_STEPS: Hoe vaak de optimizer op elke subbatch data wordt uitgevoerd. 
  • LOG_EVERY: Het aantal stappen waarna de policy wordt geëvalueerd en de beloningen worden geprint. 
FRAMES_PER_BATCH = 1024
TOTAL_FRAMES = 1048576
GAMMA = 0.99
LAMBDA = 0.95
CLIP_EPSILON = 0.2
ALPHA = 1e-4
ENTROPY_EPS = 5e-4 
SUB_BATCH_SIZE = 64
OPTIM_STEPS = 8
LOG_EVERY = 16

Importeer de basisomgeving CartPole uit Gymnasium:

device="cpu"
base_env = GymEnv('CartPole-v1', device=device) 

Declareer de TorchRL‑omgeving door de basisomgeving te importeren en modules toe te voegen voor het normaliseren van de observatietensors en het tellen van het aantal stappen:

env = TransformedEnv( 
    base_env, 
    Compose(
        ObservationNorm(in_keys=["observation"]), 
        DoubleToFloat(), 
        StepCounter()
    )
)

Initialiseer de omgeving en seed de random number generators:

env.transform[0].init_stats(1024) 
torch.manual_seed(0)
env.set_seed(0)
check_env_specs(env) 

Declareer de actor als een neuraal netwerk met 1 verborgen laag met 16 gewichten. De input is de observatie uit de omgeving en de output is de waarschijnlijkheid van elke actie in de actieruimte. 

actor_net = nn.Sequential(
    nn.Linear(env.observation_spec["observation"].shape[-1], 32, device=device),
    nn.ReLU(),
    nn.Linear(32, 32, device=device),
    nn.ReLU(),
    nn.Linear(32, env.action_spec.shape[-1], device=device),
    nn.ReLU()
)

Maak een tensordictionary (gebaseerd op bovenstaand neuraal netwerk) met keys en values die toestanden naar actiekansen mappen. 

actor_module = TensorDictModule(actor_net, in_keys=["observation"], out_keys=["logits"])

Voor het trainen van PPO (en veel andere RL‑algoritmen) kies je niet altijd de actie die tot de hoogste beloning in de volgende stap leidt. Enige willekeur in de actiekeuze stelt de agent in staat de omgeving te verkennen en betere paden te ontdekken die tot hogere langetermijnopbrengsten leiden. Maak een probabilistische actor om dit te doen:

actor = ProbabilisticActor(
    module = actor_module,
    spec = env.action_spec,
    in_keys = ["logits"],
    distribution_class = OneHotCategorical, 
    return_log_prob = True
)

Maak het netwerk dat de waardefunctie implementeert. Dit netwerk heeft 16 gewichten. De input is de toestand (observatie) van de omgeving en de output de verwachte waarde van die toestand. 

value_net = nn.Sequential(
    nn.Linear(env.observation_spec["observation"].shape[-1], 16, device=device),
    nn.ReLU(),
    nn.Linear(16, 1, device=device),
    nn.ReLU()
)

Maak een TorchRL‑module rond de waardefunctie (hierboven geïmplementeerd) met ValueOperator(). Deze module interfacet met andere TorchRL‑componenten. 

value_module = ValueOperator(
    module = value_net,
    in_keys = ["observation"]
)

Maak de replay‑buffer om de resultaten van de interacties van de agent met de omgeving op te slaan: 

replay_buffer = ReplayBuffer(
    storage = LazyTensorStorage(max_size=FRAMES_PER_BATCH),
    sampler = SamplerWithoutReplacement()
)

Maak een datacollector om de policy in de omgeving uit te voeren en per timestep (frame) de resultaten van de interacties van de agent met de omgeving te verzamelen:

collector = SyncDataCollector(
    env,
    actor,
    frames_per_batch = FRAMES_PER_BATCH,
    total_frames = TOTAL_FRAMES,
    split_trajs = True,
    reset_at_each_iter = True,
    device=device
)

Gebruik de module GAE om de advantage‑functie voor PPO te implementeren. De advantage‑functie is gebaseerd op de waardefunctie. 

advantage_module = GAE(
    gamma = GAMMA, 
    lmbda = GAMMA, 
    value_network = value_module,
    average_gae = True
) 

Gebruik de ingebouwde module ClipPPOLoss om de verliesfunctie volgens het PPO‑algoritme te implementeren:

loss_module = ClipPPOLoss(
    actor_network = actor,
    critic_network = value_module,
    clip_epsilon = CLIP_EPSILON,
    entropy_bonus = bool(ENTROPY_EPS),
    entropy_coef = ENTROPY_EPS
)

Declareer de Adam‑optimizer: 

optim = torch.optim.Adam(loss_module.parameters(), lr=ALPHA)

Maak een scheduler om de learning rate geleidelijk te verlagen naarmate de training vordert: 

scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optim, TOTAL_FRAMES // FRAMES_PER_BATCH)

Bouw de trainingslus met de hierboven gemaakte componenten. De training bestaat uit drie for‑lussen:

  • De buitenste lus doorloopt de data die is verzameld uit de interacties van de agent met de omgeving. De parameter TOTAL_FRAMES bepaalt hoeveel timesteps de agent wordt uitgevoerd. 
  • De middelste lus doet het volgende: 
    • Hij voert de binnenste lus uit voor een vast aantal iteraties (meestal tussen 5 en 10), zoals gedefinieerd door de hyperparameter OPTIM_STEPS. 
    • Hij werkt de learning rate bij na elke trainingsiteratie. 
    • Hij berekent ook de waarde van de advantage‑functie voor elke timestep. 
    • Evalueer periodiek de policy en print de beloningen. 
  • De binnenste lus voert de trainingslus uit:
    • Sample een batch trainingsdata uit de replay‑buffer.
    • Bereken het verlies met de verliesmodule. 
    • Voer backpropagatie uit op het verlies.
    • Gebruik de optimizer om gradient descent te doen. 

De onderstaande code implementeert de trainingslus:

for i, tensordict_data in enumerate(collector): 
    for _ in range(OPTIM_STEPS): 
        advantage_module(tensordict_data)
        replay_buffer.extend(tensordict_data.reshape(-1).cpu())
        for _ in range(FRAMES_PER_BATCH // SUB_BATCH_SIZE): 
            data = replay_buffer.sample(SUB_BATCH_SIZE)
            loss = loss_module(data.to(device))
            loss_value = loss["loss_objective"] + loss["loss_critic"] + loss["loss_entropy"]
            loss_value.backward()
            optim.step()
            optim.zero_grad()
    scheduler.step()

    if i % LOG_EVERY == 0:
        with torch.no_grad():
            rollout = env.rollout(FRAMES_PER_BATCH, actor)
            reward_eval = rollout["next","reward"].sum()
            #print(rollout["next","reward"].sum())
            print(reward_eval)
            rewards.append(reward_eval)
            del rollout

Deze DataLab‑workbook bevat de code (zoals hierboven) voor het trainen van een RL‑agent met het PPO‑algoritme uit TorchRL. Gebruik het als startpunt om de parameters fijn af te stellen en de prestaties van de agent te verbeteren. 

Algoritmen aanpassen

TorchRL heeft een modulaire opzet die het mogelijk maakt RL‑oplossingen aan te passen. Het framework verzorgt de interfacing tussen verschillende componenten. Om hun prestaties te testen en vergelijken, kun je omgevingen, verschillende policies, replay‑buffers en RL‑algoritmen plug‑and‑play combineren. Dankzij deze modulariteit:

  • Kun je verschillende componenten uitwisselen zonder grote delen van het programma te herschrijven. 
  • Kunnen individuele componenten ook onafhankelijk worden aangepast om maatwerkoplossingen te maken. 
  • Kun je experimenteren met verschillende modules en een geoptimaliseerde oplossing bouwen. 

Enkele voorbeelden van maatwerk in TorchRL zijn:

  • Trainingslussen kunnen worden aangepast met learning‑rate‑schedulers, loggers en aangepaste metrics. 
  • Verschillende lengtes van replay‑buffers kunnen worden gebruikt om de trainingsduur aan te passen.
  • De omgeving kan worden aangepast met schaal‑ en normalisatiefuncties, step‑counters, enz. 

RL‑training visualiseren en debuggen

De vorige secties lieten zien hoe je TorchRL‑modules gebruikt om RL‑agenten te trainen. In deze sectie bespreken we manieren om de trainingsvoortgang te monitoren en te visualiseren. 

Trainingsvoortgang monitoren

Het is handig om tijdens het trainingsproces verschillende metrics te loggen om de voortgang te monitoren. Pakketten zoals TensorBoard maken het eenvoudig om direct tijdens de training te loggen. Zo stelt TensorBoards SummaryWriter je in staat om hem binnen de trainingslus aan te roepen om metrics te loggen. De volgende pseudocode laat zien hoe:

from torch.utils.tensorboard import SummaryWriter
writer = SummaryWriter(log_dir="training_logs")

for _ in training_data (): # training loop
    loss = … 
    loss.backprop() 
    writer.add_scalar(“Loss - “, loss.item(), step)
   … 

writer.close() 

Na het afronden van de training en het loggen kun je de resultaten plotten en visualiseren. Gebruik bijvoorbeeld het commando tensorboard om de trainingsvoortgang te visualiseren. 

tensorboard --logdir=”training_logs”

Debuggen met TorchRL

Debuggen is essentieel om de interactie van de agent met de omgeving te verifiëren. Als eerste wil je de actieruimte en de observatieruimte controleren. De documentatie van de omgeving zou de specificaties moeten bevatten. Zo toont de documentatie van CartPole dat: 

  • De actieruimte twee discrete waarden bevat — 0 (kar naar links duwen) en 1 (kar naar rechts duwen) 
  • De observatieruimte 4 waarden heeft: 
    • Karpositie, met een waarde tussen 
    • −4,8 en +4,8. 
    • Karsnelheid, met elke reële waarde
    • Hoek van de paal, met een waarde tussen −24 ° en  +24 °
    • Hoeksnelheid van de paal, met elke reële waarde

Inspecteer de observatie‑ en actieruimtes om te controleren dat ze overeenkomen met de verwachte waarden. Bijvoorbeeld:

print("Observation space: ", env.observation_spec)
print("Action space: ", env.action_spec)

Daarnaast kun je willekeurige samples nemen uit de observatie‑ en actieruimtes en hun waarden controleren: 

print("Sample Observation:", base_env.observation_spec.sample().get("observation"))
print("Sample Action:", base_env.action_spec.sample())

De output lijkt op het onderstaande voorbeeld:

Sample Observation: tensor([-4.5960e+00,  3.4028e+38,  2.2261e-02,  3.4028e+38])
Sample Action: tensor([1, 0])

Merk op dat de 4 statuswaarden binnen de eerder gespecificeerde bereiken vallen. Herhaal bovenstaande opdrachten een paar keer en let erop dat de verschillende (willekeurig gesamplede) uitvoerwaarden binnen de opgegeven bereiken vallen. 

De bovenstaande twee opdrachten zijn gebaseerd op de basisomgeving, direct geïmporteerd uit Gymnasium. In de praktijk gebruiken we de getransformeerde omgeving, die transformaties zoals normalisatie toepast op de oorspronkelijke tensorwaarden. Wanneer je dus de getransformeerde TorchRL‑omgeving gebruikt om een sample van observaties te trekken, vallen hun waarden mogelijk niet meer binnen hetzelfde bereik als in de oorspronkelijke Gymnasium‑omgeving. 

Trek bijvoorbeeld een sample uit de getransformeerde omgeving:  

print("Sample Observation:", env.observation_spec.sample().get("observation"))

De output lijkt op: 

Sample Observation: tensor([-57.5869,      nan,   4.5276,      nan])

Merk op dat de waarden voor karpositie en paalhoek buiten de bereiken liggen. Dit komt doordat de tensorwaarden zijn genormaliseerd. Bovendien hebben karsnelheid en hoeksnelheid van de paal nan‑waarden omdat de agent nog niet met de omgeving is begonnen te interacteren. 

Prestaties van de agent visualiseren

Naast het plotten van de trainingsvoortgang kan het nuttig zijn de omgeving te renderen en de interacties van de agent visueel te observeren. Dit kan inzicht geven in hoe de agent presteert. 

De meest pragmatische manier om de omgeving te visualiseren is door een video te renderen. Je hebt enkele extra pakketten nodig: 

  • torchvision, om met multimediabestanden te werken
  • av, om het pakket ffmpeg te wrappen zodat het met PyTorch kan interfacen. 
pip install torchvision
pip install av==12.0.0

Volg na afloop van de training deze voorbereidende stappen om de video te renderen:

  • Declareer het (relatieve) pad om de video op te slaan.
  • Initialiseer de logger om de resultaten van de interacties van de agent in CSV‑formaat op te slaan.
  • Initialiseer de videorecorder om de CSV‑logs te gebruiken om een video te genereren.
  • Transformeer de TorchRL‑omgeving om de videorecorder op te nemen.
…
# training loop
# for _ in …
…
…

from torchrl.record import CSVLogger, VideoRecorder 

path = "./training_loop"
logger = CSVLogger(exp_name="dqn", log_dir=path, video_format="mp4")
video_recorder = VideoRecorder(logger, tag="video")
record_env = TransformedEnv(
    GymEnv("CartPole-v1", from_pixels=True, pixels_only=False), video_recorder
)

Voer de (getrainde) policy uit op de omgeving en dump de renderings naar het videobestand:

record_env.rollout(max_steps=1000, policy=policy)
video_recorder.dump()

Na het uitvoeren van het programma vind je de video in het directorypad (./training_loop in bovenstaande snippet) dat je eerder had ingesteld. Let op dat de DataLab‑workbook voor het implementeren van DQN met TorchRL de code om de video te maken niet bevat, omdat het exporteren van videobestanden met een online notebook lastig is. Voer het programma (en voeg bovenstaande stappen toe) uit op een lokale computer of server om video’s op te nemen.

Best practices voor het gebruik van TorchRL

Tot slot enkele best practices. Dit zijn mijn aanbevelingen.

Begin met eenvoudige omgevingen

Ondanks de ontwikkelgemak van TorchRL blijft het trainen van RL‑agenten die goed presteren in complexe omgevingen uitdagend. Voordat je dus moeilijke problemen probeert op te lossen, is het essentieel om eenvoudige omgevingen zoals CartPole aan te pakken. 

De modulariteit van TorchRL maakt experimenteren met verschillende algoritmen en parameters mogelijk. Voordat je alternatieve algoritmen en maatwerkopties in de praktijk gebruikt, is het nodig inzicht te krijgen in hun werking. Dit doe je het best in een eenvoudige omgeving, waar de effecten van individuele wijzigingen visueel eenvoudig te observeren zijn. 

Experimenteer met hyperparameters

De trainingsprestaties van RL‑modellen zijn gevoelig voor diverse hyperparameters, zoals learning rate, exploratieratio, discontovoet en andere algoritmespecifieke hyperparameters, zoals de clippingratio voor PPO. Een te hoge learning rate maakt de training bijvoorbeeld instabiel, terwijl een te lage learning rate te lang laat duren tot er wordt geconvergeerd. 

Evenzo voorkomt een te hoge exploratieratio dat de training convergeert, terwijl een te lage exploratieratio kan voorkomen dat de agent het optimale pad ontdekt. 

Er is geen formule om de juiste hyperparametervaarden te bepalen. Er bestaan richtlijnen en aanbevolen waarden voor standaardomgevingen, maar die zijn niet op alle problemen van toepassing. Het is daarom nodig om met verschillende methoden, zoals grid search of random search, te experimenteren om de beste waarden te vinden. 

Het is ook mogelijk om geautomatiseerde libraries zoals Weights & Biases Sweeps of Optuna te gebruiken om de trainingsprestaties over verschillende hyperparametercombinaties te testen. 

Maak gebruik van voorgebouwde algoritmen

Zoals je in de vorige voorbeelden zag, bespaart het gebruik van de vooraf gebouwde modules van TorchRL aanzienlijk ontwikkelwerk. Het alternatief is om alle functionaliteit from scratch te bouwen, wat veel meer tijd en kosten vergt om te ontwikkelen en te testen. 

Omdat veel ontwikkelaars de modules van TorchRL gebruiken, zijn ze ook in uiteenlopende scenario’s getest. Je mag ze dus als minder bug‑gevoelig verwachten dan een custom‑module. Voor de meeste standaardgebruikssituaties is het dan ook sterk aan te raden om vooraf gebouwde modules te gebruiken. 

Conclusie

In dit artikel hebben we de basisconcepten van TorchRL behandeld, een op PyTorch gebaseerd framework om RL‑algoritmen te implementeren. We zagen ook hands‑on voorbeelden van het gebruik van TorchRL om eenvoudigere oplossingen zoals Deep Q‑Learning en complexere algoritmen zoals PPO te implementeren. 

Als volgende stap kun je deze programma’s gebruiken als basis om met andere omgevingen en algoritmen te experimenteren. 

Wil je je begrip van RL‑fundamentals en praktische toepassingen verdiepen? Bekijk Reinforcement Learning with Gymnasium in Python voor meer hands‑on ervaring met Gymnasium‑omgevingen.


Arun Nanda's photo
Author
Arun Nanda
LinkedIn

Arun is een voormalige startup-oprichter die graag nieuwe dingen bouwt. Hij verkent momenteel de technische en wiskundige grondslagen van Artificial Intelligence. Hij deelt graag wat hij heeft geleerd, dus schrijft hij erover.

Naast DataCamp kun je zijn publicaties lezen op Medium, Airbyte en Vultr.

Onderwerpen
Kunstmatige intelligentie
Python

Leer meer over reinforcement learning met deze cursussen!

Cursus

Deep Reinforcement Learning in Python

4 uur
6.1K
Leer en gebruik krachtige Deep Reinforcement Learning-algoritmen, inclusief verfijnings- en optimalisatietechnieken.
Bekijk detailsRight Arrow
Start Cursus
Meer bekijkenRight 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 BekijkenMeer Bekijken