tensorflow添加自定义的auc计算operator
tensorflow可以很方便的添加用户自定义的operator(如果不添加也可以采用sklearn的auc计算函数或者自己写一个
但是会在python执行,这里希望在graph中也就是c++端执行这个计算)
这里根据工作需要添加一个计算auc的operator,只给出最简单实现,后续高级功能还是参考官方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过程,即插即用。
首先auc的operator计算的文件
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"
using
namespace tensorflow;
using
std::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");
class
AucOp : public OpKernel {
public:
explicit
AucOp(OpKernelConstruction* context) : OpKernel(context) {}
template<typename
ValueVec>
void
index_sort(const
ValueVec& valueVec, vector<int>& indexVec)
{
indexVec.resize(valueVec.size());
for (size_t
i = 0; i < indexVec.size(); i++)
{
indexVec[i] = i;
}
std::sort(indexVec.begin(), indexVec.end(),
[&valueVec](const
int
l, const
int
r) { return
valueVec(l) > valueVec(r); });
}
void
Compute(OpKernelContext* context) override {
// Grab the input tensor
const Tensor& predicts_tensor = context->input(0);
const Tensor& labels_tensor = context->input(1);
auto
predicts = predicts_tensor.flat<float>(); //输入能接受float double那么这里如何都处理?
auto
labels = labels_tensor.flat<float>();
vector<int> indexes;
index_sort(predicts, indexes);
typedef
float
Float;
Float
oldFalsePos = 0;
Float
oldTruePos = 0;
Float
falsePos = 0;
Float
truePos = 0;
Float
oldOut = std::numeric_limits<Float>::infinity();
Float
result = 0;
for (size_t
i = 0; i < indexes.size(); i++)
{
int
index = indexes[i];
Float
label = labels(index);
Float
prediction = predicts(index);
Float
weight = 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);
Float
AUC = 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
tensorflow添加自定义的auc计算operator的更多相关文章
- AUC计算 - 进阶操作
首先AUC值是一个概率值,当你随机挑选一个正样本以及负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值,AUC值越大,当前分类算法越有可能将正样本排在负样本前 ...
- ROC 曲线,以及AUC计算方式
ROC曲线: roc曲线:接收者操作特征(receiveroperating characteristic),roc曲线上每个点反映着对同一信号刺激的感受性. ROC曲线的横轴: 负正类率(false ...
- AUC计算 - 手把手步进操作
2017-07-10 14:38:24 理论参考: 评估分类器性能的度量,像混淆矩阵.ROC.AUC等 http://www.cnblogs.com/suanec/p/5941630.html ROC ...
- 110、TensorFlow张量值的计算
import tensorflow as tf #placeholders在没有提供具体值的时候不能使用eval方法来计算它的值 # 另外的建模方法可能会使得模型变得复杂 # TensorFlow 不 ...
- TensorFlow两种方式计算Cross Entropy
sparse_softmax_cross_entropy_with_logits与softmax_cross_entropy_with_logits import tensorflow as tf y ...
- 学习笔记TF067:TensorFlow Serving、Flod、计算加速,机器学习评测体系,公开数据集
TensorFlow Serving https://tensorflow.github.io/serving/ . 生产环境灵活.高性能机器学习模型服务系统.适合基于实际数据大规模运行,产生多个模型 ...
- tensorflow入门教程和底层机制简单解说——本质就是图计算,自动寻找依赖,想想spark机制就明白了
简介 本章的目的是让你了解和运行 TensorFlow! 在开始之前, 让我们先看一段使用 Python API 撰写的 TensorFlow 示例代码, 让你对将要学习的内容有初步的印象. 这段很短 ...
- 机器学习的敲门砖:手把手教你TensorFlow初级入门
摘要: 在开始使用机器学习算法之前,我们应该首先熟悉如何使用它们. 而本文就是通过对TensorFlow的一些基本特点的介绍,让你了解它是机器学习类库中的一个不错的选择. 本文由北邮@爱可可-爱生活 ...
- TensorFlow基础笔记(6) 图像风格化实验
参考 http://blog.csdn.net/wspba/article/details/53994649 https://www.ctolib.com/AdaIN-style.html Ackno ...
随机推荐
- asp.net mvc后台操作之读写xml控制首页动态页面开关显示
一.背景 在asp.net mvc项目里,用户需要开拓几个活动版面,并以侧栏的方式呈现在首页右侧,几个活动时间不一致,为避免浏览者在活动未开放之时进入未开放的服务页面.因此不仅需要在活动代码中加入限制 ...
- Linux--目录结构解释(转)
/ root --- 启动Linux时使用的一些核心文件.如操作系统内核.引导程序Grub等. home --- 存储普通用户的个人文件 ftp --- 用户所有服务 httpd samba user ...
- python的正则表达式
1 元字符: 1.1 . .除了换行符以外的任何单个字符 1.2 ^ ^只匹配起始字符 temp1=re.findall('^morra','nsudi werwuirnmorra') temp2=r ...
- [HAOI2009]求回文串
神奇到爆炸的贪心,策略很简单.但是实现上好像比较恶心.换了一种思路.先保存所有点应该转移到的位置,BIT搞个逆序对就好了. 如何找到每个点应该转移到的位置?这个处理方式也是比较玄学.看代码吧. //O ...
- for循环递归树
protected string _menu = string.Empty; public void FirstAnsyData() { try { // List<object> lsN ...
- [NHibernate]立即加载
目录 写在前面 文档与系列文章 立即加载 一个例子 总结 写在前面 上篇文章介绍了nhibernate延迟加载的相关内容,简单回顾一下延迟加载,就是需要的时候再去加载,需要的时候再向数据库发出sql指 ...
- Java 排序算法实现
package test; import java.util.Scanner; public class JavaSort { public static void quickSort(int a[] ...
- [译]reset, checkout和revert
git reset, git checkout, git revert能让你撤销你本地仓储的一些修改, 前两种命令可以作用于commit或者一个文件. Commit级别的操作 注意了git reve ...
- PHP图像裁剪为任意大小的图像,图像不变形,不留下空白
<?php /** * 说明:函数功能是把一个图像裁剪为任意大小的图像,图像不变形 * 参数说明:输入 需要处理图片的 文件名,生成新图片的保存文件名,生成新图片的宽,生成新图片的高 */ fu ...
- Java 串口通信
在Windows系统下,用Java开发串口通信相关的程序时,需要用到几个文件. (1)win32com.dll 要放在jdk\jre\bin目录下. (2)comm.jar 和javax.comm.p ...