【问题标题】:keras fit vs keras evaluatekeras fit vs keras评估
【发布时间】:2018-12-15 16:12:05
【问题描述】:

应该有人可以真正澄清这一点..

以下是 Keras 文档中的一些初始信息: Keras 中的 fit 函数只是针对给定数量的 epoch 训练模型。 evaluate 函数返回测试模式下模型的损失值和指标值。

所以,这两个函数都返回一个损失。为了举例说明,如果我有 1 个单一训练示例,则在每个训练步骤之后我从拟合函数获得的损失应该与我从评估函数获得的损失相同(在相同的训练步骤之后)。 (这里的假设是我在同一个火车组(仅包含 1 个示例)上同时运行 fitevaluate 函数。)

我将我的网络定义如下:

def identity_loss(y_true, y_pred):
    return K.mean(y_pred - 0 * y_true)

model = ResNet50(weights='imagenet')
model.layers.pop()
x = model.get_layer('flatten_1').output # layer 'flatten_1' is the last layer of the model
model_out = Dense(128, activation='relu',  name='model_out')(x)
model_out = Lambda(lambda  x: K.l2_normalize(x,axis=-1))(model_out)

new_model = Model(inputs=model.input, outputs=model_out)

anchor_input = Input(shape=(224, 224, 3), name='anchor_input')
pos_input = Input(shape=(224, 224, 3), name='pos_input')
neg_input = Input(shape=(224, 224, 3), name='neg_input')

encoding_anchor   = new_model(anchor_input)
encoding_pos      = new_model(pos_input)
encoding_neg      = new_model(neg_input)

loss = Lambda(triplet_loss)([encoding_anchor, encoding_pos, encoding_neg])
siamese_network = Model(inputs  = [anchor_input, pos_input, neg_input], 
                        outputs = loss) 
siamese_network.compile(loss=identity_loss, optimizer=Adam(lr=.00003))

稍后,我使用 fit 函数训练我的训练集(仅包含 1 个示例)10 个 epoch。为了检查拟合和评估函数之间的差异,我还在每个时期的拟合函数之后运行评估函数,输出如下所示:

nr_epoch:  0 

Epoch 1/1
1/1 [==============================] - 4s 4s/step - loss: 2.0035
1/1 [==============================] - 3s 3s/step
eval_score for train set:  2.0027356147766113

nr_epoch:  1 

Epoch 1/1
1/1 [==============================] - 1s 1s/step - loss: 1.9816
1/1 [==============================] - 1s 1s/step
eval_score for train set:  2.001833915710449

nr_epoch:  2 

Epoch 1/1
1/1 [==============================] - 1s 1s/step - loss: 1.9601
1/1 [==============================] - 1s 1s/step
eval_score for train set:  2.00126576423645

nr_epoch:  3 

Epoch 1/1
1/1 [==============================] - 1s 1s/step - loss: 1.9388
1/1 [==============================] - 1s 1s/step
eval_score for train set:  2.0009117126464844

nr_epoch:  4 

Epoch 1/1
1/1 [==============================] - 1s 1s/step - loss: 1.9176
1/1 [==============================] - 1s 1s/step
eval_score for train set:  2.000725746154785

nr_epoch:  5 

Epoch 1/1
1/1 [==============================] - 1s 1s/step - loss: 1.8964
1/1 [==============================] - 1s 1s/step
eval_score for train set:  2.0006520748138428

nr_epoch:  6 

Epoch 1/1
1/1 [==============================] - 1s 1s/step - loss: 1.8759
1/1 [==============================] - 1s 1s/step
eval_score for train set:  2.0006656646728516

nr_epoch:  7 

Epoch 1/1
1/1 [==============================] - 1s 1s/step - loss: 1.8555
1/1 [==============================] - 1s 1s/step
eval_score for train set:  2.0007567405700684

nr_epoch:  8 

Epoch 1/1
1/1 [==============================] - 1s 1s/step - loss: 1.8355
1/1 [==============================] - 1s 1s/step
eval_score for train set:  2.0009000301361084

nr_epoch:  9 

Epoch 1/1
1/1 [==============================] - 2s 2s/step - loss: 1.8159
1/1 [==============================] - 2s 2s/step
eval_score for train set:  2.001085042953491

正如所见,fit 函数(在每个时期结束时)报告的 loss 正在减少。而来自评估函数的损失并没有减少。

所以困境是:如果我在 1 个单一训练示例上运行我的模型,我是否应该从同一时期的拟合和评估函数中看到相同的损失(在每个时期之后)?如果我继续训练,训练损失会减少,但来自评估函数的损失会以某种方式保持在同一水平并且不会减少

最后,这里是我如何调用 fit 和 evaluate 函数:

z = np.zeros(len(anchor_path))

siamese_network.fit(x=[anchor_imgs, pos_imgs, neg_imgs], 
                    y=z, 
                    batch_size=batch_size, 
                    epochs=1, 
                    verbose=1, 
                    callbacks=None, 
                    validation_split=0.0, 
                    validation_data=None, 
                    shuffle=True, 
                    class_weight=None, 
                    sample_weight=None, 
                    initial_epoch=0, 
                    steps_per_epoch=None, 
                    validation_steps=None)

eval_score = siamese_network.evaluate(x=[anchor_imgs, pos_imgs, neg_imgs], 
                                      y=z,
                                      batch_size = batch_size, 
                                      verbose = 1)
print('eval_score for train set: ', eval_score)

那么,为什么在 fit 函数的执行过程中损失会减少,而不是在评估函数的执行过程中呢?我在哪里做错了?

【问题讨论】:

  • 一些层在训练和推理过程中表现不同。最值得注意的是,在后一种情况下会关闭 dropout。
  • 感谢您的回答。我不会在任何地方触摸辍学设置。您有什么具体的建议要仔细检查吗?训练损失正在迅速减少,但评估函数报告的损失几乎没有变化。并且只有 1 个单一的训练示例。这对我来说没有意义......

标签: machine-learning keras conv-neural-network face-recognition


【解决方案1】:

ResNet 使用批量归一化,在训练和测试过程中表现不同。您认为应该从 model.fitmodel.evaluate 获得相同的训练损失的假设是不正确的。

【讨论】:

  • 感谢您的回答。我明白你的意思。但是解决这个问题的方法是什么?如何匹配拟合和评估函数的损失(或至少使它们尽可能接近)? (附注:上面没有提到,但我运行以下“layer.trainable = False”并冻结原始 ResNet50 的权重。这也会影响它吗?)
  • 如果您冻结了 BN 层,那么这与损坏的 BN 肯定是相同的问题,您在答案中发布的链接中对此进行了描述。
  • @edn 我不认为有问题,你为什么要在 fit 和 evaluate 之间有匹配损失?
  • 是的,我认识到在实施迁移学习时冻结BN层参数没有任何意义。关于@MatiasValdenegro 的问题:我首先训练了我的模型,发现拟合和评估函数的损失存在巨大差异。然后我只用 1 个示例训练了模型(检查一切是否正常工作),但损失之间的差异仍然存在。否则,我不会尝试匹配损失。
【解决方案2】:

通过进一步研究(通过使用不同的关键字进行谷歌搜索),我发现以下信息也提供了解决方案。看起来,很多人都遇到过这个问题,尤其是在尝试利用迁移学习时。

这是一个问题的讨论和解决方案: Strange behaviour of the loss function in keras model, with pretrained convolutional base

这里有一篇关于这个主题的博文: http://blog.datumbox.com/the-batch-normalization-layer-of-keras-is-broken/

不幸的是,我认为 Tensorflow 和 Keras 的文档都很糟糕。

【讨论】:

    猜你喜欢
    • 2019-07-29
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 2019-04-28
    • 2021-06-12
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    相关资源
    最近更新 更多