gpt4 book ai didi

python - 连续的 DDPG 似乎没有收敛于一个二维空间搜索问题 ("Hunt the Thimble")

转载 作者:行者123 更新时间:2023-11-28 18:57:51 25 4
gpt4 key购买 nike

我尝试使用 continuous action-space DDPG为了解决下面的控制问题。目标是通过被告知每一步离目标位置有多远,在有边界的二维区域内走向最初未知的位置(类似于这个 child 游戏,玩家由 "temperature" levels, hot and cold 引导)。

在设置中,目标位置是固定的,而代理的起始位置因剧集而异。目标是学习尽可能快地走向目标位置的策略。代理的观察仅包括其当前位置。关于奖励设计,我考虑了 Reacher environment ,因为它涉及到类似的目标,并且类似地使用 control reward和一个 distance reward (见下面的代码)。越接近目标会产生更大的返回,而代理越接近目标,它就越应该支持较小的 Action 。

对于实现,我考虑了 openai/spinningup包裹。关于网络架构,我认为,如果已知目标位置,则最佳操作将是 action = target - position,即策略 pi(x) -> a可以建模为单个密集层,目标位置将以偏置项的形式学习:a = W @ x + b 其中,在收敛后(理想情况下),W = -np.eye(2)b = target。由于环境施加了一个 Action 限制,以至于目标位置可能无法在单个步骤中到达,我手动将计算的 Action 缩放为 a = a/tf.norm(a) * action_limit。这保留了朝向目标的方向,因此仍然类似于最佳 Action 。我将这种自定义架构用于策略网络以及具有 3 个隐藏层的标准 MLP 架构(参见下面的代码和结果)。

结果

在 MLP 案例中运行算法大约 400 集,在自定义策略案例中运行 700 集,每集 1000 步,它似乎没有学到任何有用的东西。在测试运行期间,平均返回没有增加,当我检查三个不同起始位置的行为时,它总是走向该区域的 (0, 1) 角落;即使它从目标位置旁边开始,它也会经过目标位置,前往 (0, 1) 角。我注意到自定义策略体系结构代理导致 std 小得多。开发者测试集返回。

问题

我想了解为什么该算法似乎无法针对给定设置学习任何内容,以及需要更改哪些内容才能使其收敛。我怀疑实现或超参数的选择存在问题,因为我无法发现在给定设置中学习策略的任何概念性问题。但是我无法查明问题的根源,所以如果有人能提供帮助,我会很高兴。


平均测试返回(自定义策略架构):

Average test return (custom policy architecture)

(竖条表示测试集返回的标准偏差)

平均测试返回(MLP 策略架构):

Average test return (MLP policy architecture)

测试用例(自定义策略架构):

Test cases (custom policy architecture)

测试用例(MLP 策略架构):

Test cases (MLP policy architecture)

代码

import logging
import os
import gym
from gym.wrappers.time_limit import TimeLimit
import numpy as np
from spinup.algos.ddpg.ddpg import core, ddpg
import tensorflow as tf


class TestEnv(gym.Env):
target = np.array([0.7, 0.8])
action_limit = 0.01
observation_space = gym.spaces.Box(low=np.zeros(2), high=np.ones(2), dtype=np.float32)
action_space = gym.spaces.Box(-action_limit * np.ones(2), action_limit * np.ones(2), dtype=np.float32)

def __init__(self):
super().__init__()
self.pos = np.empty(2, dtype=np.float32)
self.reset()

def step(self, action):
self.pos += action
self.pos = np.clip(self.pos, self.observation_space.low, self.observation_space.high)
reward_ctrl = -np.square(action).sum() / self.action_limit**2
reward_dist = -np.linalg.norm(self.pos - self.target)
reward = reward_ctrl + reward_dist
done = abs(reward_dist) < 1e-9
logging.debug('Observation: %s', self.pos)
logging.debug('Reward: %.6f (reward (ctrl): %.6f, reward (dist): %.6f)', reward, reward_ctrl, reward_dist)
return self.pos, reward, done, {}

def reset(self):
self.pos[:] = np.random.uniform(self.observation_space.low, self.observation_space.high, size=2)
logging.info(f'[Reset] New position: {self.pos}')
return self.pos

def render(self, *args, **kwargs):
pass


def mlp_actor_critic(x, a, hidden_sizes, activation=tf.nn.relu, action_space=None):
act_dim = a.shape.as_list()[-1]
act_limit = action_space.high[0]
with tf.variable_scope('pi'):
# pi = core.mlp(x, list(hidden_sizes)+[act_dim], activation, output_activation=None) # The standard way.
pi = tf.layers.dense(x, act_dim, use_bias=True) # Target position should be learned via the bias term.
pi = pi / (tf.norm(pi) + 1e-9) * act_limit # Prevent division by zero.
with tf.variable_scope('q'):
q = tf.squeeze(core.mlp(tf.concat([x,a], axis=-1), list(hidden_sizes)+[1], activation, None), axis=1)
with tf.variable_scope('q', reuse=True):
q_pi = tf.squeeze(core.mlp(tf.concat([x,pi], axis=-1), list(hidden_sizes)+[1], activation, None), axis=1)
return pi, q, q_pi


if __name__ == '__main__':
log_dir = 'spinup-ddpg'
if not os.path.exists(log_dir):
os.mkdir(log_dir)
logging.basicConfig(level=logging.INFO)
ep_length = 1000
ddpg(
lambda: TimeLimit(TestEnv(), ep_length),
mlp_actor_critic,
ac_kwargs=dict(hidden_sizes=(64, 64, 64)),
steps_per_epoch=ep_length,
epochs=1_000,
replay_size=1_000_000,
start_steps=10_000,
act_noise=TestEnv.action_limit/2,
gamma=0.99, # Use large gamma, because of action limit it matters where we walk to early in the episode.
polyak=0.995,
max_ep_len=ep_length,
save_freq=10,
logger_kwargs=dict(output_dir=log_dir)
)

最佳答案

您正在使用一个巨大的网络 (64x64x64) 来解决一个非常小的问题。仅此一项就可能是一个大问题。您还在内存中保留了 1M 个样本,同样,对于一个非常简单的问题,这可能是有害的且收敛速度慢。首先尝试使用更简单的设置(32x32 网络和 100,000 内存,甚至是具有多项式特征的线性逼近器)。另外,您如何更新目标网络?什么是 polyak?最后,像这样规范化操作可能不是一个好主意。最好只是剪辑它或在最后使用一个 tanh 层。

关于python - 连续的 DDPG 似乎没有收敛于一个二维空间搜索问题 ("Hunt the Thimble"),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56085616/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com