验证准确性低且训练准确度高-keras imagedatagenerator flow_from_directory类别分类

时间:2018-09-10 04:42:41

标签: python image keras

我正在尝试使用Keras和ResNet50将Kaggle 10k狗图像分类为120个品种。由于Kaggle(14gb ram)的内存限制,我必须使用ImageDataGenerator,该ImageDataGenerator可以将图像实时馈送到模型中,并且还可以实时进行数据扩充。

基本的卷积ResNet50模型:

conv_base = ResNet50(weights='imagenet', include_top=False, input_shape=(224,224, 3))

我的模特:

model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(120, activation='softmax'))

确保只有我最后添加的图层是可训练的-因此,在训练过程和编译模型中不会修改ResNet50原始权重:

conv_base.trainable = False
model.compile(optimizer=optimizers.Adam(), loss='categorical_crossentropy',metrics=['accuracy'])

Num trainable weights BEFORE freezing the conv base: 216
Num trainable weights AFTER freezing the conv base: 4

最后的模型摘要:

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
resnet50 (Model)             (None, 1, 1, 2048)        23587712  
_________________________________________________________________
flatten_1 (Flatten)          (None, 2048)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 256)               524544    
_________________________________________________________________
dropout_1 (Dropout)          (None, 256)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 120)               30840     
=================================================================
Total params: 24,143,096
Trainable params: 555,384
Non-trainable params: 23,587,712
_________________________________________________________________

train和validation目录每个都有120个子目录-每个犬种一个。在这些文件夹中是狗的图像。 Keras应该使用这些目录为每个图像获取正确的标签:因此Keras会自动对“ beagle”子目录中的图像进行分类-无需进行一次热编码或类似的编码。

train_dir = '../input/dogs-separated/train_dir/train_dir/'
validation_dir = '../input/dogs-separated/validation_dir/validation_dir/'

train_datagen = ImageDataGenerator(rescale=1./255)
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow_from_directory(
train_dir,target_size=(224, 224),batch_size=20, shuffle=True)
validation_generator = test_datagen.flow_from_directory(
validation_dir,target_size=(224, 224),batch_size=20, shuffle=True)

Found 8185 images belonging to 120 classes.
Found 2037 images belonging to 120 classes.

为了确保这些类正确且顺序正确,我比较了它们的train_generator.class_indices和validation_generator.class_indices-它们是相同的。 训练模型:

history = model.fit_generator(train_generator,
steps_per_epoch=8185 // 20,epochs=10,
validation_data=validation_generator,
validation_steps=2037 // 20)

在下面的图表中请注意,虽然训练精度按预期提高了-验证很快就设置在0.008左右,即1/120 ... RANDOM预测?!

enter image description here

enter image description here

我还用验证替换了火车,反之亦然-并遇到了同样的问题:训练精度提高了,而验证精度却停留在大约0.008 = 1/120。

任何想法都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

我使用批处理大小进行了测试,发现batch_size = 120(火车中的目录数以及有效目录)可以消除上述问题。现在,我可以愉快地使用数据扩充技术,而不会因为内存问题而使我的Kaggle内核崩溃。我还是想知道...

Keras ImageDataGenerator如何在分类模式下(深度或广度)从目录中采样图像?

如果深度明智-批量大小为20时,它将进入第一个目录,例如100张照片(五次),然后移至下一个目录,以20批为单位,移至下一个目录... 还是广度?

从宽度上看-最初的20张照片是前20个目录中的每张照片,然后是接下来20个目录中的每张照片? 与 flow_from _directory 和fit_generator一起使用时,我在文档中找不到Keras ImageDataGenerator如何与批处理一起使用。