使用fit_发生器的Keras传输学习Resnet50存在acc高但值低的问题

2024-04-25 21:01:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用Resnet50模型来进行迁移学习,使用总共20个场景中的100000个图像(mitplace365数据集)。由于内存的限制,训练了160层。问题是我有一个相当高的准确性,但极低的验证准确性,我认为这可能是一个过度拟合的问题,但我不知道如何解决它。如果有人能给我建议如何解决我的低值问题,我将非常感激,非常感谢。 我的代码如下:

V1 = np.load("C:/Users/Desktop/numpydataKeras_20_val/imgonehot_val_500.npy")
V2 = np.load("C:/Users/Desktop/numpydataKeras_20_val/labelonehot_val_500.npy") 


net = keras.applications.resnet50.ResNet50(include_top=False, weights='imagenet', input_tensor=None, input_shape=(224, 224, 3))

x = net.output
x = Flatten()(x)
x = Dense(128)(x)
x = Activation('relu')(x)
x = Dropout(0.5)(x)
output_layer = Dense(20, activation='softmax', name='softmax')(x)
net_final = Model(inputs=net.input, outputs=output_layer)

for layer in net_final.layers[:-160]:
    layer.trainable = False
for layer in net_final.layers[-160:]:
    layer.trainable = True

net_final.compile(Adam(lr=.00002122), loss='categorical_crossentropy', metrics=['accuracy'])

def data_generator():
    n = 100000
    Num_batch = 100000/100
    arr = np.arange(1000)
    np.random.shuffle(arr)
    while (True):
        for i in arr:
            seed01 = random.randint(0,1000000)

            X_batch  = np.load( "C:/Users/Desktop/numpydataKeras/imgonehot_"+str((i+1)*100)+".npy" )
            np.random.seed(seed01)
            np.random.shuffle(X_batch)

            y_batch = np.load( "C:/Users/Desktop/numpydataKeras/labelonehot_"+str((i+1)*100)+".npy" )
            np.random.seed(seed01)
            np.random.shuffle(y_batch)

            yield X_batch, y_batch

weights_file = 'C:/Users/Desktop/Transfer_learning_resnet50_fit_generator_02s.h5'
early_stopping = EarlyStopping(monitor='val_acc', patience=5, mode='auto', verbose=2)
model_checkpoint = ModelCheckpoint(weights_file, monitor='val_acc', save_best_only=True, verbose=2)
callbacks = [early_stopping, model_checkpoint]

model_fit = net_final.fit_generator(
    data_generator(),
    steps_per_epoch=1000,
    epochs=5,
    validation_data=(V1, V2),
    callbacks=callbacks,
    verbose=1,
    pickle_safe=False)

以下是打印输出:

^{pr2}$

Tags: layerfalsenetnpbatchloadrandomval
1条回答
网友
1楼 · 发布于 2024-04-25 21:01:27

https://github.com/keras-team/keras/issues/9214#issuecomment-397916155之后,批处理规范化似乎应该是可训练的。在

以下代码可以替换设置/取消设置可训练层的循环:

for layer in model.layers:
    if hasattr(layer, 'moving_mean') and hasattr(layer, 'moving_variance'):
        layer.trainable = True
        K.eval(K.update(layer.moving_mean, K.zeros_like(layer.moving_mean)))
        K.eval(K.update(layer.moving_variance, K.zeros_like(layer.moving_variance)))
    else:
        layer.trainable = False

根据我自己的数据,我需要减少批量以避免OOM,现在我有:

^{pr2}$

警告,这可能会影响准确性,您必须冻结您的模型,以避免奇怪的推断。但这似乎是唯一对我有用的方法。在

另一个注释https://github.com/keras-team/keras/issues/9214#issuecomment-422490253只检查层名称,如果是批处理规范化,则将其设置为可训练的,但它对我没有任何改变。也许它可以帮助你的数据集。在

相关问题 更多 >