乐趣区

关于深度学习:开启深度强化学习之路Deep-QNetworks简介和代码示例

强化学习是机器学习畛域的热门子项。因为 OpenAI 和 AlphaGo 等公司的最新冲破,强化学习引起了游戏行业许多人的留神。咱们明天以 Hill Climb Racing 这款经典的游戏来介绍 DQN 的整个概念,Hill Climb Racing 须要玩家在不同的地形上驾驶不同的车辆,驾驶间隔越长得分越高。

在本篇文章中将通过这个游戏的示例来介绍 Deep Q-Networks 的整个概念,然而因为没有环境所以咱们会将其分解成 2 个独立指标别离实现。如果已经接触过此类游戏,你可能曾经察看到游戏的两个次要指标:1、不要碰撞,2、放弃后退。

咱们将这两个指标分解成咱们的须要的做动作:1、保持平衡,2、爬坡,当然还有一些附加项,例如吃分获取处分,然而这个并不是咱们的次要指标。

在咱们深刻解决这些问题之前,首先介绍一下解强化学习和 DQN 的基础知识。

咱们先疾速介绍一下什么是强化学习,在这种学习中行为主体对环境所做的口头会依据其后果失去处分。处分会影响主体(代理、智能体)将来的行为。

  • 无利的口头,更多的处分(踊跃的)。
  • 不利的口头,较少的处分或者惩办(在某些状况下是负面的)。

Deep Q-Learning 算法是深度强化学习的外围概念之一。神经网络将输出状态映射到(动作,Q 值)对。

  • 动作 Action:代理执行的对环境进行后续更改的流动。
  • 环境 Environment:模型工作的整个状态空间。
  • 处分 Rewards:为模型提供的每个动作的反馈。
  • Q 值 Q -value:预计的最优将来值。

Q-Learning 和 Deep Q-Networks 是无模型算法,因为它们不创立环境转换函数的模型。

因为 DQN 是一种无模型算法,咱们将构建一个与问题中提到的环境兼容的代理。

class Agent:
    def __init__(self, state_size, action_size):
        self.state_size = state_size
        self.action_size = action_size
        self.memory = deque(maxlen=2000)
        self.gamma = 0.95
        self.epsilon = 1.0
        self.epsilon_decay = 0.995
        self.epsilon_min = 0.01
        self.learning_rate = 0.001
        self.model = self._create_model()

    def _create_model(self):
        model = Sequential()
        model.add(Dense(24, input_dim=self.state_size, activation='relu'))
        model.add(Dense(24, activation='relu'))
        model.add(Dense(self.action_size, activation='linear'))
        model.compile(loss='mse', optimizer=Adam(lr=self.learning_rate))
        return model
    
    def remember(self, state, action, reward, next_state, done):
        self.memory.append((state, action, reward, next_state, done))

    def act(self, state):
        if np.random.rand() <= self.epsilon:
            return random.randrange(self.action_size)
        act_values = self.model.predict(state)
        return np.argmax(act_values[0])

    def train(self, batch_size= 32):
        minibatch = random.sample(self.memory, batch_size)
        for state, action, reward, next_state, done in minibatch:
            if not done:
                target = reward + self.gamma*np.amax(self.model.predict(next_state)[0])
            else:
                target = reward
            target_f = self.model.predict(state)
            target_f[0][action] = target
            self.model.fit(state, target_f, epochs=1, verbose=0)
        if self.epsilon > self.epsilon_min:
            self.epsilon *= self.epsilon_decay
    
    def load(self, name):
        self.model.load_weights(name)
    def save(self, name):
        self.model.save_weights(name)

在这里咱们应用了一个小型网络(带有两个暗藏层)。输出大小是指状态的数量,输入大小对应于动作空间的数量。

Cartpole 均衡

CartPole 或通常称为反摆 / 倒立摆,它是一种简略的训练环境,指标是向左或向右挪动推车以均衡直立杆。在这篇文章中,咱们将应用 OpenAI 的 gym 库提供的模仿环境。

在这个环境中,咱们有离散的动作空间和间断的状态空间,如下所示:

动作空间(离散)

  • 1 单位力向左。
  • 1 单位力向右。

状态空间(间断)

  • 小车地位。
  • 小车速度。
  • 车杆角度
  • 极点速度(pole velocity)。

咱们的代理必须尽可能长时间地均衡极点以获取最大化处分。对于每个胜利的工夫步,模型都会取得 +1 处分。咱们设定进行的规定:如果车杆远离核心 2.4 个单位或垂直偏离超过 15 度,则本次迭代完结。通过模仿 1000 次更新并在每 50 次迭代后保留最佳权重进行代理的训练。

agent = Agent(state_size, action_size) # initialise agent
done = False
for e in range(n_episodes):
    state = env.reset()
    state = np.reshape(state,[1,state_size])
    
    for time in range(5000):
        env.render()
        action = agent.act(state) #action is 0 or 1
        next_state,reward,done,other_info = env.step(action) 
        reward = reward if not done else -10
        next_state = np.reshape(next_state,[1,state_size])
        agent.remember(state,action,reward,next_state,done)
        state = next_state
        
        if done:
            print("Game Episode :{}/{}, High Score:{},Exploration Rate:{:.2}".format(e,n_episodes,time,agent.epsilon))
            break
            
    if len(agent.memory)>batch_size:
        agent.train(batch_size)
    
    if e%50==0:
        agent.save(output_dir+"weights_"+'{:04d}'.format(e)+".hdf5")
        
env.close()

代理在前 250 次迭代内解决了问题,在第 199 次迭代中获得了稳固高分。咱们曾经解决了均衡问题。当初须要学习学习如何后退并爬上山坡的时候了。

爬坡

一辆能源有余的车如果想要登上平缓的山顶,应该应用对面的另一座山,来回行驶以建设所需的能源。

与 CartPole 类似,该环境也包含离散的动作空间和间断的状态空间。

动作空间(离散)

  • 在汽车的左方向施加 1 个单位的力。
  • 什么都不做。
  • 在汽车的右方向施加 1 个单位的力。

状态空间(间断)

  • 汽车地位
  • 汽车速度

个别状况下汽车在达到目标(由旗号标记)时会取得 +100 的处分。如果在汽车达到胜利状态之前,不给予处分积分,汽车随机达到指标的可能性很小。

所以咱们将用另一个处分条件来激励汽车。山谷最底部的坐标为 -0.4(OpenAI 提供的规范),而指标的坐标为 +0.5,咱们将应用汽车垂直高度按比例进行处分。高度越高,处分越多。(注:在山谷的两侧高度都进行处分)

让咱们看一下咱们将在环境中应用的处分机制和训练函数。

def get_reward(state):

    if state[0] >= 0.5:
        print("Car has reached the goal")
        return 10
    if state[0] > -0.4:
        return (1+state[0])**2
    return 0
  
  #--------------------------------------------------------------------------#
  
  def train_dqn(episode):

    loss = []
    agent = DQN(env.action_space.n, env.observation_space.shape[0])
    for e in range(episode):
        state = env.reset()
        state = np.reshape(state, (1, 2))
        score = 0
        max_steps = 3000
        for i in range(max_steps):
            action = agent.act(state)
            env.render()
            next_state, reward, done, _ = env.step(action)
            reward = get_reward(next_state)
            score += reward
            next_state = np.reshape(next_state, (1, 2))
            agent.remember(state, action, reward, next_state, done)
            state = next_state
            agent.replay()
            if done:
                print("episode: {}/{}, score: {}".format(e, episode, score))
                break
        loss.append(score)
    return loss

在咱们的环境中,汽车可能屡次达到目标!汽车在训练的过程中第 60、71、74 和 79 次迭代达到了胜利状态。

咱们还能够应用得分图上的峰值来验证它。

咱们曾经解决了下面提到的两个问题。尽管将其集成到理论游戏中目前看还是不可能的(因为 Hill Climb Racing 并没有为咱们提供环境),然而如果你有什么好的计划能够尝试一下。

总结

经典的管制问题奠定了当今大多数顶级游戏的强化学习的根底。而 OpenAI 的 GYM 库也为咱们提供了更多环境。如果你对其余的环境感兴趣,能够参考 GYM 的文档,或者看看本文提供的两个例子的源代码。

https://github.com/DSCVITBHOP…

https://github.com/DSCVITBHOP…

作者:Sidhved Warik

退出移动版