tensorflow - 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 等),但这也无济于事。
也许有人有一个可以帮助我的想法。提前致谢!
解决方案
我认为您需要正确调整模型的超参数。为此,我建议尝试使用Keras Tuner库。这将需要一些时间来运行,但会为您获取正确的超参数集。
推荐阅读
- javascript - 一键提交多个表单(动态创建),每个表单可以单独提交
- vue.js - 隐藏特定标题及其在 vuetify 数据表中的对应列
- c++ - 调用 google::cloud::storage::Client 时出现 json.exception.parse_error
- java - Java中Android Studio上的问题映射
- google-maps - 谷歌地图在打印时打印灰色
- mysql - MySQL - 在选择中包含许多案例语句的查询非常慢
- java - file.toByteArray() 方法有什么作用?
- twilio - Twilio Video - 切换媒体设备选项不起作用
- twitter-bootstrap - 为什么 col-auto 内包含多列的嵌套行的大小大于内容宽度?
- postgresql - 文本数组上的 Postgres 唯一索引