我有一个不平衡的训练
数据集,这就是我构建自定义加权分类交叉熵损失函数
的原因。但问题是我的验证
集是平衡的,我想在Keras中使用常规的分类交叉熵损失。所以我能否在Keras中为验证集传递不同的损失函数?我的意思是用加权损失函数进行训练,用常规损失函数进行验证集。
def weighted_loss(y_pred, y_ture):
'
'
'
return loss
model.compile(loss= weighted_loss, metric='accuracy')
您可以尝试使用后端函数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)在模型训练中是否起作用。如果您的模型中有dropout,则不需要手动打开它。 - Yu-Yang_uses_learning_phase = True
,就像我在此答案的示例中所做的那样 (model.outputs[0]._uses_learning_phase = True
)。这是一项实现细节,因此我认为不太可能在任何地方都有记录。 - Yu-Yang