Versterkend Leren (RL) is een van de drie belangrijkste machine learning-paradigma’s, de andere twee zijn supervisie- en ongesuperviseerd leren. In RL leert een agent om te interageren met zijn omgeving om de cumulatieve beloningen te maximaliseren. Het leert de optimale actie onder verschillende omgevingsomstandigheden door middel van trial and error. Versterkend Leren met Menselijke Feedback (RLHF) stelt de agent in staat om gedrag aan te passen op basis van menselijke input bij elke stap.
RL lost problemen op zoals zelfrijdende auto’s, geautomatiseerde handel, computer spelers in videogames, robots trainen, en meer. Wanneer diepe neurale netwerken worden gebruikt om RL-algoritmen toe te passen, wordt dit Diep Versterkend Leren genoemd.
In deze tutorial laat ik je zien hoe je kunt beginnen met Gymnasium, een open-source Python-bibliotheek voor het ontwikkelen en vergelijken van versterkende leer-algoritmen. Ik zal demonstreren hoe je het kunt instellen, verschillende RL-omgevingen kunt verkennen en Python kunt gebruiken om een eenvoudige agent te bouwen om een RL-algoritme te implementeren.
Wat is Gymnasium?
Gymnasium is een open-source Python-bibliotheek die is ontworpen om de ontwikkeling van RL-algoritmes te ondersteunen. Om onderzoek en ontwikkeling in RL te vergemakkelijken, biedt Gymnasium:
- Een breed scala aan omgevingen, van eenvoudige spellen tot problemen die echte scenario’s nabootsen.
- Gestroomlijnde API’s en wrappers om te communiceren met de omgevingen.
- De mogelijkheid om aangepaste omgevingen te creëren en gebruik te maken van het API-framework.
Ontwikkelaars kunnen RL-algoritmes bouwen en API-oproepen gebruiken voor taken zoals:
- Het doorgeven van de gekozen actie van de agent aan de omgeving.
- Het kennen van de toestand van de omgeving en de beloning na elke actie.
- Het trainen van het model.
- Het testen van de prestaties van het model.
OpenAI’s Gym versus Farama’s Gymnasium
OpenAI heeft geen significante middelen toegewezen aan de ontwikkeling van Gym omdat het geen zakelijke prioriteit voor het bedrijf was. De Farama Foundation is opgericht om RL-bibliotheken op lange termijn te standaardiseren en te onderhouden. Gymnasium is de fork van OpenAI’s Gym door de Farama Foundation. Gymnasium 0.26.2 is een drop-in vervanging voor Gym 0.26.2. Met de fork streeft Farama ernaar functionele (naast op klassen gebaseerde) methoden toe te voegen voor alle API-aanroepen, ondersteuning van vectoromgevingen en de wrappers te verbeteren. Het algemene doel is om het framework schoner en efficiënter te maken.
Gymnasium instellen
Het gymnasium heeft specifieke versies (niet de nieuwste releases) van verschillende afhankelijkheidsprogramma’s zoals NumPy en PyTorch. Daarom raden we aan om een nieuwe Conda- of venv-omgeving of een nieuw notebook te maken om Gymnasium te installeren, te gebruiken en RL-programma’s uit te voeren.
Je kunt deze DataLab-werkmap gebruiken om de tutorial te volgen.
Het installeren van Gymnasium
Om Gymnasium te installeren op een server of lokale machine, voer je het volgende uit:
$ pip install gymnasium
Om te installeren met behulp van een Notebook zoals Google’s Colab of DataCamp’s DataLab, gebruik:
!pip install gymnasium
De bovenstaande opdracht installeert Gymnasium en de juiste versies van afhankelijkheden.
Verkennen van Gymnasium omgevingen
Vanaf november 2024 bevat Gymnasium meer dan 60 ingebouwde omgevingen. Om beschikbare ingebouwde omgevingen te bekijken, gebruik de gym.envs.registry.all()
functie, zoals geïllustreerd in het onderstaande voorbeeld:
import gymnasium as gym for i in gym.envs.registry.keys(): print(i)
Je kunt ook de Gymnasium homepage bezoeken. De linker kolom bevat links naar alle omgevingen. De webpagina van elke omgeving bevat details erover, zoals acties, toestanden, enz.
Omgevingen zijn georganiseerd in categorieën zoals Classic Control, Box2D en meer. Hieronder geef ik een lijst van enkele veelvoorkomende omgevingen in elke groep:
- Classic Control: Dit zijn klassieke omgevingen die worden gebruikt in RL-ontwikkeling; ze vormen de basis van veel voorbeelden in tekstboeken. Ze geven de juiste mix van complexiteit en eenvoud om nieuwe RL-algoritmen te testen en te benchmarken. Classic control omgevingen in Gymnasium omvatten:
- Acrobot
- Cart Pole
- Mountain Car Discrete
- Mountain Car Continuous
- Pendulum
- Box2D: Box2D is een 2D-fysicamotor voor games. Omgevingen gebaseerd op deze motor omvatten eenvoudige spellen zoals:
- Lunar Lander
- Auto Racen
- ToyText: Dit zijn kleine en eenvoudige omgevingen die vaak worden gebruikt om RL-algoritmen te debuggen. Veel van deze omgevingen zijn gebaseerd op het kleine rasterwereldmodel en eenvoudige kaartspellen. Voorbeelden zijn:
- Blackjack
- Taxi
- Frozen Lake
- MuJoCo: Multi-Joint dynamics with Contact (MuJoCo) is een open-source fysicamotor die omgevingen simuleert voor toepassingen zoals robotica, biomechanica, ML, enz. MuJoCo-omgevingen in Gymnasium omvatten:
- Ant
- Hopper
- Humanoid
- Swimmer
- En meer
Naast de ingebouwde omgevingen kan Gymnasium worden gebruikt met veel externe omgevingen met dezelfde API.
We zullen een van de canonieke Classic Control-omgevingen in deze tutorial gebruiken. Om een specifieke omgeving te importeren, gebruik je de .make()
opdracht en geef je de naam van de omgeving als argument door. Bijvoorbeeld, om een nieuwe omgeving te creëren op basis van CartPole (versie 1), gebruik je de onderstaande opdracht:
import gymnasium as gym env = gym.make("CartPole-v1")
Begrijpen van concepten in versterkend leren in Gymnasium
In een notendop, versterkend leren bestaat uit een agent (zoals een robot) die interactie heeft met zijn omgeving. Een beleid bepaalt de acties van de agent. Afhankelijk van de acties van de agent, geeft de omgeving een beloning (of straf) bij elke tijdstap. De agent gebruikt RL om het optimale beleid te bepalen dat de totale beloningen maximaliseert die de agent verdient.
Componenten van een RL-omgeving
De volgende zijn de belangrijkste componenten van een RL-omgeving:
- Omgeving: Het externe systeem, wereld, of context. De agent interageert met de omgeving in een reeks tijdstappen. In elk tijdstip, op basis van de actie van de agent, geeft de omgeving:
- Geeft een beloning (of straf)
- Beslist over de volgende staat
- Staat: Een wiskundige representatie van de huidige configuratie van de omgeving.
- Bijvoorbeeld, de staat van een pendulumomgeving kan de positie van de pendulum en de hoeksnelheid bij elke tijdstap omvatten.
- Eindtoestand: Een staat die niet leidt tot nieuwe/andre staten.
- Agent: Het algoritme dat de omgeving waarneemt en verschillende acties onderneemt op basis van deze waarneming. Het doel van de agent is om zijn beloningen te maximaliseren.
- Bijvoorbeeld, de agent beslist hoe hard en in welke richting de pendulum te duwen.
- Observatie: Een wiskundige representatie van het zicht van de agent op de omgeving, verkregen bijvoorbeeld met behulp van sensoren.
- Actie: De beslissing die de agent neemt voordat hij doorgaat naar de volgende stap. De actie beïnvloedt de volgende toestand van de omgeving en levert de agent een beloning op.
- Beloning: De feedback van de omgeving aan de agent. Het kan positief of negatief zijn, afhankelijk van de actie en de toestand van de omgeving.
- Terugkeer: De verwachte cumulatieve terugkeer over toekomstige tijdstappen. Beloningen van toekomstige tijdstappen kunnen worden verdisconteerd met behulp van een discontovoet.
- Beleid: De strategie van de agent over welke actie te nemen in verschillende staten. Het wordt typisch voorgesteld als een waarschijnlijkheidsmatrix, P, die staten aan acties koppelt.
- Gegeven een eindige set van m mogelijke staten en n mogelijke acties, element Pmn in de matrix geeft de waarschijnlijkheid aan van het nemen van actie an in de staat sm.
- Aflevering: De reeks tijdstappen vanaf de (willekeurige) initiële staat totdat de agent een eindstaat bereikt.
Observatieruimte en actieruimte
De observatie is de informatie die de agent verzamelt over de omgeving. Een agent, bijvoorbeeld een robot, kan omgevingsinformatie verzamelen met behulp van sensoren. Idealiter moet de agent in staat zijn om de complete staat te observeren, die alle aspecten van de omgeving beschrijft. In de praktijk gebruikt de agent zijn observaties als een substituut voor de staat. Zo bepalen de observaties de acties van de agent.
Een ruimte is analoog aan een mathematische verzameling. De ruimte van items X omvat alle mogelijke instanties van X. De ruimte van X bepaalt ook de structuur (syntax en formaat) van alle items van het type X. Elke Gymnasium-omgeving heeft twee ruimtes, de actieruimte, action_space
, en de observatieruimte, observation_space
. Zowel de actie- als observatieruimtes zijn afgeleid van de ouderklasse gymnasium.spaces.Space
.
Observatieruimte
De observatieruimte is de ruimte die alle mogelijke observaties omvat. Het definieert ook het formaat waarin observaties worden opgeslagen. De observatieruimte wordt doorgaans gerepresenteerd als een object van het datatype Box. Dit is een ndarray dat de parameters van de observaties beschrijft. De box specificeert de grenzen van elke dimensie. Je kunt de observatieruimte voor een omgeving bekijken met de observation_space
methode:
print("observation space: ", env.observation_space)
In het geval van de CartPole-v1
omgeving ziet de output eruit zoals het voorbeeld hieronder:
observation space: Box([-4.8 -inf -0.41887903 -inf], [4.8 inf 0.41887903 inf], (4,), float32)
In dit voorbeeld heeft de CartPole-v1
observatieruimte 4 dimensies. De 4 elementen van de observatie-array zijn:
- Positie van de kar – varieert tussen -4,8 en +4,8
- Winkelwagen snelheid – varieert tussen – en +
- Staafhoek – varieert tussen -0.4189 en +0.4189
- Paalsnelheid – varieert tussen – en +
Om een voorbeeld van een individuele observatie-array te zien, gebruik het .reset()
commando.
observation, info = env.reset() print("observation: ", observation)
In het geval van de CartPole-v1
-omgeving ziet de uitvoer eruit zoals het onderstaande voorbeeld:
[ 0.03481963 -0.0277232 0.01703267 -0.04870504]
De vier elementen van deze array komen overeen met de vier waargenomen grootheden (positie van de wagen, snelheid van de wagen, hoek van de paal, hoeksnelheid van de paal), zoals eerder uitgelegd.
Actieruimte
De actieruimte omvat alle mogelijke acties die de agent kan ondernemen. De actieruimte bepaalt ook het formaat waarin acties worden weergegeven. Je kunt de actieruimte voor een omgeving bekijken met behulp van de action_space
-methode:
print("action space: ", env.action_space)
In het geval van de CartPole-v1
omgeving, ziet de output eruit als het onderstaande voorbeeld:
action space: Discrete(2)
In het geval van de CartPole-v1
omgeving, is de actieruimte discreet. Er zijn in totaal twee acties die de agent kan ondernemen:
- 0: Duwer de kar naar links
- 1: Duwer de kar naar rechts
Je Eerste RL Agent Bouwen met Gymnasium
In de vorige secties hebben we de basisconcepten van RL en Gymnasium verkend. In deze sectie laten we zien hoe je Gymnasium kunt gebruiken om een RL-agent te bouwen.
Het creëren en resetten van de omgeving
De eerste stap is het creëren van een instantie van de omgeving. Om nieuwe omgevingen te creëren, gebruik je de .make()
-methode.
env = gym.make('CartPole-v1')
De interacties van de agent veranderen de staat van de omgeving. De .reset()
-methode reset de omgeving naar een initiële staat. Standaard wordt de omgeving geïnitialiseerd naar een willekeurige staat. Je kunt een SEED
-parameter gebruiken met de .reset()
-methode om de omgeving telkens naar dezelfde staat te initialiseren wanneer het programma wordt uitgevoerd. Het onderstaande codevoorbeeld laat zien hoe je dit kunt doen:
SEED = 1111 env.reset(seed=SEED)
Het monsteren van acties omvat ook willekeurigheid. Om deze willekeurigheid te beheersen en een volledig reproduceerbaar trainingspad te krijgen, kunnen we de willekeurige generatoren van NumPy en PyTorch initialiseren:
np.random.seed(SEED) torch.manual_seed(SEED)
Willekeurige versus intelligente acties
In elke stap in een Markov-proces kan de agent willekeurig een actie kiezen en de omgeving verkennen totdat het een eindtoestand bereikt. Door willekeurig acties te kiezen:
- Duurt het lang om de eindtoestand te bereiken.
- De cumulatieve beloningen zijn veel lager dan ze hadden kunnen zijn.
Het trainen van de agent om de selectie van acties te optimaliseren op basis van eerdere ervaringen (van interactie met de omgeving) is efficiënter om langetermijnbeloningen te maximaliseren.
De ongetrainde agent begint met willekeurige acties op basis van een willekeurig geïnitialiseerd beleid. Dit beleid wordt meestal gerepresenteerd als een neuraal netwerk. Tijdens de training leert de agent het optimale beleid dat de beloningen maximaliseert. In RL wordt het trainingsproces ook wel beleidsoptimalisatie genoemd.
Er zijn verschillende methoden van beleidsoptimalisatie. De Bellman-vergelijkingen beschrijven hoe de waarde van RL-beleiden te berekenen en het optimale beleid te bepalen. In deze tutorial zullen we een eenvoudige techniek genaamd beleidsgradiënten gebruiken. Andere methoden zoals Proximal Policy Optimization (PPO) bestaan ook.
Implementatie van een eenvoudige beleidsgradiënt-agent
Om een RL-agent te bouwen die gebruikmaakt van beleidsgradiënten, creëren we een neuraal netwerk om het beleid te implementeren, schrijven we functies om de opbrengsten en verliezen te berekenen op basis van de stapgewijze beloningen en de actiekansen, en werken we iteratief het beleid bij met behulp van standaard backpropagation-technieken.
Het opzetten van het beleidsnetwerk
We gebruiken een neuraal netwerk om het beleid te implementeren. Aangezien CartPole-v1
een eenvoudige omgeving is, gebruiken we een neuraal netwerk met:
- Invoerdimensies die gelijk zijn aan de dimensionaliteit van de observatieruimte van de omgeving.
- Een enkele verborgen laag met 64 neuronen.
- De uitvoerafmetingen zijn gelijk aan de dimensionaliteit van de actieruimte van de omgeving.
Daarom is de functie van het beleidsnetwerk om waargenomen toestanden naar acties te mappen. Gegeven een invoerobservatie voorspelt het de juiste actie. De onderstaande code implementeert het beleidsnetwerk:
class PolicyNetwork(nn.Module): def __init__(self, input_dim, hidden_dim, output_dim, dropout): super().__init__() self.layer1 = nn.Linear(input_dim, hidden_dim) self.layer2 = nn.Linear(hidden_dim, output_dim) self.dropout = nn.Dropout(dropout) def forward(self, x): x = self.layer1(x) x = self.dropout(x) x = F.relu(x) x = self.layer2(x) return x
Beloning verzameling en de voorwaartse doorgang
Zoals vermeld, geeft de omgeving in elke stap van het Markov-proces een beloning op basis van de actie en de toestand van de agent. Het doel in RL is om het totale rendement te maximaliseren.
- Het rendement op elk tijdstip is de cumulatieve som van de beloningen die vanaf het begin tot die stap zijn verkregen.
- De totale opbrengst in elke aflevering wordt verkregen door alle stapgewijze beloningen van die aflevering op te tellen. Dus is de totale opbrengst de opbrengst op het laatste tijdstip (wanneer de agent een terminale staat bereikt).
In de praktijk is het gebruikelijk om bij het accumuleren van beloningen:
- Toekomstige beloningen aan te passen met een kortingsfactor.
- De array van stapgewijze opbrengsten te normaliseren om een soepele en stabiele training te waarborgen.
De onderstaande code laat zien hoe je dit doet:
def calculate_stepwise_returns(rewards, discount_factor): returns = [] R = 0 for r in reversed(rewards): R = r + R * discount_factor returns.insert(0, R) returns = torch.tensor(returns) normalized_returns = (returns - returns.mean()) / returns.std() return normalized_returns
De forward pass bestaat uit het laten draaien van de agent op basis van het huidige beleid totdat het een eindtoestand bereikt en het verzamelen van de stapsgewijze beloningen en actie waarschijnlijkheden. De onderstaande stappen leggen uit hoe de forward pass geïmplementeerd kan worden:
- Reset de omgeving naar een initiële toestand.
- Initialiseer buffers om de actie waarschijnlijkheden, de beloningen en de cumulatieve return op te slaan
- Gebruik de
.step()
functie om de agent iteratief in de omgeving te laten draaien totdat het stopt: - Krijg de observatie van de toestand van de omgeving.
- Krijg de actie die door het beleid wordt voorspeld op basis van de observatie.
- Gebruik de
Softmax
functie om de kans te schatten om de voorspelde actie te nemen. - Simuleer een categorische kansverdeling op basis van deze geschatte kansen.
- Neem een steekproef uit deze verdeling om de actie van de agent te krijgen.
- Schakel de logkans van de gesamplede actie uit de gesimuleerde verdeling in.
- Voeg de logkans van de acties en de beloningen van elke stap toe aan hun respectieve buffers.
- Schakel de genormaliseerde en verdisconteerde waarden van de opbrengsten in bij elke stap op basis van de beloningen.
def forward_pass(env, policy, discount_factor): log_prob_actions = [] rewards = [] done = False episode_return = 0 policy.train() observation, info = env.reset() while not done: observation = torch.FloatTensor(observation).unsqueeze(0) action_pred = policy(observation) action_prob = F.softmax(action_pred, dim = -1) dist = distributions.Categorical(action_prob) action = dist.sample() log_prob_action = dist.log_prob(action) observation, reward, terminated, truncated, info = env.step(action.item()) done = terminated or truncated log_prob_actions.append(log_prob_action) rewards.append(reward) episode_return += reward log_prob_actions = torch.cat(log_prob_actions) stepwise_returns = calculate_stepwise_returns(rewards, discount_factor) return episode_return, stepwise_returns, log_prob_actions
Beleid bijwerken op basis van beloningen
Het verlies vertegenwoordigt de hoeveelheid waarop we gradient descent toepassen. Het doel in RL is om de opbrengsten te maximaliseren. Daarom gebruiken we de verwachte opbrengstwaarde als een proxy voor het verlies. De verwachte opbrengstwaarde wordt berekend als het product van de stapgewijze verwachte opbrengsten en de logkans van de stapgewijze acties. De onderstaande code berekent het verlies:
def calculate_loss(stepwise_returns, log_prob_actions): loss = -(stepwise_returns * log_prob_actions).sum() return loss
Om het beleid bij te werken, voert u terugpropagatie uit ten opzichte van de verliesfunctie. De update_policy()
methode hieronder roept de calculate_loss()
methode aan. Vervolgens wordt terugpropagatie uitgevoerd op dit verlies om de beleidsparameters bij te werken, dat wil zeggen, de modelgewichten van het beleidsnetwerk.
def update_policy(stepwise_returns, log_prob_actions, optimizer): stepwise_returns = stepwise_returns.detach() loss = calculate_loss(stepwise_returns, log_prob_actions) optimizer.zero_grad() loss.backward() optimizer.step() return loss.item()
Het bijwerken van het beleid op basis van de gradiënt van de opbrengsten wordt het beleidsgradiëntmethode genoemd.
Het trainen van het beleid
We hebben nu alle benodigde componenten om het beleid te trainen en te evalueren. We implementeren de trainingslus zoals uitgelegd in de volgende stappen:
Voordat we beginnen, verklaren we de hyperparameters, creëren we een beleid en maken we een optimizer aan:
- Verklaar de hyperparameters als Python-constanten:
MAX_EPOCHS
is het maximale aantal iteraties dat we bereid zijn om uit te voeren om het beleid te trainen.DISCOUNT_FACTOR
bepaalt de relatieve betekenis van beloningen van toekomstige tijdstappen. Een discontovoet van 1 betekent dat alle beloningen even belangrijk zijn, terwijl een waarde van 0 betekent dat alleen de beloning van de huidige tijdstap belangrijk is.N_TRIALS
is het aantal afleveringen waarover we de opbrengsten gemiddeld om de prestatie van de agent te evalueren. We besluiten dat de training succesvol is als de gemiddelde opbrengst overN_TRIALS
afleveringen boven de drempel ligt.REWARD_THRESHOLD
: Als de beleidsvoering een opbrengst kan behalen die hoger is dan de drempel, wordt deze als succesvol beschouwd.DROPOUT
bepaalt het percentage van de gewichten dat willekeurig op nul moet worden gezet. De dropoutfunctie stelt willekeurig een percentage van de modelgewichten in op nul. Dit vermindert de afhankelijkheid van specifieke neuronen en voorkomt overfitting, waardoor het netwerk robuuster wordt.LEARNING_RATE
bepaalt hoe veel de beleidsparameters in elke stap kunnen worden aangepast. De update van de parameters in elke iteratie is het product van de gradient en de leersnelheid.- Definieer het beleid als een instantie van de
PolicyNetwork
klasse (eerder geïmplementeerd). - Maak een optimizer aan met behulp van het Adam-algoritme en de leersnelheid.
Om het beleid te trainen, voeren we iteratief de trainingsstappen uit totdat de gemiddelde opbrengst (over N_TRIALS
) groter is dan de beloningsdrempel:
- Voor elke aflevering, voer de voorwaartse stap eenmaal uit. Verzamel de logkans van acties, de stapgewijze opbrengsten en de totale opbrengst van die aflevering. Accumuleer de episodische opbrengsten in een array.
- Bereken het verlies met behulp van de logkansen en de stapsgewijze opbrengsten. Voer de backpropagatie uit op het verlies. Gebruik de optimizer om de beleidsparameters bij te werken.
- Controleer of de gemiddelde opbrengst over
N_TRIALS
de beloningsdrempel overschrijdt.
De onderstaande code voert deze stappen uit:
def main(): MAX_EPOCHS = 500 DISCOUNT_FACTOR = 0.99 N_TRIALS = 25 REWARD_THRESHOLD = 475 PRINT_INTERVAL = 10 INPUT_DIM = env.observation_space.shape[0] HIDDEN_DIM = 128 OUTPUT_DIM = env.action_space.n DROPOUT = 0.5 episode_returns = [] policy = PolicyNetwork(INPUT_DIM, HIDDEN_DIM, OUTPUT_DIM, DROPOUT) LEARNING_RATE = 0.01 optimizer = optim.Adam(policy.parameters(), lr = LEARNING_RATE) for episode in range(1, MAX_EPOCHS+1): episode_return, stepwise_returns, log_prob_actions = forward_pass(env, policy, DISCOUNT_FACTOR) _ = update_policy(stepwise_returns, log_prob_actions, optimizer) episode_returns.append(episode_return) mean_episode_return = np.mean(episode_returns[-N_TRIALS:]) if episode % PRINT_INTERVAL == 0: print(f'| Episode: {episode:3} | Mean Rewards: {mean_episode_return:5.1f} |') if mean_episode_return >= REWARD_THRESHOLD: print(f'Reached reward threshold in {episode} episodes') break
Tenslotte, roep de main()
functie aan om het beleid te trainen:
main()
U kunt dit DataLab-werkboek gebruiken om het bovenstaande algoritme rechtstreeks uit te voeren en de CartPole-omgeving op te lossen met RL.
Geavanceerde technieken in Gymnasium
Nadat we hebben aangetoond hoe we een RL-algoritme kunnen implementeren, bespreken we nu enkele geavanceerde technieken die vaak in de praktijk worden gebruikt.
Gebruik van vooraf gebouwde architecturen
Het implementeren van RL-algoritmen vanaf nul is een lang en moeilijk proces, vooral voor complexe omgevingen en state-of-the-art beleidsmaatregelen.
Een meer praktisch alternatief is om software zoals Stable Baselines3
te gebruiken. Het wordt geleverd met uitgeprobeerde en geteste implementaties van RL-algoritmen. Het bevat vooraf getrainde agenten, trainingscripts, evaluatietools en modules om grafieken te plotten en video’s op te nemen. Ray RLib is een andere populaire tool voor RL. RLib is ontworpen als een schaalbare oplossing, waardoor het eenvoudig is om RL-algoritmen te implementeren op multi-GPU-systemen. Het ondersteunt ook multi-agent RL, wat nieuwe mogelijkheden opent zoals:
- Onafhankelijk multi-agent leren: Elke agent behandelt andere agenten als onderdeel van de omgeving.
- Samenwerkende multi-agent training: Een groep agenten deelt hetzelfde beleid en waarderingsfuncties en leert van elkaars ervaringen parallel aan elkaar.
- Adversariële training: Agenten (of groepen agenten) concurreren tegen elkaar in competitieve spelachtige omgevingen.
Met zowel RLib als Stable Baselines3 kunt u omgevingen van OpenAI Gymnasium importeren en gebruiken.
Aangepaste omgevingen
Omgevingen die verpakt zijn met Gymnasium zijn de juiste keuze voor het testen van nieuwe RL strategieën en het trainen van beleidsregels. Voor de meeste praktische toepassingen moet je echter een omgeving creëren en gebruiken die nauwkeurig het probleem weerspiegelt dat je wilt oplossen. Je kunt Gymnasium gebruiken om een aangepaste omgeving te creëren. Het voordeel van het gebruik van aangepaste Gymnasium-omgevingen is dat veel externe tools zoals RLib en Stable Baselines3 al geconfigureerd zijn om te werken met de structuur van de Gymnasium API.
Om een aangepaste omgeving in Gymnasium te creëren, moet je het volgende definiëren:
- De observatieruimte.
- De eindvoorwaarden.
- De reeks acties waaruit de agent kan kiezen.
- Hoe de omgeving te initialiseren (wanneer de
reset()
functie wordt aangeroepen). - Hoe de omgeving beslist over de volgende staat gegeven de acties van de agent (wanneer de
step()
functie wordt aangeroepen).
Om meer te leren, volg de Gymnasium gids over het maken van aangepaste omgevingen.
Best Practices voor het Gebruik van Gymnasium
Experimenteer met verschillende omgevingen
De code in deze tutorial toonde aan hoe je het policy gradient-algoritme kunt implementeren in de CartPole-omgeving. Dit is een eenvoudige omgeving met een discrete actieruimte. Om RL beter te begrijpen, raden we je aan hetzelfde policy gradient-algoritme (en andere algoritmes, zoals PPO) toe te passen in andere omgevingen.
Bijvoorbeeld, de Pendulum-omgeving heeft een continue actieruimte. Het bestaat uit een enkele invoer die wordt weergegeven als een continue variabele – het (grootte en richting van de) koppel dat wordt toegepast op de slinger in een bepaalde toestand. Dit koppel kan elke waarde aannemen tussen -2 en +2.
Het experimenteren met verschillende algoritmes in verschillende omgevingen helpt je om verschillende soorten RL-oplossingen en hun uitdagingen beter te begrijpen.
Monitor de trainingsvoortgang
RL-omgevingen bestaan vaak uit robots, pendules, bergauto’s, videospellen, enz. Het visualiseren van de acties van de agent binnen de omgeving geeft een beter intuïtief begrip van de prestaties van het beleid.
In Gymnasium visualiseert de env.render()
methode de interacties van de agent met de omgeving. Het toont grafisch de huidige staat van de omgeving—spel schermen, de positie van de pendule of karpola, enz. Visuele feedback van de acties van de agent en de reacties van de omgeving helpt om de prestaties en voortgang van de agent tijdens het trainingsproces te monitoren.
Er zijn vier render-modus: “human”, “rgb_array”, “ansi” en “rgb_array_list”. Om de prestaties van de agent te visualiseren, gebruik de “human” render-modus. De render-modus wordt gespecificeerd wanneer de omgeving wordt geïnitialiseerd. Bijvoorbeeld:
env = gym.make(‘CartPole-v1’, render_mode=’human’)
Om de rendering uit te voeren, betrek de .render()
methode na elke actie die door de agent is uitgevoerd (door het aanroepen van de .step()
methode). De onderstaande pseudo-code illustreert hoe dit te doen:
while not done: … step, reward, terminated, truncated, info = env.step(action.item()) env.render() …
Problemen met veelvoorkomende fouten
Gymnasium maakt het eenvoudig om te interfacing met complexe RL-omgevingen. Echter, het is een continu bijgewerkte software met veel afhankelijkheden. Daarom is het essentieel om op een paar veelvoorkomende soorten fouten te letten.
Versie-inconsistenties
- Gymnasium versie mismatch: Farama’s Gymnasium softwarepakket is afgeleid van OpenAI’s Gym vanaf versie 0.26.2. Er zijn enkele ingrijpende wijzigingen geweest tussen oudere Gym-versies en nieuwere versies van Gymnasium. Veel openbaar beschikbare implementaties zijn gebaseerd op de oudere Gym-releases en werken mogelijk niet direct met de nieuwste release. In dergelijke gevallen is het noodzakelijk om de installatie terug te zetten naar een oudere versie of de code aan te passen om te werken met de nieuwere release.
- Omgevingsversie komt niet overeen: Veel Gymnasium-omgevingen hebben verschillende versies. Zo zijn er bijvoorbeeld twee CartPole-omgevingen –
CartPole-v1
enCartPole-v0
. Hoewel het gedrag van de omgeving hetzelfde is tussen beide versies, kunnen sommige parameters, zoals de episodelengte, beloningsdrempel, enz., verschillend zijn. Een beleid dat is getraind op één versie kan mogelijk niet zo goed presteren op een andere versie van dezelfde omgeving. Je moet de trainingsparameters bijwerken en het beleid opnieuw trainen voor elke omgevingsversie. - Versie-inconsistentie van afhankelijkheden: Gymnasium is afhankelijk van bibliotheken zoals NumPy en PyTorch. Vanaf december 2024 zijn de nieuwste versies van deze afhankelijkheden
numpy 2.1.3
entorch 2.5.1
. Gymnasium werkt echter het beste mettorch 1.13.0
ennumpy 1.23.3
. U kunt problemen ondervinden als u Gymnasium installeert in een omgeving waarin deze afhankelijkheden al zijn geïnstalleerd. We raden aan Gymnasium te installeren en te gebruiken in een nieuwe Conda-omgeving.
Convergentieproblemen
- Hyperparameters: Net als andere machine learning-algoritmen zijn RL-beleidsregels gevoelig voor hyperparameters zoals leersnelheid, discontovoet, enzovoort. We raden aan om te experimenteren en de hyperparameters handmatig af te stemmen of geautomatiseerde technieken zoals grid search en random search te gebruiken.
- Verkenning versus exploitatie: Voor sommige beleidsklassen (zoals PPO) hanteert de agent een tweeledige strategie: de omgeving verkennen om nieuwe paden te ontdekken en een gretige benadering aannemen om de beloningen te maximaliseren op basis van de tot nu toe bekende paden. Als het te veel verkent, convergeert het beleid niet. Daarentegen probeert het nooit het optimale pad als het niet genoeg verkent. Het vinden van de juiste balans tussen verkenning en exploitatie is essentieel. Het is ook gebruikelijk om verkenning te prioriteren in eerdere afleveringen en exploitatie in latere afleveringen tijdens de training.
Training instabiliteit
- Grote leersnelheden: Als de leersnelheid te hoog is, ondergaan de beleidsparameters grote updates in elke stap. Dit kan mogelijk leiden tot het missen van de optimale set waarden. Een veelvoorkomende oplossing is om de leersnelheid geleidelijk te verlagen, zodat kleinere en stabielere updates plaatsvinden wanneer het trainingsproces convergeert.
- Overmatige verkenning: Te veel willekeurigheid (entropie) in actieselectie voorkomt convergentie en leidt tot grote variaties in de verliesfunctie tussen opeenvolgende stappen. Om een stabiel en convergent trainingsproces te hebben, moet de verkenning in balans zijn met exploitatie.
- Verkeerde keuze van algoritme: Simpele algoritmes zoals beleidsgradiënt kunnen leiden tot instabiele training in complexe omgevingen met grote actie- en toestandsruimtes. In dergelijke gevallen raden we aan om robuustere algoritmes zoals PPO en Trust Region Policy Optimization (TRPO) te gebruiken. Deze algoritmes vermijden grote beleidsupdates in elke stap en kunnen stabieler zijn.
- Willekeurigheid: RL-algoritmes zijn berucht gevoelig voor initiële toestanden en de willekeur inherent aan actieselectie. Wanneer een trainingsrun instabiel is, kan deze soms gestabiliseerd worden door een andere willekeurige seed te gebruiken of door het beleid opnieuw te initialiseren.
Conclusie
In deze tutorial hebben we de basisprincipes van RL verkend, Gymnasium besproken als een softwarepakket met een schone API om te communiceren met verschillende RL-omgevingen, en laten zien hoe je een Python-programma kunt schrijven om een eenvoudig RL-algoritme te implementeren en toe te passen in een Gymnasium-omgeving.
Na het begrijpen van de basisprincipes in deze tutorial, raad ik aan om Gymnasium-omgevingen te gebruiken om de concepten van RL toe te passen om praktische problemen op te lossen, zoals taxiroute-optimalisatie en aandelenhandel simulaties.
Source:
https://www.datacamp.com/tutorial/reinforcement-learning-with-gymnasium