Я пытаюсь реализовать приближение линейной функции для решения MountainCar с использованием q-learning. Я знаю, что эта среда не может быть полностью аппроксимирована линейной функцией из-за спиральной формы оптимальной политики, но поведение, которое я получаю, довольно странно.
Я не понимаю, почему награда увеличивается, пока не достигнет того, что кажется сходимостью, а затем начнет снижаться
Пожалуйста, найдите мой код в приложении. Я был бы очень рад, если бы кто-нибудь дал мне представление о том, что я делаю плохо.
1012 * инициализация *
import gym
import random
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
class Agent:
def __init__(self, gamma: float, epsilon: float, alpha:float, n_actions: int, n_steps:int=1):
self.n_steps=n_steps
self.gamma=gamma
self.epsilon=epsilon
self.alpha=alpha
self.n_actions=n_actions
self.state_action_values={}
self.state_values={}
self.w=None
def get_next_action(self, state):
raise NotImplementedError
def update(self, state, action: int, reward, state_prime):
raise NotImplementedError
def reset(self):
# Optional argument
pass
Q-Learning Agent
class FunctionApproximationQLearning(Agent):
def __init__(self, gamma, epsilon, alpha, n_actions, n_features):
super().__init__(gamma, epsilon, alpha, n_actions)
self.w = np.zeros((n_features, n_actions))
def get_next_action(self, x):
if random.random()>self.epsilon:
return np.argmax(self._lr_predict(x))
else:
return np.random.choice(range(self.n_actions))
def update(self, state, action, reward, state_prime, done):
if not done:
td_target = reward + self.gamma*np.max(self._lr_predict(state_prime))
else:
td_target = reward
# Target definition
target = self._lr_predict(state)
target[action] = td_target
# Function approximation
self._lr_fit(state, target)
def _lr_predict(self, x):
# x should be (1, n_features)
#x = np.concatenate([x, [1]])
return x @ self.w
def _lr_fit(self, x, target):
pred = self._lr_predict(x)
#x = np.concatenate([x, [1]])
if len(x.shape)==1:
x = np.expand_dims(x, 0)
if len(target.shape)==1:
target = np.expand_dims(target,1)
self.w += self.alpha*((np.array(target)-np.expand_dims(pred, 1))@x ).transpose()
Исполнение
env = gym.make("MountainCar-v0").env
state = env.reset()
agent = FunctionApproximationQLearning(gamma=0.99, alpha=0.001, epsilon=0.1,
n_actions=env.action_space.n,
n_features=env.observation_space.shape[0])
rewards=[]
pos=[]
for episode in range(1000000):
done = False
cumreward=0
poss=[]
state = env.reset()
action = agent.get_next_action(state)
c=0
while not done and c<500:
action = agent.get_next_action(state)
next_state, reward, done, _ = env.step(action)
agent.update(state, action, reward, next_state, done)
state = next_state
cumreward+=reward
c+=1
poss=state[0]
rewards.append(cumreward)
if np.mean(rewards[-100:])>950:
break
pos.append(np.max(poss))
if episode % 100 == 0:
clear_output(True)
plt.plot(pd.Series(rewards).ewm(span=1000).mean())
plt.title("Returns evolution")
plt.xlabel("Episodes")
plt.ylabel("Return")
plt.show()