我尝试使用continuous action-space DDPG来解决以下控制问题。目标是通过被告知每一步距目标位置有多远,而朝着有边界的二维区域内的一个最初未知的位置走去(类似于该儿童游戏,"temperature" levels, hot and cold指导玩家)
在设置中,目标位置是固定的,而特工的起始位置因情节而异。目的是学习一种策略,以尽可能快地向目标位置行走。代理人的观察仅包括其当前位置。关于奖励设计,我考虑了Reacher environment,因为它涉及相似的目标,并且类似地使用control reward和distance reward(请参见下面的代码)。越接近目标,回报越丰厚,而代理越接近目标,它就会越倾向于采取较小的行动。
对于实现,我考虑了openai/spinningup软件包。关于网络体系结构,我认为,如果目标位置已知,则最佳操作将是action = target - position
,即可以将策略pi(x) -> a
建模为单个密集层,并且可以了解目标位置以偏见项的形式:a = W @ x + b
,在收敛(理想情况下)之后,W = -np.eye(2)
和b = target
。由于环境施加了动作限制,因此可能无法在单个步骤中达到目标位置,因此我手动将计算出的动作缩放为a = a / tf.norm(a) * action_limit
。这保留了朝向目标的方向,因此仍然类似于最佳动作。我将这种自定义体系结构用于策略网络以及具有3个隐藏层的标准MLP体系结构(请参见下面的代码和结果)。
在MLP案例中运行了大约400集,在自定义策略案例中运行了700集,每集运行1000个步骤之后,它似乎并没有学到任何有用的东西。在测试运行期间,平均收益没有增加,当我在三个不同的起始位置检查行为时,它总是朝着该区域的(0, 1)
角走去;即使它刚开始在目标位置旁边,也会经过它,驶向(0, 1)
角。我注意到的是,自定义策略体系结构代理产生的std小得多。开发。测试情节的回报。
我想了解为什么该算法对于给定的设置似乎没有学到任何东西,以及需要进行哪些更改才能使其收敛。我怀疑实现或选择超参数存在问题,因为在给定的设置中我无法发现学习策略的任何概念性问题。但是,我无法查明问题的根源,因此,如果有人可以提供帮助,我将非常高兴。
平均测试回报率(自定义策略体系结构):
(竖线表示测试情节返回的标准开发)
平均测试回报率(MLP策略体系结构):
测试用例(自定义策略体系结构):
测试用例(MLP策略体系结构):
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)
)
答案 0 :(得分:0)
您正在使用巨大的网络(64x64x64)解决一个非常小的问题。单单这可能是一个大问题。您还需要在内存中保留1M个样本,同样,对于一个非常简单的问题,这可能是有害的且收敛缓慢。首先尝试更简单的设置(32x32净值和100,000个内存,甚至具有多项式特征的线性逼近器)。另外,您如何更新目标网络?什么是Traceback (most recent call last): File "C:\pypy2.7-v7.1.1-win32\site-packages\skbuild\setuptools_wrap.py", line 578, in setup
cmkr.make(make_args, env=env)
File "C:\pypy2.7-v7.1.1-win32\site-packages\skbuild\cmaker.py", line 481, in make
os.path.abspath(CMAKE_BUILD_DIR())))
An error occurred while building with CMake.
Command:
"cmake" "--build" "." "--target" "install" "--config" "Release" "--"
Source directory:
I:\Dropbox\project\opencv-python
Working directory:
I:\Dropbox\project\opencv-python\_skbuild\win32-2.7\cmake-build
Please see CMake's output for more information.
?最后,对这样的动作进行规范化可能不是一个好主意。最好只是剪裁一下,或者在末尾使用tanh层。