python - TF-agents - 重播缓冲区将轨迹添加到批次形状不匹配
问题描述
我发布了一个由另一个用户发布然后被删除的问题。我有同样的问题,我找到了答案。原来的问题:
我目前正在尝试按照本教程实施分类 DQN:https ://www.tensorflow.org/agents/tutorials/9_c51_tutorial
以下部分让我有点头疼:
random_policy = random_tf_policy.RandomTFPolicy(env.time_step_spec(),
env.action_spec())
replay_buffer = tf_uniform_replay_buffer.TFUniformReplayBuffer(
data_spec=agent.collect_data_spec,
batch_size=1,
max_length=replay_buffer_capacity) # this is 100
# ...
def collect_step(environment, policy):
time_step = environment.current_time_step()
action_step = policy.action(time_step)
next_time_step = environment.step(action_step.action)
traj = trajectory.from_transition(time_step, action_step, next_time_step)
print(traj)
# Add trajectory to the replay buffer
replay_buffer.add_batch(traj)
for _ in range(initial_collect_steps):
collect_step(env, random_policy)
对于上下文:agent.collect_data_spec
具有以下形状:
Trajectory(step_type=TensorSpec(shape=(), dtype=tf.int32, name='step_type'), observation=BoundedTensorSpec(shape=(4, 84, 84), dtype=tf.float32, name='screen', minimum=array(0., dtype=float32), maximum=array(1., dtype=float32)), action=BoundedTensorSpec(shape=(), dtype=tf.int32, name='play', minimum=array(0), maximum=array(6)), policy_info=(), next_step_type=TensorSpec(shape=(), dtype=tf.int32, name='step_type'), reward=TensorSpec(shape=(), dtype=tf.float32, name='reward'), discount=BoundedTensorSpec(shape=(), dtype=tf.float32, name='discount', minimum=array(0., dtype=float32), maximum=array(1., dtype=float32)))
这是一个示例 traj 的样子:
Trajectory(step_type=<tf.Tensor: shape=(), dtype=int32, numpy=0>, observation=<tf.Tensor: shape=(4, 84, 84), dtype=float32, numpy=array([tensor contents omitted], dtype=float32)>, action=<tf.Tensor: shape=(), dtype=int32, numpy=1>, policy_info=(), next_step_type=<tf.Tensor: shape=(), dtype=int32, numpy=1>, reward=<tf.Tensor: shape=(), dtype=float32, numpy=0.0>, discount=<tf.Tensor: shape=(), dtype=float32, numpy=1.0>)
所以,一切都应该检查,对吧?环境输出一个形状为 [4, 84, 84] 的张量,与回放缓冲区所期望的相同。除了我收到以下错误:
tensorflow.python.framework.errors_impl.InvalidArgumentError: Must have updates.shape = indices.shape + params.shape[1:] or updates.shape = [], got updates.shape [4,84,84], indices.shape [1], params.shape [100,4,84,84] [Op:ResourceScatterUpdate]
这表明它实际上是在期待一个张量 shape [1, 4, 84, 84]
。问题是,如果我让我的环境输出该形状的张量,然后我会收到另一条错误消息,告诉我输出形状与规范形状不匹配(duh)。如果我然后将规格形状调整为[1, 4, 84, 84]
,突然重播缓冲区期望形状为[1, 1, 4, 84, 84]
,依此类推......
最后,为了完成,这里分别有我的环境time_step_spec
和action_spec
我的环境:
TimeStep(step_type=TensorSpec(shape=(), dtype=tf.int32, name='step_type'), reward=TensorSpec(shape=(), dtype=tf.float32, name='reward'), discount=BoundedTensorSpec(shape=(), dtype=tf.float32, name='discount', minimum=array(0., dtype=float32), maximum=array(1., dtype=float32)), observation=BoundedTensorSpec(shape=(4, 84, 84), dtype=tf.float32, name='screen', minimum=array(0., dtype=float32), maximum=array(1., dtype=float32)))
---
BoundedTensorSpec(shape=(), dtype=tf.int32, name='play', minimum=array(0), maximum=array(6))
我已经尝试了今天的大部分时间,试图让张量正确拟合,但你不能重塑它,因为它是一个属性,所以在最后的努力中,我希望也许有一些陌生人可以告诉我哎呀,这里发生了。
先感谢您!
解决方案
似乎在collect_step
函数中,traj
是一个单一的轨迹,而不是一个批次。因此,您需要将维度扩展为一个批次,然后使用它。请注意,您不能只做tf.expand_dims(traj, 0)
. 有一个用于嵌套结构的辅助函数。
def collect_step(environment, policy):
time_step = environment.current_time_step()
action_step = policy.action(time_step)
next_time_step = environment.step(action_step.action)
traj = trajectory.from_transition(time_step, action_step, next_time_step)
batch = tf.nest.map_structure(lambda t: tf.expand_dims(t, 0), traj)
# Add trajectory to the replay buffer
replay_buffer.add_batch(batch)
推荐阅读
- javascript - 当用户在Javascript中使用鼠标滚轮开始滚动时,如何确定用户将滚动多少像素
- vb.net - 在 Visual Basic 中旋转 BMP
- c++ - 从 C++ 项目调用 docker 容器
- wordpress - 如何在 WordPress 中禁用古腾堡
- ubuntu - AWK 提取列中具有相同单词的前两行
- azure - 通过 Azure 应用程序代理调用本地 OAuth API
- sql - 如何通过在oracle sql中同时比较多条记录来获取行
- python - 将 pandas 数据框转换为具有唯一整数对的元组列表作为第一个条目
- apache-flink - 如何使用 Flink CEP 实现模式以匹配暴力登录和端口扫描攻击
- vue.js - Vue - 检测插槽内的组件