====== RLProblem ====== 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''. ===== Veřejné rozhraní ===== Po vytvoření instance třídy ''RLProblem'' (viz [[.:30_RLProblem#pouziti|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''. ===== Použití ===== 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() [, , , ] 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í. Metoda step se pokusí v prostředí vykonat zvolenou akci: >>> env2.step(env2.sample_action()) Traceback (most recent call last): File "", line 1, in 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 >>> new_state, reward, episode_finished = env2.step(action) >>> new_state State(r=0, c=0) >>> reward -0.04 >>> episode_finished False Pokusili 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= reward=-0.04 new_state=State(r=0, c=0) episode_finished=False state=State(r=0, c=0) action= reward=-0.04 new_state=State(r=0, c=1) episode_finished=False state=State(r=0, c=1) action= 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()''.