在Keras中根据条件定制损失函数

我想为一个具有4个不同类别的多类分类问题设置一个Keras模型(使用TensorFlow后端)。我有标记和未标记的数据。

我已经处理了只使用标记数据进行训练的情况,我的模型看起来像这样:

# create modelinputs = keras.Input(shape=(len(config.variables), ))  X = layers.Dense(units=200, activation="relu")(inputs)output = layers.Dense(units=4, activation="softmax", name="output")(X)model = keras.Model(inputs=inputs, outputs=output)model.compile(optimizer=optimizers.Adam(1e-4), loss=loss_function, metrics=["accuracy"])# train modelmodel.fit(    x=train_data,     y=train_class_labels,    batch_size=200,     epochs=200,     verbose=2,     validation_split=0.2,    sample_weight       = class_weights    )

我已经有使用两种不同损失函数的功能模型,即categorical_crossentropysparse_categorical_crossentropy。根据损失函数的不同,我的train_class_labels使用的是独热编码表示(例如[[0,1,0,0], [0,0,0,1], …])或整数表示(例如[0,0,2,1,0,3, …]),一切正常运作。class_weights是一些权重向量([0.78, 1,34, …])

现在,为了进一步的计划,我需要在训练过程中包含未标记的数据,但这些数据需要被损失函数忽略。

我尝试过以下方法:

  1. 当使用categorical_crossentropy作为损失函数时,将未标记数据的标签设置为[0,0,0,0],因为我认为这样我的未标记数据就会被损失函数忽略。但这在训练后改变了预测结果。
  2. 我也尝试将未标记数据的权重设置为0,但这也没有效果

我得出结论,我需要以某种方式标记我的未标记数据,并定制我的损失函数,以便它可以被告知忽略这些样本。类似于这样

def custom_loss(y_true, y_pred):    if y_true == labeled data:        return normal loss function    if y_true == unlabeled data:        return 0

这些是我找到的一些代码片段,但它们似乎不起作用:

def custom_loss(y_true, y_pred):    loss = losses.sparse_categorical_crossentropy(y_true, y_pred)    return K.switch(K.flatten(K.equal(y_true, -1)), K.zeros_like(loss), loss)def custom_loss2(y_true, y_pred):    idx  = tf.not_equal(y_true, -1)    y_true = tf.boolean_mask(y_true, idx)    y_pred = tf.boolean_mask(y_pred, idx)    return losses.sparse_categorical_crossentropy(y_true, y_pred)

在这些例子中,我将未标记数据的标签设置为-1,所以train_class_labels看起来像这样:[0,-1,2,0,3, … ]

但当使用第一个损失函数时,我只得到Nans,而使用第二个时,我得到以下错误:Invalid argument: logits and labels must have the same first dimension, got logits shape [1,5000] and labels shape [5000]


回答:

我认为将标签设置为[0,0,0,0]是可以的。因为损失是通过每个类别的实例的对数损失的总和来计算的(在你的情况下,没有标签的实例的损失将为0)。

我不明白为什么你在监督设置中将未标记的数据插入到训练中。

我认为你得到的差异是由于批量大小和梯度步骤造成的。如果有不参与梯度下降的实例,计算出的损失将与之前不同,然后你会在预测中看到差异。

基本上,每个批次中包含的信息量较少的实例会减少。

如果你使用的数据集大小作为批量大小,那么与之前没有未标记实例的训练(但始终使用批量大小=数据集大小进行训练)将没有区别

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注