Prostředí kuimaze2.RLProblem
využijete při učení co nejlepší strategie pro neznámý MDP metodami posilovaného učení (reinforcement learning). Je použito ve čtvrté povinné úloze 11-RL
.
Po vytvoření instance třídy RLProblem
(viz Použití) můžete využívat následující metody:
env.get_states()
vrací seznam všech volných stavů (instance třídy State
), tedy bez zdí.
env.get_action_space()
vrací seznam všech akcí, které mají smysl v daném prostředí. Výsledek není závislý na aktuálním stavu (což je rozdíl proti metodě MDPProblem.get_actions(state)
).
env.sample_action(action_probs)
náhodně vybere jednu z možných akcí. Parametr action_probs
obsahuje pravděpodobnosti pro jednotlivé akce (je to slovník, kde klíčem je akce a hodnotou její pravděpodobnost). Není-li rozdělení uvedeno, vybere se rovnoměrně ze všech akcí.
env.reset()
uvádí prostředí do výchozího stavu. Metodu je třeba zavolat před každou novou epizodou (i před tou první). Metoda vrací úvodní stav (State
), v němž se agent nachází.
env.step(action)
vykoná v prostředí zvolenou akci. Vrací trojici:
new_state
je nový stav (State
), do něhož se agent po vykonání akce dostal. Je-li prostředí stochastické, může být nový stav odlišný od toho, který by odpovídal vybrané akci.
reward
je okamžitá odměna (float
) za přechod state-action-new_state.
episode_finished
je True
, pokud daná epizoda již skončila. Další případné volání metody step()
v takovém případě vyvolá vyhození výjimky. Prostředí je třeba před novou epizodou znovu resetovat metodou reset()
.
env.render()
aktualizuje grafické zobrazení prostředí. (Pokud jste grafické zobrazení při vytváření prostředí nezapnuli, nedělá nic.) Umožňuje “obarvit” jednotlivé stavy a q-stavy, umožňuje v nich zobrazit texty, umožňuje zobrazit strategii, aktuální stav a vybranou akci, či cestu, kterou agent v prostředí prošel. Vysvětlení jednotlivých parametrů této metody najdete v helpu (help(env.render)
). Viz také použití env.render()
v pomocné metodě RLAgent.render()
v ukázkovém modulu example_rl.py
.
Prostředí se vytváří prakticky stejně jako MDPProblem
, ale použití je jiné.
Import prostředí:
>>> from kuimaze2 import Map, RLProblem
Vytvoření mapy, jíž budeme prostředí inicializovat:
>>> MAP = "SG" >>> map = Map.from_string(MAP)
Vytvoření deterministického prostředí s grafickým zobrazením:
>>> env1 = RLProblem(map, graphics=True)
Vytvoření nedeterministického prostředí (určení pravděpodobností, kam se agent ve skutečnosti pohne):
>>> env2 = RLProblem(map, action_probs=dict(forward=0.8, left=0.1, right=0.1, backward=0.0))
Seznam všech validních stavů v prostředí:
>>> env2.get_states() [State(r=0, c=0), State(r=0, c=1)]
Seznam všech akcí, které lze v nějakém stavu prostředí vykonat:
>>> env2.get_action_space() [<Action.UP: 0>, <Action.RIGHT: 1>, <Action.DOWN: 2>, <Action.LEFT: 3>]
Může se hodit i náhodně vybraná akce:
>>> env2.sample_action() # Výsledkem může být kterákoli z možných akcí. <Action.UP: 0>
Metoda step se pokusí v prostředí vykonat zvolenou akci:
>>> env2.step(env2.sample_action())
Traceback (most recent call last): File "<stdin>", line 1, in <module> File "...\kuimaze2\rl.py", line 60, in step raise NeedsResetError( kuimaze2.exceptions.NeedsResetError: RLProblem: Episode terminated. You must call reset() first.Jak je vidět, před prvním použitím metody
step()
je třeba prostředí reset
ovat.
Volání metody reset()
vrátí počáteční stav agenta pro danou epizodu:
>>> state = env2.reset() >>> state State(r=0, c=0)
Nyní můžeme zavolat metodu step()
:
>>> action = env2.sample_action() >>> action <Action.DOWN: 2> >>> new_state, reward, episode_finished = env2.step(action) >>> new_state State(r=0, c=0) >>> reward -0.04 >>> episode_finished FalsePokusili jsme se vykonat akci
Action.DOWN
, ale patrně jsme narazili do zdi, protože nový stav new_state
je shodný s původním. Za vykonání akce jsme dostali okamžitou odměnu -0.04
a vidíme, že epizoda neskončila, můžeme pokračovat.
Zkusme tedy dělat náhodné kroky, dokud epizoda neskončí:
>>> while not episode_finished: ... action = env2.sample_action() ... new_state, reward, episode_finished = env2.step(action) ... print(f"{state=} {action=} {reward=} {new_state=} {episode_finished=}") ... state = new_state ... state=State(r=0, c=0) action=<Action.DOWN: 2> reward=-0.04 new_state=State(r=0, c=0) episode_finished=False state=State(r=0, c=0) action=<Action.RIGHT: 1> reward=-0.04 new_state=State(r=0, c=1) episode_finished=False state=State(r=0, c=1) action=<Action.UP: 0> reward=1.0 new_state=None episode_finished=True
Další volání metody step()
by opět vyvolalo výjimku. Epizoda skončila, chceme začít novou, musíme tedy opět zavolat reset()
.