无法使用具有函数逼近的Q-Learning来学习MountainCar

问题描述 投票:2回答:1

我正在尝试使用q-learning来实现求解MountainCar的线性函数逼近。我知道由于最优政策的螺旋状形状,这个环境不能用线性函数完全近似,但我得到的行为很奇怪。

Returns

我不明白为什么奖励会上升,直到它达到收敛状态然后开始下降

请找我附上的代码。如果有人能给我任何关于我做坏事的想法,我会很高兴的。

初始化

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()
python reinforcement-learning q-learning
1个回答
2
投票

让我知道如果我错了,但似乎你试图使用线性函数逼近器直接使用状态变量,即汽车位置和速度。在这种情况下,不仅不能完全逼近值函数,而且不可能逼近接近最优值函数的某些东西。因此,尽管你的数字似乎暗示了一些收敛,但我很确定情况并非如此。

二维玩具环境(如MountainCar)的一个非常好的功能是您可以绘制近似的Q值函数。在Sutton&Barto的书(chapter 8, Figure 8.10)中,您可以通过学习过程找到“成本计算”功能(很容易从Q值中获得)。如您所见,该功能与汽车位置和速度高度非线性。我的建议是绘制相同的成本函数,并验证它们与书中显示的相似。

使用具有Q学习的线性函数逼近器通常需要(除非在非常特定的情况下)计算一组特征,因此您的近似值相对于提取的特征是线性的,而不是原始特征。通过这种方式,您可以近似非线性函数(当然,相对于原始状态变量)。这个概念的扩展解释可以在Sutton&Barto的书中找到,section 8.3

© www.soinside.com 2019 - 2024. All rights reserved.