tensorflow - 深度Q网络无法学习

标签 tensorflow neural-network artificial-intelligence reinforcement-learning q-learning

我尝试编写一个Deep Q Network,以使用Tensorflow和OpenAI的Gym玩Atari游戏。
这是我的代码:

import tensorflow as tf
import gym
import numpy as np
import os

env_name = 'Breakout-v0'
env = gym.make(env_name)
num_episodes = 100
input_data = tf.placeholder(tf.float32,(None,)+env.observation_space.shape)
output_labels = tf.placeholder(tf.float32,(None,env.action_space.n))

def convnet(data):
    layer1 = tf.layers.conv2d(data,32,5,activation=tf.nn.relu)
    layer1_dropout = tf.nn.dropout(layer1,0.8)
    layer2 = tf.layers.conv2d(layer1_dropout,64,5,activation=tf.nn.relu)
    layer2_dropout = tf.nn.dropout(layer2,0.8)
    layer3 = tf.layers.conv2d(layer2_dropout,128,5,activation=tf.nn.relu)
    layer3_dropout = tf.nn.dropout(layer3,0.8)
    layer4 = tf.layers.dense(layer3_dropout,units=128,activation=tf.nn.softmax,kernel_initializer=tf.zeros_initializer)
    layer5 = tf.layers.flatten(layer4)
    layer5_dropout = tf.nn.dropout(layer5,0.8)
    layer6 = tf.layers.dense(layer5_dropout,units=env.action_space.n,activation=tf.nn.softmax,kernel_initializer=tf.zeros_initializer)
    return layer6

logits = convnet(input_data)
loss = tf.losses.sigmoid_cross_entropy(output_labels,logits)
train = tf.train.GradientDescentOptimizer(0.001).minimize(loss)
saver = tf.train.Saver()
init = tf.global_variables_initializer()
discount_factor = 0.5

with tf.Session() as sess:
    sess.run(init)
    for episode in range(num_episodes):
        x = []
        y = []
        state = env.reset()
        feed = {input_data:np.array([state])}
        print('episode:', episode+1)
        while True:
            x.append(state)
            if (episode+1)/num_episodes > np.random.uniform():
                Q = sess.run(logits,feed_dict=feed)[0]
                action = np.argmax(Q)
            else:
                action = env.action_space.sample()
            state,reward,done,info = env.step(action)
            Q = sess.run(logits,feed_dict=feed)[0]
            new_Q = np.zeros(Q.shape)
            new_Q[action] = reward+np.amax(Q)*discount_factor
            y.append(new_Q)
            if done:
                break

        for sample in range(len(x)):
            _,l = sess.run([train,loss],feed_dict={input_data:[x[sample]],output_labels:[y[sample]]})
            print('training loss on sample '+str(sample+1)+': '+str(l))
    saver.save(sess,os.getcwd()+'/'+env_name+'-DQN.ckpt')

问题是:
  • 训练期间的损失并没有减少,并且始终在0.7或0.8左右。
  • 当我在Breakout环境中测试了网络(即使我训练了1000集)之后, Action 似乎仍然是随机的,很少碰到球。

  • 我已经尝试使用不同的损失函数(softmax交叉熵和均方误差),使用另一个优化器(Adam)并提高了学习率,但没有任何变化。

    有人可以告诉我如何解决此问题吗?

    最佳答案

    您可以研究以下一些突出的问题(在这种情况下,很难准确地分辨出哪些是最重要的问题,这很难确定):

  • 100集似乎并不多。在下图中,您可以在Breakout(source)上看到Double DQN的一些变体(比DQN稍先进)的学习曲线。 x轴上的培训时间以那里的数百万帧而不是情节来衡量。我不确切知道x-轴上的100集将在哪里,但是我认为这不会太遥远。在100集之后再期望有任何类似的表现可能根本不合理。

  • OpenAI Baselines DQN Learning Curves Breakout
    (来源:openai.com)
  • 看来您正在网络中使用Dropout。我建议摆脱辍学。我不知道100%肯定会在深度强化学习中使用辍学很不好,但是1)这肯定不常见,并且2)直观上似乎没有必要。辍学被用来对抗监督学习中的过度拟合,但是过度拟合在强化学习中并不是真的有很大的风险(至少,如果您只是想像在这里一样一次尝试训练单个游戏,则不是这样)。
  • discount_factor = 0.5似乎非常低,这将使长期奖励无法传播给少数行动。与discount_factor = 0.99相似的东西会更常见。
  • if (episode+1)/num_episodes > np.random.uniform():,此代码看起来实际上是将epsilon从第一个情节中的1.0 - 1 / num_episodes衰减到最后一个情节中的1.0 - num_episodes / num_episodes = 0.0。使用您当前的num_episodes = 100,这意味着它在0.99情节中从0.0衰减为100。在我看来,它的衰减速度太快了。作为引用,在original DQN paper中,在 100万帧上,epsilon1.0逐渐衰减为0.1,并在此后永久保持不变。
  • 您没有使用Experience Replay,也没有使用the original DQN paper中所述的单独的目标网络。上面的所有要点都是,很明显易于研究和修复,因此,我建议先这样做。这可能已经足以在学习后开始真正看到比随机性能更好的性能,但仍可能会比添加这两个性能差。
  • 关于tensorflow - 深度Q网络无法学习,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49840892/

    相关文章:

    artificial-intelligence - 对于一群本科生来说,你对一个好的人工智能项目有什么想法?

    python - 在 keras 模型中对输入进行微分以用于损失

    javascript - Tensorflowjs 在训练时产生形状错误

    python - keras层中的参数适用于哪里?

    python - Keras 功能 API : Pooling input does not give correct output shape

    python - 名称错误 : name 'self' is not defined in Neural Network example

    neural-network - FPGA 中的神经网络模拟器?

    python - 如何对 Keras 中的整个模型应用权重归一化?

    artificial-intelligence - 通过使用良好的状态空间和搜索树解决汉诺塔

    sql-server - SSAS 的可编程性如何?