python - 使用 ResNet50,验证准确性和损失不会改变

标签 python tensorflow keras resnet cnn

我正在尝试使用 ResNet50 进行图像识别在 Python ( keras ) 中。我试图用 VGG16 做同样的任务,我得到了一些这样的结果(对我来说似乎没问题):
resultsVGG16 .训练和验证的准确率/损失函数每一步都在变好,因此网络必须学习。

但是,与 ResNet50训练函数更好,而验证函数没有改变:resultsResNet

我两次都使用了相同的代码和数据,只是模型发生了变化。

那么ResNet50的原因是什么?只学习训练数据?

我的 ResNet 模型如下所示:

'''Python

model = Sequential()
base_model = VGG16(weights='imagenet', include_top=False,input_shape= 
(image_size,image_size,3))
for layer in base_model.layers[:-4]:
    layer.trainable=False

model.add(base_model)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(NUM_CLASSES, activation='softmax'))

VGG 非常相似:
model = Sequential()
base_model = ResNet50(include_top=False, weights='imagenet', input_shape= 
(image_size,image_size,3))
for layer in base_model.layers[:-8]:
     layer.trainable=False

model.add(base_model)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.4))
model.add(Dense(NUM_CLASSES, activation='softmax'))

最佳答案

您的模型没有错误,但这可能是 ResNet 的问题。因此,由于提出了很多问题,1 , 2 , 3 ,在 Github 和 Stack Overflow 上,已经关于这个预训练模型。

话虽如此,我找到了一种解决方法,它对我有用,希望对你也有用。

解决方法是替换数据增强步骤,

Train_Datagen = ImageDataGenerator(rescale=1./255,  rotation_range=40, width_shift_range=0.2,
    height_shift_range=0.2, brightness_range=(0.2, 0.7), shear_range=45.0, zoom_range=60.0,
    horizontal_flip=True, vertical_flip=True)

Val_Datagen = ImageDataGenerator(rescale=1./255,  rotation_range=40, width_shift_range=0.2,
    height_shift_range=0.2, brightness_range=(0.2, 0.7), shear_range=45.0, zoom_range=60.0,
    horizontal_flip=True, vertical_flip=True)

tf.keras.applications.resnet.preprocess_input , 如下所示:
Train_Datagen = ImageDataGenerator(dtype = 'float32', preprocessing_function=tf.keras.applications.resnet.preprocess_input)
Val_Datagen = ImageDataGenerator(dtype = 'float32', preprocessing_function=tf.keras.applications.resnet.preprocess_input)

通过修改 Data Augmentation如上图所示,我卡在 50% 的验证准确率逐渐提高到 97%。这样做的原因可能是 ResNet 可能需要特定的预处理操作(不太确定)。

使用 ResNet50 产生超过 95% 的训练和验证准确度(对于猫和狗数据集)的完整工作代码如下所示:
import tensorflow as tf
from tensorflow.keras.applications import ResNet50
import os
import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.layers import Dense, Dropout, Flatten
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential

# The Convolutional Base of the Pre-Trained Model will be added as a Layer in this Model
Conv_Base = ResNet50(include_top = False, weights = 'imagenet', input_shape = (150,150, 3))

for layer in Conv_Base.layers[:-8]:
    layer.trainable = False

model = Sequential()
model.add(Conv_Base)
model.add(Flatten())
model.add(Dense(units = 256, activation = 'relu'))
model.add(Dropout(0.5))
model.add(Dense(units = 1, activation = 'sigmoid'))

model.summary()

base_dir = 'Deep_Learning_With_Python_Book/Dogs_Vs_Cats_Small'
if os.path.exists(base_dir):    
    train_dir = os.path.join(base_dir, 'train')
    validation_dir = os.path.join(base_dir, 'validation')
    test_dir = os.path.join(base_dir, 'test')
else:
    print("The Folder, {}, doesn't exist'".format(base_dir))

batch_size = 20

Train_Datagen = ImageDataGenerator(dtype = 'float32', preprocessing_function=tf.keras.applications.resnet.preprocess_input)
Val_Datagen = ImageDataGenerator(dtype = 'float32', preprocessing_function=tf.keras.applications.resnet.preprocess_input)

train_gen = Train_Datagen.flow_from_directory(directory = train_dir, target_size = (150,150), 
                                       batch_size = batch_size, class_mode = 'binary')

val_gen = Val_Datagen.flow_from_directory(directory = validation_dir, target_size = (150,150), 
                                       batch_size = batch_size, class_mode = 'binary')

epochs = 15
Number_Of_Training_Images = train_gen.classes.shape[0]
steps_per_epoch = Number_Of_Training_Images/batch_size

model.compile(optimizer = 'Adam', loss = 'binary_crossentropy', metrics = ['accuracy'])

history = model.fit(train_gen, epochs = epochs, 
                    #batch_size = batch_size,
                    validation_data = val_gen, steps_per_epoch = steps_per_epoch)

import matplotlib.pyplot as plt

train_acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
train_loss = history.history['loss']
val_loss = history.history['val_loss']
No_Of_Epochs = range(epochs)

plt.plot(No_Of_Epochs, train_acc, marker = 'o', color = 'blue', markersize = 12, 
                 linewidth = 2, label = 'Training Accuracy')
plt.plot(No_Of_Epochs, val_acc, marker = '.', color = 'red', markersize = 12, 
                 linewidth = 2, label = 'Validation Accuracy')

plt.title('Training Accuracy and Testing Accuracy w.r.t Number of Epochs')

plt.legend()

plt.figure()

plt.plot(No_Of_Epochs, train_loss, marker = 'o', color = 'blue', markersize = 12, 
                 linewidth = 2, label = 'Training Loss')
plt.plot(No_Of_Epochs, val_acc, marker = '.', color = 'red', markersize = 12, 
                 linewidth = 2, label = 'Validation Loss')

plt.title('Training Loss and Testing Loss w.r.t Number of Epochs')

plt.legend()

plt.show()

指标如下图所示,

enter image description here

关于python - 使用 ResNet50,验证准确性和损失不会改变,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61230762/

相关文章:

javascript - PhantomJS 的行为不同于 Firefox webdriver

tensorflow - 使用conda安装后如何升级tensorflow?

tensorflow - 加载数据时删除/跳过记录

python - 神经网络输出与输出层偏置权重完全相关(Keras)

python - 在 seq2seq 模型中添加更多层

python - 在 Keras 上正确构建模型

python - 如何计算2个目录路径之间的相对路径?

python - nltk 词语料库不包含 "okay"?

python - 生成所有可能的 n 维 k*k*...*k 数组,每个数组沿轴有一排

python - 如何在 TensorFlow 中定义加权损失函数?