损失函数结果与 Keras 不一致
Inconsistancies of loss function results with Keras
我正在实施耦合到多实例学习层的 CNN。简而言之,我有这个,C 是类别数:
[1 batch of images, 1 label] > CNN > Custom final layer -> [1 vector of size C]
我的最后一层只是暂时总结了前一层。需要明确的是,1 批输入仅给出 1 个输出。因此,该批次对应于在与 1 个标签关联的 1 个袋子中提取的多个实例。
当我训练我的模型并使用相同的集合对其进行验证时:
history = model.fit_generator(
generator=training_generator,
steps_per_epoch=training_set.batch_count,
epochs=max_epoch,
validation_data=training_generator
validation_steps=training_set.batch_count)
尽管训练集和验证集相同,但我得到了 2 个不同的结果:
35/35 [==============================] - 30s 843ms/step - loss: 1.9647 - acc: 0.2857 - val_loss: 1.9403 - val_acc: 0.3714
损失函数只是 Keras 中实现的分类交叉熵(我有 3 个类别)。我已经实现了自己的损失函数来了解发生了什么。不幸的是,我在常规损失函数和我的自定义损失函数之间发现了另一个不一致:
35/35 [==============================] - 30s 843ms/step - loss: 1.9647 - acc: 0.2857 - bag_loss: 1.1035 - val_loss: 1.9403 - val_acc: 0.3714 - val_bag_loss: 1.0874
我的损失函数:
def bag_loss(y_true, y_predicted):
y_true_mean = keras.backend.mean(y_true, axis=0, keepdims=False)
y_predicted_mean = keras.backend.mean(y_predicted, axis=0, keepdims=False)
loss = keras.losses.categorical_crossentropy(y_true_mean, y_predicted_mean)
return loss
我模型的最后一层(为了简洁,我只显示了调用部分):
def call(self, x):
x = kb.sum(x, axis=0, keepdims=True)
x = kb.dot(x, self.kernel)
x = kb.bias_add(x, self.bias)
out = kb.sigmoid(x)
return out
在使用 TensorBoard 和 TensorFlow Debugger 检查代码后,我发现我的 beg loss 和常规 loss return 在某个点确实是相同的值。但是随后,Keras 对常规 sigmoid 损失执行 6 次补充添加(我的模型中每层 1 次)。谁能帮我纠结这个结果惊人的球?我希望常规损失、验证损失和我的包损失是相同的。
好的,我终于找到了罪魁祸首:L2正则化,它被打开了,而我以为它是关闭的。显然,正则化项被添加到交叉熵中以计算有效损失。
大多数时候,睡个好觉和仔细检查您的代码足以回答您的问题。
我正在实施耦合到多实例学习层的 CNN。简而言之,我有这个,C 是类别数:
[1 batch of images, 1 label] > CNN > Custom final layer -> [1 vector of size C]
我的最后一层只是暂时总结了前一层。需要明确的是,1 批输入仅给出 1 个输出。因此,该批次对应于在与 1 个标签关联的 1 个袋子中提取的多个实例。
当我训练我的模型并使用相同的集合对其进行验证时:
history = model.fit_generator(
generator=training_generator,
steps_per_epoch=training_set.batch_count,
epochs=max_epoch,
validation_data=training_generator
validation_steps=training_set.batch_count)
尽管训练集和验证集相同,但我得到了 2 个不同的结果:
35/35 [==============================] - 30s 843ms/step - loss: 1.9647 - acc: 0.2857 - val_loss: 1.9403 - val_acc: 0.3714
损失函数只是 Keras 中实现的分类交叉熵(我有 3 个类别)。我已经实现了自己的损失函数来了解发生了什么。不幸的是,我在常规损失函数和我的自定义损失函数之间发现了另一个不一致:
35/35 [==============================] - 30s 843ms/step - loss: 1.9647 - acc: 0.2857 - bag_loss: 1.1035 - val_loss: 1.9403 - val_acc: 0.3714 - val_bag_loss: 1.0874
我的损失函数:
def bag_loss(y_true, y_predicted):
y_true_mean = keras.backend.mean(y_true, axis=0, keepdims=False)
y_predicted_mean = keras.backend.mean(y_predicted, axis=0, keepdims=False)
loss = keras.losses.categorical_crossentropy(y_true_mean, y_predicted_mean)
return loss
我模型的最后一层(为了简洁,我只显示了调用部分):
def call(self, x):
x = kb.sum(x, axis=0, keepdims=True)
x = kb.dot(x, self.kernel)
x = kb.bias_add(x, self.bias)
out = kb.sigmoid(x)
return out
在使用 TensorBoard 和 TensorFlow Debugger 检查代码后,我发现我的 beg loss 和常规 loss return 在某个点确实是相同的值。但是随后,Keras 对常规 sigmoid 损失执行 6 次补充添加(我的模型中每层 1 次)。谁能帮我纠结这个结果惊人的球?我希望常规损失、验证损失和我的包损失是相同的。
好的,我终于找到了罪魁祸首:L2正则化,它被打开了,而我以为它是关闭的。显然,正则化项被添加到交叉熵中以计算有效损失。 大多数时候,睡个好觉和仔细检查您的代码足以回答您的问题。