首页 > 解决方案 > 优化 Keras CNN

问题描述

我无法提高 CNN 的准确性和减少损失。

以下是一些初始参数:

batch_size  = 32
image_shape = 150 # Sizes input to 150x150
EPOCHS      = 250
STEPS_PER_EPOCH = 7
IMAGES_IN_CLASS_FOLDERS > 100

我将训练和验证集设置为相同的图像,但我对训练图像进行了预处理,因此验证图像不一样:

# Image formatting - Preprocessing images into floating point tensors before being fed into the network
        # Generator for our training data       - Rescales the image, Flips Images Horizontally, Rotates it
        train_image_generator      = ImageDataGenerator(rescale=1./255, horizontal_flip=True, rotation_range=45)
        # Generator for our validation data     - Rescales the image
        validation_image_generator = ImageDataGenerator(rescale=1./255)
        # Applies scaling and resizing
        train_data_gen = train_image_generator.flow_from_directory(batch_size=batch_size,
                                                                   directory=training_Images,
                                                                   shuffle=True,
                                                                   target_size=(image_shape,image_shape), #(100,100)
                                                                   class_mode='categorical')
        val_data_gen = validation_image_generator.flow_from_directory(batch_size=batch_size,
                                                                      directory=validate_Images,
                                                                      shuffle=True             ,
                                                                      target_size=(image_shape, image_shape),
                                                                      class_mode='categorical')
              

此外,我有一个 Sequential 模型,我尝试了各种参数,例如输入CONV2D(32) -> CONV2D(64) -> CONV2D(128),但我目前正在测试这个模型,但没有成功:

# Defining our model
        model = tf.keras.models.Sequential([
            # Old Method #
            tf.keras.layers.Conv2D(8 , (2,2) , activation='LeakyReLU', input_shape=(image_shape, image_shape, 3)),
            tf.keras.layers.Conv2D(16, (2,2) , activation='LeakyReLU'),
            tf.keras.layers.Conv2D(32, (2,2) , activation='LeakyReLU'),
            tf.keras.layers.MaxPooling2D(2,2),
            tf.keras.layers.Conv2D(40, (2,2) , activation='LeakyReLU'),
            tf.keras.layers.Conv2D(56, (2,2) , activation='LeakyReLU'),
            tf.keras.layers.Conv2D(64, (2,2) , activation='LeakyReLU'),
            tf.keras.layers.MaxPooling2D(2,2),
            tf.keras.layers.Conv2D(96, (2,2) , activation='LeakyReLU'),
            tf.keras.layers.Conv2D(128, (2,2), activation='LeakyReLU'),
            tf.keras.layers.MaxPooling2D(2,2),
            tf.keras.layers.Flatten(),
            tf.keras.layers.Dense(16, activation='softmax'),
            #tf.keras.layers.Dense(128, activation='relu'),
            #tf.keras.layers.Dense(512, activation='relu'),
            tf.keras.layers.Dense(120)
            # End Old Method #
            ])

我尝试了各种CONV2D层,各种激活方法。这是model.compile:

        model.compile(optimizer=SGD(lr=0.01),
                      loss=tf.keras.losses.CategoricalCrossentropy(),
                      metrics=['accuracy'])

我正在使用SGD Optimizer,我尝试过ADAM但结果相似。Loss减少了加班,但似乎达到了一定的值范围并停滞不前,没有增加Accuracy

模型.fit:

        history = model.fit(
            train_data_gen,
            steps_per_epoch= stepForEpoch,
            epochs=EPOCHS,
            validation_data=val_data_gen,
            validation_steps=stepForEpoch
        )

任何人都可以就如何提高准确性和进一步减少损失提供一些提示或指出正确的方向吗?谢谢!

结果图片 在此处输入图像描述

最终更新 截至2021 年 6月 23 日,我的模型正在显着改进,不仅有更多的 EPOCHS,而且还有更多的 STEPS_PER_EPOCH:

在此处输入图像描述

在此处输入图像描述

像这样除以图像的数量(IMAGES_IN_DATASET(20700) / BATCH_SIZE(32) = 677 STEPS_PER_EPOCH)并选择 100 个 EPOCHS 进行测试,我得到的准确度值增加了 + 10%,并且随着 MSE 的改进,损失不断减少。

ACCURACY_INCREASE = %10
MSE_IMPROVEMENT   = -0.0004
ACCURACY_LOSS_IMPROVEMENT = -1.1

感谢用户@Reda El Hail @Dr。史努比

标签: pythontensorflowmachine-learningkeras

解决方案


总结评论中的讨论,错误来自未设置激活函数的最后一层tf.keras.layers.Dense(120)

对于分类任务,它应该是tf.keras.layers.Dense(120, activation = 'softmax').

正如@Snoopysoftmax宣布的那样:在隐藏层中使用是没有意义的。它应该只用于输出层。


推荐阅读