【问题标题】:Difficulty in Connecting Layers with Keras: Graph Disconnected用 Keras 连接层的困难:图断开连接
【发布时间】:2021-04-29 04:40:17
【问题描述】:

我正在尝试使用 Keras 功能 API 为我的 Policy Gradient(深度强化学习)代理构建一个 NN 模型。我打算做的是通过在 logit 层将它们的概率分布减少到零来掩盖无效动作:

def __build_policy_network(self):
    inputs = keras.layers.Input(shape=(self.input_dim,))
    advantages = keras.layers.Input(shape=(1,))
    valid_actions = keras.layers.Input(shape=(3,))
    dense_1 = keras.layers.Dense(units=self.fc1_size, activation="relu", kernel_initializer="he_uniform")(inputs)
    dense_2 = keras.layers.Dense(units=self.fc2_size, activation="relu", kernel_initializer="he_uniform")(dense_1)
    probs_logits = keras.layers.Dense(units=self.nb_actions, activation='softmax')(dense_2)
    masked_probs = keras.layers.Multiply()([probs_logits, valid_actions])
    probs = keras.layers.Lambda(lambda x: x / keras.backend.sum(x, axis=1))(masked_probs)
    
       def custom_loss(y_true, y_pred):
           out = keras.backend.clip(y_pred, 1e-8, 1 - 1e-8)
           log_lik = y_true * keras.backend.log(out)
           return keras.backend.sum(-log_lik * advantages)
    
     policy = keras.models.Model([inputs, advantages], [probs])
     policy.compile(optimizer=keras.optimizers.Adam(lr=self.alpha), loss=custom_loss)
     predict = keras.models.Model([inputs, valid_actions], [probs])
     return policy, predict

但是,当我注释掉 advantagesvalid_actions 输入层中的任何一个(当然,删除它们对应的行)时,我遇到了臭名昭著的错误 ValueError: Graph disconnected: cannot obtain value for tensor Tensor("input_3:0", shape=(None, 3), dtype=float32) at layer "multiply".,我可以成功运行代码。我应该提一下,valid_actions 输入层仅用于屏蔽无效概率,并且不需要进行损失计算。

如果有人可以帮助我,我真的很感激。

提前感谢您的宝贵时间

【问题讨论】:

    标签: tensorflow keras deep-learning reinforcement-learning


    【解决方案1】:

    您的损失还涉及advantages,因此您需要将其传递到损失中。你可以用.add_loss来做。

    policy 模型还需要 valid_actions 作为输入来生成 probs

    predict 模型看起来还可以,可以在推理时使用。

    这里是.add_loss 的完整示例。

    inputs = keras.layers.Input(shape=(30,))
    advantages = keras.layers.Input(shape=(1,))
    valid_actions = keras.layers.Input(shape=(3,))
    true = keras.layers.Input(shape=(3,))
    dense_1 = keras.layers.Dense(units=64, activation="relu", kernel_initializer="he_uniform")(inputs)
    dense_2 = keras.layers.Dense(units=32, activation="relu", kernel_initializer="he_uniform")(dense_1)
    probs_logits = keras.layers.Dense(units=3, activation='softmax')(dense_2)
    masked_probs = keras.layers.Multiply()([probs_logits, valid_actions])
    probs = keras.layers.Lambda(lambda x: x / keras.backend.sum(x, axis=1))(masked_probs)
    
    def custom_loss(y_true, y_pred, advantages):
        out = keras.backend.clip(y_pred, 1e-8, 1 - 1e-8)
        log_lik = y_true * keras.backend.log(out)
        return keras.backend.sum(-log_lik * advantages)
    
    policy = keras.models.Model([inputs, advantages, valid_actions, true], [probs])
    policy.add_loss( custom_loss(true, probs, advantages) )
    policy.compile(optimizer=keras.optimizers.Adam(lr=0.001), loss=None)
    predict = keras.models.Model([inputs, valid_actions], [probs])
    

    【讨论】:

      【解决方案2】:

      非常感谢MarcoCerliani 的时间和跟进,我终于成功地找到了解决问题的有效方法。错误是我修改了probs 输出层,这是损失计算所需的,valid_actions 输入层确实只需要predict 模型。正如this answer所说:

      Keras 不能仅仅忽略输入层,因为输出取决于它。

      我需要做的就是将probs_logitsvalid_actions 层未修改的输出层)传递给policy model 进行损失计算并传递probs 输出层(由valid actions 层操作)给predict model

      def __build_policy_network(self):
      
       // previous lines of code left unchanged
      
       policy = keras.models.Model([inputs, advantages], [probs_logits])
       policy.compile(optimizer=keras.optimizers.Adam(lr=self.alpha), loss=custom_loss)
       predict = keras.models.Model([inputs, valid_actions], [probs])
       return policy, predict
      

      【讨论】:

        猜你喜欢
        • 2019-04-07
        • 1970-01-01
        • 1970-01-01
        • 2017-07-25
        • 1970-01-01
        • 1970-01-01
        • 2019-10-08
        • 2020-03-28
        • 2023-03-27
        相关资源
        最近更新 更多