我正在使用具有二元交叉熵的 Sigmoid 激活函数训练二元分类器,该函数的准确率约为 98%。
当我使用带有 categorical_crossentropy 的 softmax 进行训练时,同样会得到非常低的准确度(< 40%)。
我将 binary_crossentropy 的目标作为 0 和 1 的列表传递,例如;[0,1,1,1,0]。
知道为什么会这样吗?
我正在使用具有二元交叉熵的 Sigmoid 激活函数训练二元分类器,该函数的准确率约为 98%。
当我使用带有 categorical_crossentropy 的 softmax 进行训练时,同样会得到非常低的准确度(< 40%)。
我将 binary_crossentropy 的目标作为 0 和 1 的列表传递,例如;[0,1,1,1,0]。
知道为什么会这样吗?
现在,您的第二个模型总是回答“0 类”,因为它只能在一个类(最后一层的输出数量)之间进行选择。
由于您有两个类,因此您需要计算两个输出上的 softmax + categorical_crossentropy 以选择最可能的一个。
因此,您的最后一层应该是:
model.add(Dense(2, activation='softmax')
model.compile(...)
您的 sigmoid + binary_crossentropy 模型通过仅分析单个输出数字来计算“0 类”为真的概率,它已经是正确的。
编辑:这是关于Sigmoid函数的一个小解释
Sigmoid 可以看作是实数空间和概率空间之间的映射。
请注意:
Sigmoid(-infinity) = 0
Sigmoid(0) = 0.5
Sigmoid(+infinity) = 1
因此,如果你的网络输出的实数非常低,sigmoid 将判断“0 类”的概率接近 0,并判断“1 类”
相反,如果你的网络的输出非常高,sigmoid会判断“Class 0”的概率接近1,并判断“Class 0”
它的决定类似于仅通过查看输出的符号来决定 Class。但是,这不会让您的模型学习!事实上,这种二元损失的梯度几乎在所有地方都是空的,这使得您的模型无法从错误中学习,因为它没有被正确量化。
这就是使用 sigmoid 和“binary_crossentropy”的原因:
它们是二元损失的替代品,具有良好的平滑特性,并且可以学习。
另外,请查找有关Softmax 函数和交叉熵的更多信息