Uczenie maszynowe i sztuczne sieci neuronowe/Ćwiczenia 13: Różnice pomiędzy wersjami
(Utworzono nową stronę "=Wstęp= Uczenie ze wzmocnieniem (reinforcement learning RL) odbywa się przez interakcję kilku elementów: Plik:Rl.png|thumb| 400px|Ilustracja zależności pomięd...") |
(→Agent) |
||
(Nie pokazano 1 pośredniej wersji utworzonej przez tego samego użytkownika) | |||
Linia 61: | Linia 61: | ||
Drugi argument to współrzędne pola, które ma być celem agenta. | Drugi argument to współrzędne pola, które ma być celem agenta. | ||
− | Ogólnie, Maze służy do wytwarzania dwuwymiarowych labiryntów, w których możliwe pozycje to stany [[ | + | Ogólnie, Maze służy do wytwarzania dwuwymiarowych labiryntów, w których możliwe pozycje to stany [[Uczenie_maszynowe_i_sztuczne_sieci_neuronowe/Wykład_11#Proces_decyzyjny_Markowa|MDP]]. |
Każdy ze stanów może byc potencjalnym stanem startowym (poza stanem, który jest celem). Labirynt może mieć stany absorbujące, czyli takie z których jeśli agent w nie wpadnie to zadanie się kończy (domyślnie jest to stan celu, ale na wykładzie mieliśmy też przykład z negatywnym stanem absorbującym). | Każdy ze stanów może byc potencjalnym stanem startowym (poza stanem, który jest celem). Labirynt może mieć stany absorbujące, czyli takie z których jeśli agent w nie wpadnie to zadanie się kończy (domyślnie jest to stan celu, ale na wykładzie mieliśmy też przykład z negatywnym stanem absorbującym). | ||
Linia 67: | Linia 67: | ||
− | Enviroment dostaje wejścia poprzez metodę <tt> performAction()</tt> i zwraca wyjście przez metodę <tt>getSensors()</tt>. | + | Enviroment dostaje wejścia poprzez metodę <tt> performAction()</tt> i zwraca wyjście przez metodę <tt>getSensors()</tt>. |
==Agent == | ==Agent == | ||
Linia 75: | Linia 75: | ||
* kontrolera (controller), który odpowiada za wykonywanie strategii, czyli mapowanie stanów na akcje. | * kontrolera (controller), który odpowiada za wykonywanie strategii, czyli mapowanie stanów na akcje. | ||
* algorytmu uczącego (learner), który modyfikuje parametry agenta. | * algorytmu uczącego (learner), który modyfikuje parametry agenta. | ||
− | * eksploratora, który w [[ | + | * eksploratora, który w [[Uczenie_maszynowe_i_sztuczne_sieci_neuronowe/Wykład_11#Estymowanie_modelu_dla_MDP|fazie symulacji]] eksploruje stany. |
Kontrolerowi podajemy tablice wartości dla każdego stanu i możliwej akcji. W naszym przypadku rozmiar tablicy to 81(stanów) x 4(możliwe akcje). Tablicę inicjujemy wartościami 1. | Kontrolerowi podajemy tablice wartości dla każdego stanu i możliwej akcji. W naszym przypadku rozmiar tablicy to 81(stanów) x 4(możliwe akcje). Tablicę inicjujemy wartościami 1. |
Aktualna wersja na dzień 19:01, 21 maj 2015
Spis treści
Wstęp
Uczenie ze wzmocnieniem (reinforcement learning RL) odbywa się przez interakcję kilku elementów:
- Enviroment (środowisko)
- Task (zadanie)
- Agent
Enviroment dostarcza agentowi obsrewacji, a agent wykonuje akcje, które oddziaływują na środowisko; Task wraz z Enviroment dostarcza agentowi nagród.
Tutorial
Poniższy tutorial pokaże jak zrealizować uczenie ze wzmocnieniem dla zadania poruszania się w labiryncie.
Import modułów
Na początek musimy zaimportować odpowiednie moduły:
# -*- coding: utf-8 -*-
import matplotlib
matplotlib.use('TkAgg')
from scipy import *
import sys, time
import pylab as py
from pybrain.rl.environments.mazes import Maze, MDPMazeTask
from pybrain.rl.learners.valuebased import ActionValueTable
from pybrain.rl.agents import LearningAgent
from pybrain.rl.learners import Q, SARSA
from pybrain.rl.experiments import Experiment
from pybrain.rl.environments import Task
Środowisko
Enviroment to świat, w którym działa Agent. Różne środowiska są zaimplementowane w modułąch znajdujących się w
pybrain/rl/environments
W tym przykładzie posłóżymy się środowiskiem w postaci labiryntu. Opisuje się go za pomocą dwuwymiarowej tablicy, w której 1 oznacza ścianę a 0 wolną przestrzeń. Poniższa tablica definiuje przykładowy labirynt.
structure = array([[1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 0, 0, 1, 0, 0, 0, 0, 1],
[1, 0, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 0, 1, 0, 0, 1, 0, 1],
[1, 0, 0, 1, 0, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 0, 1],
[1, 0, 0, 0, 0, 0, 0, 0, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1]])
Można przerobić go na obiekt środowiska w następujący sposób:
environment = Maze(structure, (7, 7))
Drugi argument to współrzędne pola, które ma być celem agenta.
Ogólnie, Maze służy do wytwarzania dwuwymiarowych labiryntów, w których możliwe pozycje to stany MDP. Każdy ze stanów może byc potencjalnym stanem startowym (poza stanem, który jest celem). Labirynt może mieć stany absorbujące, czyli takie z których jeśli agent w nie wpadnie to zadanie się kończy (domyślnie jest to stan celu, ale na wykładzie mieliśmy też przykład z negatywnym stanem absorbującym).
Po labiryncie wędruje jeden agent. Agent może poruszać się za pomocą akcji A={N,E,S,W}. Ruch w kierunku ściany nie powoduje zmiany stanu. Każdy stan dostarcza nagrody za znalezienie się w nim. Domyślnie jest ona równa 1 dla stanu będącego celem i 0 dla wszystkich pozostałych. Zarówno obserwacje jak i akcje mogą być stochastyczne.
Enviroment dostaje wejścia poprzez metodę performAction() i zwraca wyjście przez metodę getSensors().
Agent
Agent jest obiektem, w którym zachodzi uczenie. Odziaływuje ze środowiskiem za pośrednictwem metod getAction() i integrateObservations().
Agent składa się z trzech głównych części:
- kontrolera (controller), który odpowiada za wykonywanie strategii, czyli mapowanie stanów na akcje.
- algorytmu uczącego (learner), który modyfikuje parametry agenta.
- eksploratora, który w fazie symulacji eksploruje stany.
Kontrolerowi podajemy tablice wartości dla każdego stanu i możliwej akcji. W naszym przypadku rozmiar tablicy to 81(stanów) x 4(możliwe akcje). Tablicę inicjujemy wartościami 1.
controller = ActionValueTable(81, 4)
controller.initialize(1.)
Teraz wytwarzamy instancję algorytmu uczącego:
learner = Q()
Ostatecznie wytwarzamy agenta wyposażając go w przygotowany kontroler i algorytm uczący:
agent = LearningAgent(controller, learner)
Zadanie i eksperyment
Jak na razie nie ma połączenia pomiędzy agentem a środowiskiem. Elementem pozwalającym na powiązanie agenta i środowiska jest zadanie: task. Obiekt task określa także jaki jest cel agenta i jakie nagrody dostaje.
task = MDPMazeTask(environment)
Ostatecznie zadanie i agent łączone są poprzez eksperyment:
experiment = Experiment(task, agent)
Przełączamy grafikę w tryb interaktywny, żeby móc podglądać postepy algorytmu.
py.gray()
py.ion()
Teraz można uruchomić eksperyment np. na 50 iteracji. W każdej iteracji agent będzie oddziaływał ze środowiskiem wskazaną ilość razy, tzn. agent będzie wykonywał jakieś akcje, które task przekaże do środowiska. Środowisko odpowie nowym stanem, który za pośrednictwem taska zostanie zwrócony agentowi. Po zakończeniu symulacji na podstawie zgromadzonych danych agent będzie się uczył.
for i in range(50):
experiment.doInteractions(100)
agent.learn()
agent.reset()
py.pcolor(controller.params.reshape(81,4).max(1).reshape(9,9))
py.draw()
Widoczny w powyższym kodzie reset agenta powoduje, że zapomina on kroki wykonane w poprzedniej symulacji, ale nie resetuje parametrów, które były wyuczone w poprzednich cyklach symulacji.
Dwie ostatnie linie kodu pozwalają na obserwowanie procesu uczenia się agenta. Wizualizują one maksymalne wartości w tablicy wartości, czyli funkcję wartościującą V. W czasie nauki kolory w tablicy będą się zmieniać, ale ostatecznie powinny zbiec do sytuacji, w której pola czym bliższe celowi tym będą miały wartości większe (jaśniejsze).
Po zakończeniu procesu uczenia gotowa strategia wyboru akcji polega na wykonywaniu akcji, które prowadzą do sąsiedniego pola o największej wartości V.
Najprostszym sposobem na zmianę właściwości poszczególnych elementów MDP jest wykorzystanie dziedziczenia. Np. domyślna funkcja nagrody daje +1 w stanie docelowym i 0 w pozostałych. Aby to zmienić możemy wykonać następującą podmianę:
class MyTask(MDPMazeTask):
def getReward(self):
""" compute and return the current reward (i.e. corresponding to the last action performed) """
if self.env.goal == self.env.perseus:
self.env.reset()
reward = 1.
else:
reward = -0.02
return reward
#def performAction(self, action):
# """ The action vector is stripped and the only element is cast to integer and given
# to the super class.
# """
# print action
# Task.performAction(self, int(action[0]))
....
task = MyTask(environment)# MDPMazeTask(environment)
Proszę zaimplementować zadanie labiryntu z ostatniego wykładu i zbadać jak funkcja nagrody wpływa na strategię.