tensorflow添加自定义的auc计算operator

本文介绍如何在 TensorFlow 中添加自定义的 AUC 计算 Operator,通过 C++ 编写并编译为插件形式,直接在计算图中执行以提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

tensorflow添加自定义的auc计算operator

tensorflow可以很方便的添加用户自定义的operator(如果不添加也可以采用sklearnauc计算函数或者自己写一个但是会在python执行,这里希望在graph中也就是c++端执行这个计算)

这里根据工作需要添加一个计算aucoperator,只给出最简单实现,后续高级功能还是参考官方wiki

https://www.tensorflow.org/versions/r0.7/how_tos/adding_an_op/index.html

注意tensorflow现在和最初的官方wiki有变化,原wiki貌似是需要重新bazel编译整个tensorflow,然后使用比如tf.user_op.auc这样。

目前wiki给出的方式>=0.6.0版本,采用plug-in的方式,更加灵活可以直接用g++编译一个so载入,解耦合,省去了编译tensorflow过程,即插即用。

  

首先aucoperator计算的文件

  

tensorflow/core/user_ops/auc.cc

  

/* Copyright 2015 Google Inc. All Rights Reserved.

  

Licensed under the Apache License, Version 2.0 (the "License");

you may not use this file except in compliance with the License.

You may obtain a copy of the License at

  

http://www.apache.org/licenses/LICENSE-2.0

  

Unless required by applicable law or agreed to in writing, software

distributed under the License is distributed on an "AS IS" BASIS,

WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and

limitations under the License.

==============================================================================*/

  

// An auc Op.

  

#include"tensorflow/core/framework/op.h"

#include"tensorflow/core/framework/op_kernel.h"

  

usingnamespace tensorflow;

usingstd::vector;

//@TODO add weight as optional input

REGISTER_OP("Auc")

.Input("predicts: T1")

.Input("labels: T2")

.Output("z: float")

.Attr("T1: {float, double}")

.Attr("T2: {float, double}")

//.Attr("T1: {float, double}")

//.Attr("T2: {int32, int64}")

.SetIsCommutative()

.Doc(R"doc(

Given preidicts and labels output it's auc

)doc");

  

classAucOp : public OpKernel {

public:

explicitAucOp(OpKernelConstruction* context) : OpKernel(context) {}

  

template<typenameValueVec>

voidindex_sort(constValueVec& valueVec, vector<int>& indexVec)

{

indexVec.resize(valueVec.size());

for (size_ti = 0; i < indexVec.size(); i++)

{

indexVec[i] = i;

}

std::sort(indexVec.begin(), indexVec.end(),

[&valueVec](constintl, constintr) { returnvalueVec(l) > valueVec(r); });

}

  

voidCompute(OpKernelContext* context) override {

// Grab the input tensor

const Tensor& predicts_tensor = context->input(0);

const Tensor& labels_tensor = context->input(1);

autopredicts = predicts_tensor.flat<float>(); //输入能接受float double那么这里如何都处理?

autolabels = labels_tensor.flat<float>();

  

vector<int> indexes;

index_sort(predicts, indexes);

typedeffloatFloat;

  

FloatoldFalsePos = 0;

FloatoldTruePos = 0;

FloatfalsePos = 0;

FloattruePos = 0;

FloatoldOut = std::numeric_limits<Float>::infinity();

Floatresult = 0;

  

for (size_ti = 0; i < indexes.size(); i++)

{

intindex = indexes[i];

Floatlabel = labels(index);

Floatprediction = predicts(index);

Floatweight = 1.0;

//Pval3(label, output, weight);

if (prediction != oldOut) //存在相同值得情况是特殊处理的

{

result += 0.5 * (oldTruePos + truePos) * (falsePos - oldFalsePos);

oldOut = prediction;

oldFalsePos = falsePos;

oldTruePos = truePos;

}

if (label > 0)

truePos += weight;

else

falsePos += weight;

}

result += 0.5 * (oldTruePos + truePos) * (falsePos - oldFalsePos);

FloatAUC = result / (truePos * falsePos);

  

// Create an output tensor

Tensor* output_tensor = NULL;

TensorShape output_shape;

  

OP_REQUIRES_OK(context, context->allocate_output(0, output_shape, &output_tensor));

output_tensor->scalar<float>()() = AUC;

}

};

  

REGISTER_KERNEL_BUILDER(Name("Auc").Device(DEVICE_CPU), AucOp);

  

  

编译:

$cat gen-so.sh

  

TF_INC=$(python -c 'import tensorflow as tf; print(tf.sysconfig.get_include())')

TF_LIB=$(python -c 'import tensorflow as tf; print(tf.sysconfig.get_lib())')

i=$1

o=${i/.cc/.so}

g++ -std=c++11 -shared $i -o $o -I $TF_INC -l tensorflow_framework -L $TF_LIB -fPIC -Wl,-rpath $TF_LIB

  

$sh gen-so.sh auc.cc

会生成auc.so

  

使用的时候

auc_module = tf.load_op_library('auc.so')

#auc = tf.user_ops.auc #0.6.0之前的tensorflow 自定义op方式

auc = auc_module.auc

  

evaluate_op = auc(py_x, Y) #py_x is predicts, Y is labels
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值