关于在Tensorflow中使用策略梯度来训练乒乓球游戏代理商的问题

时间:2018-07-23 07:48:59

标签: python tensorflow machine-learning deep-learning reinforcement-learning

我试图了解策略梯度的工作原理,并使用Tensorflow从草图构建pong游戏代理,但似乎不起作用。我不确定我是否对政策梯度有误解。在这里,我发布了带有解释的代码。

首先创建占位符,以保存从环境获取的输入帧

input_frame = tf.placeholder(tf.float32, [380*400, None], name='input_frame')

定义简单网络和模型的参数

W1 = tf.get_variable(name='w1', shape=[200, 380*400],initializer=tf.contrib.layers.xavier_initializer(seed=2))
b1 = tf.get_variable(name='b1', shape=[200, 1], initializer=tf.zeros_initializer())
W2 = tf.get_variable(name='w2', shape=[3, 200],initializer=tf.contrib.layers.xavier_initializer(seed=2))
b2 = tf.get_variable(name='b2', shape=[3, 1], initializer=tf.zeros_initializer())

def build_model():
    L_1 =tf.nn.relu(tf.add(tf.matmul(W1, input_frame), b1))
    L_2 =tf.nn.relu(tf.add(tf.matmul(W2, L_1), b2))

    Y = tf.nn.softmax(L_2, axis=0)
    return Y

折扣奖励功能

def discount_rewards(r):
  discounted_r = np.zeros_like(r)
  running_add = 0
  for t in reversed(range(0, discounted_r.size)):
    if r[t] != 0: running_add = 0
    #https://github.com/hunkim/ReinforcementZeroToAll/issues/1
    running_add = running_add * gamma + r[t]
    discounted_r[t] = running_add
  return discounted_r

建立模型

Y = build_model()

示例操作

sample_op = tf.multinomial(logits=tf.reshape(Y, (1, 3)), num_samples=1)
Y_action = sample_op - 1    #Move up: -1, stay still: 0, move down: 1

常规初始化

global_step = tf.train.get_or_create_global_step()
init = tf.global_variables_initializer()
sess = tf.Session()
sess.run(init)

通过裁剪从环境中检索下一帧

next_frame = my_pong.get_next_frame().T[pong_game.SCOREBOARD_HEIGHT + 6 : pong_game.WINDOW_HEIGHT, 0 + pong_game.PADDLE_THICKNESS:pong_game.WINDOW_WIDTH - pong_game.PADDLE_THICKNESS].reshape(380*400, 1)

通过减去当前帧和最后一帧来获得观察结果

observation_ = next_frame - last_frame
action_ = sess.run(Y_action, feed_dict={
        input_frame: observation_})

对于每一帧,通过输入采样动作从环境中获得奖励,并附加情节记忆。

done_, reward_ = my_pong.paddle_2_control(action_)
episode_menory.append((observation_, action_, float(reward_)))
last_frame = next_frame

如果一方获得21分,则done_值为true,并开始训练过程

第一笔折扣并标准化奖励

if done_:
    obs, lab, rwd = zip(*episode_menory)
    prwd = discount_rewards(rwd)
    prwd -= np.mean(prwd)
    prwd /= np.std(prwd)

    obs_reshape = np.squeeze(obs).T

使用情节中的示例动作来建立一个热门标签

    lab_one_hot = tf.one_hot(np.squeeze(lab)+1, 3, axis=0)

交叉熵损失。一个热门标签是采样操作,而logit是模型的输出。 (我不确定这是否正确)

    cross_entropy = tf.losses.softmax_cross_entropy(onehot_labels=lab_one_hot, logits=Y)

通过将处理后的奖励“ prwd”与损失的交叉熵相乘来定义成本函数

    cost = cross_entropy * prwd

定义优化程序并开始培训

    optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01)
        train_op = optimizer.minimize(cost)

    _, cost_ = sess.run([train_op, cost], feed_dict={input_frame: obs_reshape})

    episode_menory = []

    print("Episode %d finish! Cost = %f" % (episode, np.sum(cost_)))

    episode += 1

我在Titan X设备上运行了一个周末的程序,但性能似乎没有任何改善。成本是随机输出,有时是负数,有时是正数。而且我不知道如何根据输出的成本值来衡量模型偏好。我想知道我错过或弄错了哪一部分。非常感谢你。

我将完整的代码发布在这里:https://github.com/ivonchan0414/pg_pong

1 个答案:

答案 0 :(得分:0)

您在此处进行了丰富(复杂)的培训和反馈设置。我无法通过简单的偶然检查来查明错误。

解决问题的一种方法可能是遵循典型的管道调试和验证过程:

  • 通过保存中间结果来指示管道的各个阶段
  • 验证中间结果:然后您将缩小行为与预期差异的范围

此外:

  • 从具有已知预期行为的测试输入数据集开始。最初,您可能会没有看到它:但是至少您可以确定原因不是由于模型无法轻易处理的数据引起的。