多标签和多分类,别再分不清了
作者:互联网
本文已同步至公众号,欢迎关注。
目录
多标签和多分类任务是深度学习中常见的两种模式。有几个核心问题,是需要回答的?
什么是多标签,什么是多分类?
什么时候用多标签,什么时候用多分类?
多标签损失函数用那个?
多任务损失函数用那个?
怎么选择损失函数?
如果你非常熟悉,就没必要再往下了。部分内容来源于各种网络。
第一节 什么是多标签和多分类
话不多说,上图。
我们先看看什么是多标签分类。例如上面这个截图,来自于一部电影。很显然,每一部电影的名字只有一个,上面的电影是《红海行动》,它不可能是《金刚大战哥斯拉》,也不是《美国队长》。这就是多分类。也就是说,也很多类别,但是对一个实例而言,有且只有一个类别是属于它的,就像电影名字。
那什么是多标签呢?
还是看上面的图,红色的框标出了几个例子。这个电影被标记了“战争”,“普通话”,“华语”这几个标签。这就是多标签。也就是说,一个实例,在某个时刻,可能有多个标签来描述它。
分类是一个预测建模问题,它涉及到在给定输入的情况下输出类标签。不同于涉及预测数值的回归任务,通常,分类任务涉及预测单个标签,在这些情况下,类是互斥的,这意味着分类任务假定输入只属于一个类。
有些分类任务需要预测多个类标签。这意味着类标签或类成员不是互斥的。这些任务称为多标签分类,简称多标签分类。在多标签分类中,每个输入样本需要零个或多个标签作为输出,同时需要输出。
第二节 什么时候用多标签和多分类
上面的例子已经说的很详细了。一般情况下,我们对类或者标签做one-hot编码。
我们还是用上面的例子,对于多分类任务。
样例 | 《红海行动》 | 《葫芦娃》 | 《美国队长》 | 《中国队长》 | 《俄罗斯队长》 |
X1 | 1 | 0 | 0 | 0 | 0 |
X2 | 0 | 1 | 0 | 0 | 0 |
X3 | 0 | 0 | 1 | 0 | 0 |
X4 | 0 | 0 | 0 | 1 | 0 |
对于多标签任务。
样例 | 科幻 | 战争 | 普通话 | 俄语 | 剧情 |
X1 | 1 | 1 | 1 | 0 | 0 |
X2 | 0 | 1 | 0 | 1 | 1 |
X3 | 1 | 1 | 1 | 0 | 1 |
X4 | 0 | 1 | 0 | 1 | 1 |
第三节 多分类怎么做
多分类任务只有一个类别是1,其他都是0。如果用以往的机器学习方法,只需要按照二分类的方式进行学习即可。如果采用深度学习方法,即可采用softmax激活函数。
第四节 多标签怎么做
传统的多标签任务,已经有很多博客介绍了。比如说,将各个标签单独进行训练,例如训练科幻这个标签时,忽略其他标签。例如传统的机器学习方法可以把各标签分开来:
如果采用深度学习方法,不需要把各标签分开。假设输出有4个标签,那么最后的全连接层只需要4个输出节点,激活函数用sigmoid,那么输出的就是4个标签的值,然后每个标签设置一个阈值,作为判断是否属于的依据。
第五节 交叉熵
交叉熵是信息论领域的一种度量,它建立在熵的基础上,通常计算两个概率分布之间的差异。它与KL散度密切相关,但不同于KL散度。KL散度计算两个概率分布之间的相对熵,而交叉熵可以认为是计算分布之间的总熵。
交叉熵也与逻辑损失(logistic loss)(通常称为对数损失)相关,并且经常与之混淆。尽管这两个量度有不同的来源,但是当用作分类模型的损失函数时,这两个量度计算的量相同,可以互换使用。
在本节主要介绍:
(5.1)什么是交叉熵?
交叉熵是对给定随机变量或事件集的两个概率分布之间差异的度量。在信息论中,事件发生的可能性越小越令人惊讶,这意味着它包含更多的信息。低概率事件更让人兴奋,比如说,你突然中了一等奖,真是简直了,信息量真的大,可能是500万,可能是1000万,也可能是2000万。你说大不大。
对于事件x,给定事件概率P(x),可以为事件x计算信息h(x),如下所示:
h(x)=-log(P(x))
对于一组离散的随机变量,熵H(x)可以用一组离散的X及其概率P(x)来计算,如下所示:
H(x)=-∑P(x)*log(P(x))
交叉熵建立在信息论的熵概念的基础上,并计算出一种分布与另一种分布相比代表或传输平均事件所需的位数。
从P到Q的交叉熵就表示为:
H(x)=-∑P(x)*log(Q(x))
其中H()是交叉熵函数,P可以是目标分布,而Q是目标分布的近似值。P(x)是事件x在P中的概率,Q(x)是事件x在Q中的概率,log是以2为底的对数,这意味着结果以位为单位。如果改为使用base-e或自然对数,则结果的单位称为nats。尽管可以使用事件之间的积分而不是总和来对连续概率分布进行类似的计算,但是此计算是针对离散概率分布进行的。如果两个概率分布相同,则结果将是一个以位为单位的正数,并且将等于分布的熵。
(5.2)交叉熵与KL散度
交叉熵与散度度量有关,例如Kullback-Leibler,或KL,散度度量一个分布与另一个分布的差异。
具体来说,KL散度度量的量与交叉熵非常相似。它测量用Q而不是P表示消息所需的额外位的平均数,而不是位的总数。
KL散度的计算方法:KL散度可以计算为P中多个事件的概率的对数乘以Q中事件的概率与P中事件的概率的对数得出。通常,使用对数以2为底
KL(P || Q) = -∑P(x) * log(Q(x) / P(x))
也就是说,
交叉熵是当我们使用模型q时,对来自具有分布p的源数据进行编码所需的平均位数。
KL散度是编码数据所需的额外位数的平均数,这是由于我们使用分布q而不是真实分布p来编码数据这一事实。
(5.3)如何计算交叉熵
(5.3.1)两种离散概率分布
举个例子:将具有三个离散事件的随机变量视为不同的颜色:红色,绿色和蓝色。
events = ['red', 'green', 'blue']
p = [0.10, 0.40, 0.50]
q = [0.80, 0.15, 0.05]
用直方图表示更为直观.
(5.3.2)计算分布之间的交叉熵
接下来,我们可以开发一个函数来计算两个分布之间的交叉熵。我们将使用以2为底的对数,以确保结果的单位为位。
# calculate cross entropy
def cross_entropy(p, q):
return -sum( [ p[i] * log2(q[i]) for i in range(len(p)) ] )
调用这个函数,交换p和q的位置,得到:
H(P, Q): 3.288 bits
H(Q, P): 2.906 bits
(5.3.3)计算分布与自身之间的交叉熵
如果两个概率分布相同,则它们之间的交叉熵将是分布的熵。
H(P, P): 1.361 bits
H(Q, Q): 0.884 bits
(5.3.4)使用KL散度计算交叉熵
我们还可以使用KL散度计算交叉熵。
首先,我们可以定义一个函数,使用对数基数2来计算分布之间的KL散度,以确保结果也以位为单位。
def kl_divergence(p, q):
return sum( p[i] * log2(p[i]/q[i]) for i in range(len(p)) )
接下来,我们可以定义一个函数来计算给定概率分布的熵。
def entropy(p):
return -sum( [ p[i] * log2(p[i]) for i in range(len(p)) ] )
最后,我们可以使用entropy()和kl_divergence()函数来计算交叉熵。
def cross_entropy(p, q):
return entropy(p) + kl_divergence(p, q)
为了使示例简单,我们可以将H(P,Q)的交叉熵与KL散度KL(P || Q)和熵H(P)进行比较。
H(P): 1.361 bits
KL(P || Q): 1.927 bits
H(P, Q): 3.288 bits
(5.4)交叉熵作为损失函数
优化分类模型时,交叉熵被广泛用作损失函数。您可能会遇到两个示例,包括逻辑回归算法(线性分类算法)和可用于分类任务的人工神经网络。分类问题是那些涉及一个或多个输入变量以及分类标签的预测问题。对于输出变量仅具有两个标签的分类任务称为二进制分类问题,而具有两个以上标签的那些问题称为分类或多类分类问题。
我们可以看到,交叉熵的思想对于优化分类模型可能有用。对于分类问题,每个示例都有一个已知的类别标签,概率为1.0,所有其他标签的概率为0.0。 模型可以估计示例属于每个类别标签的概率。 然后可以使用交叉熵来计算两个概率分布之间的差异。
在分类任务中,我们知道输入的目标概率分布P类别标签为0或1,分别解释为概率为“不可能”或“确定”。 这些概率一点也不令人惊讶,因此它们没有信息内容或零熵。我们的模型试图近似目标P,其概率分布为Q。因此,我们可以使用上述交叉熵来估算单个预测的交叉熵。二进制分类任务中单个示例的交叉熵可以通过展开求和运算来表示,如下所示:
H(P, Q) = – (P(class0) * log(Q(class0)) + P(class1) * log(Q(class1)))
我们通常感兴趣的是在整个训练数据集上最小化模型的交叉熵。 这是通过计算所有训练样本的平均交叉熵来计算的。
(5.4.1)计算类别标签的熵
回想一下,当两个分布相同时,它们之间的交叉熵等于概率分布的熵。在为分类任务准备数据时,使用值0和1对类标签进行编码。例如,如果一个分类问题具有三个类别,而一个样本具有一个第一类别的标签,则概率分布将为[1、0、0]。如果一个样本具有第二类的标签,则这两个事件的概率分布为[0,1,0]。这称为“one-hot编码”。由于结果是确定的,因此这种概率分布没有任何信息。因此,该变量的熵为零。
假设有一个具有3个类的分类问题,并且我们有一个属于每个类的样本。我们可以将每个样本表示为离散的概率分布,样本所属的类别的概率为1.0,所有其他类别的概率为0.0。我们可以计算出“事件”中每个“变量”的概率分布的熵。也就是H(P)=0.0,即H([1,0,0])=0.0
这意味着对于类标签,具有相同概率分布的两个分布(实际分布和预测分布)的交叉熵也将始终为0.0。
回想一下,当在训练数据集上使用交叉熵评估模型时,我们对数据集中所有示例的交叉熵求平均值。
因此,训练模型时的交叉熵为0.0表示预测的类别概率与训练数据集中的概率相同。也就是说,使得P和Q的分布尽量相同,那么训练的目的就达到了。
在实践中,交叉熵损失为0.0通常表明该模型已经过拟合训练数据集,但这是另一回事。
(5.4.2)计算类标签和概率之间的交叉熵
我们可以通过一个工作示例将交叉熵用作损失函数。考虑一个具有以下10个实际类别标签(P)和预测类别标签(Q)的两类分类任务。
p = [1, 1, 1, 1, 1, 0, 0, 0, 0, 0]
q = [0.8, 0.9, 0.9, 0.6, 0.8, 0.1, 0.4, 0.2, 0.1, 0.3]
对于每个样本,我们构建这样的概率分布(相当于把list拆开)
results = list()
for i in range(len(p)):
# create the distribution for each event {0, 1}
expected = [1.0 - p[i], p[i]]
predicted = [1.0 - q[i], q[i]]
# calculate cross entropy for the two events
ce = cross_entropy(expected, predicted)
print('>[y=%.1f, yhat=%.1f] ce: %.3f nats' % (p[i], q[i], ce))
results.append(ce)
最后,我们可以计算整个数据集的平均交叉熵,并将其报告为数据集上模型的交叉熵损失。
mean_ce = mean(results)
这是在交叉熵损失函数下优化逻辑回归模型或神经网络模型时如何计算交叉熵损失的方法。
(5.4.3)预测概率的交叉熵
当预测的概率分布与目标分布匹配时,交叉熵从0.0开始,然后随着预测的概率分布的发散而逐渐增加。当预测的概率分布与目标分布恰好相反时,即与目标[0,1]相比,预测的是[1,0],我们还可以看到交叉熵的巨大飞跃。
如果您正在做训练,并且平均交叉熵小于0.2,那么您将有一个良好的开端,而小于0.1或0.05甚至更好。另一方面,如果平均交叉熵大于0.2或0.3,则可能会有所改善;如果平均交叉熵大于1.0,则说明预测结果很差。一点指导性的数据:
Cross-Entropy = 0.00: Perfect probabilities.
Cross-Entropy < 0.02: Great probabilities.
Cross-Entropy < 0.05: On the right track.
Cross-Entropy < 0.20: Fine.
Cross-Entropy > 0.30: Not great.
Cross-Entropy > 1.00: Terrible.
Cross-Entropy > 2.00 Something is broken.
第六节 如何选择损失函数
6.1回归损失函数
回归预测建模问题涉及预测实数值。在本节中,我们将研究适用于回归预测建模问题的损失函数。
6.1.1 均方误差损失
均方误差或MSE损失是用于回归问题的默认损失。在数学上,如果目标变量的分布为高斯分布,则是在最大似然推理框架下的首选损失函数。计算均方误差作为预测值与实际值之间平方差的平均值。无论预测值和实际值的符号如何,结果始终为正,理想值为0.0。 平方表示较大的错误比较小的错误导致更多的错误,这意味着该模型因犯有较大的错误而受到惩罚。
可以在Keras中使用均方误差损失函数,在编译模型时指定“ mse”或“ mean_squared_error”作为损失函数。
6.1.2 均方对数误差损失
可能存在回归问题,其中目标值具有分散的值,并且在预测大值时,您可能不希望像均方误差那样对模型进行如此严厉的惩罚。相反,您可以首先计算每个预测值的自然对数,然后计算均方误差。 这称为均方对数误差损失,或简称为MSLE。它具有缓解较大预测值中较大差异的惩罚效果的作用。
作为一种损失度量,当模型直接预测未按比例缩放的数量时,它可能更合适。
训练时可以使用“ mean_squared_logarithmic_error”损失函数。
6.1.3平均绝对误差损失
在某些回归问题上,目标变量的分布可能主要是高斯分布,但可能有离群值,例如 远离平均值的大或小值。在这种情况下,平均绝对误差或MAE损失是一种适当的损失函数,因为它对异常值更为稳健。
训练时可以使用“ mean_absolute_error”损失函数。
6.2二分类损失函数
二分类是指那些将两个标签之一分配给示例的预测建模问题。该问题通常被设计为预测第一或第二类的值为0或1,并且通常被实现为预测该示例属于类值1的概率。在本节中,我们将研究适用于二分类预测建模问题的损失函数。
6.2.1 二元互熵
交叉熵是用于二进制分类问题的默认损失函数。它适用于目标值在集合{0,1}中的二进制分类。
从数学上讲,它是最大似然推理框架下的首选损失函数。交叉熵将计算一个分数,该分数总结了预测类1的实际概率分布与预测概率分布之间的平均差。该分数被最小化,并且理想的交叉熵值为0。
Keras中可以在编译模型时通过指定“ binary_crossentropy”将交叉熵指定为损失函数。最后一层激活函数可以用sigmoid。
6.2.2 Hinge 损失
二进制分类问题的交叉熵的替代方法是Hinge 损失函数,该函数主要是为与支持向量机(SVM)模型一起使用而开发的。它适用于目标值位于集合{-1,1}中的二进制分类。
Hinge 损失函数使得样本具有正确的符号,当实际值和预测的类值之间的符号不同时,分配更多的错误。有时在二元分类问题上比交叉熵的性能更好。
Keras中可以在编译模型时通过指定“hinge”定为损失函数。最后一层激活函数可以用tanh。
6.2.3 平方hinge损失
它具有使误差函数的表面变平滑并使它在数值上更易于使用的效果。如果使用hinge损失确实可以在给定的二元分类问题上实现更好的性能,则平方hinge损失可能是合适的。与使用hinge损失函数一样,必须将目标变量修改为具有{-1,1}集的值。
Keras中可以在编译模型时通过指定“squared_hinge”定为损失函数。最后一层激活函数可以用tanh。
6.3 多类分类损失函数
多类别分类是指那些将两个以上类别之一分配给示例的预测建模问题。该问题通常被认为是预测整数值,其中为每个类分配一个从0到(num_classes – 1)的唯一整数值。 该问题通常被实现为预测该示例属于每个已知类的概率。
在本节中,我们将研究适用于多类分类预测建模问题的损失函数。
6.3.1多类交叉熵损失
交叉熵是用于多类分类问题的默认损失函数。在这种情况下,它适用于多类分类,其中目标值位于集合{0,1,3,…,n}中,其中每个类都分配有唯一的整数值。从数学上讲,它是最大似然推理框架下的首选损失函数。交叉熵将计算得分,该得分总结问题中所有类别的实际概率分布与预测概率分布之间的平均差。
Keras可以在编译模型时通过指定“ categorical_crossentropy”将交叉熵指定为损失函数。
一般输出层配置有n个节点(每个类一个节点),对所有样本做one-hot编码,以及“softmax”激活,以便预测每个类的概率。
6.3.2稀疏多类互熵损失
将交叉熵与带有大量标签的分类问题一起使用时,造成结果不理想的可能原因是one-hot编码过程。
例如,预测词汇表中的单词可能具有数以万计的类别,每个标签一个。 这可能意味着每个训练样本的目标元素可能需要一个带有成千上万个零值的one-hot编码矢量,从而需要大量内存。
稀疏交叉熵通过执行相同的误差交叉熵计算来解决此问题,而无需在训练之前将目标变量进行one-hot编码。
keras可以使用“ sparse_categorical_crossentropy”将稀疏交叉熵用于多类分类。
该功能要求输出层配置有n个节点(每个类一个节点),以及“softmax”激活,以便预测每个类的概率。无需对目标变量进行one-hot编码,这是损失函数的一项优势。
上面两个函数的选择取决于样本是怎么展现的。假设有三个类别标签,如果你的样本标签是 [1,0,0] , [0,1,0], [0,0,1]这样的,那么就用categorical_crossentropy。如果你的样本标签是这样的:[1,2,3],那么就用sparse_categorical_crossentropy。本质上,他们损失函数的内部没啥区别。
当类别很多时,第二个函数可以节省大量的内存开销。不用再one-hot编码了。
标签:函数,交叉,概率分布,标签,分类,损失,分不清 来源: https://blog.csdn.net/Aoulun/article/details/116805094