繁体   English   中英

使用 VGG16 预训练模型处理灰度图像时出错

[英]Error while using VGG16 pretrained model for grayscale images

我正在使用带有灰度图像的 VGG16 预训练模型进行手语检测。 当我尝试运行 model.fit 命令时,出现以下错误。

澄清

我已经有 RGB 形式的图像,但我想将它们用作灰度来检查它们是否适用于灰度。 原因是,对于彩色图像,我没有得到我期望的准确性。 它仅具有最大 40% 的测试准确度,并且在数据集上过度拟合。

错误信息

另外,这是我的模型命令

vgg = VGG16(input_shape= [128, 128] + [3], weights='imagenet', include_top=False)

这是我的 model.fit 命令

history = model.fit(
  train_x,
  train_y,
  epochs=15,
  validation_data=(test_x, test_y),
  callbacks=[early_stop, checkpoint],
  batch_size=32,shuffle=True)

我是使用预训练模型的新手。 当我尝试使用具有 3 个通道的彩色图像运行代码时,我的模型正在过度拟合并且 val_accuracy 没有上升到 40% 以上,所以我想尝试灰度图像,因为我添加了许多数据增强技术,但准确度是没有改善。 欢迎任何线索,因为我现在已经坚持了很长时间。

我能想到的最简单(也可能是最快)的解决方案是将图像转换为 rgb。 您可以将此作为模型的一部分。

model = Sequential([
  tf.keras.layers.Lambda(tf.image.grayscale_to_rgb),
  vgg
])

这将解决您的 VGG 问题。 我还看到您缺少图像的最后一个维度。 灰度图像的形状应为[height, width, 1] ,但您只需拥有[height, width] 您可以使用tf.expand_dims解决此问题:

model = Sequential([
  tf.keras.layers.Lambda(
    lambda x: tf.image.grayscale_to_rgb(tf.expand_dims(x, -1))
  ),
  vgg,
])

请注意,此解决方案解决了图中的问题,因此它在线运行。 这意味着,在运行时,您可以以与现在完全相同的方式提供数据(形状为[128, 128] ,没有通道维度),并且它仍然可以正常工作。 如果这是您在运行时所期望的维度,那么这将比在将数据投入模型之前对其进行操作要快。

顺便说一句,考虑到 VGG 经过专门训练以最好地处理彩色图像,这一切都不是理想的。 只是觉得我应该补充一点。

为什么你会过度拟合?

也许出于不同的原因:

  1. 您的图像和标签在火车 Val 测试中并不相同。 (也许你在训练中有图像但没有在测试中。)或者你的训练,Val,测试数据没有正确分层,你在数据和特征的特定区域训练你的模型。
  2. 您的数据集非常小,您需要更多数据。
  3. 也许你的数据中有噪音,首先确保从数据集中去除噪音。 (如果你有噪音,模型适合你的噪音。)

如何将灰度图像输入到VGG16

对于使用VGG16 ,您需要输入 3 通道图像。 出于这个原因,您需要像下面这样连接您的图像以从灰度中获取三个通道图像:

image = tf.concat([image, image, image], -1)

在来自fashion_mnist数据集的灰度图像上训练VGG16的示例:

from tensorflow.keras.applications.vgg16 import VGG16
import tensorflow_datasets as tfds
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np

train, val, test = tfds.load(
    'fashion_mnist',
    shuffle_files=True, 
    as_supervised=True, 
    split = ['train[:85%]', 'train[85%:]', 'test']
)

def resize_preprocess(image, label):
    image = tf.image.resize(image, (32, 32))
    image = tf.concat([image, image, image], -1)
    image = tf.keras.applications.densenet.preprocess_input(image)
    return image, label
    

train = train.map(resize_preprocess, num_parallel_calls=tf.data.AUTOTUNE)
test  = test.map(resize_preprocess, num_parallel_calls=tf.data.AUTOTUNE)
val   = val.map(resize_preprocess, num_parallel_calls=tf.data.AUTOTUNE)


train = train.repeat(15).batch(64).prefetch(tf.data.AUTOTUNE)
test = test.batch(64).prefetch(tf.data.AUTOTUNE)
val  = val.batch(64).prefetch(tf.data.AUTOTUNE)


base_model = VGG16(weights="imagenet", include_top=False, input_shape=(32,32,3))
base_model.trainable = False ## Not trainable weights


model = tf.keras.Sequential()
model.add(base_model)
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(1024, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=.4))    
model.add(tf.keras.layers.Dense(256, activation='relu'))
model.add(tf.keras.layers.Dropout(rate=.4))
model.add(tf.keras.layers.Dense(10, activation='sigmoid'))        
model.compile(loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),
              optimizer='Adam', 
              metrics=['accuracy'])
model.summary()

fit_callbacks = [tf.keras.callbacks.EarlyStopping(
    monitor='val_accuracy', patience = 4, restore_best_weights = True)]

history = model.fit(train, steps_per_epoch=150, epochs=5, batch_size=64, validation_data=val, callbacks=fit_callbacks)
model.evaluate(test)

输出:

Model: "sequential_17"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 vgg16 (Functional)          (None, 1, 1, 512)         14714688  
                                                                 
 flatten_3 (Flatten)         (None, 512)               0         
                                                                 
 dense_9 (Dense)             (None, 1024)              525312    
                                                                 
 dropout_6 (Dropout)         (None, 1024)              0         
                                                                 
 dense_10 (Dense)            (None, 256)               262400    
                                                                 
 dropout_7 (Dropout)         (None, 256)               0         
                                                                 
 dense_11 (Dense)            (None, 10)                2570      
                                                                 
=================================================================
Total params: 15,504,970
Trainable params: 790,282
Non-trainable params: 14,714,688
_________________________________________________________________
Epoch 1/5
150/150 [==============================] - 6s 35ms/step - loss: 0.8056 - accuracy: 0.7217 - val_loss: 0.5433 - val_accuracy: 0.7967
Epoch 2/5
150/150 [==============================] - 4s 26ms/step - loss: 0.5560 - accuracy: 0.7965 - val_loss: 0.4772 - val_accuracy: 0.8224
Epoch 3/5
150/150 [==============================] - 4s 26ms/step - loss: 0.5287 - accuracy: 0.8080 - val_loss: 0.4698 - val_accuracy: 0.8234
Epoch 4/5
150/150 [==============================] - 5s 32ms/step - loss: 0.5012 - accuracy: 0.8149 - val_loss: 0.4334 - val_accuracy: 0.8329
Epoch 5/5
150/150 [==============================] - 4s 25ms/step - loss: 0.4791 - accuracy: 0.8315 - val_loss: 0.4312 - val_accuracy: 0.8398
157/157 [==============================] - 2s 15ms/step - loss: 0.4457 - accuracy: 0.8325
[0.44566288590431213, 0.8324999809265137]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM