我想使用
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分数的代码。可以转换吗?
有一种方法可以解决这个问题,将 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
,情况可能会有所不同。