【问题标题】:bad results on binary classification with very little data数据很少的二元分类结果不佳
【发布时间】:2018-03-04 23:29:52
【问题描述】:

我只有141张图片,每个班级71张(医学图片) 我想对它们进行分类。我知道这是非常少的数据,所以我想使用增强。

我的问题是即使在使用增强的训练数据上,我也无法通过 0.5 的准确度!

当我只训练 141 张图像时,我可以达到 80%,所以这一定意味着我使用了错误的增强?

如果有人能理解我做错了什么,我会很高兴:

我的模特:

from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import optimizers
K.clear_session()
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(256,256,1)))
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(2, activation='softmax'))


sgd = optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True)

model.compile(loss='categorical_crossentropy',
              optimizer=sgd,
              metrics=['accuracy'])
#normalize
meanImg = np.mean(X , axis = 0)
stdImg = np.std(X , axis = 0)
X_norm = (X - meanImg)  / (stdImg + 0.0001)


# we will split again without normalizing, the DataGenerator will normalize
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X_norm, y,test_size=0.2)
train_datagen = ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    zoom_range = 0.2,
    height_shift_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(featurewise_center=True,
                                 featurewise_std_normalization = True)

train_datagen.fit(X_train)
test_datagen.fit(X_test)
train_generator = train_datagen.flow(X_train,y_train,batch_size = 16 , save_to_dir='train',save_prefix='aug')
validation_generator = test_datagen.flow(X_test,y_test,batch_size =16 , save_to_dir='test' , save_prefix = 'aug')

这会产生不好的结果:

batch_size = 16
model.fit_generator(
        train_generator,
        steps_per_epoch=2000// batch_size,
        epochs=10,
        validation_data=validation_generator,
        validation_steps=400 // batch_size)
model.save_weights('first_try.h5')  # always save your weights after training or during training

这给出了很好的结果:

history = model.fit(X_train, y_train, batch_size=16,
          epochs=20, verbose=1, validation_split=0.2)

【问题讨论】:

  • 只是出于好奇:你为什么要适应train_datagentest_datagen,然后用fit_generatorfit() 训练?这似乎没有任何意义。我还建议使用flow_from_directory 并通过您的几个样本不断增加。

标签: deep-learning keras classification


【解决方案1】:

我会首先使用更简单的网络并尝试获得重要的结果。此外,请尝试使用适合训练集的相同数据生成器作为测试集。

另外:您是否真的在两种情况下都应用了相同的预处理?我隐约记得featurewise_centerfeaturewise_std_normalization 经常以错误的方式应用......只需禁用增强(以及其他选项),看看会发生什么。然后你可以断定你的扩充是否错误。

另请参阅:Debugging neural networks

【讨论】:

  • 我确实使用了更简单的网络。我在训练数据上获得了近乎完美的分数,但在验证上却不是很好。换句话说,过拟合。这就是为什么我尝试使用更多数据进行增强
  • 您一次只能更改一件事。使用更简单的网络但使用增强功能会发生什么?
【解决方案2】:

尝试添加更多的卷积层或增加卷积过滤器的内核。 您使用 3 个带有 3x3 过滤器的 conv 层,因此您的感受野只有 7x7。

我也建议使用 BatchNormalization:

model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(256,256,1), activation='relu'))
BatchNormalization(axis=1)
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(32, (3, 3), activation='relu'))
BatchNormalization(axis=1),
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
BatchNormalization(axis=1),
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(64), activation='relu')
BatchNormalization(axis=1)
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))

【讨论】:

    猜你喜欢
    • 2017-06-28
    • 2020-09-10
    • 2021-09-06
    • 2013-11-08
    • 2019-08-14
    • 1970-01-01
    • 2020-07-18
    • 2013-03-06
    • 1970-01-01
    相关资源
    最近更新 更多