使用tf.estimator的自定义指标

mst*_*ger 5 python tensorflow tensorflow-estimator

我想在我的估算器评估期间使用tensorflow来计算确定系数(R平方).我试图以下面的方式基于官方指标的实现松散地实现它:

def r_squared(labels, predictions, weights=None,
              metrics_collections=None,
              updates_collections=None,
              name=None):

    total_error = tf.reduce_sum(tf.square(labels - tf.reduce_mean(labels)))
    unexplained_error = tf.reduce_sum(tf.square(labels - predictions))
    r_sq = 1 - tf.div(unexplained_error, total_error)

    # update_rsq_op = ?

    if metrics_collections:
        ops.add_to_collections(metrics_collections, r_sq)

    # if updates_collections:
    #     ops.add_to_collections(updates_collections, update_rsq_op)

    return r_sq #, update_rsq_op
Run Code Online (Sandbox Code Playgroud)

然后,我将此函数用作EstimatorSpec中的度量标准:

estim_specs = tf.estimator.EstimatorSpec(
    ...
    eval_metric_ops={
        'r_squared': r_squared(labels, predictions),
        ...
    })
Run Code Online (Sandbox Code Playgroud)

但是,由于我的R平方实现没有返回update_op,因此失败了.

TypeError: Values of eval_metric_ops must be (metric_value, update_op) tuples, given: Tensor("sub_4:0", dtype=float64) for key: r_squared
Run Code Online (Sandbox Code Playgroud)

现在我想知道,update_op究竟应该做什么?我是否真的需要实现update_op,还是可以以某种方式创建某种虚拟update_op?如果有必要,我该如何实施呢?

mst*_*ger 8

好的,所以我能够搞清楚.我可以将度量标准包装在一个平均度量中并使用其update_op.这似乎对我有用.

def r_squared(labels, predictions, weights=None,
              metrics_collections=None,
              updates_collections=None,
              name=None):

    total_error = tf.reduce_sum(tf.square(labels - tf.reduce_mean(labels)))
    unexplained_error = tf.reduce_sum(tf.square(labels - predictions))
    r_sq = 1 - tf.div(unexplained_error, total_error)

    m_r_sq, update_rsq_op = tf.metrics.mean(r_sq)

    if metrics_collections:
        ops.add_to_collections(metrics_collections, m_r_sq)

    if updates_collections:
        ops.add_to_collections(updates_collections, update_rsq_op)

    return m_r_sq, update_rsq_op
Run Code Online (Sandbox Code Playgroud)