获取标签和预测tf.math.confusion_matrix的错误

发布于 2025-02-11 00:26:25 字数 6595 浏览 0 评论 0原文

我在为我的二进制分类CNN模型生成混淆矩阵时遇到困难。我正在使用tf.math.confusion_matrix()函数来获取我的混乱矩阵,但是在定义标签预测参数方面遇到麻烦。谁能帮忙?

这是我从tf tutorial 产生我的混乱矩阵:和我的混乱矩阵:

import seaborn as sns
def predict_class_label_number(dataset):
  """Runs inference and returns predictions as class label numbers."""
  rev_label_names = {l: i for i, l in enumerate(class_names)}
  return [
      rev_label_names[o[0][0]]
      for o in model2.predict_top_k(dataset, batch_size=BATCH_SIZE)
  ]

def show_confusion_matrix(cm, labels):
  plt.figure(figsize=(10, 8))
  sns.heatmap(cm, xticklabels=labels, yticklabels=labels, 
              annot=True, fmt='g')
  plt.xlabel('Prediction')
  plt.ylabel('Label')
  plt.show()

confusion_mtx = tf.math.confusion_matrix(
    list(validation_dataset.map(lambda x, y: y)),
    predict_class_label_number(validation_dataset),
    num_classes=len(class_names))

show_confusion_matrix(confusion_mtx, class_names)

和和我收到以下错误:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-20-17f81800b34f> in <module>()
      1 confusion_mtx = tf.math.confusion_matrix(
      2     list(validation_dataset.map(lambda x, y: y)),
----> 3     predict_class_label_number(validation_dataset),
      4     num_classes=len(class_names))
      5 

<ipython-input-19-5d0965aa3d77> in predict_class_label_number(dataset)
      5   return [
      6       rev_label_names[o[0][0]]
----> 7       for o in model2.predict_top_k(dataset, batch_size=BATCH_SIZE)
      8   ]
      9 

AttributeError: 'Functional' object has no attribute 'predict_top_k'

错误代码提示我会遇到此错误,因为混淆矩阵代码期望功能模型,而我的是顺序的。但是我不知道如何修复它,因此任何帮助都将不胜感激!

这是我的完整代码以供参考:

from keras.callbacks import TensorBoard
import os
from os.path import exists

import tensorflow as tf

import matplotlib.pyplot as plt

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Variables
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
BATCH_SIZE = 16
IMG_SIZE = (160, 160)
directory = "/content/drive/MyDrive/Microscopy Data/05102022"
# training_directory = "/content/drive/MyDrive/Microscopy Data/03282022"
# validation_directory = "/content/drive/MyDrive/Microscopy Data/03282022_validation"

train_dataset = tf.keras.utils.image_dataset_from_directory(directory,
                                             shuffle=True,
                                             batch_size=BATCH_SIZE,
                                             image_size=IMG_SIZE,
                                             validation_split=0.2,
                                             subset='training',
                                             seed=42)
validation_dataset = tf.keras.utils.image_dataset_from_directory(directory,
                                             shuffle=True,
                                             batch_size=BATCH_SIZE,
                                             image_size=IMG_SIZE,
                                             validation_split=0.2,
                                             subset='validation',
                                             seed=42)
    
class_names = train_dataset.class_names
print( "class_names: " + str( class_names ) )

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Functions
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
def huvec_model (image_shape=IMG_SIZE, data_augmentation = tf.keras.Sequential([ tf.keras.layers.RandomFlip('horizontal'), tf.keras.layers.RandomRotation(0.2), ])):
# def huvec_model (image_shape=IMG_SIZE, data_augmentation=data_augmenter()):
    ''' Define a tf.keras model for binary classification out of the MobileNetV2 model
    Arguments:
    image_shape -- Image width and height
    data_augmentation -- data augmentation function
    Returns:
    Returns:
    tf.keras.model
    '''

    input_shape = image_shape + (3,)
    
    base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
        include_top=False,
        weights='imagenet')
    base_model.trainable = False
    inputs = tf.keras.Input(shape=input_shape)
    x = data_augmentation(inputs)
    x = preprocess_input(x)
    x = base_model(x, training=False)
    x = tf.keras.layers.GlobalAveragePooling2D()(x)
    x = tf.keras.layers.Dropout(.2)(x)
    prediction_layer = tf.keras.layers.Dense(units = 1, activation='sigmoid')

    outputs = prediction_layer(x) 
    model = tf.keras.Model(inputs, outputs)

    return model

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
DataSet
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)
preprocess_input = tf.keras.applications.mobilenet_v2.preprocess_input

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Model Initialize
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
IMG_SHAPE = IMG_SIZE + (3,)
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
            include_top=True,
            weights='imagenet')

# base_model.summary()

model2 = huvec_model(IMG_SIZE)

base_model.trainable = True
# Let's take a look to see how many layers are in the base model
print("Number of layers in the base model: ", len(base_model.layers))

# Fine-tune from this layer onwards
fine_tune_at = 120
base_learning_rate = 0.01

for layer in base_model.layers[:fine_tune_at]:
    layer.trainable = False
    
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Optimizer
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
optimizer = tf.keras.optimizers.Adam(learning_rate=0.1*base_learning_rate)

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Loss Fn
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""                               
lossfn = tf.keras.losses.BinaryCrossentropy(from_logits=False)

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Model Summary
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
model2.compile(optimizer=optimizer, loss=lossfn, metrics=[ 'accuracy' ])

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Training
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
history = model2.fit(train_dataset, validation_data=validation_dataset, epochs=10, callbacks=[cp_callback])

I am having trouble generating the confusion matrix for my binary classification CNN model. I am using tf.math.confusion_matrix() function to obtain my confusion matrix, but having trouble with defining labels and predictions arguments. Could anyone help?

Here is the code that I borrowed from a TF tutorial to generate my confusion matrix:

import seaborn as sns
def predict_class_label_number(dataset):
  """Runs inference and returns predictions as class label numbers."""
  rev_label_names = {l: i for i, l in enumerate(class_names)}
  return [
      rev_label_names[o[0][0]]
      for o in model2.predict_top_k(dataset, batch_size=BATCH_SIZE)
  ]

def show_confusion_matrix(cm, labels):
  plt.figure(figsize=(10, 8))
  sns.heatmap(cm, xticklabels=labels, yticklabels=labels, 
              annot=True, fmt='g')
  plt.xlabel('Prediction')
  plt.ylabel('Label')
  plt.show()

confusion_mtx = tf.math.confusion_matrix(
    list(validation_dataset.map(lambda x, y: y)),
    predict_class_label_number(validation_dataset),
    num_classes=len(class_names))

show_confusion_matrix(confusion_mtx, class_names)

and I am getting the following error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-20-17f81800b34f> in <module>()
      1 confusion_mtx = tf.math.confusion_matrix(
      2     list(validation_dataset.map(lambda x, y: y)),
----> 3     predict_class_label_number(validation_dataset),
      4     num_classes=len(class_names))
      5 

<ipython-input-19-5d0965aa3d77> in predict_class_label_number(dataset)
      5   return [
      6       rev_label_names[o[0][0]]
----> 7       for o in model2.predict_top_k(dataset, batch_size=BATCH_SIZE)
      8   ]
      9 

AttributeError: 'Functional' object has no attribute 'predict_top_k'

The error code hints that I'm getting this error because the confusion matrix code expects a functional model, whereas mine is sequential. But I have no clue how to fix it, so any help would be much appreciated!

Here is my complete code for reference:

from keras.callbacks import TensorBoard
import os
from os.path import exists

import tensorflow as tf

import matplotlib.pyplot as plt

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Variables
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
BATCH_SIZE = 16
IMG_SIZE = (160, 160)
directory = "/content/drive/MyDrive/Microscopy Data/05102022"
# training_directory = "/content/drive/MyDrive/Microscopy Data/03282022"
# validation_directory = "/content/drive/MyDrive/Microscopy Data/03282022_validation"

train_dataset = tf.keras.utils.image_dataset_from_directory(directory,
                                             shuffle=True,
                                             batch_size=BATCH_SIZE,
                                             image_size=IMG_SIZE,
                                             validation_split=0.2,
                                             subset='training',
                                             seed=42)
validation_dataset = tf.keras.utils.image_dataset_from_directory(directory,
                                             shuffle=True,
                                             batch_size=BATCH_SIZE,
                                             image_size=IMG_SIZE,
                                             validation_split=0.2,
                                             subset='validation',
                                             seed=42)
    
class_names = train_dataset.class_names
print( "class_names: " + str( class_names ) )

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
Functions
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
def huvec_model (image_shape=IMG_SIZE, data_augmentation = tf.keras.Sequential([ tf.keras.layers.RandomFlip('horizontal'), tf.keras.layers.RandomRotation(0.2), ])):
# def huvec_model (image_shape=IMG_SIZE, data_augmentation=data_augmenter()):
    ''' Define a tf.keras model for binary classification out of the MobileNetV2 model
    Arguments:
    image_shape -- Image width and height
    data_augmentation -- data augmentation function
    Returns:
    Returns:
    tf.keras.model
    '''

    input_shape = image_shape + (3,)
    
    base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
        include_top=False,
        weights='imagenet')
    base_model.trainable = False
    inputs = tf.keras.Input(shape=input_shape)
    x = data_augmentation(inputs)
    x = preprocess_input(x)
    x = base_model(x, training=False)
    x = tf.keras.layers.GlobalAveragePooling2D()(x)
    x = tf.keras.layers.Dropout(.2)(x)
    prediction_layer = tf.keras.layers.Dense(units = 1, activation='sigmoid')

    outputs = prediction_layer(x) 
    model = tf.keras.Model(inputs, outputs)

    return model

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
DataSet
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
AUTOTUNE = tf.data.experimental.AUTOTUNE
train_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)
preprocess_input = tf.keras.applications.mobilenet_v2.preprocess_input

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Model Initialize
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
IMG_SHAPE = IMG_SIZE + (3,)
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
            include_top=True,
            weights='imagenet')

# base_model.summary()

model2 = huvec_model(IMG_SIZE)

base_model.trainable = True
# Let's take a look to see how many layers are in the base model
print("Number of layers in the base model: ", len(base_model.layers))

# Fine-tune from this layer onwards
fine_tune_at = 120
base_learning_rate = 0.01

for layer in base_model.layers[:fine_tune_at]:
    layer.trainable = False
    
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Optimizer
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
optimizer = tf.keras.optimizers.Adam(learning_rate=0.1*base_learning_rate)

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Loss Fn
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""                               
lossfn = tf.keras.losses.BinaryCrossentropy(from_logits=False)

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Model Summary
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
model2.compile(optimizer=optimizer, loss=lossfn, metrics=[ 'accuracy' ])

"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
: Training
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""
history = model2.fit(train_dataset, validation_data=validation_dataset, epochs=10, callbacks=[cp_callback])

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

红ご颜醉 2025-02-18 00:26:25

并不是因为您的模型是顺序的,因此失败了。这是因为Tensorflow中没有model.predict_top_k方法。您可以检查方法部分在这里

您可以使用 tf.math.top_k .predict 获得所需的结果。

It's not that because your model is Sequential that it's failing. It's because there is no model.predict_top_k method in Tensorflow. You can check the methods section here.

You can use tf.math.top_k after using model.predict to get the result you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文