Reinforcement Learning#
The way positive reinforcement is carried out is more important than the amount.
— Burrhus Frederic Skinner
Reinforcement Learning (RL) ist ein Bereich des maschinellen Lernens, bei dem ein Agent lernt, in einer Umgebung durch Interaktionen zu handeln, um eine maximale Belohnung zu erzielen. Der Agent nimmt Aktionen basierend auf seinem aktuellen Zustand vor und erhält Belohnungen oder Bestrafungen, die er verwendet, um seine Strategie zu verbessern.
Das macht auf der einen Seite RL vom Konzept her einfach zu verstehen und zu implementieren. Die Spezifikation der Belohnungsstrategie ist allerdings meist schwierig, da dies Verständnis des Problems erfordert. Der Ansatz benötigt keine gelabelte Trainingsdaten, ist also kein Überwachter ML-Ansatz. Er ist auch kein unüberwachter Ansatz, da ja durchaus Wissen in Form der Belohnungsstrategie notwendig ist.
RL eignet sich insbesondere für dynamische Entscheidungen und wird häufig in der Robotik verwendet, aber wird auch immer beliebter in traditionellen Gebieten.
Folien#
Grundlegende Konzepte#
Reinforcement Learning basiert auf einer iterativen Lernstrategie, bei der die Qualität der Lösung durch positives oder negatives Feedback bewertet wird. Das RL-Modell wird hierbei als Agent gesehen, der mit der Umgebung interagiert. Die Begriffe in diesem Kontext sind:
Agent (Agent): Der Lernende oder Entscheidungsträger, der in der Umgebung agiert.
Umgebung (Environment): Alles, mit dem der Agent interagiert.
Aktion (Action): Eine Entscheidung oder Bewegung, die der Agent treffen kann.
Belohnung (Reward): Rückmeldung aus der Umgebung, die angibt, wie gut eine Aktion im gegebenen Zustand war.
Wertfunktion (Value Function): Eine Funktion, die angibt, wie gut ein bestimmter Zustand oder eine Aktion ist.
Strategie (Policy): Eine Strategie, die der Agent verwendet, um Aktionen zu wählen basierend auf dem Zustand und der Wertfunktion.
Zustand (State): Eine Repräsentation der aktuellen Situation der Umgebung und ggf. der Strategie.
Zur Modellierung der Umgebung und aktuellen Strategie verwendet man im RL oft ein Markov Decision Processes (MDPs). Das ist ein diskretes Zustandsmodell, bei dem das System sich immer nur in einem einzigen Zustand befinden kann, der die Umgebung (oder Strategie) widerspiegelt und die Aktion bestimmt. Jeder Zustand beschreibt eine bestimmte Bedingung oder Position im Verhalten des Systems. Der Zustand wird auf Basis der Belohnung von der Umgebung gewechselt.
Markov-Modelle sind eine sehr beliebte Modelltyp im Maschinellem Lernen. Sie basieren alle auf der Markov-Bedingung, dass die Übergangswahrscheinlichkeit von einem Zustand in den anderen nur von dem aktuellen Zustand abhängt und nicht vorhergehenden Zuständen (es gibt also keine Autokorrelation). Man spricht dabei auch von der Gedächtnislosigkeit. Dies basiert auf der Idee, dass der Zustand des Systems zu einem bestimmten Zeitpunkt alle Informationen enthält, die notwendig sind, um sein zukünftiges Verhalten vorherzusagen.
Ein MDP besteht aus:
\( S \): Menge aller möglichen Zustände.
\( A \): Menge aller möglichen Aktionen.
\( P(s'|s, a) \): Übergangswahrscheinlichkeit vom Zustand \( s \) zum Zustand \( s' \) bei Aktion \( a \).
\( R(s, a) \): Belohnungsfunktion, die die Belohnung angibt, die der Agent erhält, wenn er im Zustand \( s \) die Aktion \( a \) ausführt.
\( \gamma \): Diskontierungsfaktor, der zukünftige Belohnungen abwertet.
Der MDP modelliert also die Zustände und die bisherige Übergangswahrscheinlichkeit sowie die erhaltenen Belohnungen. Die entscheidende Frage im Reinforcement Learning ist nun, wie man daraus die beste Aktion und somit den nächsten Zustand ableiten kann. Hierbei gibt es das Dilemma, das aufgrund der Markov-Bedingung das Modell zwar einfach ist, aber wir auch gedächtnislos sind, wir also nicht die Historie der Zustände mit in unserer Entscheidung betrachten können. Das ist problematisch, wenn das Ziel nur erreicht werden kann, wenn eine bestimmte Zustandsfolge eintritt, wie in dem Gridworld-Beispiel unten diskutiert.
Eine wichtige Gleichung ist hierfür die Bellman-Gleichung. Sie beschreibt die Beziehung zwischen dem aktuellen Zustands-Aktionspaar \((s,a)\), der beobachteten Belohnung und den möglichen Nachfolge-Zustands-Aktionspaaren \(s',a'\). Diese Beziehung wird verwendet, um die optimale Wertfunktion zu finden.
Die Bellman-Gleichung basiert auf dem Prinzip der Optimalität, das besagt, dass ein optimaler Policy eine rekursive Struktur aufweist. Das bedeutet, dass der Wert eines Zustands unter einer optimalen Policy aus der sofortigen Belohnung und dem diskontierten Wert der zukünftigen Zustände besteht. Die Bellman-Gleichung für die Wertfunktion \(V(s)\) eines Zustands \(s\) definiert den Wert eines Zustands als die erwartete Belohnung für die beste Aktion in diesem Zustand plus den diskontierten Wert des besten nächsten Zustands, unter der Annahme, dass der Agent die optimale Policy verfolgt. Mathematisch formuliert lautet die Bellman-Optimalitätsgleichung:
Diese Gleichung besagt, dass der optimale Wert eines Zustands \(s\) die maximale erwartete Belohnung ist, die der Agent erhalten kann, wenn er im Zustand \(s\) startet, die Aktion \(a\) wählt und danach der optimalen Policy folgt. Dadurch berücksichtigen wir bei der Bewertung des Zustandsüberganges durch die Aktion \(a\) nicht nur den aktuellen Zustand, sondern auch die durch Aktion \(a\) ermöglichten zukünftigen Zustandsübergänge. Damit lösen wir das Dilemma der Gedächtnislosigkeit, das aus der Markov-Bedingung folgt.
Die Bellman-Gleichung wird genutzt, um die optimale Strategie in Form einer Q-Funktion \(Q(s,a)\) im Q-Learning zu erlernen. Das ist ein populärer Off-Policy-Algorithmus, bei dem der Agent eine Q-Funktion \( Q(s, a) \) lernt, welche Belohnungen einer Aktion \( a \) in einem Zustand \( s \) erwartet wird.
hierbei stellt \(\alpha\) die Lernrate dar. Die ist ein sehr wichtiger Parameter, da er entscheidet, wie schnell das Modell auf eine Lösung konvergiert. Ein niedriger Wert sorgt dazu, dass der Algorithmus mehr positive Beispiele zum Lernen benötigt, was also längeres Training erfordert, insbesondere bei seltenen, positiven Feedback. Ein hoher Wert kann dazu sorgen, dass sich das Modell schnell in einer schlechteren Lösung (lokales Optimum) verrennt.
Deshalb kombiniert man den Algorithmus man meist mit einer Erkundungsstrategie. Statt immer nur die geschätzte optimale Strategie \(Q(s,a)\) zu nehmen, wählt man mit der Wahrscheinlichkeit \(\epsilon\) zufällige Strategien aus, um somit alternative Strategien zu entdecken. Ein hoher \(\epsilon\)-Wert sorgt für eine hohe Erkundungsrate (Exploration), während ein niedriger ein verlässlichere Vorhersage erlaubt. Um hier einen Trade-Off zu finden, macht man oft beides und wählt am Anfang des Trainings ein hohes \(\epsilon\), um den Lösungsbereich zu erkunden und am Ende des Trainings ein niedriges \(\epsilon\) um schneller und verlässlicher zu konvergieren.
Beispiel: Gridworld-Umgebung#
Wir werden eine einfache Gridworld-Umgebung verwenden, um die Grundprinzipien von Reinforcement Learning zu veranschaulichen. In dieser Umgebung versucht ein Agent, in einem Grid von einem Startzustand zu einem Zielzustand zu gelangen und dabei den kürzesten Weg zu finden.
Wir erstellen uns als erstes eine Klasse, welche die Umgebung repräsentiert und die Zustände enthält. Die Umgebung initialisiert zuerst unser Raster (Grid) mit der Start- und Endposition. Dieses Raster definiert unseren Zustandsraum, da der Agent, wenn er sich fort bewegt sich in jeder dieser Zellen im Raster aufhalten kann.
Damit wir Experimente beim Lernen wiederholen können gibt es eine reset
-Funktion. Mit der step
-Funktion kann der Agent sich fortbewegen. Wir übergeben der Funktion als action
die Richtung, in der wir uns bewegen wollen. Dadurch wechselt sich die aktuelle Position, also der aktuelle Zustand in unserem Zustandsmodell.
import numpy as np # Import von NumPy
# Definition der Gridworld-Umgebung
class Gridworld:
def __init__(self, size, start, goal):
self.size = size
self.start = start
self.goal = goal
self.state = start
self.actions = ['up', 'down', 'left', 'right']
self.grid=np.zeros((self.size,self.size))
self.grid[start]=1
self.grid[goal]=0
def reset(self):
self.state = self.start
return self.state
def step(self, action):
x, y = self.state
if action == 'up':
x = max(0, x - 1)
elif action == 'down':
x = min(self.size - 1, x + 1)
elif action == 'left':
y = max(0, y - 1)
elif action == 'right':
y = min(self.size - 1, y + 1)
self.state = (x, y)
self.grid[self.state]+=1
reward = 1 if self.state == self.goal else -0.1
done = self.state == self.goal
return self.state, reward, done
Erstellen wir uns als Beispiel ein 3x3 Gridworld und wollen uns vom Punkt \([0,0]\) zum Punkt \([3,3]\) bewegen.
env = Gridworld(size=4, start=(0, 0), goal=(3, 3))
state = env.reset()
print("Startzustand:", state)
env.grid
Startzustand: (0, 0)
array([[1., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
Der Zustandsraum ist hierbei ein 2D Grid
Bewegen wir uns einmal manuell durch das Grid, so sehen wir wie die Zustände (unsere Position) sich ändern und welche Belohnungen wir erhalten. Wichtig hierbei ist, dass wir eine positive Belohnung erst beim letzten Schritt erhalten, vorher immer nur bestraft werden (z.B. Erschöpfung).
# Beispiel für einen Schritt in der Umgebung
steps=['right','down','right','down','right','down']
for step in steps:
next_state, reward, done = env.step(step)
print("Nächster Zustand:", next_state, "Belohnung:", reward, "Ziel erreicht:", done)
Nächster Zustand: (0, 1) Belohnung: -0.1 Ziel erreicht: False
Nächster Zustand: (1, 1) Belohnung: -0.1 Ziel erreicht: False
Nächster Zustand: (1, 2) Belohnung: -0.1 Ziel erreicht: False
Nächster Zustand: (2, 2) Belohnung: -0.1 Ziel erreicht: False
Nächster Zustand: (2, 3) Belohnung: -0.1 Ziel erreicht: False
Nächster Zustand: (3, 3) Belohnung: 1 Ziel erreicht: True
import plotly.express as px
px.imshow(env.grid)
Random Walk#
Ein naiver Lösungsansatz ist der so genannte Random Walk (Zufallsweg), bei dem man bei jedem Schritt in eine zufällig gewählte Richtung läuft, was auch bedeutet, dass man ggf. zurück läuft. Untersuchen wir einmal in 500 Experimenten die Erfolgschancen dieser Lösungsstrategie.
env = Gridworld(size=4, start=(0, 0), goal=(3, 3))
trials = 500
rewards = []
retries = []
for trial in range(trials):
env.reset()
n, r_sum = 0, 0
done = False
while not done:
# Wir wählen eine zufällige Aktion
action = np.random.choice(env.actions)
# Führe die Aktion aus und erhalte von der Umgebung den neuen Zustand und die Belohnung
new_state, reward, done = env.step(action)
# Sammel Erfolgsstatistik
r_sum += reward
n += 1
rewards.append(r_sum)
retries.append(n)
In allen Experimenten ist unser Agent zum Ziel gekommen, was zeigt, dass diese zufällige Explorations-Strategie durchaus erfolgreich ist. Schauen wir auf die Anzahl der Versuche bis zum Ziel über unsere Experimente, so sehen wir, dass diese gleichbleibend stark variiert. Wir haben also kein Lerneffekt.
import plotly.express as px
px.line(retries)
Entsprechend niedrig sind auch die Belohnungen, die das Programm pro Experiment sammelt.
px.line(rewards)
Wenn wir uns die Häufigkeit ansehen, der besuchten Rasterpunkte, so zeigt sich, dass der Großteil der Versuche um dem Starpunkt herum hängen bleibt, also oft auch wieder sich zurückbewegt.
px.imshow(env.grid)
Q-Learning#
Wir implementieren als nächstes den Q-Learning Ansatz wie er oben beschrieben worden ist. Hierfür initialisieren wir als erstes die Q-Matrix, in welcher wir die erlernten Q-Werte speichern. Da unser Zustandsraum die Große 3x3 hat und wir 4 Aktionen haben, hat die Q-Matrix eine Größe von 3x3x4.
Der Q-Learning Algorithmus besteht nun zum einen in der Möglichkeit mit der Wahrscheinlichkeit \(\epsilon\) ein explorativen zufälligen Schritt zu machen oder den vielversprechendsten Schritt unseres aktuellen Zustands \(s_1,s_2\) mit dem maximalen Q-Wert (argmax).
env = Gridworld(size=4, start=(0, 0), goal=(3, 3))
# Initialisiere Q-Werte
Q = np.zeros((env.size, env.size, len(env.actions)))
# Hyperparameter
alpha = 0.2 # Lernrate
gamma = 0.9 # Diskontierungsfaktor
epsilon = 0.1 # Epsilon für die Epsilon-Greedy-Strategie
rewardsQ=[]
retriesQ=[]
for trial in range(trials):
state = env.reset()
done = False
n, r_sum=0, 0
while not done:
if np.random.uniform(0,1) < epsilon:
# Wähle Aktion entweder Zufällig aus
action = np.random.randint(0, len(env.actions))
else:
# Wähle Aktion mit maximaler erwarteten Belohnung Q(s)
action = np.argmax(Q[state[0], state[1], :])
# Führe die Aktion aus und erhalte von der Umgebung den neuen Zustand und die Belohnung
new_state, reward, done = env.step(env.actions[action])
# Aktualisiere Q-Werte auf Basis der erhaltenen Belohnung
Q[state[0], state[1], action] += alpha * (reward + gamma * np.max(Q[new_state[0], new_state[1], :]) - Q[state[0], state[1], action])
# Aktualisiere den Zustand
state = new_state
# Sammel Erfolgsstatistik
r_sum+=reward
n += 1
rewardsQ.append(r_sum)
retriesQ.append(n)
Wenn wir nun die Wiederholungsversuche uns ansehen, dann sehen wir, dass diese schnell auf das Minimum von nur 6 Schritte abfallen. Es gibt immer noch Schwankungen, die an dem Zufallsanteil \(\epsilon\) liegen.
px.line(retriesQ)
Betrachten wir die Belohnungen, so sehen wir, dass der Ansatz sehr schnell nur noch positive Belohnungen erzieht.
px.line(rewardsQ)
Der resultierende Weg ist hierbei einer von vielen optimalen Wegen.
px.imshow(env.grid)
Zeitreihe#
Mit Reinforcement Learning kann man auch Modelle auf Zeitreihen trainieren. Wir wollen uns zum Beispiel einen Entscheidungsalgorithmus trainieren, welcher lernt, wann er Aktien oder Shorts auf diese kaufen soll und wann er sie verkaufen soll. Hier ein zufälliger Aktienkurs.
import numpy as np
import pandas as pd
# Simulierte Zeitreihe (z.B. Aktienpreise)
np.random.seed(42)
data = np.cumsum(np.random.randn(200) + 0.5)
# Daten visualisieren
px.line(data)
Wir definieren uns wieder eine Trainingsumgebung. Dieses Mal haben wir allerdings die Schwierigkeit, dass der Wert kontinuierlich sind und nicht diskret, wir also keine natürliche Zustandsraumdarstellung haben. Deshalb müssen wir die kontinuierliche Zeitreihe des Aktienwertes zuerst diskretisieren.
class StockTradingEnv:
def __init__(self, data, num_states=40):
self.data = data
self.current_step = 0
self.state = None
self.states = np.linspace(min(data), max(data), num_states)
self.done = False
self.actions = ['kaufen', 'verkauf']
self.position = 0 # 1 = long, -1 = short, 0 = neutral
self.balance = 0
self.current_price=0
self.old_price = 0
def discretize(self):
return np.digitize(self.data[self.current_step], self.states) - 1
def reset(self):
self.current_step = 0
#self.state = self.data[self.current_step:self.current_step+5]
self.state = self.discretize()
self.done = False
self.position = 0
self.balance = 0
self.old_price = 0
self.current_price=0
return self.state
def step(self, action):
self.current_step += 1
if self.current_step > len(self.data) - 2:
self.done = True
self.current_price = self.data[self.current_step]
reward = 0
if action == 0: # Kaufen
if self.position == 0: # Kaufe Aktie
self.position = 1
self.balance -= self.current_price
self.old_price = self.current_price
elif self.position == -1: # Verkaufe Short
reward = 2 * (self.old_price - self.current_price)
self.position = 0
self.balance += self.old_price
elif action == 1: # Verkaufen
if self.position == 0: # Kaufe Short
self.position = -1
self.balance += self.current_price
self.old_price = self.current_price
elif self.position == 1: # Verkaufe Aktie
reward = 2 * (self.current_price - self.old_price)
self.position = 0
self.balance -= self.old_price
elif action == 2: # Halten
pass
self.state = self.discretize()
return self.state, reward, self.done
Als Beispiel kaufen wir Akten, halten sie für 6 Züge und verkaufen sie. Dann kaufen wir Shorts, um auf fallende Aktien zu wetten, halten sie wieder und verkaufen sie.
num_states=40
# Beispiel für die Erstellung und Verwendung der StockTradingEnv-Umgebung
env = StockTradingEnv(data, num_states)
state = env.reset()
print("Startzustand:", state)
# Beispiel für einen Schritt in der Umgebung
for action in [0,2,2,2,2,2,1,1,2,2,2,2,2,0]:# 0 = Kaufen, 2 = Halten, 1 = Verkaufen
next_state, reward, done = env.step(action)
print("Nächster Zustand:", next_state, "Belohnung:", reward, "Ziel erreicht:", done)
Startzustand: 0
Nächster Zustand: 0 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 0 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 1 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 1 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 1 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 2 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 3 Belohnung: 14.098151214993003 Ziel erreicht: False
Nächster Zustand: 3 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 3 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 3 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 3 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 3 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 3 Belohnung: 0 Ziel erreicht: False
Nächster Zustand: 2 Belohnung: 1.565646416803098 Ziel erreicht: False
Als nächstes implementieren wir wieder den Q-Learning Algorithmus. Der ist fast identisch zu dem Gridworld-Beispiel. Unterschiede gibt es nur, da wir nur eine zweidimensionale Q-Matrix haben, statt einer dreidimensionalen, da der Zustandsraum weniger Dimensionen hat.
import time
# Beispiel für die Erstellung und Verwendung der StockTradingEnv-Umgebung
tic=time.time()
env = StockTradingEnv(data, num_states)
# Initialisiere Q-Werte
Q = np.zeros((num_states, 3))
# Hyperparameter
alpha = 0.1 # Lernrate
gamma = 0.9 # Diskontierungsfaktor
epsilon = 0.1 # Epsilon für die Epsilon-Greedy-Strategie
# Training des Q-Learning-Agenten
for episode in range(1000):
state = env.reset()
done = False
actions = []
rewards = []
total_reward = 0
while not done:
if np.random.random() < epsilon:
# Wähle Aktion entweder Zufällig aus
action = np.random.randint(0, len(env.actions))
else:
# Wähle Aktion mit maximaler erwarteten Belohnung Q(s)
action = np.argmax(Q[env.state])
# Führe die Aktion aus und erhalte von der Umgebung den neuen Zustand und die Belohnung
new_state, reward, done = env.step(action)
new_state_idx = env.current_step
# Aktualisiere Q-Werte auf Basis der erhaltenen Belohnung
Q[state, action] += alpha * (reward + gamma * np.max(Q[new_state]) - Q[state, action])
# Aktualisiere den Zustand
state = new_state
# Sammel Erfolgsstatistik
actions.append(action)
total_reward+=-reward
rewards.append(total_reward)
print(f"Execution Time: {time.time()-tic}")
Execution Time: 0.8142070770263672
Auch hier zeigt sich, dass der Q-Learning Algorithmus erfolgreich lernt, wann er Aktien kaufen, verkaufen oder shorten soll, so dass er am Ende Gewinn macht.
px.line(rewards)
Hierbei macht der Algorithmus gar nicht so viele Transaktionen, wie er könnte, um das Ergebnis zu maximieren.
px.line(actions)
RL Frameworks#
RL gehört nicht zu den traditionellen ML-Verfahren und ist deshalb auch nicht in SciKit-Learn oder Statsmodels enthalten. Das liegt unter anderem daran, dass man beim RL nicht einfach ein Modell auf einem Datensatz trainiert, wie es von der Standard-API von SciKit-Learn erwartet wird, sondern manuell ein Umgebungsmodell erstellen muss.
Mit der wachsenden Popularität von RL in den letzten Jahren haben sich aber spezielle Bibliotheken für RL entwickelt, die dies vereinfachen und das Lösen komplexer Probleme vereinfachen. Eine Bibliothek dafür ist Gymnasium
oder kurz Gym
von OpenAI. Die Gym
-Bibliothek ist eine Open-Source-Bibliothek, die speziell für die Entwicklung und das Testen von RL-Algorithmen entwickelt wurde. Sie bietet eine standardisierte API und eine Vielzahl von vordefinierten Umgebungen, die es ermöglichen RL-Algorithmen effizient zu implementieren und zu evaluieren. Hierbei spielt insbesondere die Definition der Umgebung eine wichtige Rolle.
Das Standard-Interface in Gym
für eine Umgebung für den Börsenfall ist mehr oder weniger identisch mit der Klasse, die wir oben definiert haben.
import gymnasium as gym
from gymnasium import spaces
import numpy as np
import pandas as pd
class StockTradingEnvGym(gym.Env):
def __init__(self, data):
super(StockTradingEnvGym, self).__init__()
self.data = data.copy()
self.current_step = 0
self.balance = 10000 # Startguthaben
self.position = 0 # 0: neutral, 1: long, -1: short
self.old_price = 0
self.current_price = self.data[self.current_step]
# Actions: 0 = Kaufen, 1 = Verkaufen, 2 = Halten
self.action_space = spaces.Discrete(3)
# Observation space: [current price, position, balance]
self.observation_space = spaces.Box(
low=np.array([-np.inf, -1, -np.inf]),
high=np.array([np.inf, 1, np.inf]),
dtype=np.float32
)
def reset(self, seed=0, options=None):
self.current_step = 0
self.balance = 10000
self.position = 0
self.current_price = self.data[self.current_step]
return self._get_obs(), {}
def _get_obs(self):
return np.array([self.current_price, self.position, self.balance])
def step(self, action):
prev_price = self.current_price
self.current_step += 1
self.current_price = self.data[self.current_step]
reward = 0
if action == 0: # Kaufen
if self.position == 0: # Kaufe Aktie
self.position = 1
self.balance -= self.current_price
self.old_price = self.current_price
elif self.position == -1: # Verkaufe Short
reward = 2 * (self.old_price - self.current_price)
self.position = 0
self.balance += self.old_price
elif action == 1: # Verkaufen
if self.position == 0: # Kaufe Short
self.position = -1
self.balance += self.current_price
self.old_price = self.current_price
elif self.position == 1: # Verkaufe Aktie
reward = 2 * (self.current_price - self.old_price)
self.position = 0
self.balance -= self.old_price
elif action == 2: # Halten
reward = 0
done = self.current_step >= len(self.data) - 1
return self._get_obs(), reward, done, False, {}
def render(self, mode='human'):
print(f'Step: {self.current_step}, Price: {self.current_price}, Position: {self.position}, Balance: {self.balance}')
Ein Aspekt warum RL in den letzten Jahren so beliebt geworden ist, ist dass sich der Lernvorgang gut parallelisieren lässt. Da wir zum Lernen viele Experimente machen müssen, können wir diese natürlich auch parallel ausführen und dadurch gut in einem Rechenzentrum in der Cloud oder auf Grafikkarten mit ihren tausenden kleinen Prozessoren verteilen.
Eine Bibliothek, die hierbei viel genutzt wird, ist Ray welche auch gerne zur Parallelisierung von ML-Aufgaben genutzt wird, da die Bibliothek das Verteilen der Lernaufgaben im Cluster und das Sammeln der Ergebnisse übernimmt.
Wir nutzen hier den Proximale Policy Optimization (PPO) Algorithmus. Er ist ein iteratives Verfahren, welches zur Optimierung von Richtlinien in Agenten verwendet wird und instabile Updates der Policy vermeidet und ermöglicht so die effiziente Handhabung komplexer Aufgaben mit kontinuierlichen Aktionsräumen. Dies wird durch die Einführung eines Clip-Parameters ε erreicht, der die maximale Änderung der Policy-Parameter begrenzt.
import os
os.environ["PYTHONWARNINGS"]="ignore::DeprecationWarning"
from ray.rllib.algorithms.ppo import PPOConfig
from ray.tune.registry import register_env
tic=time.time()
def env_creator(env_config):
return StockTradingEnvGym(data) # return an env instance
register_env("StockTradingEnvGym", env_creator)
config = (
PPOConfig()
.environment("StockTradingEnvGym")
.env_runners(num_env_runners=2)
.framework("torch")
.training()
.evaluation(evaluation_num_env_runners=1)
)
algo = config.build() # 2. build the algorithm,
for _ in range(10):
algo.train() # 3. train it,
#algo.evaluate() # 4. and evaluate it.
print(f"Execution Time: {time.time()-tic}")
Matplotlib is building the font cache; this may take a moment.
2025-04-08 07:55:24,060 WARNING algorithm_config.py:4355 -- You have specified 1 evaluation workers, but your `evaluation_interval` is 0 or None! Therefore, evaluation doesn't occur automatically with each call to `Algorithm.train()`. Instead, you have to call `Algorithm.evaluate()` manually in order to trigger an evaluation run.
2025-04-08 07:55:24,074 WARNING ppo.py:295 -- You are running PPO on the new API stack! This is the new default behavior for this algorithm. If you don't want to use the new API stack, set `config.api_stack(enable_rl_module_and_learner=False,enable_env_runner_and_connector_v2=False)`. For a detailed migration guide, see here: https://docs.ray.io/en/master/rllib/new-api-stack-migration-guide.html
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/algorithms/algorithm.py:569: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
`UnifiedLogger` will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `JsonLogger interface is deprecated in favor of the `ray.tune.json.JsonLoggerCallback` interface and will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `CSVLogger interface is deprecated in favor of the `ray.tune.csv.CSVLoggerCallback` interface and will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `TBXLogger interface is deprecated in favor of the `ray.tune.tensorboardx.TBXLoggerCallback` interface and will be removed in Ray 2.7.
2025-04-08 07:55:27,308 INFO worker.py:1821 -- Started a local Ray instance.
(SingleAgentEnvRunner pid=48135) /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/spaces/box.py:235: UserWarning: WARN: Box low's precision lowered by casting to float32, current low.dtype=float64
(SingleAgentEnvRunner pid=48135) gym.logger.warn(
(SingleAgentEnvRunner pid=48135) /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/spaces/box.py:305: UserWarning: WARN: Box high's precision lowered by casting to float32, current high.dtype=float64
(SingleAgentEnvRunner pid=48135) gym.logger.warn(
(SingleAgentEnvRunner pid=48135) 2025-04-08 07:55:31,359 WARNING deprecation.py:50 -- DeprecationWarning: `RLModule(config=[RLModuleConfig object])` has been deprecated. Use `RLModule(observation_space=.., action_space=.., inference_only=.., model_config=.., catalog_class=..)` instead. This will raise an error in the future!
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/spaces/box.py:235: UserWarning:
WARN: Box low's precision lowered by casting to float32, current low.dtype=float64
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/spaces/box.py:305: UserWarning:
WARN: Box high's precision lowered by casting to float32, current high.dtype=float64
2025-04-08 07:55:31,445 WARNING deprecation.py:50 -- DeprecationWarning: `RLModule(config=[RLModuleConfig object])` has been deprecated. Use `RLModule(observation_space=.., action_space=.., inference_only=.., model_config=.., catalog_class=..)` instead. This will raise an error in the future!
2025-04-08 07:55:31,462 WARNING algorithm_config.py:4355 -- You have specified 1 evaluation workers, but your `evaluation_interval` is 0 or None! Therefore, evaluation doesn't occur automatically with each call to `Algorithm.train()`. Instead, you have to call `Algorithm.evaluate()` manually in order to trigger an evaluation run.
2025-04-08 07:55:31,462 WARNING ppo.py:295 -- You are running PPO on the new API stack! This is the new default behavior for this algorithm. If you don't want to use the new API stack, set `config.api_stack(enable_rl_module_and_learner=False,enable_env_runner_and_connector_v2=False)`. For a detailed migration guide, see here: https://docs.ray.io/en/master/rllib/new-api-stack-migration-guide.html
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:642: UserWarning:
WARN: Overriding environment rllib-single-agent-env-v0 already in registry.
2025-04-08 07:55:34,020 WARNING rl_module.py:427 -- Could not create a Catalog object for your RLModule! If you are not using the new API stack yet, make sure to switch it off in your config: `config.api_stack(enable_rl_module_and_learner=False, enable_env_runner_and_connector_v2=False)`. Some algos already use the new stack by default. Ignore this message, if your RLModule does not use a Catalog to build its sub-components.
2025-04-08 07:55:34,910 INFO trainable.py:161 -- Trainable.setup took 10.709 seconds. If your trainable is slow to initialize, consider setting reuse_actors=True to reduce actor creation overheads.
(SingleAgentEnvRunner pid=48135) /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/utils/passive_env_checker.py:174: UserWarning: WARN: The default seed argument in `Env.reset` should be `None`, otherwise the environment will by default always be deterministic. Actual default: seed=0
(SingleAgentEnvRunner pid=48135) logger.warn(
(SingleAgentEnvRunner pid=48135) /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/utils/passive_env_checker.py:134: UserWarning: WARN: The obs returned by the `reset()` method was expecting numpy array dtype to be float32, actual type: float64
(SingleAgentEnvRunner pid=48135) logger.warn(
(SingleAgentEnvRunner pid=48135) /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/utils/passive_env_checker.py:158: UserWarning: WARN: The obs returned by the `reset()` method is not within the observation space.
(SingleAgentEnvRunner pid=48135) logger.warn(f"{pre} is not within the observation space.")
(SingleAgentEnvRunner pid=48135) /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/utils/passive_env_checker.py:134: UserWarning: WARN: The obs returned by the `step()` method was expecting numpy array dtype to be float32, actual type: float64
(SingleAgentEnvRunner pid=48135) logger.warn(
(SingleAgentEnvRunner pid=48135) /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/utils/passive_env_checker.py:158: UserWarning: WARN: The obs returned by the `step()` method is not within the observation space.
(SingleAgentEnvRunner pid=48135) logger.warn(f"{pre} is not within the observation space.")
Execution Time: 44.63499689102173
# Evaluierung des Agents
env = StockTradingEnvGym(data)
state = env.reset()
done = False
total_reward = 0
actions = []
rewards = []
while not done:
action = algo.compute_single_action(env._get_obs(), state)
state, reward, done, _, _ = env.step(action[0])
total_reward += reward
actions.append(action)
rewards.append(total_reward)
env.render()
print("Gesamtbelohnung:", total_reward)
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/spaces/box.py:235: UserWarning:
WARN: Box low's precision lowered by casting to float32, current low.dtype=float64
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/spaces/box.py:305: UserWarning:
WARN: Box high's precision lowered by casting to float32, current high.dtype=float64
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In[21], line 10
8 rewards = []
9 while not done:
---> 10 action = algo.compute_single_action(env._get_obs(), state)
11 state, reward, done, _, _ = env.step(action[0])
12 total_reward += reward
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/algorithms/algorithm.py:2122, in Algorithm.compute_single_action(self, observation, state, prev_action, prev_reward, info, input_dict, policy_id, full_fetch, explore, timestep, episode, unsquash_action, clip_action, **kwargs)
2118 assert observation is not None, err_msg
2120 # Get the policy to compute the action for (in the multi-agent case,
2121 # Algorithm may hold >1 policies).
-> 2122 policy = self.get_policy(policy_id)
2123 if policy is None:
2124 raise KeyError(
2125 f"PolicyID '{policy_id}' not found in PolicyMap of the "
2126 f"Algorithm's local worker!"
2127 )
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/algorithms/algorithm.py:1991, in Algorithm.get_policy(self, policy_id)
1984 @OldAPIStack
1985 def get_policy(self, policy_id: PolicyID = DEFAULT_POLICY_ID) -> Policy:
1986 """Return policy for the specified id, or None.
1987
1988 Args:
1989 policy_id: ID of the policy to return.
1990 """
-> 1991 return self.env_runner.get_policy(policy_id)
AttributeError: 'SingleAgentEnvRunner' object has no attribute 'get_policy'
px.line([a[0] for a in actions])
px.line(rewards)
Robotik#
DL ist insbesondere in der Robotik ein beliebtes Lernverfahren. Das liegt daran, das zum einen einfache Aufgaben, wie das Greifen von Objekten für Roboter hochkomplex sind und die Regelungen und Steuerungen sehr komplex zu entwickeln sind. Auch wir Menschen brauchen Wochen als Kleinkind um die Grob- und Feinmotorik dafür zu lernen. Trotzdem ist die Aufgabe und die Umgebung eines Roboters einfach zu simulieren. Deshalb setzt man vermehrt auf RL, um solche komplexen Steuerungsprobleme zu erlernen, statt selbstständisch Steuerungen zu entwickeln.
Robot Pusher#
Pusher-v4 ist eine Umgebung aus der gym-Bibliothek, die zur Simulation von Aufgaben im Bereich der Robotersteuerung verwendet wird. In dieser speziellen Umgebung wird ein Roboterarm simuliert, der darauf trainiert wird, ein Objekt zu einer bestimmten Zielposition zu schieben.
Das Ziel des Agenten (Roboterarms) in der Pusher-v4-Umgebung ist es, ein Objekt (in der Regel ein Block) zu einer festgelegten Zielposition zu schieben. Der Agent muss lernen, wie er seine Gelenke bewegen kann, um das Objekt erfolgreich zu schieben.
Der Aktionsraum ist kontinuierlich und repräsentiert die Steuerung des Roboterarms. Typischerweise handelt es sich um einen Vektor von Gelenkbewegungen, die der Agent ausführen kann.
Der Beobachtungsraum umfasst verschiedene Aspekte des Zustands der Umgebung, einschließlich der Position des Endeffektors des Roboterarms; die Position des zu schiebenden Objekts und die Zielposition, zu der das Objekt geschoben werden soll.
Die Belohnung in der Pusher-v4-Umgebung basiert darauf, wie nah das Objekt an der Zielposition ist. Der Agent erhält eine höhere Belohnung, wenn das Objekt näher an der Zielposition ist, und eine geringere Belohnung, wenn es weiter entfernt ist.
Da das Modell in Gym
enthalten ist, ist die Initialisierung einfach.
from ray.rllib.algorithms.ppo import PPOConfig
config = ( # 1. Configure the algorithm,
PPOConfig()
.environment("Pusher-v4", render_env=True)
.env_runners(num_env_runners=2)
.framework("torch")
.training()
.evaluation(evaluation_num_env_runners=1)
)
algo = config.build() # 2. build the algorithm,
for _ in range(5):
algo.train() # 3. train it,
#algo.evaluate() # 4. and evaluate it.
print(f"Execution Time: {time.time()-tic}")
2025-04-08 07:56:08,947 WARNING algorithm_config.py:4355 -- You have specified 1 evaluation workers, but your `evaluation_interval` is 0 or None! Therefore, evaluation doesn't occur automatically with each call to `Algorithm.train()`. Instead, you have to call `Algorithm.evaluate()` manually in order to trigger an evaluation run.
2025-04-08 07:56:08,947 WARNING deprecation.py:50 -- DeprecationWarning: `AlgorithmConfig.render_env` has been deprecated. The `render_env` setting is not supported on the new API stack! In order to log videos to WandB (or other loggers), take a look at this example here: https://github.com/ray-project/ray/blob/master/rllib/examples/envs/env_rendering_and_recording.py This will raise an error in the future!
2025-04-08 07:56:08,948 WARNING ppo.py:295 -- You are running PPO on the new API stack! This is the new default behavior for this algorithm. If you don't want to use the new API stack, set `config.api_stack(enable_rl_module_and_learner=False,enable_env_runner_and_connector_v2=False)`. For a detailed migration guide, see here: https://docs.ray.io/en/master/rllib/new-api-stack-migration-guide.html
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/algorithms/algorithm.py:569: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
`UnifiedLogger` will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `JsonLogger interface is deprecated in favor of the `ray.tune.json.JsonLoggerCallback` interface and will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `CSVLogger interface is deprecated in favor of the `ray.tune.csv.CSVLoggerCallback` interface and will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `TBXLogger interface is deprecated in favor of the `ray.tune.tensorboardx.TBXLoggerCallback` interface and will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:642: UserWarning:
WARN: Overriding environment rllib-single-agent-env-v0 already in registry.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:517: DeprecationWarning:
WARN: The environment Pusher-v4 is out of date. You should consider upgrading to version `v5`.
2025-04-08 07:56:14,949 WARNING algorithm_config.py:4355 -- You have specified 1 evaluation workers, but your `evaluation_interval` is 0 or None! Therefore, evaluation doesn't occur automatically with each call to `Algorithm.train()`. Instead, you have to call `Algorithm.evaluate()` manually in order to trigger an evaluation run.
2025-04-08 07:56:14,949 WARNING deprecation.py:50 -- DeprecationWarning: `AlgorithmConfig.render_env` has been deprecated. The `render_env` setting is not supported on the new API stack! In order to log videos to WandB (or other loggers), take a look at this example here: https://github.com/ray-project/ray/blob/master/rllib/examples/envs/env_rendering_and_recording.py This will raise an error in the future!
2025-04-08 07:56:14,950 WARNING ppo.py:295 -- You are running PPO on the new API stack! This is the new default behavior for this algorithm. If you don't want to use the new API stack, set `config.api_stack(enable_rl_module_and_learner=False,enable_env_runner_and_connector_v2=False)`. For a detailed migration guide, see here: https://docs.ray.io/en/master/rllib/new-api-stack-migration-guide.html
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:642: UserWarning:
WARN: Overriding environment rllib-single-agent-env-v0 already in registry.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:517: DeprecationWarning:
WARN: The environment Pusher-v4 is out of date. You should consider upgrading to version `v5`.
2025-04-08 07:56:17,580 WARNING rl_module.py:427 -- Could not create a Catalog object for your RLModule! If you are not using the new API stack yet, make sure to switch it off in your config: `config.api_stack(enable_rl_module_and_learner=False, enable_env_runner_and_connector_v2=False)`. Some algos already use the new stack by default. Ignore this message, if your RLModule does not use a Catalog to build its sub-components.
Execution Time: 71.48267698287964
Betrachten wir einmal das Ergebnis einer zufälligen Bewegung, so sehen wir wie der Arm vorerst orientierungslos agiert.
Nach mehreren Trainingsepisoden lernt der Algorithmus allerdings den Arm gut zu benutzen. Hier ein Vergleich unterschiedlicher RL-Ansätze. Zu beobachten ist, dass über die Trainings-Episoden die Modelle durch Zufall die Lösung entdecken und dann wiederholen können. Die finalen Lösungen sind dabei aber auch nach vielen Trainings-Episoden nicht perfekt.
from IPython.display import IFrame
IFrame(width="800", height="413", src="https://www.youtube.com/embed/_QmcH1TyNwg", title="Gymnasium - Pusher-v4, Test with different algorithms",
frameborder="0", allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share", referrerpolicy="strict-origin-when-cross-origin", allowfullscreen=True)
Pick and Place#
“FetchPickAndPlaceDense-v2” ist eine Umgebung in der ein simulierter Roboterarm verwendet, um Objekte aufzuheben (Pick) und an einem Zielort abzulegen (Place).
Das Hauptziel des Agenten (Roboterarms) in der FetchPickAndPlaceDense-v2-Umgebung ist es, ein Objekt zu greifen (Pick) und es an einer festgelegten Zielposition abzulegen (Place). Der Agent muss lernen, wie er seine Gelenke und den Greifer steuern kann, um diese Aufgabe erfolgreich zu erfüllen.
Der Aktionsraum ist kontinuierlich und besteht aus den Koordinaten \(x, y, z\) der Hand des Roboterarms (Endeffektors) und die Öffnung des Greifers \(w\) (öffnen oder schließen). Der Beobachtungsraum enthält die Position und Geschwindigkeit des Endeffektors; die Position des zu bewegenden Objekts, die Zielposition, zu der das Objekt bewegt werden soll und den Zustand des Greifers (geöffnet oder geschlossen).
Die Umgebung bietet eine dichte Belohnungsstruktur, was bedeutet, dass der Agent kontinuierlich Rückmeldungen erhält, die ihn darauf hinweisen, wie gut er sich in Richtung seines Ziels bewegt. Die Belohnung basiert hauptsächlich darauf, wie nah das Objekt an der Zielposition ist und ob das Objekt erfolgreich gegriffen und bewegt wurde.
Auch hier ist die Initialisierung einfach.
from ray.rllib.algorithms.ppo import PPOConfig
config = ( # 1. Configure the algorithm,
PPOConfig()
.environment('FetchPickAndPlaceDense-v2')
.env_runners(num_env_runners=2)
.framework("torch")
.training()
.evaluation(evaluation_num_env_runners=1)
)
algo = config.build() # 2. build the algorithm,
for _ in range(5):
algo.train() # 3. train it,
#algo.evaluate() # 4. and evaluate it.
print(f"Execution Time: {time.time()-tic}")
2025-04-08 07:56:35,548 WARNING algorithm_config.py:4355 -- You have specified 1 evaluation workers, but your `evaluation_interval` is 0 or None! Therefore, evaluation doesn't occur automatically with each call to `Algorithm.train()`. Instead, you have to call `Algorithm.evaluate()` manually in order to trigger an evaluation run.
2025-04-08 07:56:35,548 WARNING ppo.py:295 -- You are running PPO on the new API stack! This is the new default behavior for this algorithm. If you don't want to use the new API stack, set `config.api_stack(enable_rl_module_and_learner=False,enable_env_runner_and_connector_v2=False)`. For a detailed migration guide, see here: https://docs.ray.io/en/master/rllib/new-api-stack-migration-guide.html
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/algorithms/algorithm.py:569: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
`UnifiedLogger` will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `JsonLogger interface is deprecated in favor of the `ray.tune.json.JsonLoggerCallback` interface and will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `CSVLogger interface is deprecated in favor of the `ray.tune.csv.CSVLoggerCallback` interface and will be removed in Ray 2.7.
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/logger/unified.py:53: RayDeprecationWarning:
This API is deprecated and may be removed in future Ray releases. You could suppress this warning by setting env variable PYTHONWARNINGS="ignore::DeprecationWarning"
The `TBXLogger interface is deprecated in favor of the `ray.tune.tensorboardx.TBXLoggerCallback` interface and will be removed in Ray 2.7.
2025-04-08 07:56:38,962 ERROR actor_manager.py:804 -- Ray error (The actor died because of an error raised in its creation task, ray::SingleAgentEnvRunner.__init__() (pid=48136, ip=127.0.0.1, actor_id=df79e2c24809d4656d3737c501000000, repr=<ray.rllib.env.single_agent_env_runner.SingleAgentEnvRunner object at 0x3b8147dd0>)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 687, in make
env_spec = _find_spec(id)
^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 531, in _find_spec
_check_version_exists(ns, name, version)
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 397, in _check_version_exists
_check_name_exists(ns, name)
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 374, in _check_name_exists
raise error.NameNotFound(
gymnasium.error.NameNotFound: Environment `FetchPickAndPlaceDense` doesn't exist.
During handling of the above exception, another exception occurred:
ray::SingleAgentEnvRunner.__init__() (pid=48136, ip=127.0.0.1, actor_id=df79e2c24809d4656d3737c501000000, repr=<ray.rllib.env.single_agent_env_runner.SingleAgentEnvRunner object at 0x3b8147dd0>)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py", line 89, in __init__
self.make_env()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py", line 627, in make_env
gym.make_vec(
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 918, in make_vec
env = gym.vector.SyncVectorEnv(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py", line 86, in __init__
self.envs = [env_fn() for env_fn in env_fns]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py", line 86, in <listcomp>
self.envs = [env_fn() for env_fn in env_fns]
^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 903, in create_single_env
single_env = make(env_spec, **env_spec_kwargs.copy())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 740, in make
env = env_creator(**env_spec_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/utils/__init__.py", line 122, in _gym_env_creator
raise EnvError(ERR_MSG_INVALID_ENV_DESCRIPTOR.format(env_descriptor))
ray.rllib.utils.error.EnvError: The env string you provided ('FetchPickAndPlaceDense-v2') is:
a) Not a supported or -installed environment.
b) Not a tune-registered environment creator.
c) Not a valid env class string.
Try one of the following:
a) For Atari support: `pip install gym[atari] autorom[accept-rom-license]`.
For PyBullet support: `pip install pybullet`.
b) To register your custom env, do `from ray import tune;
tune.register('[name]', lambda cfg: [return env obj from here using cfg])`.
Then in your config, do `config['env'] = [name]`.
c) Make sure you provide a fully qualified classpath, e.g.:
`ray.rllib.examples.envs.classes.repeat_after_me_env.RepeatAfterMeEnv`), taking actor 1 out of service.
2025-04-08 07:56:38,963 ERROR actor_manager.py:804 -- Ray error (The actor died because of an error raised in its creation task, ray::SingleAgentEnvRunner.__init__() (pid=48137, ip=127.0.0.1, actor_id=4b4e389efbedaac8ae189a7401000000, repr=<ray.rllib.env.single_agent_env_runner.SingleAgentEnvRunner object at 0x3b92cbf50>)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 687, in make
env_spec = _find_spec(id)
^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 531, in _find_spec
_check_version_exists(ns, name, version)
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 397, in _check_version_exists
_check_name_exists(ns, name)
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 374, in _check_name_exists
raise error.NameNotFound(
gymnasium.error.NameNotFound: Environment `FetchPickAndPlaceDense` doesn't exist.
During handling of the above exception, another exception occurred:
ray::SingleAgentEnvRunner.__init__() (pid=48137, ip=127.0.0.1, actor_id=4b4e389efbedaac8ae189a7401000000, repr=<ray.rllib.env.single_agent_env_runner.SingleAgentEnvRunner object at 0x3b92cbf50>)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py", line 89, in __init__
self.make_env()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py", line 627, in make_env
gym.make_vec(
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 918, in make_vec
env = gym.vector.SyncVectorEnv(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py", line 86, in __init__
self.envs = [env_fn() for env_fn in env_fns]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py", line 86, in <listcomp>
self.envs = [env_fn() for env_fn in env_fns]
^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 903, in create_single_env
single_env = make(env_spec, **env_spec_kwargs.copy())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 740, in make
env = env_creator(**env_spec_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/utils/__init__.py", line 122, in _gym_env_creator
raise EnvError(ERR_MSG_INVALID_ENV_DESCRIPTOR.format(env_descriptor))
ray.rllib.utils.error.EnvError: The env string you provided ('FetchPickAndPlaceDense-v2') is:
a) Not a supported or -installed environment.
b) Not a tune-registered environment creator.
c) Not a valid env class string.
Try one of the following:
a) For Atari support: `pip install gym[atari] autorom[accept-rom-license]`.
For PyBullet support: `pip install pybullet`.
b) To register your custom env, do `from ray import tune;
tune.register('[name]', lambda cfg: [return env obj from here using cfg])`.
Then in your config, do `config['env'] = [name]`.
c) Make sure you provide a fully qualified classpath, e.g.:
`ray.rllib.examples.envs.classes.repeat_after_me_env.RepeatAfterMeEnv`), taking actor 2 out of service.
2025-04-08 07:56:38,963 ERROR env_runner_group.py:805 -- Validation of EnvRunner failed! Error=The actor died because of an error raised in its creation task, ray::SingleAgentEnvRunner.__init__() (pid=48136, ip=127.0.0.1, actor_id=df79e2c24809d4656d3737c501000000, repr=<ray.rllib.env.single_agent_env_runner.SingleAgentEnvRunner object at 0x3b8147dd0>)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 687, in make
env_spec = _find_spec(id)
^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 531, in _find_spec
_check_version_exists(ns, name, version)
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 397, in _check_version_exists
_check_name_exists(ns, name)
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 374, in _check_name_exists
raise error.NameNotFound(
gymnasium.error.NameNotFound: Environment `FetchPickAndPlaceDense` doesn't exist.
During handling of the above exception, another exception occurred:
ray::SingleAgentEnvRunner.__init__() (pid=48136, ip=127.0.0.1, actor_id=df79e2c24809d4656d3737c501000000, repr=<ray.rllib.env.single_agent_env_runner.SingleAgentEnvRunner object at 0x3b8147dd0>)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py", line 89, in __init__
self.make_env()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py", line 627, in make_env
gym.make_vec(
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 918, in make_vec
env = gym.vector.SyncVectorEnv(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py", line 86, in __init__
self.envs = [env_fn() for env_fn in env_fns]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py", line 86, in <listcomp>
self.envs = [env_fn() for env_fn in env_fns]
^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 903, in create_single_env
single_env = make(env_spec, **env_spec_kwargs.copy())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 740, in make
env = env_creator(**env_spec_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/utils/__init__.py", line 122, in _gym_env_creator
raise EnvError(ERR_MSG_INVALID_ENV_DESCRIPTOR.format(env_descriptor))
ray.rllib.utils.error.EnvError: The env string you provided ('FetchPickAndPlaceDense-v2') is:
a) Not a supported or -installed environment.
b) Not a tune-registered environment creator.
c) Not a valid env class string.
Try one of the following:
a) For Atari support: `pip install gym[atari] autorom[accept-rom-license]`.
For PyBullet support: `pip install pybullet`.
b) To register your custom env, do `from ray import tune;
tune.register('[name]', lambda cfg: [return env obj from here using cfg])`.
Then in your config, do `config['env'] = [name]`.
c) Make sure you provide a fully qualified classpath, e.g.:
`ray.rllib.examples.envs.classes.repeat_after_me_env.RepeatAfterMeEnv`
2025-04-08 07:56:38,964 ERROR env_runner_group.py:805 -- Validation of EnvRunner failed! Error=The actor died because of an error raised in its creation task, ray::SingleAgentEnvRunner.__init__() (pid=48137, ip=127.0.0.1, actor_id=4b4e389efbedaac8ae189a7401000000, repr=<ray.rllib.env.single_agent_env_runner.SingleAgentEnvRunner object at 0x3b92cbf50>)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 687, in make
env_spec = _find_spec(id)
^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 531, in _find_spec
_check_version_exists(ns, name, version)
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 397, in _check_version_exists
_check_name_exists(ns, name)
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 374, in _check_name_exists
raise error.NameNotFound(
gymnasium.error.NameNotFound: Environment `FetchPickAndPlaceDense` doesn't exist.
During handling of the above exception, another exception occurred:
ray::SingleAgentEnvRunner.__init__() (pid=48137, ip=127.0.0.1, actor_id=4b4e389efbedaac8ae189a7401000000, repr=<ray.rllib.env.single_agent_env_runner.SingleAgentEnvRunner object at 0x3b92cbf50>)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py", line 89, in __init__
self.make_env()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py", line 627, in make_env
gym.make_vec(
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 918, in make_vec
env = gym.vector.SyncVectorEnv(
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py", line 86, in __init__
self.envs = [env_fn() for env_fn in env_fns]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py", line 86, in <listcomp>
self.envs = [env_fn() for env_fn in env_fns]
^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 903, in create_single_env
single_env = make(env_spec, **env_spec_kwargs.copy())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py", line 740, in make
env = env_creator(**env_spec_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/utils/__init__.py", line 122, in _gym_env_creator
raise EnvError(ERR_MSG_INVALID_ENV_DESCRIPTOR.format(env_descriptor))
ray.rllib.utils.error.EnvError: The env string you provided ('FetchPickAndPlaceDense-v2') is:
a) Not a supported or -installed environment.
b) Not a tune-registered environment creator.
c) Not a valid env class string.
Try one of the following:
a) For Atari support: `pip install gym[atari] autorom[accept-rom-license]`.
For PyBullet support: `pip install pybullet`.
b) To register your custom env, do `from ray import tune;
tune.register('[name]', lambda cfg: [return env obj from here using cfg])`.
Then in your config, do `config['env'] = [name]`.
c) Make sure you provide a fully qualified classpath, e.g.:
`ray.rllib.examples.envs.classes.repeat_after_me_env.RepeatAfterMeEnv`
/opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:642: UserWarning:
WARN: Overriding environment rllib-single-agent-env-v0 already in registry.
---------------------------------------------------------------------------
NameNotFound Traceback (most recent call last)
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/utils/__init__.py:120, in _gym_env_creator(env_context, env_descriptor)
119 else:
--> 120 env = gym.make(env_descriptor, **env_context)
121 except gym.error.Error:
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:687, in make(id, max_episode_steps, disable_env_checker, **kwargs)
686 # The environment name can include an unloaded module in "module:env_name" style
--> 687 env_spec = _find_spec(id)
689 assert isinstance(env_spec, EnvSpec)
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:531, in _find_spec(env_id)
530 if env_spec is None:
--> 531 _check_version_exists(ns, name, version)
532 raise error.Error(
533 f"No registered env with id: {env_name}. Did you register it, or import the package that registers it? Use `gymnasium.pprint_registry()` to see all of the registered environments."
534 )
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:397, in _check_version_exists(ns, name, version)
395 return
--> 397 _check_name_exists(ns, name)
398 if version is None:
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:374, in _check_name_exists(ns, name)
372 suggestion_msg = f" Did you mean: `{suggestion[0]}`?" if suggestion else ""
--> 374 raise error.NameNotFound(
375 f"Environment `{name}` doesn't exist{namespace_msg}.{suggestion_msg}"
376 )
NameNotFound: Environment `FetchPickAndPlaceDense` doesn't exist.
During handling of the above exception, another exception occurred:
EnvError Traceback (most recent call last)
Cell In[26], line 12
1 from ray.rllib.algorithms.ppo import PPOConfig
3 config = ( # 1. Configure the algorithm,
4 PPOConfig()
5 .environment('FetchPickAndPlaceDense-v2')
(...)
9 .evaluation(evaluation_num_env_runners=1)
10 )
---> 12 algo = config.build() # 2. build the algorithm,
14 for _ in range(5):
15 algo.train() # 3. train it,
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/algorithms/algorithm_config.py:949, in AlgorithmConfig.build(self, env, logger_creator, use_copy)
946 if isinstance(self.algo_class, str):
947 algo_class = get_trainable_cls(self.algo_class)
--> 949 return algo_class(
950 config=self if not use_copy else copy.deepcopy(self),
951 logger_creator=self.logger_creator,
952 )
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/algorithms/algorithm.py:585, in Algorithm.__init__(self, config, env, logger_creator, **kwargs)
582 # Evaluation EnvRunnerGroup and metrics last returned by `self.evaluate()`.
583 self.eval_env_runner_group: Optional[EnvRunnerGroup] = None
--> 585 super().__init__(
586 config=config,
587 logger_creator=logger_creator,
588 **kwargs,
589 )
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/tune/trainable/trainable.py:158, in Trainable.__init__(self, config, logger_creator, storage)
154 logger.debug(f"StorageContext on the TRAINABLE:\n{storage}")
156 self._open_logfiles(stdout_file, stderr_file)
--> 158 self.setup(copy.deepcopy(self.config))
159 setup_time = time.time() - self._start_time
160 if setup_time > SETUP_TIME_THRESHOLD:
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/algorithms/algorithm.py:671, in Algorithm.setup(self, config)
668 self.config.off_policy_estimation_methods = ope_dict
670 # Create a set of env runner actors via a EnvRunnerGroup.
--> 671 self.env_runner_group = EnvRunnerGroup(
672 env_creator=self.env_creator,
673 validate_env=self.validate_env,
674 default_policy_class=self.get_default_policy_class(self.config),
675 config=self.config,
676 num_env_runners=(
677 0
678 if (
679 self.config.input_
680 and (
681 isinstance(self.config.input_, str)
682 or (
683 isinstance(self.config.input_, list)
684 and isinstance(self.config.input_[0], str)
685 )
686 )
687 and self.config.input_ != "sampler"
688 and self.config.enable_rl_module_and_learner
689 )
690 else self.config.num_env_runners
691 ),
692 local_env_runner=True,
693 logdir=self.logdir,
694 tune_trial_id=self.trial_id,
695 )
697 # If an input path is available and we are on the new API stack generate
698 # an `OfflineData` instance.
699 if (
700 self.config.input_
701 and (
(...)
709 and self.config.enable_rl_module_and_learner
710 ):
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/env_runner_group.py:194, in EnvRunnerGroup.__init__(self, env_creator, validate_env, default_policy_class, config, num_env_runners, local_env_runner, logdir, _setup, tune_trial_id, num_workers, local_worker)
192 if _setup:
193 try:
--> 194 self._setup(
195 validate_env=validate_env,
196 config=config,
197 num_env_runners=num_env_runners,
198 local_env_runner=local_env_runner,
199 )
200 # EnvRunnerGroup creation possibly fails, if some (remote) workers cannot
201 # be initialized properly (due to some errors in the EnvRunners's
202 # constructor).
203 except RayActorError as e:
204 # In case of an actor (remote worker) init failure, the remote worker
205 # may still exist and will be accessible, however, e.g. calling
206 # its `sample.remote()` would result in strange "property not found"
207 # errors.
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/env_runner_group.py:285, in EnvRunnerGroup._setup(self, validate_env, config, num_env_runners, local_env_runner)
283 # Create a local worker, if needed.
284 if local_env_runner:
--> 285 self._local_env_runner = self._make_worker(
286 cls=self.env_runner_cls,
287 env_creator=self._env_creator,
288 validate_env=validate_env,
289 worker_index=0,
290 num_workers=num_env_runners,
291 config=self._local_config,
292 spaces=spaces,
293 )
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/env_runner_group.py:1190, in EnvRunnerGroup._make_worker(self, cls, env_creator, validate_env, worker_index, num_workers, recreated_worker, config, spaces)
1176 def _make_worker(
1177 self,
1178 *,
(...)
1188 ] = None,
1189 ) -> Union[EnvRunner, ActorHandle]:
-> 1190 worker = cls(
1191 env_creator=env_creator,
1192 validate_env=validate_env,
1193 default_policy_class=self._policy_class,
1194 config=config,
1195 worker_index=worker_index,
1196 num_workers=num_workers,
1197 recreated_worker=recreated_worker,
1198 log_dir=self._logdir,
1199 spaces=spaces,
1200 dataset_shards=self._ds_shards,
1201 tune_trial_id=self._tune_trial_id,
1202 )
1204 return worker
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py:89, in SingleAgentEnvRunner.__init__(self, config, **kwargs)
87 self.env: Optional[gym.vector.VectorEnvWrapper] = None
88 self.num_envs: int = 0
---> 89 self.make_env()
91 # Create the env-to-module connector pipeline.
92 self._env_to_module = self.config.build_env_to_module_connector(self.env)
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/single_agent_env_runner.py:627, in SingleAgentEnvRunner.make_env(self)
619 entry_point = partial(
620 _gym_env_creator,
621 env_descriptor=self.config.env,
622 env_context=env_ctx,
623 )
624 gym.register("rllib-single-agent-env-v0", entry_point=entry_point)
626 self.env = DictInfoToList(
--> 627 gym.make_vec(
628 "rllib-single-agent-env-v0",
629 num_envs=self.config.num_envs_per_env_runner,
630 vectorization_mode=(
631 VectorizeMode.ASYNC
632 if self.config.remote_worker_envs
633 else VectorizeMode.SYNC
634 ),
635 )
636 )
638 self.num_envs: int = self.env.num_envs
639 assert self.num_envs == self.config.num_envs_per_env_runner
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:918, in make_vec(id, num_envs, vectorization_mode, vector_kwargs, wrappers, **kwargs)
913 if env_spec.entry_point is None:
914 raise error.Error(
915 f"Cannot create vectorized environment for {env_spec.id} because it doesn't have an entry point defined."
916 )
--> 918 env = gym.vector.SyncVectorEnv(
919 env_fns=(create_single_env for _ in range(num_envs)),
920 **vector_kwargs,
921 )
922 elif vectorization_mode == VectorizeMode.ASYNC:
923 if env_spec.entry_point is None:
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py:86, in SyncVectorEnv.__init__(self, env_fns, copy, observation_mode)
83 self.observation_mode = observation_mode
85 # Initialise all sub-environments
---> 86 self.envs = [env_fn() for env_fn in env_fns]
88 # Define core attributes using the sub-environments
89 # As we support `make_vec(spec)` then we can't include a `spec = self.envs[0].spec` as this doesn't guarantee we can actual recreate the vector env.
90 self.num_envs = len(self.envs)
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/vector/sync_vector_env.py:86, in <listcomp>(.0)
83 self.observation_mode = observation_mode
85 # Initialise all sub-environments
---> 86 self.envs = [env_fn() for env_fn in env_fns]
88 # Define core attributes using the sub-environments
89 # As we support `make_vec(spec)` then we can't include a `spec = self.envs[0].spec` as this doesn't guarantee we can actual recreate the vector env.
90 self.num_envs = len(self.envs)
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:903, in make_vec.<locals>.create_single_env()
902 def create_single_env() -> Env:
--> 903 single_env = make(env_spec, **env_spec_kwargs.copy())
905 if wrappers is None:
906 return single_env
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/gymnasium/envs/registration.py:740, in make(id, max_episode_steps, disable_env_checker, **kwargs)
734 logger.warn(
735 f"The environment is being initialised with render_mode={render_mode!r} "
736 f"that is not in the possible render_modes ({render_modes})."
737 )
739 try:
--> 740 env = env_creator(**env_spec_kwargs)
741 except TypeError as e:
742 if (
743 str(e).find("got an unexpected keyword argument 'render_mode'") >= 0
744 and apply_human_rendering
745 ):
File /opt/miniconda3/envs/lehre/lib/python3.11/site-packages/ray/rllib/env/utils/__init__.py:122, in _gym_env_creator(env_context, env_descriptor)
120 env = gym.make(env_descriptor, **env_context)
121 except gym.error.Error:
--> 122 raise EnvError(ERR_MSG_INVALID_ENV_DESCRIPTOR.format(env_descriptor))
124 return env
EnvError: The env string you provided ('FetchPickAndPlaceDense-v2') is:
a) Not a supported or -installed environment.
b) Not a tune-registered environment creator.
c) Not a valid env class string.
Try one of the following:
a) For Atari support: `pip install gym[atari] autorom[accept-rom-license]`.
For PyBullet support: `pip install pybullet`.
b) To register your custom env, do `from ray import tune;
tune.register('[name]', lambda cfg: [return env obj from here using cfg])`.
Then in your config, do `config['env'] = [name]`.
c) Make sure you provide a fully qualified classpath, e.g.:
`ray.rllib.examples.envs.classes.repeat_after_me_env.RepeatAfterMeEnv`
Das RL-Modell lernt auch hier den Roboter Arm zu kontrolieren und die Kugel aufzunehmen.