我正在实现一个耦合到多实例学习层的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 调试器检查代码后,我发现,事实上,我的乞求损失和常规损失在索姆点返回相同的值。但是,Keras对常规的Igmoid损失执行了6个补充添加(在我的模型中每层1个(。有人可以帮助我纠缠这个令人惊讶的结果吗?我希望常规损失、验证损失和我的行李损失相同。
好吧,我终于找到了罪魁祸首:L2 正则化,它被打开了,而我认为它已经关闭了。调节项显然被添加到交叉熵中以计算有效损失。 大多数时候,睡个好觉和仔细检查您的代码足以回答您的问题。