无法将tensorflow.python.framework.ops.Tensor对象转换为numpy数组以将其传递到sklearn.metrics.cohen_kappa_score函数

问题描述 投票:0回答:1

我想使用

sklearn.metrics.cohen_kappa_score

来实现 kappaScore 指标
def kappaScore(y_true,y_pred):
    k = cohen_kappa_score(y_true,y_pred,weights='quadratic')
    return k

当我尝试运行此代码时出现错误:

OperatorNotAllowedInGraphError: in user code:

    /opt/conda/lib/python3.7/site-packages/keras/engine/training.py:853 train_function  *
        return step_function(self, iterator)
    /tmp/ipykernel_33/1006337667.py:2 kappaScore  *
        k = cohen_kappa_score(y_true,y_pred,weights='quadratic')
    /opt/conda/lib/python3.7/site-packages/sklearn/utils/validation.py:555 inner_f  *
        return f(**kwargs)
    /opt/conda/lib/python3.7/site-packages/sklearn/metrics/_classification.py:600 cohen_kappa_score  *
        confusion = confusion_matrix(y1, y2, labels=labels,
    /opt/conda/lib/python3.7/site-packages/sklearn/utils/validation.py:555 inner_f  *
        return f(**kwargs)
    /opt/conda/lib/python3.7/site-packages/sklearn/metrics/_classification.py:276 confusion_matrix  *
        y_type, y_true, y_pred = _check_targets(y_true, y_pred)
    /opt/conda/lib/python3.7/site-packages/sklearn/metrics/_classification.py:81 _check_targets  *
        check_consistent_length(y_true, y_pred)
    /opt/conda/lib/python3.7/site-packages/sklearn/utils/validation.py:253 check_consistent_length  *
        uniques = np.unique(lengths)
    <__array_function__ internals>:6 unique  **
        
    /opt/conda/lib/python3.7/site-packages/numpy/lib/arraysetops.py:261 unique
        ret = _unique1d(ar, return_index, return_inverse, return_counts)
    /opt/conda/lib/python3.7/site-packages/numpy/lib/arraysetops.py:322 _unique1d
        ar.sort()
    /opt/conda/lib/python3.7/site-packages/tensorflow/python/framework/ops.py:900 __bool__
        self._disallow_bool_casting()
    /opt/conda/lib/python3.7/site-packages/tensorflow/python/framework/ops.py:504 _disallow_bool_casting
        "using a `tf.Tensor` as a Python `bool`")
    /opt/conda/lib/python3.7/site-packages/tensorflow/python/framework/ops.py:491 _disallow_when_autograph_enabled
        " indicate you are trying to use an unsupported feature.".format(task))

    OperatorNotAllowedInGraphError: using a `tf.Tensor` as a Python `bool` is not allowed: AutoGraph did convert this function. This might indicate you are trying to use an unsupported feature.

这里

y_true
y_pred
的类型需要在列表或numpy数组中

但是

y_true
y_pred
的类型是,

y_true: <class 'tensorflow.python.framework.ops.Tensor'>
y_pred: <class 'tensorflow.python.framework.ops.Tensor'>

当直接尝试打印它时(即没有 type() 函数),它显示如下:

y_true: Tensor("IteratorGetNext:1", shape=(None, None), dtype=float32)
y_pred: Tensor("sequential_5/dense_5/Softmax:0", shape=(None, 5), dtype=float32)

无法使用

y_true.numpy()
在Tensorflow中将张量转换为numpy数组?)和
tf.make_ndarray(y_true)
https://www.tensorflow.org/api_docs/python/tf/make_ndarray#:~:text=tf .make_ndarray(proto_tensor))尝试过..

如何以可以传递给 sklearn.metrics.cohen_kappa_score 函数的方式转换这些数据类型? 我不想写kappa分数的代码。可以转换吗?

python numpy tensorflow scikit-learn deep-learning
1个回答
0
投票

有一种方法可以解决这个问题,将 cohen_kappa_score 包装在

tf.py_function
中。它在tensorflow 2.x中可用,但我不知道从哪个版本的框架开始;
py_function
为您完成所有繁重的工作,将 Python 函数包装到急切执行它的 TensorFlow 操作中。

import tensorflow as tf
import numpy as np
from sklearn.metrics import cohen_kappa_score


def cohen_kappa_score_wrapper(y_true, y_pred):
  y_pred = np.argmax(y_pred, axis=1)
  return cohen_kappa_score(y_true, y_pred, weights='quadratic')


def kappaScore(y_true, y_pred):
  return tf.py_function(
      func=cohen_kappa_score_wrapper,
      inp=[y_true, y_pred],
      Tout=tf.float32
    )


model.compile('adam', 'sparse_categorical_crossentropy', metrics=[kappaScore])

首先,定义

cohen_kappa_score_wrapper
。这很重要,因为最后一个密集层通常会返回每个样本的每个类别的概率数组。但 Cohen kappa 分数接受类的整数标签,因此必须将概率转换为带有
np.argmax()
的标签。我们仍然在 Python 的领域,所以可以只使用 numpy 函数。

然后用

cohen_kappa_score_wrapper
包裹
py_function
:参见
kappaScore

使用 MNIST 的完整示例:

import keras 
import tensorflow as tf
from keras.layers import Input, LSTM, RepeatVector, TimeDistributed, Dense
from keras import Model
import numpy as np

from sklearn.metrics import cohen_kappa_score
from keras.datasets import mnist

(x_train, x_test), (y_train, y_test) = mnist.load_data()
model = keras.Sequential([
   keras.layers.Flatten(),
   keras.layers.Dense(128, activation='relu'),
   keras.layers.Dense(10, activation='softmax'),
])

def cohen_kappa_score_wrapper(y_true, y_pred):
  y_pred = np.argmax(y_pred, axis=1)
  return cohen_kappa_score(y_true, y_pred, weights='quadratic')


def kappaScore(y_true, y_pred):
  return tf.py_function(
      func=cohen_kappa_score_wrapper,
      inp=[y_true, y_pred], #  weights='quadratic']
      Tout=tf.float32
    )

model.compile('adam', 'sparse_categorical_crossentropy', metrics=[kappaScore])
model.fit(x_train / 255., x_test)
60000/60000 [==============================] - 5s 90us/sample - loss: 0.2612 - kappaScore: 0.9202
<keras.callbacks.History at 0x7fcea289cc50>

注意 尽管docs声明包装函数会急切执行,但如果我关闭急切执行,它仍然对我有用:

tf.compat.v1.disable_eager_execution()
。我用
tf2.7
。但我对其他版本的框架/不同的环境不太有信心。有时可能会很棘手。另外,如果您使用
tf1.x
,情况可能会有所不同。

© www.soinside.com 2019 - 2024. All rights reserved.