【问题标题】:Why is my resnet50 model in Keras not converging?为什么我在 Keras 中的 resnet50 模型不收敛?
【发布时间】:2020-11-30 17:53:32
【问题描述】:

我目前正在尝试在缺陷和非缺陷图像中对集成电路进行分类。我已经尝试过 VGG16 和 InceptionV3 并且两者都得到了非常好的结果(95% 的验证准确率和低 val 损失)。现在我想尝试 resnet50,但我的模型没有收敛。它的准确率也达到了 95 %,但验证损失不断增加,而 val acc 卡在 50 %。

到目前为止,这是我的脚本:

from keras.applications.resnet50 import ResNet50
from keras.optimizers import Adam
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D, Dropout
from keras import backend as K
from keras_preprocessing.image import ImageDataGenerator
import tensorflow as tf

class ResNet:
    def __init__(self):
        self.img_width, self.img_height = 224, 224  # Dimensions of cropped image
        self.classes_num = 2  # Number of classifications

        # Training configurations
        self.epochs = 32
        self.batch_size = 16  # Play with this to determine number of images to train on per epoch
        self.lr = 0.0001

    def build_model(self, train_path):
        train_data_path = train_path
        train_datagen = ImageDataGenerator(rescale=1. / 255, validation_split=0.25)

        train_generator = train_datagen.flow_from_directory(
            train_data_path,
            target_size=(self.img_height, self.img_width),
            color_mode="rgb",
            batch_size=self.batch_size,
            class_mode='categorical',
            subset='training')

        validation_generator = train_datagen.flow_from_directory(
            train_data_path,
            target_size=(self.img_height, self.img_width),
            color_mode="rgb",
            batch_size=self.batch_size,
            class_mode='categorical',
            subset='validation')

        # create the base pre-trained model
        base_model = ResNet50(weights='imagenet', include_top=False, input_shape=    (self.img_height, self.img_width, 3))

        # add a global spatial average pooling layer
        x = base_model.output
        x = GlobalAveragePooling2D()(x)
        # let's add a fully-connected layer
        x = Dense(1024, activation='relu')(x)
        #x = Dropout(0.3)(x)
        # and a logistic layer -- let's say we have 200 classes
        predictions = Dense(2, activation='softmax')(x)

        # this is the model we will train
        model = Model(inputs=base_model.input, outputs=predictions)

        # first: train only the top layers (which were randomly initialized)
        # i.e. freeze all convolutional InceptionV3 layers
        for layer in base_model.layers:
            layer.trainable = True

        # compile the model (should be done *after* setting layers to non-trainable)
        opt = Adam(self.lr)  # , decay=self.INIT_LR / self.NUM_EPOCHS)
        model.compile(opt, loss='binary_crossentropy', metrics=["accuracy"])

        # train the model on the new data for a few epochs
        from keras.callbacks import ModelCheckpoint, EarlyStopping
        import matplotlib.pyplot as plt

        checkpoint = ModelCheckpoint('resnetModel.h5', monitor='val_accuracy', verbose=1, save_best_only=True,
                                 save_weights_only=False, mode='auto', period=1)

        early = EarlyStopping(monitor='val_accuracy', min_delta=0, patience=16, verbose=1, mode='auto')
        hist = model.fit_generator(steps_per_epoch=self.batch_size, generator=train_generator,
                               validation_data=validation_generator, validation_steps=self.batch_size, epochs=self.epochs,
                               callbacks=[checkpoint, early])

        plt.plot(hist.history['accuracy'])
        plt.plot(hist.history['val_accuracy'])
        plt.plot(hist.history['loss'])
        plt.plot(hist.history['val_loss'])
        plt.title("model accuracy")
        plt.ylabel("Accuracy")
        plt.xlabel("Epoch")
        plt.legend(["Accuracy", "Validation Accuracy", "loss", "Validation Loss"])
        plt.show()

        plt.figure(1)

import tensorflow as tf

if __name__ == '__main__':
    x = ResNet()
    config = tf.compat.v1.ConfigProto()
    config.gpu_options.allow_growth = True
    sess = tf.compat.v1.Session(config=config)
    x.build_model("C:/Users/but/Desktop/dataScratch/Train")

这就是模型的训练

除了 vgg 和 inception 正常工作之外,resnet 失败的原因可能是什么? 我的脚本有错误吗?

【问题讨论】:

    标签: python keras deep-learning resnet transfer-learning


    【解决方案1】:

    至少对于代码,我没有看到任何可能影响训练过程的错误。

    # and a logistic layer -- let's say we have 200 classes
    predictions = Dense(2, activation='softmax')(x)
    

    这些台词有点可疑。不过好像是评论里的错字,应该没问题吧。

    # first: train only the top layers (which were randomly initialized)
    # i.e. freeze all convolutional InceptionV3 layers
    for layer in base_model.layers:
        layer.trainable = True
    

    这些也很可疑。如果你想冻结 ResNet-50 的层,你需要做的是

    ...
    base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(self.img_height, self.img_width, 3))
    for layer in base_model.layers:
        layer.trainable = False
    ...
    

    但事实证明layer.trainable = True实际上是你的意图,所以也没关系。

    首先,如果您使用的是用于训练 VGG16 和 Inception V3 的相同代码,则代码不太可能是问题所在。

    您为什么不检查以下易受感染的原因?

    • 模型可能太小/太大以至于它欠拟合/过拟合。 (参数数量)
    • 模型可能需要更多时间才能收敛。 (训练更多时期)
    • ResNet 可能不适合这种分类。
    • 您使用的预训练权重可能不适合此分类。
    • 学习率可能太小/太大。
    • 等等...

    【讨论】:

    • 感谢您的回答!您所说的模型可能太小/太大是什么意思?有更多的时间来收敛你意味着更多的时代吗?学习率是什么?我应该改变它,因为它可能太小了吗?是的,我认为权重不合适,但后来我发现 inception 和 vgg 正在工作很奇怪。
    • @NECben067 是的,“更多时间收敛”我的意思是“更多时代”。我所说的“模型可能太小/太大”是指参数的数量。 (我认为在这种情况下这不是问题,因为您正在进行迁移学习,但谁知道呢。)您也可以尝试不同的学习率。
    • 好的,我现在就试试。当我将所有层设置为可训练时,它仍然是迁移学习吗?我想可能冻结前 x 层并训练最后 y 层,但我不完全知道要冻结哪些层以及要训练哪些层。我也收到此警告:用户警告:ResNet50(include_top=False) 的输出形状自 Keras 2.2.0 以来已更改。 warnings.warn('ResNet50(include_top=False) 的输出形状' 但这会是我不知道的问题。
    • @NECben067 我很确定它仍然是迁移学习。您也可以尝试在最后添加另一个全连接层。我也不确定如何冻结前 x 层并训练最后 y,但您可以通过谷歌搜索轻松找到如何做这些事情。我认为 UserWarning 不是问题。
    • @NECben067 我认为layer.trainable = True 不是你想要的。尝试删除 layer.trainable = True for 循环。并将其写在base_model = ResNet50(weights='imagenet', include_top=False, input_shape= (self.img_height, self.img_width, 3)) 下,但这次使用layer.trainable = False
    猜你喜欢
    • 2020-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-26
    • 2018-06-27
    • 1970-01-01
    • 2017-10-28
    • 2016-02-16
    相关资源
    最近更新 更多