我正在从目录层次结构(使用ImageDataGenerator类的生成器的flow_from_directory)读取图像。该模型是固定参数mobilenetv2 +可训练的softmax层。当我使模型适合训练数据时,训练和验证的准确性水平是可比的。如果我使用验证参数或重置生成器,则使用model.evaluate验证验证生成器的准确性会大大降低,或者如果我重新使用model.fit拟合模型,则会大大降低验证生成器的准确性。该数据库是3D视图数据库。 相关代码:
'''
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)
'''
通过执行以下操作来重现陌生感:
'''
val_gen.batch_size=4
val_gen.reset()
val_gen.batch_size=batch_size
'''
然后,在拟合或评估期间,验证准确性会自动降低(可能是偶然的)
'''
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)))
'''
答案 0 :(得分:0)
我认为该委员会的主要答复解决了我观察到的问题 Keras: Accuracy Drops While Finetuning Inception
答案 1 :(得分:0)
此处提供一些您可以尝试的方法。您可以通过如下更改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)
您不需要Lamda调整大小图层,因为您在目录流中指定了目标大小。 在val_gen中,您有shuffle = True。这将改变每个时期的验证图像顺序。最好将其设置为False以获得一致性。 在移动网络的代码中,您具有include_top = True和pooling ='avg'。当include_top为True时,将忽略合并参数。 设置include_top = True将使模型的顶层具有1000个节点的密集层和softmax激活函数。 我会设置include_top = False。这样,移动网络输出就是一个全局池层,可以直接为您的密集分类层提供数据。在生成器中,设置class_mode ='binary'。但是在model.compile中,您将损失设置为 sparse_categorical_crossentropy。这将起作用,但最好使用loss = BinaryCrossentropy进行编译。 为确保一致性,最好每个时期精确地通过一次验证样本。为此,应选择批大小,以使验证样本/ batch_size为整数,并使用该整数作为验证步骤的数量。 下面的代码将为您做到这一点。
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)
更改验证批次大小可以更改验证丢失和准确性的结果。通常,批量越大,损失的波动越小,但可能会导致卡在局部最小值中的可能性更高。尝试这些更改,看看结果差异是否较小。