【问题标题】:Why there's a bad accuracy on dataset when it's used both for validation and training?当数据集用于验证和训练时,为什么它的准确性很差?
【发布时间】:2020-03-14 09:43:14
【问题描述】:

我使用 ResNet50 训练了一个模型,并在训练集上获得了惊人的 95% 准确率。 我用同样的训练集进行验证,准确率似乎很差。(

from keras.preprocessing.image import ImageDataGenerator

train_set = ImageDataGenerator(horizontal_flip=True,rescale=1./255,shear_range=0.2,zoom_range=0.2).flow_from_directory(data,target_size=(256,256),classes=['airplane','airport','baseball_diamond',
                                                                    'basketball_court','beach','bridge',
                                                                  'chaparral','church','circular_farmland',
                                                                  'commercial_area','dense_residential','desert',
                                                                  'forest','freeway','golf_course','ground_track_field',
                                                                  'harbor','industrial_area','intersection','island',
                                                                  'lake','meadow','medium_residential','mobile_home_park',
                                                                  'mountain','overpass','parking_lot','railway','rectangular_farmland',
                                                                  'roundabout','runway'],batch_size=31)

from keras.applications import ResNet50 
from keras.applications.resnet50 import preprocess_input
from keras import layers,Model

conv_base = ResNet50(
    include_top=False,
    weights='imagenet')


for layer in conv_base.layers:
    layer.trainable = False

x = conv_base.output
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(128, activation='relu')(x) 
predictions = layers.Dense(31, activation='softmax')(x)
model = Model(conv_base.input, predictions)

# here you will write the path for train data or if you create your val data then you can test using that too. 
# test_dir = ""
test_datagen = ImageDataGenerator(rescale=1. / 255) 
test_generator = test_datagen.flow_from_directory( 
    data, 
    target_size=(256, 256), classes=['airplane','airport','baseball_diamond',
                                                                    'basketball_court','beach','bridge',
                                                                  'chaparral','church','circular_farmland',
                                                                  'commercial_area','dense_residential','desert',
                                                                  'forest','freeway','golf_course','ground_track_field',
                                                                  'harbor','industrial_area','intersection','island',
                                                                  'lake','meadow','medium_residential','mobile_home_park',
                                                                  'mountain','overpass','parking_lot','railway','rectangular_farmland',
                                                                  'roundabout','runway'],batch_size=1,shuffle=True)

model.compile(loss='categorical_crossentropy',optimizer='Adam',metrics=['accuracy'])
model.fit_generator(train_set,steps_per_epoch=1488//31,epochs=10,verbose=True,validation_data = test_generator, 

validation_steps = test_generator.samples // 31)

Epoch 1/10
48/48 [==============================] - 27s 553ms/step - loss: 1.9631 - acc: 0.4825 - val_loss: 4.3134 - val_acc: 0.0208
Epoch 2/10
48/48 [==============================] - 22s 456ms/step - loss: 0.6395 - acc: 0.8212 - val_loss: 4.7584 - val_acc: 0.0833
Epoch 3/10
48/48 [==============================] - 23s 482ms/step - loss: 0.4325 - acc: 0.8810 - val_loss: 5.3852 - val_acc: 0.0625
Epoch 4/10
48/48 [==============================] - 23s 476ms/step - loss: 0.2925 - acc: 0.9153 - val_loss: 6.0963 - val_acc: 0.0208
Epoch 5/10
48/48 [==============================] - 23s 477ms/step - loss: 0.2275 - acc: 0.9341 - val_loss: 5.6571 - val_acc: 0.0625
Epoch 6/10
48/48 [==============================] - 23s 478ms/step - loss: 0.1855 - acc: 0.9489 - val_loss: 6.2440 - val_acc: 0.0208
Epoch 7/10
48/48 [==============================] - 23s 483ms/step - loss: 0.1704 - acc: 0.9543 - val_loss: 7.4446 - val_acc: 0.0208
Epoch 8/10
48/48 [==============================] - 23s 487ms/step - loss: 0.1828 - acc: 0.9476 - val_loss: 7.5198 - val_acc: 0.0417

可能是什么原因?!

【问题讨论】:

  • 你不应该使用相同的数据进行训练和验证,这违背了验证的想法,试图找出你的模型的泛化程度。请发布一个可重现的示例
  • @Alistair 谢谢你的回复!这只是一个实验。只是想了解使用相同数据集作为验证时准确性低的原因。
  • 如果数据相同,准确率应该相同。可能是代码问题
  • @Alistair 不,检查代码。当我从互联网上的各种博客文章中阅读时,这个问题可能是由于过度拟合造成的。但我希望从这里的任何人那里找到一些直观的解释。
  • @Samuel Liew♦ 我请求您重新提出问题。

标签: python tensorflow keras


【解决方案1】:

您以不同方式分配了 train_set 和 test_datagen。特别是一个在另一个没有的地方被翻转和缩放。正如我在评论中提到的,如果它的数据相同,它将具有相同的准确性。当您正确使用验证并使用未见过的数据进行验证时,您可以看到模型过度拟合。使用相同的数据将始终为训练和验证提供相同的准确性

【讨论】:

    【解决方案2】:

    不确定到底是什么问题,但这不是一个过度拟合的问题。很明显,您的验证数据(与训练数据相同)没有正确输入。一方面,您将验证批量大小设置为 =1,但将验证步骤设置为 validation_steps = test_generator.samples // 31) 。如果 test_generator,samples = 1488 那么您有 48 个步骤,但批量大小为 1 您将仅验证 48 个样本。您想设置批量大小和步骤,以便 batch_size X validation_steps 等于样本总数。这样,您就可以准确地完成一次验证集。我还建议您为测试生成器设置 shuffle=False。还有你为什么要麻烦输入所有的类名。如果您将类目录标记为“飞机”、“机场”、“baseball_diamond”等,那么您不需要专门定义来自目录的类流会自动为您完成。请参阅下面的文档。

    classes:类子目录的可选列表(例如 ['dogs', 'cats'])。默认值:无。如果未提供,则将自动从目录下的子目录名称/结构中推断出类列表,其中每个子目录将被视为不同的类(并且将映射到标签索引的类的顺序将是字母数字)。包含从类名到类索引的映射的字典可以通过属性 class_indices 获得。

    您的训练数据实际上与您的测试数据不同,因为您在生成器中使用了数据增强。没关系,这可能会导致您的测试和验证准确性之间存在微小差异,但是一旦您正确输入验证数据,您的验证准确性应该非常接近

    【讨论】:

    • 嘿@Gerry P,感谢您的回复!是的,我想将批量大小设置为 1。因为我在玩,我尝试了各种不同的方法,但没有得到很好的准确性。所以在这里,我做了一些改变。就像您指出的那样,我将测试集中的 batch_size 更改为 31,这一次在验证步骤中,它在每个时期的验证期间覆盖了整个 1488 张图像。我请你看看这个 colab 笔记本,colab.research.google.com/drive/…
    • 如果你有 1448 张图片和 31 个班级,那么平均每个班级大约有 47 张图片。即使您在图像生成器中进行了增强,我也怀疑 47 个图像是否足够大以捕获类的完整概率分布。结果,您将获得较高的训练准确度,但验证准确度较低。在这一点上,我只能建议收集更多图像。尝试每堂课至少获得 100 张图像。如果可能的话,通过每个类别的图像数量非常接近来保持数据集的平衡。
    • 我怀疑该模型目前过度拟合,不是吗?每个班级有48张图片.....总共1488imgs
    猜你喜欢
    • 2019-07-09
    • 2018-08-26
    • 2021-09-07
    • 1970-01-01
    • 2018-07-28
    • 2020-03-11
    • 1970-01-01
    • 2020-07-08
    • 2020-03-12
    相关资源
    最近更新 更多