首页 > 解决方案 > Keras CNN:图像的多标签分类

问题描述

我对深度学习相当陌生,并且在使用 keras 卷积神经网络执行多标签图像分类任务时遇到了一些问题。这些主要是指评估执行多标签分类任务的 keras 模型。我将对此进行一些结构化,以便首先获得更好的概述。

问题描述

底层数据集是来自不同类型的专辑封面图像。就我而言,这些是电子、摇滚、爵士、流行、嘻哈。所以我们有 5 个可能的类,它们不是互斥的。任务是预测给定专辑封面的可能类型。每个专辑封面的大小为 300 像素 x 300 像素。图像被加载到 tensorflow 数据集中,大小调整为 150px x 150px。 训练、验证和测试数据中的数据集分布。

模型架构

该模型的架构如下。

import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential

data_augmentation = keras.Sequential(
  [
    layers.experimental.preprocessing.RandomFlip("horizontal", 
                                                 input_shape=(img_height, 
                                                              img_width,
                                                              3)),
   layers.experimental.preprocessing.RandomFlip("vertical"),
    layers.experimental.preprocessing.RandomRotation(0.4),
   layers.experimental.preprocessing.RandomZoom(height_factor=(0.2, 0.6), width_factor=(0.2, 0.6))
  ]
)

def create_model(num_classes=5, augmentation_layers=None):
  model = Sequential()

  # We can pass a list of layers performing data augmentation here
  if augmentation_layers:
    # The first layer of the augmentation layers must define the input shape
    model.add(augmentation_layers)
    model.add(layers.experimental.preprocessing.Rescaling(1./255))
  else:
    model.add(layers.experimental.preprocessing.Rescaling(1./255, input_shape=(img_height, img_width, 3)))

  model.add(layers.Conv2D(32, (3, 3), activation='relu'))
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Conv2D(64, (3, 3), activation='relu'))
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Conv2D(128, (3, 3), activation='relu'))
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Conv2D(128, (3, 3), activation='relu'))
  model.add(layers.MaxPooling2D((2, 2)))
  model.add(layers.Flatten())
  model.add(layers.Dense(512, activation='relu'))

  # Use sigmoid activation function. Basically we train binary classifiers for each class by specifiying binary crossentropy loss and sigmoid activation on the output layer.
  model.add(layers.Dense(num_classes, activation='sigmoid'))
  model.summary()

  return model

我在这里没有使用通常的指标,比如标准精度。在本文中,我读到您无法使用通常的方法评估多标签分类模型。在第 7 章评估指标中,展示了我用于该模型的汉明损失和调整后的准确度(精确匹配的变体)。

汉明损失已经由 tensorflow-addons(见这里)和我在这里找到的子集精度的实现(见这里)提供。

from tensorflow_addons.metrics import HammingLoss

hamming_loss = HammingLoss(mode="multilabel", threshold=0.5)

def subset_accuracy(y_true, y_pred):
    # From https://stackoverflow.com/questions/56739708/how-to-implement-exact-match-subset-accuracy-as-a-metric-for-keras

    threshold = tf.constant(.5, tf.float32)
    gtt_pred = tf.math.greater(y_pred, threshold)
    gtt_true = tf.math.greater(y_true, threshold)
    accuracy = tf.reduce_mean(tf.cast(tf.equal(gtt_pred, gtt_true), tf.float32), axis=-1)
    return accuracy

 # Create model
 model = create_model(num_classes=5, augmentation_layers=data_augmentation)

 # Compile model  
 model.compile(loss="binary_crossentropy", optimizer="adam", metrics=[subset_accuracy, hamming_loss])

 # Fit the model
 history = model.fit(training_dataset, epochs=epochs, validation_data=validation_dataset, callbacks=callbacks)

这个模型有问题

在训练模型时,subset_accuracy hamming_loss 有时会卡住,如下所示: 培训历史 什么可能导致这种行为。老实说,我现在有点失落。这可能是垂死的relu问题的案例吗?或者是错误使用了提到的指标,还是这些指标的实施可能是错误的?

到目前为止,我尝试测试不同的优化器并降低学习率(例如从 0.01 到 0.001、0.0001 等),但这也无济于事。

也许有人有一个可以帮助我的想法。提前致谢!

标签: tensorflowkerasmultilabel-classificationimage-classification

解决方案


我认为您需要正确调整模型的超参数。为此,我建议尝试使用Keras Tuner库。这将需要一些时间来运行,但会为您获取正确的超参数集。


推荐阅读