一、Q-learning
关于Q-learning,网上的资料很多。

Q-learning最核心的是有一个Q表,它记录了在环境中的 所有状态(s) 以及每个状态可以进行的 所有行为(a) 的Q值,初值设为0。
| 状态 \ 行为 | a1 | a2 | a3 | a4 |
|---|---|---|---|---|
| s1 | ||||
| s2 | ||||
| s3 | ||||
| …… |
Q值的更新公式如下:
Q ( s , a ) ← Q ( s , a ) + α [ r + γ m a x a ′ Q ( s ′ , a ′ ) − Q ( s , a ) ] Q(s,a)←Q(s,a)+α[r+\gamma max_{a'}Q(s^′,a^′)−Q(s,a)] Q(s,a)←Q(s,a)+α[r+γmaxa′Q(s′,a′)−Q(s,a)]
- 其中 α α α表示学习速率,取值小于1
- r r r是设置的奖励
- 智能体在状态s经过行为a转移到状态s’, m a x a ′ Q ( s ′ , a ′ ) max_{a'}Q(s^′,a^′) maxa′Q(s′,a′) 是状态 s ′ s' s′ 那一行最大Q值
- γ \gamma γ则是衰减速率,取值在0到1之间, γ \gamma γ越大,智能体就会越注重长期利益, γ \gamma γ越小,智能体越短视。
每改变一次状态就会更新一次Q值
Q-learning 是一个 off-policy 的算法,它可以离线学习。它可以随机进行若干次游戏,将游戏过程保存起来,学习的时候就可以避免陷入局部最优。
Q-learning 的代码实现:
# -*- coding: UTF-8 -*-
import numpy as np
import pandas as pd
class QLearningTable:
def __init__(self, actions, learning_rate=0.01, reward_decay=0.9, e_greedy=0.9):
self.actions = actions # a list
self.lr = learning_rate
self.gamma = reward_decay
self.epsilon = e_greedy
self.q_table = pd.DataFrame(columns=self.actions, dtype=np.float64)
def choose_action(self, observation):
self.check_state_exist(observation)
# action selection
if np.random.uniform() < self.epsilon:
# choose best action
state_action = self.q_table.loc[observation, :]
state_action = state_action.reindex(np.random.permutation(state_action.index)) # some actions have same value
action = state_action.idxmax()
else:
# choose random action
action = np.random.choice(self.actions)
return action
def learn(self, s, a, r, s_):
self.check_state_exist(s_)
q_predict = self.q_table.loc[s, a]
if s_ != 'terminal':
q_target = r + self.gamma * self.q_table.loc[s_, :].max() # next state is not terminal
else:
q_target = r # next state is terminal
self.q_table.loc[s, a] += self.lr * (q_target - q_predict) # update
def check_state_exist(self, state):
if state not in self.q_table.index:
# append new state to q table
self.q_table = self.q_table.append(
pd.Series(
[0]*len(self.actions),
index=self.q_table.columns,
name=state,
)
)
二、Deep Q Network
如果想用Q-learning玩之前的CartPole-v0游戏,会发现CartPole-v0的状态值太多了,它的observation有 车的位置,车的速度,杆子的角度,杆子顶端的速度 四个值,并且是连续的数值,四个值再进行量化,Q表实在是太大了。用Q-learning玩游戏和随机玩游戏没区别,学习不到东西。可能Q-learning只适用于走迷宫类的游戏,每一步的状态都可以很简单的描述出来,4*4的迷宫只需要用16个状态就可以全部囊括。
我们用Deep Q Network来解决这个问题, Deep Q Network融合了神经网络和 Q learning。
- 我们可以将状态和动作当成神经网络的输入, 然后经过神经网络分析后得到动作的 Q 值, 这样我们就没必要在表格中记录 Q 值, 而是直接使用神经网络生成 Q 值.
- 或者只输入状态值, 输出所有的动作值, 然后按照 Q learning 的原则, 直接选择拥有最大值的动作当做下一步要做的动作.

需要搭建两个神经网络,target_net 和 eval_net ,
target_net 用于预测 q_target 值, 他不会及时更新参数.
target_net 用于预测 q_eval, 这个神经网络拥有最新的神经网络参数.
两个神经网络结构是完全一样的, 只是里面的参数不一样. target_net 是 eval_net 的一个历史版本, 拥有 eval_net 很久之前的一组参数, 而且这组参数被固定一段时间, 然后再被 eval_net 的新参数所替换. 而 eval_net 是不断在被提升的。这样做是为了打乱数据间的相关性,避免陷入局部最优。
神经网络的输入数据是[s,a,r,s’],输出数据是状态s下所有行为a的Q值。
target_net 只会输出Q值(q_target ),不会进行训练,而eval_net 输出Q值(q_eval)之后会根据q_target和q_eval进行反向传播训练,更新eval_net 的参数。
Deep Q Network整个算法的运作:
- 初始化target_net 和 target_net。
- 观察游戏状态observation,选择合适的observation作为输入,一般情况会对observation做数据处理,使其更容易训练,这里不用。
- 设置合适的奖励reward。
- 先进行若干次游戏,将游戏数据存储到memory中。
- 从memory中随机选取训练数据batch_memory用于批量训练。
- 训练eval_net 一段时间后,将eval_net 的参数复制给target_net 。
- 训练过程中产生的新的游戏数据会替代memory中的旧数据。
回到游戏CartPole-v0
DQN.py:
import numpy as np
import tensorflow as tf
np.random.seed(1)
tf.set_random_seed(1)
# Deep Q Network off-policy
class DeepQNetwork:
def __init__(
self,
n_actions,
n_features,
learning_rate=0.01,
reward_decay=0.9,
e_greedy=0.9

本文深入探讨了强化学习的核心算法,从Q-learning的基础概念出发,逐步过渡到深度强化学习的DeepQNetwork(DQN)及其改进版DoubleDQN。详细解析了算法原理,包括Q-table的构建、Q值更新公式、神经网络的应用以及如何避免过估计等问题。
最低0.47元/天 解锁文章
596

被折叠的 条评论
为什么被折叠?



