图像分类准确率低

数据挖掘 Python 神经网络 深度学习 喀拉斯 图像分类
2022-02-14 10:50:32

我有一个数据集,其中有两个用于训练和测试的文件夹。我正在尝试确定患者是否患有眼疾。但是,我所拥有的图像很难处理。我在下面运行了这段代码,通过更改时期、批量大小、添加更多 conv2D 和调整图像大小对其进行了调整,但准确度仍然很低。

我的猜测是精度很低,因为图像具有不同的高度(500px-1300px)(相同的宽度,但 496px)或者图像也有导致精度降低的倾斜。https://i.stack.imgur.com/2XUjJ.jpg

验证文件夹中有 3 个疾病和 1 个非疾病相关文件夹,每个文件夹包含 100 张图像(总共 400 张图像)训练文件夹包含大约:

  • 疾病 1 的 37,000 张图像
  • 疾病 2 的 11,000 张图像
  • 9,000 张疾病 3 图像
  • 27,000 张非疾病图像

关于我应该做些什么来提高准确性的任何反馈?

from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D,MaxPooling2D
from keras.layers import Activation,Dropout,Flatten,Dense
from keras import backend as K
import numpy as np
from keras.preprocessing import image

img_width, img_height= 496,900

train_data_dir='/content/drive/My Drive/Research/train'
validation_data_dir='/content/drive/My Drive/Research/validation'
nb_train_samples=1000
nb_validation_samples=100
epochs=10
batch_size=20

if K.image_data_format() == 'channels_first':
    input_shape=(3,img_width,img_height)
else:
    input_shape=(img_width,img_height,3)

train_datagen=ImageDataGenerator(
        rescale=1/255,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True)

test_datagen=ImageDataGenerator(rescale=1. /255)
train_generator=train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width,img_height),
        batch_size=batch_size,
        class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width,img_height),
    batch_size=batch_size,
    class_mode='binary')

############

model=Sequential()
model.add(Conv2D(64,(2,2),input_shape=input_shape))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.summary()

model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(32,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Conv2D(64,(3,3)))
model.add(Activation('relu'))
model.add(MaxPooling2D(pool_size=(2,2)))

model.add(Flatten())
model.add(Dense(64))
model.add(Activation('relu'))
model.add(Dropout(0.5))
model.add(Dense(1))
model.add(Activation('softmax'))

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

model.fit_generator(
        train_generator,
        steps_per_epoch=nb_train_samples // batch_size,
        epochs=epochs,
        validation_data=validation_generator,
        validation_steps=nb_validation_samples // batch_size)


model.save_weights('first_try.h5')

Epoch 1/10
50/50 [==============================] - 919s 18s/step - loss: -4.7993 - accuracy: 0.1400 - val_loss: -7.6246 - val_accuracy: 0.2500
Epoch 2/10
50/50 [==============================] - 902s 18s/step - loss: -5.1060 - accuracy: 0.1440 - val_loss: -9.9120 - val_accuracy: 0.2300
Epoch 3/10
50/50 [==============================] - 914s 18s/step - loss: -4.4773 - accuracy: 0.1200 - val_loss: -5.3372 - val_accuracy: 0.2700
Epoch 4/10
50/50 [==============================] - 879s 18s/step - loss: -3.8793 - accuracy: 0.1390 - val_loss: -4.5748 - val_accuracy: 0.2500
Epoch 5/10
50/50 [==============================] - 922s 18s/step - loss: -4.4160 - accuracy: 0.1470 - val_loss: -7.6246 - val_accuracy: 0.2200
Epoch 6/10
50/50 [==============================] - 917s 18s/step - loss: -3.9253 - accuracy: 0.1310 - val_loss: -11.4369 - val_accuracy: 0.3100
Epoch 7/10
50/50 [==============================] - 907s 18s/step - loss: -4.2166 - accuracy: 0.1230 - val_loss: -7.6246 - val_accuracy: 0.2200
Epoch 8/10
50/50 [==============================] - 882s 18s/step - loss: -3.6493 - accuracy: 0.1480 - val_loss: -7.6246 - val_accuracy: 0.2500
Epoch 9/10
50/50 [==============================] - 926s 19s/step - loss: -3.5266 - accuracy: 0.1330 - val_loss: -7.6246 - val_accuracy: 0.3300
Epoch 10/10
50/50 [==============================] - 932s 19s/step - loss: -5.2440 - accuracy: 0.1430 - val_loss: -13.7243 - val_accuracy: 0.2100
2个回答

您想要做的是多类分类,但是损失和您的网络是为二进制分类而设计的。

改变:

train_generator=train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width,img_height),
        batch_size=batch_size,
        class_mode='binary')
validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width,img_height),
    batch_size=batch_size,
    class_mode='binary')

到:

train_generator=train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width,img_height),
        batch_size=batch_size,
        class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width,img_height),
    batch_size=batch_size,
    class_mode='categorical')

这应该使您的生成器从您的文件夹结构中生成正确的标签。

并改变:

model.add(Dense(1))
model.add(Activation('softmax'))

到:

model.add(Dense(4))
model.add(Activation('softmax'))

4 用于层中的输出节点,应对应于您的不同类别、疾病 1-3 和非疾病。

然后也改变:

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

到:

model.compile(loss='categorical_crossentropy',
                    optimizer='rmsprop',
                    metrics=['accuracy'])

这会将您的损失函数从二进制更改为多类。

也许清理你的数据集?Fastai 有一些很好的工具——你基本上从数据中删除了最有把握分类错误的图像。稍后我可以使用一些代码示例进行扩展。

编辑:

我说的功能是

ds, idxs = DatasetFormatter().from_toplosses(learn)

它打开了一个交互式工具,用于重新标记/删除最有把握分类错误的图像(因此导致最高损失)。

是文档。是一个很好的教程