DQN——深度强化学习的理解以及keras实现
起源
Q-learing与SARSA算法
Q-learing是一种经典的时序差分离线控制算法,与之相对的SARSA算法是时序差分在线控制算法的代表。
所谓的在线,是一直使用一个策略来更新价值函数和选择新的动作。而离线是使用两个控制策略,一个策略用于选择新的动作,另一个策略用于更新价值函数。
SARSA算法流程为:
- 起初,我们使用ϵ−\epsilon-ϵ−贪婪法在当前状态S选择一个动作A,这样系统会转到一个新的状态S′S^\primeS′, 同时给我们一个即时奖励RRR, 在新的状态S′S^\primeS′,
- 然后,我们使用ϵ−\epsilon-ϵ−贪婪法在状态S′S^\primeS′选择一个动作A′A^\primeA′,但是注意这时候我们并不执行这个动作A′,只是用来更新的我们的价值函数:
Q(S,A)=Q(S,A)+α(R+γQ(S′,A′)−Q(S,A)) Q(S,A)=Q(S,A)+\alpha(R+\gamma Q(S^\prime,A^\prime)-Q(S,A)) Q(S,A)=Q(S,A)+α(R+γQ(S′,A′)−Q(S,A)) - S=S′S=S^\primeS=S′,A=A′A=A^\primeA=A′
注释:
- Q(S,A)Q(S,A)Q(S,A)更新时使用的A′A^\primeA′将会作为下一阶段开始时候的执行动作AAA。
- 选择的动作A′A^\primeA′只会参与价值函数的更新,不会真正的执行。
Q-learing算法流程为:
- 起初,我们使用ϵ−\epsilon-ϵ−贪婪法在当前状态S选择一个动作A,这样系统会转到一个新的状态S′S^\primeS′, 同时给我们一个即时奖励RRR, 在新的状态S′S^\primeS′,
- 然后,我们使用贪婪法在状态S′S^\primeS′选择一个动作A′A^\primeA′,但是注意这时候我们并不执行这个动作A′,只是用来更新的我们的价值函数:
Q(S,A)=Q(S,A)+α(R+γmaxaQ(S′,A′)−Q(S,A)) Q(S,A)=Q(S,A)+\alpha(R+\gamma \mathop{max}\limits_{a}Q(S^\prime,A^\prime)-Q(S,A)) Q(S,A)=Q(S,A)+α(R+γamaxQ(S′,A′)−Q(S,A)) - S=S′S=S^\primeS=S′
注释:
1.选择的动作A′A^\primeA′只会参与价值函数的更新,不会真正的执行。
2. Q(S,A)Q(S,A)Q(S,A)更新后,下一轮迭代新的执行动作AAA需要基于状态S′,用ϵ−贪婪法重新选择得到。
DQN算法解读
与Q-learning相比,DQN的Q(S,A)Q(S,A)Q(S,A)不是直接通过状态值SSS和动作AAA来计算,而是通过一个神经网络QQQ网络来计算。
如果想用神经网络取而代之,就需要一个技巧取代先前用来存放QQQ值表格,这里用到了经验回放(experience replay)。其作用是将每次和环境交互得到的奖励RRR与状态SSS得更新情况都保存起来,用于后面目标QQQ值的更新。
DQN算法流程为:
- 基于状态SSS,可得到对应得特征向量h(S)h(S)h(S)。
- 将h(S)h(S)h(S)作为神经网络的输入。神经网络输出得到所有动作对应的QQQ值输出。用ϵ−\epsilon-ϵ−贪婪法在当前QQQ值输出中选择对应的动作AAA。
- 在状态SSS执行当前动作AAA,得到新状态S′S^\primeS′对应的特征向量h(S′)h(S^\prime)h(S′)和奖励RRR。
- 将[h(S),A,R,h(S′),done][h(S),A,R,h(S^\prime),done][h(S),A,R,h(S′),done]这个5元组存入经验回放集合DDD。
- S=S′S=S\primeS=S′
- 从经验回放集合DDD中采样mmm个样本[h(Sj),Aj,Rj,h(Sj′),done][h(S_j),A_j,R_j,h(S_j^\prime),done][h(Sj),Aj,Rj,h(Sj′),done],j=1,2.,,,mj=1,2.,,,mj=1,2.,,,m,计算当前目标QQQ值:
yj=Rj+Q(h(Sj′),Aj′,w) y_j=R_j+Q(h(S_j^\prime),A^\prime_j,w) yj=Rj+Q(h(Sj′),Aj′,w) - 使用mse损失函数更新网络参数:
Loss=1m(yj−Q(h(Sj),Aj,w)) Loss=\frac{1}{m}(y_j-Q(h(S_j),A_j,w)) Loss=m1(yj−Q(h(Sj),Aj,w))
注:使用神经网络计算Q(h(Sj),Aj,w)Q(h(S_j),A_j,w)Q(h(Sj),Aj,w)和Q(h(Sj′),Aj′,w)Q(h(S_j^\prime),A^\prime_j,w)Q(h(Sj′),Aj′,w)的值。
此外,平时阅读各类文献出现的名词:目标QQQ值(target Q−Q-Q−value)为Rt+1+Q(St+1,At+1)R_{t+1}+Q(S_{t+1},A_{t+1})Rt+1+Q(St+1,At+1)。再根据贝尔曼方程(Bellman Equation)可知:
Vπ(S)=E(Rt+1+γRt+2+γ2Rt+3+...∣St=s)=uA⋅nB=E(Rt+1+γ(Rt+2+γRt+3+...)∣St=s)=E(Rt+1+γGt+1∣St=s)=E(Rt+1+Q(St+1,At+1)∣St=s)
\begin{aligned}
V_\pi(S)
& = E(R_{t+1}+\gamma R_{t+2}+\gamma ^2R_{t+3}+...|S_t=s)
& =uA\cdot nB \\
& =E(R_{t+1}+\gamma (R_{t+2}+\gamma R_{t+3}+...)|S_t=s)\\
& = E(R_{t+1}+\gamma G_{t+1}|S_t=s) \\
& = E(R_{t+1}+Q(S_{t+1},A_{t+1})|S_t=s)
\end{aligned}
Vπ(S)=E(Rt+1+γRt+2+γ2Rt+3+...∣St=s)=E(Rt+1+γ(Rt+2+γRt+3+...)∣St=s)=E(Rt+1+γGt+1∣St=s)=E(Rt+1+Q(St+1,At+1)∣St=s)=uA⋅nB
将VVV换成QQQ的话,我们可以发现(target Q−Q-Q−value)是Q(St,At)Q(S_{t},A_{t})Q(St,At)的估计值,这也就解释了神经网络损失函数LossLossLoss为什么是那样。
keras实现DQN
这里使用Gym进行模拟。
Gym 是 OpenAI 发布的用于开发和比较强化学习算法的工具包。使用它我们可以让 AI 智能体做很多事情,比如行走、跑动,以及进行多种游戏。在这个Demo中,我们使用的是车杆游戏(Cart-Pole)这个小游戏。
游戏规则:游戏里面有一个小车,上有竖着一根杆子。小车需要左右移动来保持杆子竖直。如果杆子倾斜的角度大于15°,那么游戏结束。小车也不能移动出一个范围(中间到两边各2.4个单位长度)。
环境
- Python 3.6
- Tensorflow-gpu 1.1.0
- Keras 2.1.1
- Gym 0.10.8
from DRL import DRL from collections import deque import os import random from keras.layers import Dense,Input from keras import Model from keras.optimizers import Adam import numpy as np class DQN(DRL): def __init__(self): super(DQN, self).__init__() self.model = self.build_model() self.memory_buffer = deque(maxlen=200) self.gamma = 0.95 self.epsilon = 1.0 self.epsilon_decay = 0.995 self.epsilon_min = 0.01 def load(self): if os.path.exists("model/dqn.h5"): self.model.load_weights("model/dqn.h5") def build_model(self): inputs = Input(shape=(4,)) x = Dense(16, activation='relu')(inputs) x = Dense(16, activation= 'relu')(x) x = Dense(2, activation='linear')(x) model = Model(inputs=inputs, outputs=x) model.compile(loss='mse', optimizer=Adam(1e-3)) return model def egreedy_action(self, state): if np.random.rand() >= self.epsilon: return random.randint(0,1) else: q_values = self.model.predict(state) return np.argmax(q_values) def remember(self, state, action, reward, next_state, done): item = (state, action, reward, next_state, done) self.memory_buffer.append(item) def update_epsilon(self): if self.epsilon >= self.epsilon_min: self.epsilon *= self.epsilon_decay def process_batch(self,batch): data = random.sample(self.memory_buffer, batch) # 这里取元组的第1个值,即当前state states = np.array([d[0] for d in data]) # 这里取元组的第4个值,即下一个state next_states = np.array([d[3] for d in data]) y = self.model.predict(states) q = self.model.predict(next_states) print("y value {}, and q value {}".format(y, q)) for i, (_, action, reward, _, done) in enumerate(data): target = reward if not done: target += self.gamma * np.amax(q[i]) y[i][action] = target return states, y def train(self, episode, batch): history = {'episode': [], 'Episode_reward': [], 'Loss': []} count = 0 for i in range(episode): observation = self.env.reset() reward_sum = 0 loss = np.infty done = False while not done: # 一个参数为-1时,reshape函数会根据另一个参数的维度计算出数组的另外一个shape属性值 x = observation.reshape(-1, 4) action = self.egreedy_action(x) observation, reward, done, _ = self.env.step(action) reward_sum += reward self.remember(x[0], action, reward, observation, done) if len(self.memory_buffer) > batch: X, y = self.process_batch(batch) loss = self.model.train_on_batch(X, y) count += 1 self.update_epsilon() if i % 5 == 0: history['episode'].append(i) history['Episode_reward'].append(reward_sum) history['Loss'].append(loss) print('Episode: {} | Episode reward: {} | loss: {:.3f} | e:{:.2f}'.format(i, reward_sum, loss, self.epsilon)) self.model.save_weights('model/dqn.h5') return history if __name__ == '__main__': model = DQN() history = model.train(600, 32) model.save_history(history, 'dqn.csv') model.load() model.play()
- 深度强化学习(DQN)实现CartPole
- 论文结果难复现?本文教你完美实现深度强化学习算法DQN
- (尤其是训练集验证集的生成)深度学习 tensorflow 实战(2) 实现简单神经网络以及随机梯度下降算法S.G.D
- 深度学习 14. 深度学习调参,CNN参数调参,各个参数理解和说明以及调整的要领。underfitting和overfitting的理解,过拟合的解释。
- 深度学习 python 脚本实现 keras mninst 数字识别 预测端 code
- tensorflow40《TensorFlow实战》笔记-08-01 TensorFlow实现深度强化学习-策略网络 code
- 用Keras和“直方图均衡”为深度学习实现“图像扩充”
- 快乐的强化学习2——DQN及其实现方法
- 深度学习Deeplearning4j 入门实战(5):基于多层感知机的Mnist压缩以及在Spark实现
- 深度强化学习实战:Tensorflow实现DDPG - PaperWeekly 第48期
- Tensorflow实现策略网络(深度强化学习一)
- DL之Yolo系列:深度学习实现目标检测之Yolo系列的论文简介、概念理解、思路配图等详细攻略
- 深度学习:学习AlexNet论文及于keras的实现
- 实战深度强化学习DQN-理论和实践
- 深度强化学习中的DQN系列算法
- 深度学习实例1-----利用深度学习keras工具包实现销量预测
- 详解Nervana最新开源深度强化学习库Coach,支持DQN、DDQN等十多种算法|附开源代码
- Tensorflow实例:实现深度强化学习--策略网络
- keras实现常用深度学习模型LeNet,AlexNet,ZFNet,VGGNet,GoogleNet,Resnet
- 深度强化学习:资源以及思考。