简体   繁体   English

当我更改其属性时,验证生成器的准确性几乎下降 - keras ImageDataGenerator,model.evaluate

[英]Validation generator accuracy drop near to chance when I change its properties-- keras ImageDataGenerator, model.evaluate

I am reading images from a directory hierarchy (flow_from_directory using generators from the ImageDataGenerator class).我正在从目录层次结构(使用 ImageDataGenerator 类的生成器的 flow_from_directory )读取图像。 The model is a fixed parameter mobilenetv2 + a trainable softmax layer.该模型是一个固定参数的 mobilenetv2 + 一个可训练的 softmax 层。 When I fit the model to training data, accuracy levels are comparable for training and validation.当我将模型拟合到训练数据时,训练和验证的准确度水平是可比的。 If I play with the validation parameters or reset the generator, accuracy for the validation generator drops significantly using model.evaluate or if I restart fitting the model with model.fit.如果我使用验证参数或重置生成器,使用 model.evaluate 或如果我重新开始使用 model.fit 拟合模型,验证生成器的准确性会显着下降。 The database is a 3D view database.该数据库是一个 3D 视图数据库。 Relevant code:相关代码:

''' '''

batch_size=16

rescaled3D_gen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255, zoom_range=0.2, 
                                                                 shear_range=0.2,  
                                                                 horizontal_flip=True)             

train_gen =rescaled3D_gen.flow_from_directory(data_directory + '/train/', seed=3,
                                              target_size = (pixels, pixels), shuffle=True,
                                              batch_size = batch_size, class_mode='binary')

val_gen =rescaled3D_gen.flow_from_directory(data_directory + '/test/', seed=3,
                                            target_size = (pixels, pixels), shuffle=True,
                                            batch_size = batch_size, class_mode='binary')
#MODEL
inputs = tf.keras.Input(shape=(None, None, 3), batch_size=batch_size)
x = tf.keras.layers.Lambda(lambda img: tf.image.resize(img, (pixels,pixels)))(inputs)
x = tf.keras.layers.Lambda(tf.keras.applications.mobilenet_v2.preprocess_input)(x)

mobilev2 = tf.keras.applications.mobilenet_v2.MobileNetV2(weights = 'imagenet', input_tensor = x,
                                                          input_shape=(pixels,pixels,3),
                                                          include_top=True, pooling = 'avg')
#add a dense layer for task-specific categorization.
full_model = tf.keras.Sequential([mobilev2, 
                                tf.keras.layers.Dense(train_gen.num_classes, activation='softmax')])

for idx, layers in enumerate(mobilev2.layers):
    layers.trainable = False

mobilev2.layers[-1].trainable=True

full_model.compile(optimizer = tf.keras.optimizers.RMSprop(learning_rate=0.0001), 
             loss = 'sparse_categorical_crossentropy',
             metrics=['accuracy'])
#start fitting
val_gen.reset()
train_gen.reset()

full_model.fit(train_gen, 
               steps_per_epoch = samples_per_epoch, 
               epochs=30,
               validation_data=val_gen,
               validation_steps = int(np.floor(val_gen.samples/val_gen.batch_size)))

good_acc_score = full_model.evaluate(val_gen, steps=val_gen.n//val_gen.batch_size)

''' '''

reproduce strangeness by doing something like this:通过做这样的事情来重现陌生感:

''' '''

val_gen.batch_size=4
val_gen.reset()
val_gen.batch_size=batch_size

''' '''

Then validation accuracy is automatically lower (perhaps to chance) during fit or evaluation然后在拟合或评估期间验证准确性会自动降低(可能是偶然的)

''' '''

bad_acc_score = full_model.evaluate(val_gen, steps=val_gen.n//val_gen.batch_size)

#or

full_model.fit(train_gen, 
               steps_per_epoch = samples_per_epoch, 
               epochs=1,
               validation_data=val_gen,
               validation_steps = int(np.floor(val_gen.samples/val_gen.batch_size)))

''' '''

我认为该板的主要答案解决了我观察到的Keras问题:微调 Inception 时准确率下降

here area few things you might try.这里有一些你可以尝试的事情。 You can eliminate the Lamda layers by changing the train_gen as follows您可以通过如下更改 train_gen 来消除 Lamda 层

rescaled3D_gen = tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255, zoom_range=0.2,shear_range=0.2, horizontal_flip=True,
            preprocessing_function=tf.keras.applications.mobilenet_v2.preprocess_input) 

You do not need the Lamda resize layer since you specify the target size in flow from directory.您不需要 Lamda 调整大小层,因为您在目录流中指定了目标大小。 In the val_gen you have shuffle=True.在 val_gen 你有 shuffle=True。 This will shuffle the validation image order for each epoch.这将打乱每个时期的验证图像顺序。 Better to set it to False for consistancy.最好将其设置为 False 以保持一致性。 In the code for mobilenet you have include_top=True and pooling='avg' When include_top is True the pooling parameter is ignored.在 mobilenet 的代码中,您有 include_top=True 和 pooling='avg' 当 include_top 为 True 时,池参数被忽略。 Setting include_top=True leaves the top layer of your model with a dense layer of 1000 nodes and a softmax activation function.设置 include_top=True 使模型的顶层具有 1000 个节点的密集层和 softmax 激活函数。 I would set include_top=False.我会设置 include_top=False。 That way the mobilenet output is a global pooling layer that can directly feed your dense categorization layer.这样,mobilenet 输出是一个全局池化层,可以直接提供给您的密集分类层。 In the generators you set the class_mode='binary'.在生成器中设置 class_mode='binary'。 but in model.compile you set the loss as sparse_categorical_crossentropy.但在 model.compile 中,您将损失设置为 sparse_categorical_crossentropy。 This will work but better to compile with loss=BinaryCrossentropy.这将工作,但更好地与损失 = BinaryCrossentropy 编译。 It is preferable to go through the validation samples exactly one time per epoch for consistancy.为了一致性,最好每个 epoch 只通过一次验证样本。 To do that the the batch size should be selected such that validation samples/batch_size is an integer and use that integer as the number of validation steps.为此,应选择批量大小,使得验证样本/batch_size 是一个整数,并使用该整数作为验证步骤的数量。 The code below will do that for you.下面的代码将为您做到这一点。

b_max=80 # set this to the maximum batch size you will allow based on memory capacity
length=val_gen.samples       
batch_size=sorted([int(length/n) for n in range(1,length+1) if length % n ==0 and length/n<=b_max],reverse=True)[0]  
val_steps=int(length/batch_size)

Changing validation batch size can change the results of validation loss and accuracy.更改验证批量大小可以更改验证损失和准确性的结果。 Generally a larger batch size will result in less fluctuation of the loss but can lead to a higher probability of getting stuck in a local minimum.通常,较大的批量大小会导致损失的波动较小,但会导致陷入局部最小值的可能性更高。 Try these changes and see if there is less variance in the results.尝试这些更改,看看结果中的差异是否较小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM