Loud fit vs Hard评估
keras fit vs keras evaluate
应该有人能真正弄清楚这个..
以下是 Keras 文档中的一些初步信息:
Keras 中的 fit 函数只是针对给定数量的 epoch 训练模型。
评估函数return是测试模式下模型的损失值和指标值。
所以,这两个功能return都是一个损失。为了举个例子,如果我有 1 个训练示例,我在每个训练步骤后从 fit 函数得到的损失应该与我从 evaluate 函数(在相同的训练步骤之后)得到的损失相同。 (这里的假设是我 运行 fit 和 evaluate 在同一个训练集上的函数(仅包含 1 个示例))
我定义我的网络如下:
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))
稍后,我用 10 个时期的拟合函数训练我的训练集(仅包含 1 个示例)。只是为了检查拟合函数和评估函数之间的差异,我还在每个时期的拟合函数之后 运行 评估函数,输出如下所示:
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 个训练样本上,我是否应该从同一时期的拟合和评估函数中看到相同的损失(在每个时期之后)?如果我继续训练,火车损失正在减少,但来自评估函数的损失以某种方式保持在同一水平并且不会减少
最后,我是这样调用拟合函数和求值函数的:
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)
那么,为什么loss在执行fit函数的时候变小了,而在evaluate函数的时候却没有?我哪里出错了?
ResNet 使用批量归一化,这在训练和测试期间表现不同。您应该从 model.fit
和 model.evaluate
获得相同训练损失的假设是不正确的。
通过进一步研究(通过使用不同的关键字进行谷歌搜索),我发现了以下信息,这些信息也提供了解决方案。看起来,很多人都被这个问题所困扰,尤其是在尝试利用迁移学习时。
这里是问题的讨论和解决方案:
这里有一篇关于这个主题的博文:
http://blog.datumbox.com/the-batch-normalization-layer-of-keras-is-broken/
不幸的是,我认为 Tensorflow 和 Keras 的文档都很糟糕。
应该有人能真正弄清楚这个..
以下是 Keras 文档中的一些初步信息: Keras 中的 fit 函数只是针对给定数量的 epoch 训练模型。 评估函数return是测试模式下模型的损失值和指标值。
所以,这两个功能return都是一个损失。为了举个例子,如果我有 1 个训练示例,我在每个训练步骤后从 fit 函数得到的损失应该与我从 evaluate 函数(在相同的训练步骤之后)得到的损失相同。 (这里的假设是我 运行 fit 和 evaluate 在同一个训练集上的函数(仅包含 1 个示例))
我定义我的网络如下:
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))
稍后,我用 10 个时期的拟合函数训练我的训练集(仅包含 1 个示例)。只是为了检查拟合函数和评估函数之间的差异,我还在每个时期的拟合函数之后 运行 评估函数,输出如下所示:
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 个训练样本上,我是否应该从同一时期的拟合和评估函数中看到相同的损失(在每个时期之后)?如果我继续训练,火车损失正在减少,但来自评估函数的损失以某种方式保持在同一水平并且不会减少
最后,我是这样调用拟合函数和求值函数的:
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)
那么,为什么loss在执行fit函数的时候变小了,而在evaluate函数的时候却没有?我哪里出错了?
ResNet 使用批量归一化,这在训练和测试期间表现不同。您应该从 model.fit
和 model.evaluate
获得相同训练损失的假设是不正确的。
通过进一步研究(通过使用不同的关键字进行谷歌搜索),我发现了以下信息,这些信息也提供了解决方案。看起来,很多人都被这个问题所困扰,尤其是在尝试利用迁移学习时。
这里是问题的讨论和解决方案:
这里有一篇关于这个主题的博文: http://blog.datumbox.com/the-batch-normalization-layer-of-keras-is-broken/
不幸的是,我认为 Tensorflow 和 Keras 的文档都很糟糕。