用keras搭建DQN


title: 用keras搭建DQN
date: 2018-09-14 20:25:30
tags: reinforecementLearning
categories: 日志

dqn总结:
最近时间虽然一直看这个dqn代码,虽然看懂了,但是思路却一直不明确,无法自己复写出自己的代码,所以就想写一篇博客来整理一下思路。如果这篇文章写完了,应该思路就清晰了。

本文主要是看了莫烦的教学视频,在视频中,老师(尊称一声老师O(∩_∩)O哈哈~)是用tensoflow1.2来搭建框架的。本人在看懂了代码后,认为DQN中采用了两个模型,此时用tensorflow来完成这些网络的灵活搭建时当让是最好的选择,但是在我看来,似乎keras中的函数式模型似乎也可以做到啊(Sequential模型肯定是不能完成这件事的),所以我就想用keras来重写这个代码,以此来验证自己是不是真的把DQN的实现过程搞懂了。(突然发现代码粘贴错了,github上代码上传的也是错的。。。。。一个多月才发现,还有人浏览这篇文章,尴尬极了)

#首先我们要构建一个DQN类
class DQN:
	#之后我们需要构建网络
    def _build_net(self):
    	pass
	#学习需要经验池,这个学习是off-learning
    def store_transition(self,s,a,r,s_):
    	pass
	#进行学习
    def learn(self):
        pass
    #动作决策
    def choose_action(self,observation):
        pass

以上就是我们要完成的东西了,按四个部分一次完成就可以实现DQN类了

但是我们还要重写类方法中__init__方法:

def __init__(
    self,
    n_actions,
    n_features,
    learning_rate=0.01,
    reward_decay=0.9,
    e_greedy=0.9,
    replace_target_iter=300,
    memory_size=500,
    batch_size=32,
    e_greedy_increment=None,
    output_graph=False,
):
    self.n_actions = n_actions
    self.n_features = n_features
    self.lr = learning_rate
    self.gamma = reward_decay
    self.epsilon_max = e_greedy
    self.replace_target_iter = replace_target_iter
    self.memory_size = memory_size
    self.batch_size = batch_size
    self.epsilon_increment = e_greedy_increment
    self.epsilon = 0 if e_greedy_increment is not None else self.epsilon_max
    self.learn_step_counter = 0
	self.memory = np.zeros((self.memory_size, n_features * 2 + 2))
	self._build_net()

其实用keras来实现DQN的话,和tenosrflow来写,没有很大的区别。主要是就是在构建网络时代码有些许差别。代码如下:

def _build_net(self):
    # 构建evaluation网络
    eval_inputs = Input(shape=(self.n_features,))
    x = Dense(64, activation='relu')(eval_inputs)
    x = Dense(64, activation='relu')(x)
    self.q_eval = Dense(self.n_actions)(x)
    # 构建target网络,注意这个target层输出是q_next而不是,算法中的q_target
    target_inputs = Input(shape=(self.n_features,))
    x = Dense(64, activation='relu')(target_inputs)
    x = Dense(64, activation='relu')(x)
    self.q_next = Dense(self.n_actions)(x)

    self.model1 = Model(target_inputs, self.q_next)
    self.model2 = Model(eval_inputs, self.q_eval)
    rmsprop = RMSprop(lr=self.lr)
    self.model1.compile(loss='mean_squared_error', optimizer=rmsprop, metrics=['accuracy'])
    self.model2.compile(loss='mean_squared_error', optimizer=rmsprop, metrics=['accuracy'])

每隔一段时间将evaluation层参数赋值给target层

    def target_replace_op(self):
        v1 = self.model2.get_weights()
        self.model1.set_weights(v1)
        print("params has changed")

接着是learning函数

    def learn(self):
        if self.learn_step_counter % self.replace_target_iter == 0:
            self.target_replace_op()
            print('\ntarget_params_replaced\n')

        if self.memory_counter > self.memory_size:
            sample_index = np.random.choice(self.memory_size, size=self.batch_size)
        else:
            sample_index = np.random.choice(self.memory_counter, size=self.batch_size)
        batch_memory = self.memory[sample_index, :]
        q_next, q_eval = self.model1.predict(batch_memory[:, -self.n_features:]), self.model2.predict(
            batch_memory[:, :self.n_features])
        q_target = q_eval.copy()
        batch_index = np.arange(self.batch_size, dtype=np.int32)
        eval_act_index = batch_memory[:, self.n_features].astype(int)
        reward = batch_memory[:, self.n_features + 1]
        q_target[batch_index, eval_act_index] = reward + self.gamma * np.max(q_next, axis=1)
        self.model2.fit(batch_memory[:, :self.n_features], q_target, epochs=10)
        self.epsilon = self.epsilon + self.epsilon_increment if self.epsilon < self.epsilon_max else self.epsilon_max
        self.learn_step_counter += 1

其他部分和莫凡代码是一样的,就不贴出来了。

完整的网络部分代码和环境部分代码放在github上了:https://github.com/Jason33Wang/ReinforcementLearning_by_keras

注明:DQN.py和maze_env.py文件是直接fork莫凡的

下面也贴上原莫凡的tensorflow代码:https://github.com/MorvanZhou/Reinforcement-learning-with-tensorflow/tree/master/contents/5_Deep_Q_Network

用keras搭建的网络用来训练这个游戏时,收敛的并没有莫凡原代码收敛的好,之后在原基础上,把memory的size增加了一倍后才收敛的较好。

写完这篇文章后,发现没什么技术含量,不过自己的思路更加清晰了,大家仅供参考吧。希望自己经过以后的学习能写出更好,更有深度的文章吧!

发布了13 篇原创文章 · 获赞 5 · 访问量 6955
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览