1

我注意到在使用 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任何东西无关(至少直接在代码中)。

4

1 回答 1

0

基本上,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()功能无关,这是正确的。您的阶跃函数会采取一些行动并将其应用于环境。这个动作是如何形成的才是真正的重点。

问题是您选择了值并将其赋予tf_env.step()函数。如果您实际上已将操作选择委托给代理tf_env.step(agent.policy.action)(或者tf_env.step(agent.policy.action.action),有时 TF-Agent 让我感到困惑),代理将不得不查看您的action_spec定义以了解环境期望操作的样子。

如果action_spec未定义,代理将不知道在 0 代表“水果”、1 代表“蔬菜”(您想要并定义)之间选择什么,或者意外结果为 2 代表“肉类”,或 [3, 2] 代表2瓶水,因为3可以代表“瓶水”。TF-Agent 需要这些定义,因此它知道您的环境规则。

至于实际的更改以及它们对您的自定义环境代码的作用,我相信您可以通过查看 TF-Agents 库的源代码来获得更好的想法。

于 2021-07-27T14:53:24.557 回答