使用tf_agents.environments.TFPyEnvironment将Python的RL环境转为TF环境会发生什么变化?
What changes occur when using tf_agents.environments.TFPyEnvironment to convert a Python RL environment into a TF environment?
我注意到在使用 tf_agents.environments.TFPyEnvironment 将 Python 环境转换为 TF 环境时发生了一些奇怪的事情,我想问你发生了什么一般变化。
为了澄清问题,请在下面找到我的代码。我希望环境模拟(以过于简单的方式)与想要购买水果或蔬菜的顾客的互动。智能体应该知道当顾客要水果时,例如应该执行动作 0。
class CustomEnv(py_environment.PyEnvironment):
def __init__(self):
self._action_spec = array_spec.BoundedArraySpec(
shape=(), dtype=np.int32, minimum=0, maximum=1)
self._observation_spec = array_spec.BoundedArraySpec(
shape=(1,1), dtype=np.int32, minimum=0, maximum=1)
self._state = [0]
self._counter = 0
self._episode_ended = False
self.dictionary = {0: ["Fruits"],
1: ["Vegetables"]}
def action_spec(self):
return self._action_spec
def observation_spec(self):
return self._observation_spec
def _reset(self):
self._state = [0]
self._counter = 0
self._episode_ended = False
return ts.restart(np.array([self._state], dtype=np.int32))
def preferences(self):
return np.random.randint(2)
def pickedBasket(self, yes):
reward = -1.0
if yes:
reward = 0.0
return reward
def _step(self, action):
if self._episode_ended:
self._reset()
if self._counter<50:
self._counter += 1
basket = self.preferences()
condition = basket in self.dictionary[action]
reward = self.pickedBasket(condition)
self._state[0] = basket
if self._counter==50:
self._episode_ended=True
return ts.termination(np.array([self._state],
dtype=np.int32),
reward,
1)
else:
return ts.transition(np.array([self._state],
dtype=np.int32),
reward,
discount=1.0)
当我执行以下代码以检查一切是否正常工作时:
py_env = ContextualMBA()
tf_env = tf_py_environment.TFPyEnvironment(py_env)
time_step = tf_env.reset()
action = 0
next_time_step = tf_env.step(action)
我得到一个 不可散列的类型:'numpy.ndarray' 行 condition = basket in self.dictionary[action]
所以我把它改成 condition = basket in self.dictionary[int(action)]
并且它工作得很好。我还想准确地说,即使不添加 int
部分,它也可以作为 Python 环境使用。所以我想问一下 tf_agents.environments.TFPyEnvironment 有什么变化。我看不出它如何影响操作的类型 action
,因为它与 action_spec
或任何东西(至少直接在代码中)无关。
基本上,tf_agents.environments.TFPyEnvironment
是在您的 Python 环境和 TF-Agents API 之间工作的翻译器。 TF-Agents API 不知道它可以选择多少个动作,要观察和学习哪些数据,或者特别是动作的选择将如何影响您的自定义环境。
您的自定义环境用于提供环境规则,它遵循一些标准,以便 TFPyEnvironment 能够正确翻译它,以便 TF-Agent 可以使用它。您需要在自定义环境中定义元素和方法,例如:
__init__()
self._action_spec
self._observation_spec
_reset()
_step()
我不确定您的疑虑是否来自于您为代理提供了 action = 0
而与 action_spec 无关的事实,该代理确实有效。 action_spec 与您的 _step()
函数无关,这是正确的。您的 step 函数采取一些行动并将其应用于环境。这个动作如何形才是重点。
问题是您选择了值并将其提供给 tf_env.step()
函数。如果您实际上已通过 tf_env.step(agent.policy.action)
(或 tf_env.step(agent.policy.action.action)
,有时 TF-Agents 让我感到困惑)将操作选择委托给代理,代理将不得不查看您的 action_spec
定义了解环境对动作的期望。
如果未定义 action_spec
,则代理将不知道在“水果”为 0、“蔬菜”为 1(您想要的)和定义的“意外结果”为“2”之间选择什么肉”,或 [3, 2] 代表 2 瓶水,因为 3 可以代表“瓶装水”。 TF-Agent 需要这些定义,以便它了解您的环境规则。
至于实际的变化以及它们对您的自定义环境代码的作用,我相信您通过查看 TF-Agents 库的源代码会有更好的想法。
我注意到在使用 tf_agents.environments.TFPyEnvironment 将 Python 环境转换为 TF 环境时发生了一些奇怪的事情,我想问你发生了什么一般变化。
为了澄清问题,请在下面找到我的代码。我希望环境模拟(以过于简单的方式)与想要购买水果或蔬菜的顾客的互动。智能体应该知道当顾客要水果时,例如应该执行动作 0。
class CustomEnv(py_environment.PyEnvironment):
def __init__(self):
self._action_spec = array_spec.BoundedArraySpec(
shape=(), dtype=np.int32, minimum=0, maximum=1)
self._observation_spec = array_spec.BoundedArraySpec(
shape=(1,1), dtype=np.int32, minimum=0, maximum=1)
self._state = [0]
self._counter = 0
self._episode_ended = False
self.dictionary = {0: ["Fruits"],
1: ["Vegetables"]}
def action_spec(self):
return self._action_spec
def observation_spec(self):
return self._observation_spec
def _reset(self):
self._state = [0]
self._counter = 0
self._episode_ended = False
return ts.restart(np.array([self._state], dtype=np.int32))
def preferences(self):
return np.random.randint(2)
def pickedBasket(self, yes):
reward = -1.0
if yes:
reward = 0.0
return reward
def _step(self, action):
if self._episode_ended:
self._reset()
if self._counter<50:
self._counter += 1
basket = self.preferences()
condition = basket in self.dictionary[action]
reward = self.pickedBasket(condition)
self._state[0] = basket
if self._counter==50:
self._episode_ended=True
return ts.termination(np.array([self._state],
dtype=np.int32),
reward,
1)
else:
return ts.transition(np.array([self._state],
dtype=np.int32),
reward,
discount=1.0)
当我执行以下代码以检查一切是否正常工作时:
py_env = ContextualMBA()
tf_env = tf_py_environment.TFPyEnvironment(py_env)
time_step = tf_env.reset()
action = 0
next_time_step = tf_env.step(action)
我得到一个 不可散列的类型:'numpy.ndarray' 行 condition = basket in self.dictionary[action]
所以我把它改成 condition = basket in self.dictionary[int(action)]
并且它工作得很好。我还想准确地说,即使不添加 int
部分,它也可以作为 Python 环境使用。所以我想问一下 tf_agents.environments.TFPyEnvironment 有什么变化。我看不出它如何影响操作的类型 action
,因为它与 action_spec
或任何东西(至少直接在代码中)无关。
基本上,tf_agents.environments.TFPyEnvironment
是在您的 Python 环境和 TF-Agents API 之间工作的翻译器。 TF-Agents API 不知道它可以选择多少个动作,要观察和学习哪些数据,或者特别是动作的选择将如何影响您的自定义环境。
您的自定义环境用于提供环境规则,它遵循一些标准,以便 TFPyEnvironment 能够正确翻译它,以便 TF-Agent 可以使用它。您需要在自定义环境中定义元素和方法,例如:
__init__()
self._action_spec
self._observation_spec
_reset()
_step()
我不确定您的疑虑是否来自于您为代理提供了 action = 0
而与 action_spec 无关的事实,该代理确实有效。 action_spec 与您的 _step()
函数无关,这是正确的。您的 step 函数采取一些行动并将其应用于环境。这个动作如何形才是重点。
问题是您选择了值并将其提供给 tf_env.step()
函数。如果您实际上已通过 tf_env.step(agent.policy.action)
(或 tf_env.step(agent.policy.action.action)
,有时 TF-Agents 让我感到困惑)将操作选择委托给代理,代理将不得不查看您的 action_spec
定义了解环境对动作的期望。
如果未定义 action_spec
,则代理将不知道在“水果”为 0、“蔬菜”为 1(您想要的)和定义的“意外结果”为“2”之间选择什么肉”,或 [3, 2] 代表 2 瓶水,因为 3 可以代表“瓶装水”。 TF-Agent 需要这些定义,以便它了解您的环境规则。
至于实际的变化以及它们对您的自定义环境代码的作用,我相信您通过查看 TF-Agents 库的源代码会有更好的想法。