首页 > 解决方案 > 将使用可训练参数在层中定义的损失包含在最终损失中以进行优化

问题描述

您好我正在尝试创建一个 VariationalDenseLayer,其中 KL 损失在调用函数中计算。

def call(self, inputs, **kwargs):
    kernel_sigma = tf.math.softplus(self.kernel_rho)
    kernel = self.kernel_mu + kernel_sigma * tf.random.normal(self.kernel_mu.shape)

    bias_sigma = tf.math.softplus(self.bias_rho)
    bias = self.bias_mu + bias_sigma * tf.random.normal(self.bias_mu.shape)

    self.add_loss(self.kl_loss(kernel, self.kernel_mu, kernel_sigma) +
                  self.kl_loss(bias, self.bias_mu, bias_sigma))

    outputs = gen_math_ops.MatMul(a = inputs, b = kernel)

    if self.use_bias:
        outputs = nn_ops.bias_add(outputs, bias)

    if self.activation is not None:
        outputs = self.activation(outputs)

    return outputs


def kl_loss(self, w, mu, sigma):
    variational_dist = tfp.distributions.Normal(mu, sigma)
    return self.kl_weight * K.sum(variational_dist.log_prob(w) - self.log_prior_prob(w))

def log_prior_prob(self, w):
    comp_1_dist = tfp.distributions.Normal(0.0, self.prior_sigma_1)
    comp_2_dist = tfp.distributions.Normal(0.0, self.prior_sigma_2)
    return K.log(self.prior_pi_1 * comp_1_dist.prob(w) +
                 self.prior_pi_2 * comp_2_dist.prob(w))
    

但是,当我尝试将最终损失定义为 neg_log_likelihhood + kl_loss 时出现以下错误:

TypeError:函数构建代码之外的操作正在传递一个“图形”张量。通过在函数构建代码中包含 tf.init_scope ,可以使 Graph 张量从函数构建上下文中泄漏。例如,以下函数将失败:@tf.function def has_init_scope(): my_constant = tf.constant(1.) with tf.init_scope(): added = my_constant * 2 图张量的名称为:dense_flipout/divergence_kernel:0

如果我添加

tf.compat.v1.disable_eager_execution()

我有跟随错误。但是,我仍然不清楚我做错了什么。

loss = neg_log_likelihood + kl * kl_weight 文件“/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/ops/math_ops.py”,第 1266 行,在 r_binary_op_wrapper y 中, x = maybe_promote_tensors(y, x) 文件“/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/ops/math_ops.py”,第 1202 行,在 maybe_promote_tensors 操作中.convert_to_tensor(tensor, dtype, name="x")) 文件 "/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/profiler/trace.py",第 163 行,在包装的 return func(*args, **kwargs) 文件“/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/framework/ops.py”中,第 1566 行,在 convert_to_tensor ret = conversion_func(value, dtype=dtype, name=name, as_ref=as_ref) 文件中“/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/framework/constant_op.py”,第 339 行,在 _constant_tensor_conversion_function 返回常量(v,dtype=dtype,name=名称)文件“/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/framework/constant_op.py”,第 264 行,不断返回 _constant_impl(value, dtype,形状,名称,verify_shape=False,文件“/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/framework/constant_op.py”,第 281 行,在 _constant_impl tensor_util .make_tensor_proto(文件“/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/framework/tensor_util.py”,第457行,在make_tensor_proto_AssertCompatible(值,dtype)文件 ”/d/dev01/chungh/lib2/anaconda3-2020.11/lib/python3.8/site-packages/tensorflow/python/framework/tensor_util.py”,第 336 行,在 _AssertCompatible raise TypeError(“预期 %s,得到 %s '%s' 类型。”% TypeError: 预期的 float32,在 0x2aab06930b80> 处得到了 'function' 类型的 <function neg_log_likelihood>。

计算最终损失的代码是:

def neg_log_likelihood(y_obs, y_pred, sigma=noise):
    dist = tfp.distributions.Normal(loc=y_pred, scale=sigma)
    return K.sum(-dist.log_prob(y_obs))

kl = sum(model.losses)
loss = kl * kl_weight

model.compile(loss=loss, optimizer=optimizers.Adam(lr=0.08), metrics=['mse'])

非常感谢任何帮助和指示!

标签: pythontensorflowtensorflow-probability

解决方案


我假设你已经检查了Tensorflow 中的变分层实现

您可以参考这个使用 FlipOut 层的示例实现。


推荐阅读