将"num_classes"从2减少到1,以便AUC/TF/TN/FP/FN度量有效



我有一些数据集,它们有两个类。当我尝试使用某些度量时——例如,tf.keras.metrics.AUCtf.keras.metrics.FalseNegativestf.keras.metrics.FalsePositivestf.keras.metrics.TrueNegativestf.keras.metrics.TruePositives——我会得到类似于的错误

ValueError: Shapes (None, None, None, 2) and (None, 1) are incompatible.

我想我可以使用tfa.metrics.MultiLabelConfusionMatrix并为PR和ROC编写自己的AUC。但说真的,我只有两节课。AFAIK,两个类相当于一个类。

如何将tfrecords分解为一个类?


完整地说,这里有一个完整的工作示例来重新创建这个错误,从导入、全局和争用开始:

from tempfile import mkdtemp
from os import path, mkdir
from shutil import rmtree
import tensorflow as tf
import numpy as np
from PIL import Image
NUM_CLASSES = 2
INPUT_SHAPE = 32, 32, 3

def create_random_ds(tempdir):
for class_num in range(NUM_CLASSES):
directory = path.join(tempdir, 'class{}'.format(class_num))
mkdir(directory)
for i in range(20):
Image 
.fromarray((np.random.rand(100,100,3) * 255).astype('uint8')) 
.convert('RGBA') 
.save(path.join(directory, 'image{}.png'.format(i)))
return tf.keras.preprocessing.image_dataset_from_directory(
tempdir, labels='inferred', label_mode='int',
)
tempdirs = mkdtemp(), mkdtemp()
train_dataset = create_random_ds(tempdirs[0])
validation_dataset = create_random_ds(tempdirs[1])

然后CNN模型构建:

model = tf.keras.Sequential([
tf.keras.layers.Conv2D(INPUT_SHAPE[0], (INPUT_SHAPE[-1], INPUT_SHAPE[-1]),
activation='relu', ),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.MaxPooling2D((2, 2)),
tf.keras.layers.Conv2D(64, (3, 3), activation='relu'),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(64, activation='relu'),
tf.keras.layers.Dense(NUM_CLASSES)
])

最后是肉:

try:
model.compile(loss=tf.keras.losses.BinaryCrossentropy(from_logits=False),
optimizer=tf.keras.optimizers.RMSprop(),
metrics=['accuracy', tf.keras.metrics.AUC(curve="PR")
])
model.fit(train_dataset,
epochs=2,
validation_data=validation_dataset)
finally:
for directory in tempdirs:
rmtree(directory)
ValueError: Shapes (None, 2) and (None, 1) are incompatible

由于您想将模型输出的形状从2更改为1,以下是您可以做的。

更改型号的最后一行

tf.keras.layers.Dense(NUM_CLASSES)

tf.keras.layers.Dense(1, activation='sigmoid')

这将使您的模型与AUC指标兼容。

另外,这里需要注意的是,两个类等价于一个类,但不等价于输出层的形状。你可以训练你的二进制分类模型,输出层有两个值,而不是一个,反之亦然,但在计算值时,你需要考虑形状。

相关内容

  • 没有找到相关文章

最新更新