Tensorflow提取分类预测

我有一个用于分类独热编码组标签的神经网络模型(组是互斥的),其结尾是(layerActivs[-1]是最后一层的激活):

probs = sess.run(tf.nn.softmax(layerActivs[-1]),...)classes = sess.run(tf.round(probs))preds = sess.run(tf.argmax(classes))

tf.round被用来将任何低概率强制设为0。如果某一观测的所有概率都低于50%,这意味着不会预测任何类。例如,如果有4个类,我们可能会有probs[0,:] = [0.2,0,0,0.4],因此classes[0,:] = [0,0,0,0];接着preds[0] = 0

显然这是模糊的,因为如果我们有probs[1,:]=[.9,0,.1,0] -> classes[1,:] = [1,0,0,0] -> preds[1] = 0,结果会是一样的。这在使用Tensorflow内置的度量类时是个问题,因为这些函数无法区分没有预测和预测为类0的情况。这段代码展示了这一点:

import numpy as npimport tensorflow as tfimport pandas as pd''' prepare '''classes = 6n = 100# simulate datanp.random.seed(42)simY = np.random.randint(0,classes,n)     # pretend actual datasimYhat = np.random.randint(0,classes,n)  # pretend pred datatruth = np.sum(simY == simYhat)/ntabulate = pd.Series(simY).value_counts()# create placeholderslab = tf.placeholder(shape=simY.shape, dtype=tf.int32)prd = tf.placeholder(shape=simY.shape, dtype=tf.int32)AM_lab = tf.placeholder(shape=simY.shape,dtype=tf.int32)AM_prd = tf.placeholder(shape=simY.shape,dtype=tf.int32)# create one-hot encoding objectssimYOH = tf.one_hot(lab,classes)# create accuracy objectsacc = tf.metrics.accuracy(lab,prd)            # real accuracy with tf.metricsaccOHAM = tf.metrics.accuracy(AM_lab,AM_prd)  # OHE argmaxed to labels - expected to be correct# now setup to pretend we ran a model & generated OHE predictions all unclassedz = np.zeros(shape=(n,classes),dtype=float)testPred = tf.constant(z)''' run it all '''# setupsess = tf.Session()sess.run([tf.global_variables_initializer(),tf.local_variables_initializer()])# real accuracy with tf.metricsACC = sess.run(acc,feed_dict = {lab:simY,prd:simYhat})# OHE argmaxed to labels - expected to be correct, but is it?l,p = sess.run([simYOH,testPred],feed_dict={lab:simY})p = np.argmax(p,axis=-1)ACCOHAM = sess.run(accOHAM,feed_dict={AM_lab:simY,AM_prd:p})sess.close()''' print stuff '''print('Accuracy')print('-known truth: %0.4f'%truth)print('-on unprocessed data: %0.4f'%ACC[1])print('-on faked unclassed labels data (s.b. 0%%): %0.4f'%ACCOHAM[1])print('----------\nTrue Class Freqs:\n%r'%(tabulate.sort_index()/n))

其输出为:

Accuracy-known truth: 0.1500-on unprocessed data: 0.1500-on faked unclassed labels data (s.b. 0%): 0.1100----------True Class Freqs:0    0.111    0.192    0.113    0.254    0.175    0.17dtype: float64Note freq for class 0 is same as faked accuracy...

我尝试将没有预测的观测的preds值设为np.nan,但tf.metrics.accuracy抛出ValueError: cannot convert float NaN to integer;我也尝试了np.inf,但得到OverflowError: cannot convert float infinity to integer

如何将四舍五入的概率转换为类预测,同时适当处理未预测的观测?


回答:

这个问题已经很久没有答案了,所以我在这里发布我的解决方案。我通过一个包含三个主要步骤的新函数将归属概率转换为类预测:

  1. 将任何NaN概率设为0
  2. 将任何低于1/num_classes的概率设为0
  3. 使用np.argmax()提取预测类,然后将任何未分类的观测随机设为一个类

结果得到的整数类标签向量可以传递给tf.metrics函数。以下是我的函数:

def predFromProb(classProbs):  '''  Take in as input an (m x p) matrix of m observations' class probabilities in  p classes and return an m-length vector of integer class labels (0...p-1).   Probabilities at or below 1/p are set to 0, as are NaNs; any unclassed  observations are randomly assigned to a class.  '''  numClasses = classProbs.shape[1]  # zero out class probs that are at or below chance, or NaN  probs = classProbs.copy()  probs[np.isnan(probs)] = 0  probs = probs*(probs > 1/numClasses)  # find any un-classed observations  unpred = ~np.any(probs,axis=1)  # get the predicted classes  preds = np.argmax(probs,axis=1)  # randomly classify un-classed observations  rnds = np.random.randint(0,numClasses,np.sum(unpred))  preds[unpred] = rnds  return preds

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注