如何训练带有Keras的DDPG根据观察结果回显点?

时间:2017-05-05 14:11:26

标签: python machine-learning keras reinforcement-learning keras-layer

我正在尝试训练强化学习模型,以便使用keras-rl向我回应一个点。

我的代码如下所示,使用20x20的世界形状。

import numpy as np
import rl.core as krl


class EchoEnv(krl.Env):

    def __init__(self):
        self.shape = np.array([20, 20])
        self.desired = np.random.rand(*self.shape.shape)

    def step(self, action):

        action = np.clip(action, 0, 1) * self.shape
        self.action = action

        observation = self.desired

        dx = action - (self.desired * self.shape)
        distance_to_goal = np.sqrt((dx**2).sum())

        done = distance_to_goal < 1

        reward = -distance_to_goal

        # observation, reward, done, info
        return observation, reward, done, {}

    def reset(self):
        self.desired = np.random.rand(*self.shape.shape)
        return self.desired

每次迭代,提供的observation是当前的随机self.desired值。 (代理应该学会立即返回此值。)done值表示所选点是否在合理的误差范围内。提供的奖励是-distance,因此它应该选择一个更靠近目标的点来最大化此值。

from rl.agents import DDPGAgent
from rl.memory import SequentialMemory
from rl.random import OrnsteinUhlenbeckProcess
from keras.layers import Dense, Input, concatenate, Flatten, Activation
from keras.models import Model, Sequential
from keras.optimizers import Adam

actor_n = 3
critic_n = 3

env = EchoEnv()
nb_actions = len(env.desired)
observation_shape = (nb_actions,)

actor = Sequential()
actor.add(Flatten(input_shape=(1,) + observation_shape))
for _ in range(actor_n):
    actor.add(Dense(16))
    actor.add(Activation("relu"))
actor.add(Dense(nb_actions))
actor.add(Activation("sigmoid"))
actor.summary()

action_input = Input(shape=observation_shape, name="action_input")
observation_input = Input(
    shape=(1,) + observation_shape, name="observation_input")
flattened_observation = Flatten()(observation_input)
output = concatenate([action_input, flattened_observation])
for _ in range(critic_n):
    output = Dense(32)(output)
    output = Activation("relu")(output)
output = Dense(1)(output)
output = Activation("linear")(output)
critic = Model(inputs=[action_input, observation_input], outputs=[output])
critic.summary()

memory = SequentialMemory(limit=10000, window_length=1)
random_process = OrnsteinUhlenbeckProcess(
    size=nb_actions, theta=.15, mu=0, sigma=.1)
agent = DDPGAgent(
    nb_actions=nb_actions,
    actor=actor,
    critic=critic,
    critic_action_input=action_input,
    memory=memory,
    nb_steps_warmup_critic=100,
    nb_steps_warmup_actor=100,
    random_process=random_process,
    gamma=.99,
    target_model_update=1e-3
)
agent.compile(Adam(lr=1e-2), metrics=["mae"])

agent.fit(env, nb_steps=100000, visualize=False, verbose=2)

agent.test(env, nb_episodes=10, visualize=True)

演员是Sequential模型,从初始Flatten图层开始。添加了具有16个节点的actor_n = 3层的一些数字(在这种情况下为Dense),然后激活ReLU。最后,添加Densenb_actions个节点(在本例中为2)和sigmoid激活。

评论家从行动和观察的Input层开始,观察是Flatten。输出定义为concatenate d动作和展平观察输入。添加一些具有32个节点的critic_n = 3层的数字(在这种情况下为Dense),然后激活ReLU。最后,添加带Dense节点的1图层,并添加线性激活函数。

使用的随机过程是Ornstein–Uhlenbeck processmu = 0sigma = 0.1theta = 0.15

最后,使用actor,crit,random进程和其他参数(如上面的代码所示)创建实际的DDPGAgent。它使用Adam优化程序进行编译,学习率为0.01,平均绝对误差指标。

理论上,这个代理人应该很快知道返回观察到的值将提供最高的回报。但是,有两个主要问题。

学习不一致

偶尔,随机,这将有效。它将开始返回非常接近所提供观察的行动,在[-1, 0)范围内获得奖励,这是可能的最佳奖励。

但是,这里要注意的重要事项是“随机”。通常,它会训练数万个步骤,而不是学习这个简单的属性。偶尔,偶然,似乎有效。

不变的输出

如果我在找到最佳策略之前取消训练,则算法会反复猜测相同的错误值。我之前的机器学习经验让我有理由相信,即使在测试过程中,代理人也应该尝试优化策略,尽量使奖励最大化并快速结束这一集,而不是“放弃”并反复选择相同的值。

我的环境似乎没有问题。因此,问题必须在我的DDPG模型中。我的直觉告诉我,无论是演员还是评论家,它都必须是层次的东西。但是,问题很可能与任何其他参数一起,包括在随机过程或优化器中。

我怎样才能解决这些问题?

0 个答案:

没有答案