Vor kurzem bin ich süchtig danach, das Lernen zu stärken. Immerhin ist es ein Mann, der beim Lernen der Verstärkung einen Stock aushalten will. Daher werde ich nach dem letzten Mal den CartPole </ font> von OpenAI Gym vorstellen.
Vorheriger Artikel Ich möchte mit verbessertem Lernen einen Berg besteigen
Was das im vorherigen Artikel erwähnte Q-Lernen betrifft, möchte ich diesmal eine Methode namens SARSA verwenden. Lassen Sie uns überprüfen. Aktualisierung des Zustandsverhaltenswerts Q beim Bestärkungslernen,
Wird für jeden Zustandsübergang durchgeführt. Der Unterschied zwischen SARSA- und Q-Lernen besteht darin, wie dieses $ G_ {t} $ bestimmt wird.
Für ** Q-Lernen ** </ font>
Für ** SARSA ** </ font>
Hier gibt $ a_ {t + 1} ^ {\ pi} $ die Aktion an, wenn die nächste Aktion gemäß der Richtlinie im Status $ s_ {t + 1} $ ausgewählt wird. Was wir aus dem Obigen sehen können, ist, dass Q-Lernen max verwendet, um den Wert zu aktualisieren, das heißt, es ist eine ** optimistische ** Lernmethode, die unter Verwendung des maximalen Zustandswerts aktualisiert wird, der erhalten werden kann. Im Gegensatz dazu berücksichtigt SARSA die folgenden Aktionen, wodurch es eine ** realistischere ** Methode zur Bestimmung von Strategien darstellt. Dieses Mal werden wir auch diese vergleichen.
Wenn Sie diesen Stick lange stehen lassen (200 Schritte), wird er gelöscht. Es sind vier Zustände angegeben: ** die Position des Wagens, die Geschwindigkeit des Wagens, der Winkel der Stange und die Winkelgeschwindigkeit der Stange **. Die Aktionen beschränken sich darauf, den Wagen nach links zu schieben: 0 und nach rechts zu schieben: 1. Der Winkel der Stange ist um 12 Grad oder mehr geneigt, oder die Ausdauer beträgt 200 Schritte.
Importieren Sie zunächst die Bibliothek.
import gym
from gym import logger as gymlogger
gymlogger.set_level(40) #error only
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
%matplotlib inline
import math
import glob
import io
import base64
Definiert eine Klasse SARSA, die das Lernen implementiert.
class SARSA:
def __init__(self, env):
self.env = env
self.env_low = self.env.observation_space.low #Mindestzustand
self.env_high = self.env.observation_space.high #Maximalwert angeben
tmp = [7,7,7,7] #Teilen Sie den Staat in 7 Staaten
self.env_dx = [0,0,0,0]
self.env_dx[0] = (self.env_high[0] - self.env_low[0]) / tmp[0]
self.env_dx[1] = (self.env_high[1] - self.env_low[1]) / tmp[1]
self.env_dx[2] = (self.env_high[2] - self.env_low[2]) / tmp[2]
self.env_dx[3] = (self.env_high[3] - self.env_low[3]) / tmp[3]
self.q_table = np.zeros((tmp[0],tmp[1],tmp[2],tmp[3],2)) #Initialisierung der Zustandswertfunktion
def get_status(self, _observation): #Diskriminierungszustand
s1 = int((_observation[0] - self.env_low[0])/self.env_dx[0]) #Lassen Sie sich in einen der sieben Staaten fallen
if _observation[1] < -1.5: #Klassifizieren Sie selbst
s2 = 0
elif -1.5 <= _observation[1] < - 1:
s2 = 1
elif -1 <= _observation[1] < -0.5:
s2 = 2
elif -0.5 <= _observation[1] < 0.5:
s2 = 3
elif 0.5 <= _observation[1] < 1.5:
s2 = 4
elif 1.5 <= _observation[1] < 2:
s2 = 5
elif 2 <= _observation[1]:
s2 = 6
s3 = int((_observation[2] - self.env_low[2])/self.env_dx[2]) #Lassen Sie sich in einen der sieben Staaten fallen
if _observation[3] < -1: #Klassifizieren Sie selbst
s4 = 0
elif -1 <= _observation[3] < -0.7:
s4 = 1
elif -0.7 <= _observation[3] < -0.6:
s4 = 2
elif -0.6 <= _observation[3] < -0.5:
s4 = 3
elif -0.5 <= _observation[3] < -0.4:
s4 = 4
elif -0.4 <= _observation[3] < -0.4:
s4 = 5
else:
s4 = 6
return s1, s2, s3, s4
def policy(self, s, epi): #Wählen Sie eine Aktion im Status s aus
epsilon = 0.5 * (1 / (epi + 1))
if np.random.random() <= epsilon:
return np.random.randint(2) #Wählen Sie nach dem Zufallsprinzip
else:
s1, s2, s3, s4 = self.get_status(s)
return np.argmax(self.q_table[s1][s2][s3][s4]) #Wählen Sie die Aktion mit dem höchsten Aktionswert aus
def learn(self, time = 200, alpha = 0.5, gamma = 0.99): #Lerne so oft wie möglich
log = [] #Notieren Sie die Gesamtbelohnung für jede Episode
t_log = [] #Notieren Sie die Anzahl der Schritte pro Episode
for j in range(time+1):
t = 0 #Anzahl der Schritte
total = 0 #Gesamtbelohnung
s = self.env.reset()
done = False
while not done:
t += 1
a = self.policy(s, j)
next_s, reward, done, _ = self.env.step(a)
reward = t/10 #Je länger Sie aushalten, desto mehr Belohnungen erhalten Sie
if done:
if t < 195:
reward -= 1000 #Strafen für Nichterhaltung
else:
reward = 1000 #Geben Sie mehr Belohnungen für den Erfolg
total += reward
s1, s2, s3, s4 = self.get_status(next_s)
G = reward + gamma * self.q_table[s1][s2][s3][s4][self.policy(next_s, j)] #Berechnung der kumulierten Belohnung
s1, s2, s3, s4 = self.get_status(s)
self.q_table[s1][s2][s3][s4][a] += alpha*(G - self.q_table[s1][s2][s3][s4][a]) #Q Update
s = next_s
t_log.append(t)
log.append(total)
if j %1000 == 0:
print(str(j) + " ===total reward=== : " + str(total))
return plt.plot(t_log)
def show(self): #Lernergebnisse anzeigen
s = self.env.reset()
img = self.env.render()
done = False
t = 0
while not done:
t += 1
a = self.policy(s, 10000)
s, _, done, _ = self.env.step(a)
self.env.render()
print(t)
self.env.reset()
self.env.close()
Hier bin ich gestolpert. Bei init bereite ich mich darauf vor, jeden der vier Zustände mit env_dx zu zerstreuen, aber ich habe hier ein Problem. Wenn Sie sich die Referenz genau ansehen, Der variable Bereich des Geschwindigkeitswertes ist ** inf **. Ja, ** es ist unendlich! **
In diesem Fall wird auch der Wert von env_dx unendlich und die Streuung kontinuierlicher Werte funktioniert nicht. Deshalb,
from random import random
env.step(random.randint(2))
Wir haben viele Male gearbeitet und Schwankungen in der Geschwindigkeit des Wagens und dann in der Winkelgeschwindigkeit der Stange beobachtet. Dann,
if _observation[1] < -1.5: #Die Geschwindigkeit des Wagens
s2 = 0
elif -1.5 <= _observation[1] < - 1:
s2 = 1
elif -1 <= _observation[1] < -0.5:
s2 = 2
elif -0.5 <= _observation[1] < 0.5:
s2 = 3
elif 0.5 <= _observation[1] < 1.5:
s2 = 4
elif 1.5 <= _observation[1] < 2:
s2 = 5
elif 2 <= _observation[1]:
s2 = 6
if _observation[3] < -1: #Polwinkelgeschwindigkeit
s4 = 0
elif -1 <= _observation[3] < -0.7:
s4 = 1
elif -0.7 <= _observation[3] < -0.6:
s4 = 2
elif -0.6 <= _observation[3] < -0.5:
s4 = 3
elif -0.5 <= _observation[3] < -0.4:
s4 = 4
elif -0.4 <= _observation[3] < -0.4:
s4 = 5
else:
s4 = 6
Mir wurde klar, dass ich es so klassifizieren konnte.
Lerne so. Es ist ungefähr 3000 Mal und ich kann es mir leisten.
env = gym.make('CartPole-v0')
agent = SARSA(env)
agent.learn(time = 3000)
Die Änderung der Anzahl der Schritte ist wie folgt.
Lassen Sie uns nun die Animation mit `agent.show ()`
überprüfen.
Es ist ziemlich stabil und hat eine große Nachhaltigkeit. Ich bin froh, ein ** Mann ** zu sein.
Vergleichen wir Q-Learning und SARSA in dieser Umgebung. G im Q-Lernen
G = reward + gamma * max(self.q_table[s1][s2][s3][s4])
Machen. Wenn ich versuche, damit zu lernen, Die Stabilität der Konvergenz scheint bei SARSA besser zu sein. Wenn Sie ein Mann sind, betrachten Sie die Realität wie SARSA. Ja.
In diesem Umfeld habe ich mich gefragt, ob die Streuung von Staaten der schwierigste Teil ist. Es scheint, dass DQN geboren wurde, um dieses Problem zu lösen. Nächstes Mal werde ich versuchen, einen DQN zu erstellen. wir sehen uns!
Recommended Posts