当前位置: 首页 > 知识库问答 >
问题:

在keras中使用批处理规范化进行微调

梁丘洲
2023-03-14

我已经成功训练了一个超过100000个样本的模型,该模型在训练集和测试集都表现良好。然后,我尝试对一个特定样本(100000个样本中的一个)进行微调,并使用经过训练的权重作为初始化。

但结果有点奇怪,我相信这是由批处理规范化层引起的。具体而言,我的代码可以列出如下:

model = mymodel()
model.load_weights('./pre_trained.h5') #start from history
rate = model.evaluate(x, y)
print(rate)
checkpoint = tf.keras.callbacks.ModelCheckpoint('./trained.h5', monitor='loss',
        verbose=0, save_best_only=True, mode='min',save_weights_only=True)
model.fit(x, y,validation_data=[x, y], epochs=5, verbose=2, callbacks=[checkpoint])

model.load_weights速率=model.evaluate(x, y)打印速率

mymodel是一个自定义函数来生成我的模型,由密集和批次规范化组成。x, y是一个特定样本的输入和标签。我想进一步优化样本的损失。但是,结果很奇怪:

 1/1 [==============================] - 0s 209ms/step
-6.087581634521484
Train on 1 samples, validate on 1 samples
Epoch 1/200
 - 1s - loss: -2.7749e-01 - val_loss: -6.0876e+00
Epoch 2/200
 - 0s - loss: -2.8791e-01 - val_loss: -6.0876e+00
Epoch 3/200
 - 0s - loss: -3.0012e-01 - val_loss: -6.0876e+00
Epoch 4/200
 - 0s - loss: -3.1325e-01 - val_loss: -6.0876e+00

如图所示,首先是模型。评估工作正常,损失结果(-6.087581634521484)接近加载训练模型的性能。但是火车组的损失(实际上与model.fit()中的验证集相同)是奇怪的。val\u损失为正常值,与模型结果相似。在第一行进行评估。所以我真的很困惑,为什么火车损失和推断损失之间仍然有很大的差异(火车损失更严重),因为火车样本和验证样本是相同的,我认为结果也应该是相同的,或者至少非常接近。我怀疑问题是由BN层引起的,因为训练和推理之间存在很大的差异。然而,我已经在加载预训练权重后和模型之前设置了BN层的可训练=假。安装,但问题未解决。

out = tf.keras.layers.BatchNormalization(trainable=False)(out)

我仍然怀疑BN层,不知道settrainable=False是否足以保持BN的参数不变。

有人能给我一些建议吗?事先非常感谢你的帮助。对不起我的英语,但我尽力解释我的问题。


共有3个答案

裴哲
2023-03-14

我在这里找到了一个可能的解释:https://github.com/keras-team/keras/pull/9965和这里:https://github.com/keras-team/keras/issues/9214

柴岳
2023-03-14

我在pytorch也有类似的发现,我想与大家分享。首先,你的keras版本是什么?因为在2.1.3之后,设置BN layer trainable=False将使BN在推理模式中表现完全相同,这意味着它不会将输入标准化为0均值1方差(与训练模式类似),而是将输入标准化为运行均值和方差。如果将学习阶段设置为1,则BN本质上成为实例规范,它忽略了运行的平均值和方差,只需将其规格化为0平均值和1方差,这可能是您想要的行为。

keras发行说明参考链接:https://github.com/keras-team/keras/releases/tag/2.1.3

API更改BatchNormize中的可训练属性现在禁用批次统计信息的更新(即如果可训练==False,该层现在将在推理模式下100%运行)。

司空丰
2023-03-14
匿名用户

有点尴尬,我在另一个问题中找到了一个奇怪的方法来解决这个问题Keras:精度下降,而微调盗梦空间

事实上,我认为这还不够,但是当我加上

 tf.keras.backend.set_learning_phase(1)

在<代码>模型之前。compile()。结果变得很正常,但仍存在一些问题:

1/1 [==============================] - 0s 246ms/step
-6.087581634521484
Train on 1 samples, validate on 1 samples
Epoch 1/10
 - 1s - loss: -6.0876e+00 - val_loss: -6.0893e+00
Epoch 2/10
 - 0s - loss: -6.0893e+00 - val_loss: -6.0948e+00
Epoch 3/10
 - 0s - loss: -6.0948e+00 - val_loss: -6.0903e+00
Epoch 4/10
 - 0s - loss: -6.0903e+00 - val_loss: -6.0927e+00

这是惊人的,也是我想要的,但我仍然对这个问题感到困惑。首先,它为什么工作,什么是tf。凯拉斯。后端。设置\u learning\u阶段(1)do?此外,我还设置了层。trainbale=True,在这种情况下,BN层为什么正常工作?那么,为什么损失和val\u损失仍然有很小的区别呢?由于样本相同,是什么导致了这种现象?最后,我发现是否使用tf。凯拉斯。后端。设置\u learning\u phase(0)或tf。凯拉斯。后端。设置\u learning\u phase(1),结果相似且正常。以下是tf的结果。凯拉斯。后端。设置\u learning\u阶段(0):

1/1 [==============================] - 0s 242ms/step
-6.087581634521484
Train on 1 samples, validate on 1 samples
Epoch 1/10
 - 1s - loss: -6.0876e+00 - val_loss: -6.0775e+00
Epoch 2/10
 - 0s - loss: -6.0775e+00 - val_loss: -6.0925e+00
Epoch 3/10
 - 0s - loss: -6.0925e+00 - val_loss: -6.0908e+00
Epoch 4/10
 - 0s - loss: -6.0908e+00 - val_loss: -6.0883e+00

它与tf有点不同。凯拉斯。后端。设置\u learning\u phase(1),这也需要等待正确的解释。

我对deep learning和Keras是新手,我从堆栈溢出中受益匪浅。就我的知识和英语而言。

感谢您提前提供帮助。

 类似资料:
  • 我目前正在尝试在Keras中使用批处理规范化实现一个模型。我已经成功地在训练阶段实现了它。 然而,对于测试,在通过网络进行前向传递之前,批次归一化会计算整个群体的统计信息(平均值和方差)(BN平均值和方差是预先计算的,然后保持不变;这与训练阶段相反,在训练阶段,平均值和方差由批次确定)。 我关于Keras的问题是: 假设(X, y)是整个总体。假设(X_batch,y_batch)是一个批次(整个

  • 我了解批次归一化有助于更快的训练,将激活转向单位高斯分布,从而解决梯度消失问题。批次规范行为在训练(使用每个批次的平均值/var)和测试时间(使用训练阶段的最终运行平均值/var)中的应用不同。 另一方面,实例归一化作为对比度归一化,如本文所述https://arxiv.org/abs/1607.08022。作者提到,输出样式化的图像不应依赖于输入内容图像的对比度,因此实例规范化有助于实现。 但是

  • 我想使用Batchnormalization来规范化批次维度,但keras中的批次维度自然是无维度的。那我该怎么办呢。 keras示例显示,conv2d的轴为-1,这表示通道尺寸。 轴:整数,应规格化的轴(通常是特征轴)。例如,在具有data\u format=“channels\u first”的Conv2D层之后,在BatchNormalization中设置axis=1。

  • 问题内容: 从文档 如果遇到需要插入1000 000行/对象的情况: 为什么我们应该使用这种方法?与StatelessSession一相比,它给我们带来了什么好处: 我的意思是,这个(“替代”)最后一个示例不使用内存,不需要进行同步,清除缓存,那么对于这样的情况,这应该是最佳实践吗?那么为什么要使用前一个呢? 问题答案: 从文档中,您链接到: 特别是,无状态会话不会实现第一级缓存,也不会与任何第二

  • BatchNormalization层 keras.layers.normalization.BatchNormalization(epsilon=1e-06, mode=0, axis=-1, momentum=0.9, weights=None, beta_init='zero', gamma_init='one') 该层在每个batch上将前一层的激活值重新规范化,即使得其输出数据的均值接

  • BatchNormalization层 keras.layers.normalization.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001, center=True, scale=True, beta_initializer='zeros', gamma_initializer='ones', moving_mean_initia