图像分类模型训练若使用交叉熵损失函数,通常会遇到一种尴尬的错误
该错误显示:
Assertion failed: contradiction between batch data and targets orientation: got (BxC) for self.label.data but expected (B)!
其含义是:网络输出的维度是 [BxC],即一批数据中每个样本对应的输出向量的行数等于样本数 B,列数等于网络最后一层输出的神经元数量,而真实标签的维度却是 [B],即样本数等于 B,没有对应的维度。即:网络输出的维度与标签的维度不一致。
为什么会造成这样的维度不一致呢?
因为交叉熵损失函数的算法本身要求网络输出的是:假设网络最后一层输出为 [BxC],即一批数据中每个样本对应的输出向量X,行数等于样本数B,列数等于网络最后一层输出的神经元数量C。则交叉熵损失函数要求最后一层的输出是每个样本对应的输出向量X ∈ R^(C) = [x1, …, xC],其中 C 为类别数,即softmax 回归中的 C 维输出,而非分类结果。
对于 C 个类别,输出层的神经元数目应该是 C,也即输出维度是[BxC],而不是[B]。
而交叉熵损失函数本身是每个样本利用其对应的标签在对应 softmax 方式的 self.C 维输出上求交叉熵,获取的结果是长度为 B 的向量,然后再对这个向量求平均或求和得到最终结果,即:获得的 loss 值是一个长度为 B 的向量,则最终 loss = mean (vector)或者 loss = sum(vector)。
所以,交叉熵损失函数的原理就是:对于每一个样本,只取在其真实标签位置对应的 softmax 值作为交叉熵的输入,然后对所有样本的交叉熵求平均或求和即可。
全部回复 (3)
想当场把话说完?进全球 AI 聊天室,登录就能开口。
最烦这种CUDA版本对不上的死循环,查了三个小时才发现是驱动没更新,心态崩了!此外,交叉熵损失函数的算法要求网络输出格式为何? 该错误显示:
Assertion failed: contradiction between batch data and targets orientation: got (BxC) for self.label.data but expected (B)!
其含义是:网络输出的维度是 [BxC],即一批数据中每个样本对应的输出向量的行数等于样本数 C,列数等于网络最后一层输出的神经元数量,而真实标签的维度却是 [B],即样本数等于 B,没有对应的维度。即:网络输出的维度与标签的维度不一致。 为什么会造成这样的维度不一致呢? ## 交叉熵损失函数如何处理每个样本的标签和输出? 因为交叉熵损失函数的算法本身要求网络输出的是: > 假设网络最后一层输出为 [BxC],即一批数据中每个样本对应的输出向量X,行数等于样本数B,列数等于网络最后一层输出的神经元数量C。 > 则交叉熵损失函数要求最后一层的输出是每个样本对应的输出向量X ∈ R^(C) = [x1, …, xC],其中 C 为类别数,即softmax 回归中的 C 维输出,而非分类结果。 那么,网络最后一层应该有多少个神经元呢? > 对于 C 个类别,输出层的神经元数目应该是 C,也即输出维度是[BxC],而不是[B]。 因此,对于 C 类分类任务,网络最后一层的输出层神经元个数应该是 C。 ## 交叉熵损失函数的最终结果是如何计算的? 而交叉熵损失函数本身是每个样本利用其对应的标签在对应 softmax 方式的 self.C 维输出上求交叉熵,获取的结果是长度为 B 的向量,然后再对这个向量求平均或求和得到最终结果,即: > 获得的 loss 值是一个长度为 B 的向量,则最终 loss = mean (vector)或者 loss = sum(vector)。 所以,交叉熵损失函数的原理就是:对于每一个样本,只取在其真实标签位置对应的 softmax 值作为交叉熵的输入,然后对所有样本的交叉熵求平均或求和即可。
最绝的是那种隐藏的 NaN 陷阱,尤其是交叉熵损失函数要求最后一层输出是每个样本对应的输出向量而非分类结果,如果维度没对齐,洗完数据跑模型才发现全崩了,心态直接炸裂。
最怕遇到那个 shape mismatch 报错,对着代码对齐半小时还没找到哪儿错了!尤其是当网络输出的维度是 [BxC],而真实标签的维度却是 [B] 时,这种错误显示:
。这是因为交叉熵损失函数要求网络输出的是每个样本对应的输出向量 X ∈ R^(C) = [x1, …, xC],其中 C 为类别数,即 softmax 回归中的 C 维输出,而非分类结果。因此,对于 C 类分类任务,网络最后一层的输出层神经元个数应该是 C。