Keras中验证集的不同损失函数
Posted
技术标签:
【中文标题】Keras中验证集的不同损失函数【英文标题】:Different loss function for validation set in Keras 【发布时间】:2019-02-06 00:28:58 【问题描述】:我有不平衡的training
数据集,这就是我构建自定义weighted categorical cross entropy loss
函数的原因。但问题是我的validation
集合是平衡的,我想使用常规的分类交叉熵损失。那么我可以为 Keras 中的验证集传递不同的损失函数吗?我的意思是训练集的 wighted 和验证集的常规集?
def weighted_loss(y_pred, y_ture):
'
'
'
return loss
model.compile(loss= weighted_loss, metric='accuracy')
【问题讨论】:
【参考方案1】:您可以尝试后端函数K.in_train_phase()
,Dropout
和BatchNormalization
层使用该函数在训练和验证中实现不同的行为。
def custom_loss(y_true, y_pred):
weighted_loss = ... # your implementation of weighted crossentropy loss
unweighted_loss = K.sparse_categorical_crossentropy(y_true, y_pred)
return K.in_train_phase(weighted_loss, unweighted_loss)
K.in_train_phase()
的第一个参数是训练阶段使用的张量,第二个是测试阶段使用的张量。
例如,如果我们将weighted_loss
设置为0(只是为了验证K.in_train_phase()
函数的效果):
def custom_loss(y_true, y_pred):
weighted_loss = 0 * K.sparse_categorical_crossentropy(y_true, y_pred)
unweighted_loss = K.sparse_categorical_crossentropy(y_true, y_pred)
return K.in_train_phase(weighted_loss, unweighted_loss)
model = Sequential([Dense(100, activation='relu', input_shape=(100,)), Dense(1000, activation='softmax')])
model.compile(optimizer='adam', loss=custom_loss)
model.outputs[0]._uses_learning_phase = True # required if no dropout or batch norm in the model
X = np.random.rand(1000, 100)
y = np.random.randint(1000, size=1000)
model.fit(X, y, validation_split=0.1)
Epoch 1/10
900/900 [==============================] - 1s 868us/step - loss: 0.0000e+00 - val_loss: 6.9438
如您所见,训练阶段的损失确实是乘以0。
请注意,如果您的模型中没有 dropout 或 batch norm,您需要手动“打开”_uses_learning_phase
布尔开关,否则默认情况下K.in_train_phase()
将不起作用。
【讨论】:
这就是我要找的。谢谢于阳。关于你所说的关于打开“_uses_learning_phase”的最后一件事,只有一个问题。我认为测试的默认值为“0”,训练的默认值为“1”,我的模型有 batch_normalizaition 和 dropout 层。那我需要手动开启吗? 你的意思是'训练'标志,因为我没有找到'_uses_learning_phase'标志。我的意思是在 tf.keras.backend.in_train_phase 中只有 ( x, alt, training=None ) 我提到的_uses_learning_phase
是另一回事。这是一个布尔变量,用于控制“学习阶段”变量(即您提到的那个——0 表示测试,1 表示训练)是否会对模型训练产生任何影响。如果您的模型中有 dropout,那么您不需要手动打开它。
_uses_learning_phase
是一个内部变量,如果有任何在训练/验证中表现不同的组件(例如 dropout、batch norm),它将附加到模型输出。
您可以选择模型的任何输出张量并设置其_uses_learning_phase = True
,就像我在此答案的示例中所做的一样 (model.outputs[0]._uses_learning_phase = True
)。这是一个实现细节,所以我认为它不太可能被记录在任何地方。【参考方案2】:
验证损失函数只是一个指标,实际上并不需要用于训练。它在那里是因为比较您的网络实际优化的指标是有意义的。 因此,您可以在编译期间添加任何其他损失函数作为指标,并且您会在训练期间看到它。
【讨论】:
我知道每个 epoch 结束时验证损失报告的值只是为了优化目的,看看你的模型有多好。但是当验证集是平衡的,这意味着每个时期报告的验证损失值是错误的数字,因为它是基于训练不平衡集的,所以要查看它并调整模式。我是赖特吗?当你说我可以添加任何其他损失函数作为度量时,我不明白你能解释更多。我需要具有与验证集在训练中具有不同权重的损失函数。 听起来不错。至于指标:keras model.compile 有一个指标参数,您可以在其中传递精度等指标函数。这些指标将在 epoch 结束时在训练和评估集上进行评估。因此,您可以使用不同的权重添加自定义权重损失函数。如果这是不可能的,请展示一些关于如何将自定义损失函数作为模型损失函数传递的代码。 我修改了帖子以包含简单的代码。我想我明白你的意思。您的意思是将正常的分类交叉熵损失作为指标传递,以报告准确验证损失的值。但是我想要它用于模型评估的准确度指标呢,我可以通过两个指标进行评估吗? 是的,您可以传递任意数量的指标数组以上是关于Keras中验证集的不同损失函数的主要内容,如果未能解决你的问题,请参考以下文章