精华内容
下载资源
问答
  • 首先,说下类分类和多标签分类的区别 多标签分类: 一个样本可以属于个类别(或标签),不同类之间是有关联的,比如一个文本被被划分成“人物”和“体育人物”两个标签。很显然这两个标签不是互斥的,而是有...

    首先,说下多类分类和多标签分类的区别

     

    多标签分类: 一个样本可以属于多个类别(或标签),不同类之间是有关联的,比如一个文本被被划分成“人物”和“体育人物”两个标签。很显然这两个标签不是互斥的,而是有关联的

    多类分类:  一个样本属于且只属于多个分类中的一个,一个样本只能属于一个类,不同类之间是互斥的,比如一个文本只能被划分成“人物”,或者被划分成“文化”,而不能同时被划分成“人物”和“文化”,“文化”和“人物”这两个分类就是互斥的

     

    那么,如何用softmax和sigmoid来做多类分类和多标签分类呢?

    1、如何用softmax做多分类和多标签分类

    现假设,神经网络模型最后的输出是这样一个向量logits=[1,2,3,4], 就是神经网络最终的全连接的输出。这里假设总共有4个分类

    用softmax做多分类的方法:

      tf.argmax(tf.softmax(logits))

      首先用softmax将logits转换成一个概率分布,然后取概率值最大的作为样本的分类

      这样看似乎,tf.argmax(logits)同样可以取得最大的值,也能得到正确的样本分类,这样的话softmax似乎作用不大

      那么softmax的主要作用其实是在计算交叉熵上,首先样本集中y是一个one-hot向量,如果直接将模型输出logits和y来计算交叉熵,

      因为logits=[1,2,3,4],计算出来的交叉熵肯定很大,这种计算方式不对,而应该将logits转换成一个概率分布后再来计算,

      就是用tf.softmax(logits)和y来计算交叉熵,当然我们也可以直接用tensorflow提供的方法sofmax_cross_entropy_with_logits来计算

      这个方法传入的参数可以直接是logits,因为这个根据方法的名字可以看到,方法内部会将参数用softmax进行处理 

      现在我们取的概率分布中最大的作为最终的分类结果,这是多分类

      我们也可以取概率的top几个,作为最终的多个标签,或者设置一个阈值,并取大于概率阈值的。这就用softmax实现了多标签分类 

     

    2、如何用sigmoid做多标签分类

    sigmoid一般不用来做多类分类,而是用来做二分类的

    它是将一个标量数字转换到[0,1]之间,如果大于一个概率阈值(一般是0.5),则认为属于某个类别,否则不属于某个类别

    那么如何用sigmoid来做多标签分类呢?其实就是针对logits中每个分类计算的结果分别作用一个sigmoid分类器,分别判定样本是否属于某个类别

    同样假设,神经网络模型最后的输出是这样一个向量logits=[1,2,3,4], 就是神经网络最终的全连接的输出。这里假设总共有4个分类

    tf.sigmoid(logits)

    sigmoid应该会将logits中每个数字都变成[0,1]之间的概率值,假设结果为[0.01, 0.05, 0.4, 0.6],然后设置一个概率阈值,比如0.3,如果概率值大于0.3,则判定类别符合,那这里,样本会被判定为类别3和类别4都符合。

     

     

    展开全文
  • 多标签分类

    千次阅读 2019-06-29 18:24:55
    1、多标签分类 VS 单标签分类 在图像的分类和识别领域,传统的单标签分类旨在解决一个示例只属于一个类别的问题,不同的标签之间完全独立、互相之间没有关联。然而,在更加复杂的分类任务中,如文本分类、图像类别...

    1、多标签分类 VS 单标签分类

    在图像的分类和识别领域,传统的单标签分类旨在解决一个示例只属于一个类别的问题,不同的标签之间完全独立、互相之间没有关联。然而,在更加复杂的分类任务中,如文本分类、图像类别标注、语义场景分类等一些实际应用中,常常会出现一个示例同时属于多个类别(比如:一张电影海报图片可能会同时有科幻、动作、喜剧等多个标签),下图展示了单标签分类和多标签分类之间的区别。

    单标签分类
    多标签分类

    在实际多标签分类问题中,标签之间并非完全独立,标签之间存在一定的依赖关系或者互斥关系。但由于多标签分类任务往往涉及的标签数量较大,导致类别之间的依赖关系较为复杂,难以找到合理的方式对其进行描述。因此,多标签分类相对于传统的单标签分类任务而言更加复杂,难以分析。

    2、多标签分类算法

    参考论文:A Review On Multi-Label Learning Algorithms

    多标签分类的输出空间会随着标签的数量指数增长,为了应对指数复杂度的标签空间,需要挖掘标签之间的相关性。有效的挖掘标签之间的相关性,是多标签学习成功的关键。根据多标签分类算法所利用的标签相关性情况,分为一阶、二阶、高阶策略分类算法。

    a) 一阶策略(First-order strategy)

    忽略和其他标签的相关性,比如把多标签分类分解为多个独立的二分类问题。 一阶策略的显著优点在于其概念简单、效率高。另一方面,由于其忽略了标签相关性,多标签分类算法的性能可能较差。

    b) 二阶策略(Second-order strategy)

    考虑标签之间的成对关联关系,比如为相关标签和不相关标签排序。由于二阶策略一定程度上利用了标签相关性,因此,基于二阶策略的多标签分类算法可以获得较好的泛化性能。然而,在实际的应用当中,标签相关性一般超出了二阶相关。

    c) 高阶策略(High-order strategy)

    考虑多个标签之间的关联,比如对每个标签考虑所有其他标签的影响。显然,高阶策略比一阶策略和二阶策略具有更强的相关性建模能力,而另一方面,高阶策略在计算上要求更高。

    如果根据算法设计思想的来源,可以将多标签分类算法分为两类:问题转换的方法和算法改编的方法。如下图所示,基于问题转换的多标签分类方法一般将多标签分类问题转换为其他学习场景,比如转换为二分类问题、标签排序问题、多分类问题等。基于算法改编的多标签分类方法一般是通过改编流行的学习算法去直接处理多标签数据,比如改编决策树、支持向量机等等,随着近些年深度学习的发展,部分学者将CNN、RNN等深度学习算法进行改编,常常是修改多分类神经网络的输出层或者将多种模型并联使用,使其适用于多标签的分类,下面将对部分算法进行简要介绍。

    1、问题转换方法

    a)Binary Relevance

    将多标签分类问题转换为二分类问题,将标签分类开来针对N个标签建立N个二分类器对每个标签进行预测,这是最为简单直接的方法,没有考虑标签之间的关联性,是一阶策略分类算法。

    b)Calibrated Label Ranking

    将多标签分类问题转换为标签排序问题,对于N个标签,构建N(N-1)/2个标签对,为每个标签对(y_j,y_k)构建二分类器时,将属于标签y_j但不属于标签y_k的样本看作是正类样本,将属于标签y_k但不属于标签y_j的样本看作是负类样本,忽略其他样本,可以构建N(N-1)/2个数据集,用每一个数据集训练一个二分类器,给定一个测试样本,当分类器的返回值大于零时,样本属于标签y_j,否则属于标签y_k,对每个二分类器的预测值进行投票,对每个标签添加一个额外的虚拟标记y_v,将其作为测试样本与每个标签的相关与不相关的一个划分点,将排序后的投票结果划分为该样本的相关标签和不相关标签。最终不仅给出样本所属标签集合,还根据标签与样本的相关程度给出类别标签的顺序。该算法只考虑两个标签之间的关联,是二阶策略。

    c)Random k-labelsets

    将多标签分类问题转换为多分类问题。把2^q个可能的标签对,映射成2^q个自然数。其映射函数记为\sigma _y,则原数据集变为:

    根据新构建的数据集训练一个多分类器,给定一个测试样本后,多分类器输出一个自然数,根据输出的自然数映射回标签集,该算法被称为LP(Label Powerest)算法,该算法有两个主要的局限性:

    • 预测的标签集是训练集中已经出现的,无法泛化到未见过的标签集
    • 当标签数量较大时,该算法较为低效

    为了克服LP算法的局限性,Random k-labelsets算法使用LP分类器只训练Y中一个长度为k的子集,然后集成大量的LP分类器来预测。Y_k表示Y的所有的长度为k的子集,Y^k(l)表示随机取的一个长度为k的子集,这样就可以进行收缩样本空间,得到如下样本集和标签集:

    随机选取n个子集:Y^{k(l_r))},1\leq i\leq n来构造n个多分类器做集成使用。在预测阶段计算两个指标,标签j的最大投票数,实际投票数,对未知样本进行预测时,以0.5为阈值进行预测,得到标签集。

    因为对多标签分类器进行训练时,所使用的训练集是随机长度为k的子集,考虑了多个标签之间的相关性,是高阶策略。

    2、算法改编方法

    a)Multi-Label k-Nearest Neighbor(ML-KNN)

    该算法是一种懒惰的多标签分类算法,是由传统的k近邻算法衍生出来的。对于每个测试样本,用N(x)表示测试样本xk个近邻样本,用表示样本x的邻居中带有标签y_i的个数。用H_j表示样本x含有标签y_i,根据后验概率最大化的规则,有

    该算法没有考虑标签之间的相关性,是一阶策略。

    b)Multi-Label Decision Tree(ML-DT)

    使用决策树的思想来处理多标签分类问题在数据集T中,使用第i个标签,划分值为δ,计算出如下信息增益:

    递归的构建一棵决策树每次选取标签和划分值,使得上式的信息增益最大,其中熵可以按照如下方式进行计算:

    其中,p_j表示标签y_j在样本集T中的分数,对未知样本进行测试时,向下遍历决策树,找到叶子节点,若p_j大于0.5,则表示含有标签y_j,该算法没有考虑标签之间的相关性,是一阶策略。

    c)CNN-RNN

    参考文献:CNN-RNN: A Unified Framework for Multi-label Image Classification

    使用深度学习思想来解决多标签分类问题,如下图所示将CNN与RNN并联使用。

    在该模型中,CNN部分用于提取图像的语义特征,RNN部分用于描述图像/标签关系,因为RNN可以通过中间状态保存上下文信息,作为输入影响下一时序的预测,所以在该模型中,RNN同时用于表示标签之间的依赖关系,是高阶策略。

    将当前被预测标签通过独热编码进行表示,即标签k表示为e_k = [0,0,0.....,1......,0,0],k个位置为1,其余位置为0。标签嵌入矩阵为U_l,嵌入矩阵的第k行为标签k的嵌入表示,获取标签k的嵌入表示:

    RNN部分内存有此前被预测标签的表示,结合当前输入的标签表示对标签相关性进行建模,RNN的状态更新如下,其中,r(t)为第t步时RNN的隐藏状态,o(t)为第t步时RNN的输出。

    将RNN部分输出与CNN部分提取的图像语义特征共同映射到低维的特征嵌入空间,U_o^xU_I^x为映射矩阵。

    通过计算x_t与每个特征嵌入之间的距离来计算测试样本的标签得分,预测标签的概率可以使用softmax函数进行计算。

    使用交叉熵作为的模型损失函数,其中,p表示样本的真实标签分布,q表示预测标签的概率分布,交叉熵越小,两个概率分布越接近。

    3、评价指标

     在多样本分类中,所使用的评价指标沿用了单标签分类的评价指标,对其做了部分修改以适用于多标签分类任务。如下图所示,可分为两类评价准则:基于样本的评价指标,基于标签的评价指标。

    1、基于样本的评价指标

    a)Subset Accuracy

    该评价指标的衡量标准是被正确分类的样本所占的比例,预测的样本的标签集与真实的标签集完全一样算正确,该评价指标对于标签的准确度的要求较为严格,所以,多数的多标签分类算法在该指标下的性能较差,尤其是当标签空间较大时。

    b)Hamming Loss

    该评价指标的衡量标准是被错分的标签的比例,即正确标签没有被预测以及错误的标签被预测的占比,△表示两个集合之间的对称差分。

    c)Accuracy_{exam},Precision_{exam},Recall_{exam},F_{exam}^\beta

    即单标签分类中的准确率,精确率,召回率,F_{exam}^\beta是精准率与召回率在平衡系数β(β>0)下的集成版本,当β=1时,F_{exam}^\beta是精准率与召回率的调和平均数。

    d)Ranking Loss

    该指标的评价标准是反序标签对的占比,即不相关标签比相关标签的相关性还大的情况,\overline{Y_i}为标签集Y_i的补集,y_'从标签集Y_i中选取,y_{''}从标签集\overline{Y_i}中选取。值越小,分类器的表现越好。

    2、基于标签的评价指标

    a)Macro-averaging, Micro-averaging

    对于多标签分类任务中的每个标签y_j,定义表征二分类性能的四个基本量。

    换而言之,TP_j,FP_j,TN_j,FN_j表示标签y_j的真正例、假正例、真反例、假反例,且TP_j+FP_j+TN_j+FN_j=pp为样本总数。Macro-averaging先对单个标签下的数量表征进行计算指标,然后再对多个标签取平均值。Micro-averaging先对多个标签的数量表征进行计算,再根据数量表征得到常规指标。B(\cdot )表示对四个表征进行相关运算得到常规的二分类指标。

    b)AUC

    AUC所表示的是随机挑选一个正样本及一个负样本,根据当前分类器进行预测,正样本预测为正的概率值大于负样本预测为正的概率值。对于多标签分类而言,有两种计算方式。

    4、存在的问题及挑战  

    1、分类算法的性能有待提高

    现如今已有的多标签分类算法的分类性能仍有待提高,同时多标签分类的输出空间会随着样本关联到标签个数的增长呈现指数式增长,导致分类问题变得越来越复杂,导致模型的整体性能较差。近年来,部分学者将深度学习应用到了多标签分类任务中,虽然对于传统算法而言精确度有所提升,但是深度学习模型较为复杂,导致基于深度学习的多标签分类模型的分类效率较低。

    2、标签之间的依赖关系难以描述

    对于标签之间的依赖关系的描述有三种策略:1、一阶策略,忽略标签之间的相关性,比如把多标签分类分解为多个独立的二分类问题;2、二阶策略,只考虑标签之间的成对关联关系;3、高阶策略,考虑多个标签之间的关联关系。针对具体的应用场景,该采用哪种相关性建模策略仍然是一个未解决的问题且缺乏相应的指导依据。

    3、多标签分类数据集存在类别不平衡问题

    同时,多样本分类数据集中正样本/负样本数量可能远远少于负样本/正样本数量,即多标签分类中存在类的不平衡问题,该问题也是单标签分类中常见的问题,该问题会导致大多数多标签分类方法性能的下降。例如,在预测肺癌的场景中,肺癌患者在所有来诊病人中所占的比例非常低,该场景下如果直接构建模型,会导致数据集以负样本为主,有很少的正样本。由分类模型的目标是希望准确率尽可能达到最高,因此该场景问题最终会导致预测的结果全部偏向负样本,但在实际生活中,医生和病人更加关注肺癌患者的情况,对非肺癌患者的关注度并没有那么高,类不平衡问题会严重影响到分类的效果。

    4、多标签分类数据集含噪声

    现有的多标签分类数据集,多数是由人工进行标注的,在人工标注的过程中由于各种各样的原因如每个人对相同事务的不同理解,造成标签的错误标注或者丢失了部分标注,最终得到的数据标签是不准确的或者是带有噪声的。因此在实际应用中,有完整正确的已知标签的数据量是很有限的,但是标签错误或者丢失部分标签的数据却很多。因此,有必要对此类数据进行深入研究,充分挖掘其内在的结构并将其应用到分类模型的构造中,进而提高分类准确度。

    展开全文
  • 详解sigmoid与softmax, 分类及多标签分类

    万次阅读 多人点赞 2018-09-19 21:35:50
    详解sigmoid与softmax, 分类及多标签分类激活函数介绍sigmoid激活函数sigmoid激活函数的性质sigmoid激活函数的使用 激活函数介绍 对于熟悉机器学习或神经网络的读者来说,sigmoid与softmax两个激活函数并不陌生,...

    激活函数介绍

    对于熟悉机器学习或神经网络的读者来说,sigmoid与softmax两个激活函数并不陌生,但这两个激活函数在逻辑回归中应用,也是面试和笔试会问到的一些内容,掌握好这两个激活函数及其衍生的能力是很基础且重要的,下面为大家介绍下这两类激活函数。

    sigmoid激活函数

    从函数定义上来看,sigmoid激活函数的定义域能够取任何范围的实数,而返回的输出值在0到1的范围内。sigmoid函数也被称为S型函数,这是由于其函数曲线类似于S型,在下面的内容中可以看到。此外,该函数曲线也可以用于统计中,使用的是累积分布函数。

    sigmoid激活函数的性质

    根据定义,sigmoid激活函数的计算公式如下:
    在这里插入图片描述
    其中:

    • x: 输入
    • float:表示浮点型数据
    • exp:对其求指数
    • f(x): 函数输出

    从上述函数可以看到,x的取值范围可以是全实数,sigmoid函数返回一个实数值输出,此外,sigmoid函数的一阶导数是非负或非正:

    • 非负: 如果输入数字大于或等于零;
    • 非正: 如果输入数字小于或等于零;

    sigmoid激活函数的使用

    • Sigmoid函数用于逻辑回归模型中的二进制分类。
    • 在创建人造神经元时,Sigmoid函数用作激活函数。
    • 在统计学中,S形函数图像是常见的累积分布函数。

    sigmoid激活函数python实现并画图

    实现代码

    # Required Python Package
    import numpy as np
    
    def sigmoid(inputs):
        """
        Calculate the sigmoid for the give inputs (array)
        :param inputs:
        :return:
        """
        sigmoid_scores = [1 / float(1 + np.exp(- x)) for x in inputs]
        return sigmoid_scores
    
    
    sigmoid_inputs = [2, 3, 5, 6]
    print "Sigmoid Function Output :: {}".format(sigmoid(sigmoid_inputs))
    

    上是Sigmoid函数的实现代码。该函数将以列表形式的值作为输入参数。列表中的每个元素值将被视为Sigmoid函数的输入,并计算输出值。
    接下来,我们将一个列表sigmiod_inputs作为函数的输入,列表值为2,3,5,6,经过sigmoid函数计算后获得Sigmoid分数。
    函数输出:

    Sigmoid Function Output :: [0.8807970779778823, 0.9525741268224334, 0.9933071490757153, 0.9975273768433653]
    

    画图

    现在使用上面的函数来创建图像,以方便了解Sigmoid函数的性质。传递一个包含0到21范围内的数字的列表,计算输入列表的sigmoid分数,然后使用输出值来显示图像。

    # Required Python Packages
    import numpy as np
    import matplotlib.pyplot as plt
    
    
    def sigmoid(inputs):
        """
        Calculate the sigmoid for the give inputs (array)
        :param inputs:
        :return:
        """
        sigmoid_scores = [1 / float(1 + np.exp(- x)) for x in inputs]
        return sigmoid_scores
    
    
    def line_graph(x, y, x_title, y_title):
        """
        Draw line graph with x and y values
        :param x:
        :param y:
        :param x_title:
        :param y_title:
        :return:
        """
        plt.plot(x, y)
        plt.xlabel(x_title)
        plt.ylabel(y_title)
        plt.show()
    
    
    graph_x = range(0, 21)
    graph_y = sigmoid(graph_x)
    
    print "Graph X readings: {}".format(graph_x)
    print "Graph Y readings: {}".format(graph_y)
    
    line_graph(graph_x, graph_y, "Inputs", "Sigmoid Scores")
    

    创建一个包含0到21范围内的数字的graph_x列表,之后在graph_y列表中存储给定graph_x输入的计算sigmoid分数,调用line_graph函数,该函数采用图像的x,y和标题来创建线形图。
    脚本输出:

    Graph X readings: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
    
    Graph Y readings: [0.5, 0.7310585786300049, 0.8807970779778823, 0.9525741268224334, 0.9820137900379085, 0.9933071490757153, 0.9975273768433653, 0.9990889488055994, 0.9996646498695336, 0.9998766054240137, 0.9999546021312976, 0.999983298578152, 0.9999938558253978, 0.999997739675702, 0.9999991684719722, 0.999999694097773, 0.9999998874648379, 0.9999999586006244, 0.9999999847700205, 0.9999999943972036, 0.9999999979388463]
    

    在这里插入图片描述

    从上图可以看出,随着输入值的增加,sigmoid得分增加到1。

    softmax激活函数

    Softmax函数计算事件超过’n’个不同事件的概率分布。一般来说,这个函数将会计算每个目标类别在所有可能的目标类中的概率。计算出的概率将有助于确定给定输入的目标类别。
    使用Softmax的主要优点是输出概率的范围,范围为0到1,所有概率的和将等于1。如果将softmax函数用于多分类模型,它会返回每个类别的概率,并且目标类别的概率值会很大。指数公式计算给定输入值的指数和输入中所有值的指数值之和。那么输入值的指数与指数值之和的比值就是softmax函数的输出。

    softmax激活函数的性质

    根据定义,softmax激活函数的计算公式如下:
    在这里插入图片描述
    其中:

    • x: 输入
    • exp:对其求指数
    • f(x): 函数输出
      从上述计算公式可以看出:
    • 计算出的概率将在0到1的范围内。
    • 所有概率的和等于1。

    softmax激活函数的使用

    • 用于多重分类逻辑回归模型。
    • 在构建神经网络中,在不同的层使用softmax函数。

    softmax激活函数python实现并画图

    实现代码

    # Required Python Package
    import numpy as np
    
    
    def softmax(inputs):
        """
        Calculate the softmax for the give inputs (array)
        :param inputs:
        :return:
        """
        return np.exp(inputs) / float(sum(np.exp(inputs)))
    
    
    softmax_inputs = [2, 3, 5, 6]
    print "Softmax Function Output :: {}".format(softmax(softmax_inputs))
    

    脚本输出:

    Softmax Function Output :: [ 0.01275478  0.03467109  0.25618664  0.69638749]
    

    从中可以观察到,输入值为6时,函数输出值的概率最高,这是可以从softmax函数预先知道的。之后在分类任务中,可以使用高概率值来预测给定输入特征的目标类别。

    画图

    现在让我们使用实现的Softmax函数创建图像来了解这个函数的表现。
    创建一个包含0到21范围内的值的列表,之后将通过此列表来计算已实现函数的分数,使用列表和估计分数创建图像。

    # Required Python Packages
    import numpy as np
    import matplotlib.pyplot as plt
    
    
    def softmax(inputs):
        """
        Calculate the softmax for the give inputs (array)
        :param inputs:
        :return:
        """
        return np.exp(inputs) / float(sum(np.exp(inputs)))
    
    
    def line_graph(x, y, x_title, y_title):
        """
        Draw line graph with x and y values
        :param x:
        :param y:
        :param x_title:
        :param y_title:
        :return:
        """
        plt.plot(x, y)
        plt.xlabel(x_title)
        plt.ylabel(y_title)
        plt.show()
    
    
    graph_x = range(0, 21)
    graph_y = softmax(graph_x)
    
    print "Graph X readings: {}".format(graph_x)
    print "Graph Y readings: {}".format(graph_y)
    
    line_graph(graph_x, graph_y, "Inputs", "Softmax Scores")
    

    脚本输出:

    Graph X readings: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
    Graph Y readings: [ 1.30289758e-09 3.54164282e-09 9.62718331e-09 2.61693975e-08 7.11357976e-08 1.93367146e-07 5.25626399e-07 1.42880069e-06 3.88388295e-06 1.05574884e-05 2.86982290e-05 7.80098744e-05 2.12052824e-04 5.76419338e-04 1.56687021e-03 4.25919483e-03 1.15776919e-02 3.14714295e-02 8.55482149e-02 2.32544158e-01 6.32120559e-01]
    

    在这里插入图片描述
    该图显示了softmax函数的基本属性,输入值越大,其概率越高。

    多类分类及多标签分类

    多类分类意味着候选集是一个多分类,而不仅仅是二分类,不是是与否的问题,而是属于多类中哪一类的问题。一个样本属于且只属于多个分类中的一个,一个样本只能属于一个类,不同类之间是互斥的。举例而言,MNIST数据集,常用的数字手写体识别数据集,它的标签是一个多分类的过程,要将数字手写体识别为0~9中的某一个数字:
    在这里插入图片描述

    而对于多标签分类而言,一个样本的标签不仅仅局限于一个类别,可以具有多个类别,不同类之间是有关联的。比如一件衣服,其具有的特征类别有长袖、蕾丝等属性等,这两个属性标签不是互斥的,而是有关联的。

    使用softmax和sigmoid激活函数来做多类分类和多标签分类

    在实际应用中,一般将softmax用于多类分类的使用之中,而将sigmoid用于多标签分类之中,对于图像处理而言,网络模型抽取图像特征的结构基本相同,只是根据不同的任务改变全连接层后的输出层。下面介绍如何使用softmax和sigmoid完成对应的分类任务。

    softmax激活函数应用于多类分类

    假设神经网络模型的最后一层的全连接层输出的是一维向量logits=[1,2,3,4,5,6,7,8,9,10],这里假设总共类别数量为10,使用softmax分类器完成多类分类问题,并将损失函数设置为categorical_crossentropy损失函数:
    用tensorflow实现:

    tf.argmax(tf.softmax(logits))
    

    首先用softmax将logits转换成一个概率分布,然后取概率值最大的作为样本的分类 。softmax的主要作用其实是在计算交叉熵上,将logits转换成一个概率分布后再来计算,然后取概率分布中最大的作为最终的分类结果,这就是将softmax激活函数应用于多分类中。

    sigmoid激活函数应用于多标签分类

    sigmoid一般不用来做多类分类,而是用来做二分类,它是将一个标量数字转换到[0,1]之间,如果大于一个概率阈值(一般是0.5),则认为属于某个类别,否则不属于某个类别。这一属性使得其适合应用于多标签分类之中,在多标签分类中,大多使用binary_crossentropy损失函数。它是将一个标量数字转换到[0,1]之间,如果大于一个概率阈值(一般是0.5),则认为属于某个类别。本质上其实就是针对logits中每个分类计算的结果分别作用一个sigmoid分类器,分别判定样本是否属于某个类别同样假设,神经网络模型最后的输出是这样一个向量logits=[1,2,3,4,5,6,7,8,9,10], 就是神经网络最终的全连接的输出。这里假设总共有10个分类。通过:

    tf.sigmoid(logits)
    

    sigmoid应该会将logits中每个数字都变成[0,1]之间的概率值,假设结果为[0.01, 0.05, 0.4, 0.6, 0.3, 0.1, 0.5, 0.4, 0.06, 0.8], 然后设置一个概率阈值,比如0.3,如果概率值大于0.3,则判定类别符合,那么该输入样本则会被判定为类别3、类别4、类别5、类别7及类别8。即一个样本具有多个标签。
    在这里强调一点:将sigmoid激活函数应用于多标签分类时,其损失函数应设置为binary_crossentropy。

    展开全文
  • 分类一般分为三种情况:二分类... 在阅读了一篇类似综述总结的博客后,了以下总结,主要是实现多标签分类的几种思想,以及在深度网络的背景下实现多标签分类的几种方法。 实现多标签分类主要有两种思想,一种是...

    目录

    一、两种思想总结

    1、问题转换

    2、算法改编

    二、深度网络多标签分类

    三、多标签分类评价指标

    四、多标签分类的损失函数

    1、二分类和多分类

    2、多标签分类

    五、参考文章


    :本文为总结性文章,应该算是非原创,是在阅读了其他博主的文章的基础上总结的,感觉就是一个多标签分类学习的系统性整理,以便后续再学习查阅使用,有一些细节的实现也需要再找相应的代码或者资料学习。所有参考的文章都在最后的参考部分。

           分类一般分为三种情况:二分类、多分类和多标签分类。多标签分类比较直观的理解是,一个样本可以同时拥有几个类别标签,比如一首歌的标签可以是流行、轻快,一部电影的标签可以是动作、喜剧、搞笑,一本书的标签可以是经典、文学等,这都是多标签分类的情况。多标签分类的一个重要特点是样本的所有标签是不具有排他性的。

           在阅读了一篇类似综述总结的博客后,做了以下总结,主要是实现多标签分类的几种思想,以及在深度网络的背景下实现多标签分类的几种方法。

           实现多标签分类主要有两种思想,一种是转换,一种是直接设计多标签分类的计算,其实基于深度网络的多标签分类也包含在这两种思想里面。

    一、两种思想总结

    1、问题转换

             顾名思义,就是将多标签问题转换成其它问题进行求解,这里其实都是直接转换成分类问题,只不是根据转换思路的不同,又分成了三种不同的问题转换方式,而且这三种转换方式都在scikit-multilearn里面有实现。

    (1)二元关联

           其实这个算法非常好理解,针对每一个标签都训练一个分类器,然后用所有的分类器对样本进行预测,样本的预测标签就是所有分类器预测的标签的集合,这样,针对每一个标签训练一个二分类器就可以了。用sklearn的包的实现示例如下所示:

    # 问题转换-二元关联的方法,把每一个标签当做一个二元分类来计算
    from skmultilearn.problem_transform import BinaryRelevance
    from sklearn.naive_bayes import GaussianNB
    from sklearn.metrics import accuracy_score
    
    classifier_br = BinaryRelevance(GaussianNB())
    classifier_br.fit(x_train, y_train)
    predictions_br = classifier_br.predict(x_test)
    acc_br = accuracy_score(y_test, predictions_br)

    (2)分类器链

            这个方式也是比较好理解的,它在二元关联的基础上加上了标签的排序,在每次预测当前标签时,不仅要考虑特征数据,也要考虑这个标签的前一个标签,具体是怎么对标签进行排序,以及如何考虑前一个标签的,还需要看源码了解细节。下面是使用示例:

    # 问题转换-分类器链的方式,每一次都是一个二分类问题,每一次的分类的输入都是特征数据加上前一个标签。
    # 所以就是在二元关联方法的基础上加上了分类器的顺序
    from skmultilearn.problem_transform import ClassifierChain
    
    classifier_cc = ClassifierChain(GaussianNB())
    classifier_cc.fit(x_train, y_train)
    predictions_cc = classifier_cc.predict(x_test)
    acc_cc = accuracy_score(y_test, predictions_cc)

    (3)标签集

            英文叫法是Label Powerset,这个做法也是很直观,就是把一个样本的标签集作为一个整体,即当做一个类别标签,如果两个样本的标签集完全一样,那么这两个样本就有被认为有一样的类别标签,就被认为是一类,这就把原来的多标签问题转换成了一个多分类问题。不过这个方法有个问题就是,两两标签之间可以组合成一个新类,这样当标签很多时,要分的类别会非常多,应该会存在类别不均衡的情况。示例如下:

    # 问题转换—标签组分类。将标签一样的样本归为一类,这样就转换成了一个多分类的问题。
    from skmultilearn.problem_transform import LabelPowerset
    
    classifier_lp = LabelPowerset(GaussianNB())
    classifier_lp.fit(x_train, y_train)
    predictions_lp = classifier_lp.predict(x_test)
    acc_lp = accuracy_score(y_test, predictions_lp)
    print(acc_br, acc_cc, acc_lp)

    2、算法改编

          这种方法其实也很直观,就是把标签分类当做一个全新的任务,设计属于这个任务的实现方式,而不是将问题转换成多个相同的问题子集,这个也叫自适应算法。在sklearn中,对分类算法做了改编之后,也可以用于多标签分类,目前支持多标签分类的算法有:决策树, 随机森林,最近的邻居。在深度神经网络中,修改最后一层的输出,也是属于这种思想。下面是sklearn中的多标签算法使用示例,注意,这里有两种使用方式:

    from sklearn.datasets import make_multilabel_classification
    from sklearn import model_selection
    from sklearn.tree import DecisionTreeClassifier
    from sklearn.metrics import accuracy_score
    
    # 生成数据集
    x, y = make_multilabel_classification(n_samples=1000, n_features=5, n_classes=3, n_labels=2)
    x_train, x_test, y_train, y_test = model_selection.train_test_split(x, y, test_size=0.25, random_state=7)
    
    # 方法一,直接使用sklearn支持多分类的分类器,不需要做其它的改变
    cls = DecisionTreeClassifier()
    cls.fit(x_train, y_train)
    y_pred = cls.predict(x_test)
    acc = accuracy_score(y_test, y_pred)
    
    # 方法二,使用scikit-multilearn这个库里面的分类器
    from skmultilearn.adapt import MLkNN
    cls_mk = MLkNN(k=20)
    cls_mk.fit(x_train, y_train)
    y_pred_mk = cls_mk.predict(x_test)
    acc_mk = accuracy_score(y_test, y_pred_mk)
    print(acc, acc_mk)

    二、深度网络多标签分类

           当数据量较小的时候,可以使用上面sklearn中比较传统的多标签分类模型,当数据量较多的时候,为了准确性,可以尝试直接使用深度神经网络来做多标签分类,特别是文本分类这种任务。根据看过的一篇文章的总结,目前用深度网络实现多标签分类的方式有三种,分别如下:

    (1)比较直接的在最后加上一层全连接,在计算概率的时候用sigmod计算,即将每一个标签当做一个二分类问题,loss函数则为cross_entropy。

    (2)在网络的最后一层,针对每一个标签,使用一个全连接层,然后在每个标签上就是一个二分类问题,这个其实跟第一种方式很像,只是第一种方法中,每个标签公用了最后一层全连接层。

    (3)第三种方式就是,将任务当做是一个标签生成的过程,那这样就可以使用一个seq2seq的框架来完成了。前面使用一个encoder结构来对输入的特征数据编码,  然后在经过decoder进行解码最终生成多个标签,这个就跟机器翻译是一个思路,所以在最终生成标签的时候,会有标签的依赖关系。

            总结下来,多标签分类网络对于分类网络,修改的大概就是下面三点:

            a、转换成二分类的就是用sigmod的计算概率值

            b、根据计算的概率值和任务,使用相应的cross_entropy_loss计算

            c、网络结构的变化,比如方式(2)。

    关于这一部分的具体示例和代码,可以参考下面这篇总结文章,总结得非常全面:多标签文本分类介绍,以及对比训练

    三、多标签分类评价指标

           参考之前写的分类评价指标:分类问题中的各种评价指标

     

    四、多标签分类的损失函数

              对于分类问题,一般都用交叉熵来计算样本的损失,而loss的计算又依赖于最后一层的概率输出,所以总结下来如下:

    1、二分类和多分类

    (1)如果只是输出一个概率,来表示样本属于某类的概率是多少,那么这个时候,最后的概率输出则用sigmod(wx+b),这个使用的是sigmod_cross_entropy_loss,计算公式如下:

    例如:判断一个样本是不是猫,输入的是一个正样本,也就是是猫的样本,那么,输入样本可以表示为{x = feature,y = 1},模型的输出就是一个[在0到1之间的一个概率值p,这个概率就是通过sigmod计算出来,然后再根据样本的真实标签是0或者1(也就是上面公式中的y_i),和这个概率值p(对应公式中的h_theat(x)),根据上面的公式,计算该样本的loss。

    (2)如果对于一个二分类问题,想要输出一个二维的向量,一维表示是这个类别的概率是多少,一个表示不是的概率是多少,那么这个时候最后一层输出的概率就要用softmax来计算,公式如下:

     针对这种情况,就要用softmax_cross_entropy来计算loss,计算公式就是常规的交叉熵的计算公式,公式如下:

    例如: 判断一个样本是不是猫,输入的是一个正样本,也就是是猫的样本,那么,输入样本也可以表示为{x = feature,y = [1, 0]},如果是负样本,则相应的y=[0, 1],模型的输出则为[p, 1-p],这个时候,样本的loss就根据上面的公式计算了。感觉这个例子比较无聊,比较没有意义,下面可以换个例子。

    加入判断一个样本是猫还是狗,y=[1, 0]表示样本是猫,y=[0, 1]表示样本时是狗,模型的输出根据公式计算也会是[p, 1-p],后面的loss计算也是上面的公式

    (3)对于一个多分类问题,比如判断是猫、狗或者人,是一个三分类问题,每个类别分类对应的y就是[1, 0, 0]、[0, 1, 0]、[0, 0, 1],最终样本的概率输出,以及loss计算也就是(2)中的两个公式。

    2、多标签分类

           对于多标签分类,概率输出和loss计算也是遵循上面的计算原则。对于多标签分类的时候,因为标签之间不互斥,所以只需要确定每个标签存不存在即可,所以最终每个标签可以当做一个二分类问题来看,那么在相应的标签上的概率和loss计算则可以沿用二分类的计算方法。

           例如,需要预测的标签有5个,对于给定的样本{x, y=[y1, y2, y3, y4, y5]},模型的输出为y=[p1, p2, p3, p4, p5],那么这个里面的p值就是直接使用sigmod计算得来的,每个标签的loss也用sigmod_cross_entropy计算,公式如下:

    这里有5个标签,每一个标签要分别将对应的yi和预测的pi带入到上面的式子计算一个loss,然后5个标签的loss平均,即为给定样本的loss。具体计算可以参考这里:多标签分类要用什么损失函数? - tik boa

    五、参考文章

    1、多标签(multi-label)数据的学习问题,常用的分类器或者分类策略有哪些? - 景略集智

    2、多标签分类(multi-label classification)综述

    3、sklearn 多分类多标签算法

    4、多标签文本分类介绍,以及对比训练 - HelloNLP的文章 

    5、多标签分类要用什么损失函数? - tik boa

    6、一个提供多标签分类的数据集:Mulan: A Java Library for Multi-Label Learning

    展开全文
  • 文本分类之多标签分类

    千次阅读 2020-02-19 11:30:12
    多标签分类综述 意义 网络新闻往往含有丰富的语义,一篇文章既可以属于“经济”也可以属于“文化”。给网络新闻打标签可以更好地反应文章的真实意义,方便日后的分类和使用。 难点 类标数量不确定,有些样本...
  • 多标签分类问题的评价指标

    万次阅读 2018-09-09 09:39:04
    多标签分类的评价指标 标签学习系统中的性能评估与经典的单标签学习问题中不同,在单标签问题中使用的经典度量标准包括准确率,Precision,Recall 和 F-measure.在标签学习中,评估会更加复杂,对于一个测试...
  • 多标签分类(multilabel classification )

    万次阅读 2018-05-17 10:25:48
        这几天看了几篇相关的文章, 写篇文章总结一下,就像个小综述一样, 文章会很乱   &...多标签分类问题很常见, 比如一部电影可以同时被分为动作片和犯罪片,...
  • 使用python和sklearn的文本多标签分类实战开发

    千次阅读 多人点赞 2019-03-04 20:41:40
    文本分类一般可以分为二分类、分类、多标签分类三种情况,二分类是指将一组文本分成两个类(0或1),比较常见的应用如垃圾邮件分类、电商网站的用户评价数据的正负面分类等,分类是指将文本分成若干个类中的某一个类,...
  • 深度学习---多标签分类问题

    万次阅读 多人点赞 2018-05-06 11:18:10
    由于本项目既有涉及multi-class(分类),也有涉及multi-label(标记分类)的部分,multi-class分类网上已经很相关的文章了。这里就说一说multi-label的搭建网络的部分。之后如果有时间的时候,再说一说...
  • 类别分类(Multiclass Classification) ...多标签分类又称标签学习、标记学习,不同于多类别分类,一个样本可以属于个类别(或标签),不同类之间是有关联的。 sklearn.multiclass 提供了很机器学习...
  • keras解决多标签分类问题

    万次阅读 热门讨论 2018-03-19 17:18:47
    multi-class classification problem: 分类问题是相对于二分类问题(典型的0-1分类)来...multi-label classification problem:多标签分类(或者叫标记分类),是指一个样本的标签数量不止一个,即一个样本对...
  • 使用Bert模型进行多标签分类

    千次阅读 2019-08-28 10:42:47
    使用Bert模型的run_classifier进行Fine-Tuning https://blog.csdn.net/liu_sir_/article/details/85117239
  • caffe任务学习之多标签分类

    万次阅读 多人点赞 2016-11-15 20:50:30
    后来发现现在深度学习中的任务学习可以实现多标签分类,所有的类别只需要训练一个分类模型就行,其不同属性的类别之间是共享卷积层的。我所有的项目开发都是基于caffe框架的,默认的,Caffe中的Data层只支持单维
  • 分类:类别数目大于2个,类别之间是互斥的。比如是猫,就不能是狗、猪 标签:类别之间不是互斥的。它有个label,比如既有类别,又有...多标签分类: 一个样本可以属于个类别(或标签),不同类之间是有关联...
  • 多标签分类的激活函数和损失函数

    千次阅读 2019-07-16 15:39:58
    于是查阅了一些资料,了解一下分类任务与多标签分类任务的异同。 -分类任务:只有一个标签,但是标签有多种类别。 -多标签分类任务:一条数据可能有一个或者个标签,比如一个病人的眼底检测报告,它可能被...
  • pytorch 多标签分类以及BCEloss

    千次阅读 2019-11-15 10:35:12
    什么是多标签分类 学习过机器学习的你,也许对分类问题很熟悉。比如下图: image.png 图片中是否包含房子?你的回答就是有或者没有,这就是一个典型的二分类问题。 image.png 同样...
  • 使用Keras进行单模型多标签分类

    千次阅读 2019-03-26 12:14:38
    最后,我们将通过在示例图像上测试我们的网络来结束今天的博客文章,并讨论何时适合多标签分类,包括您需要注意的一些注意事项。 数据集 图1:类深度学习数据集的蒙太奇。 我们将使用Keras训练多标签分类器...
  • 基于ML-KNN的多标签分类算法

    万次阅读 热门讨论 2018-04-12 10:41:50
    最近有一个项目需要用多标签分类思想来建模,之前对这块不是太了解,查了一些论文,发现目前主流的算法包括ML-KNN、ML-DT、Rank-SVM、CML等,其中ML-KNN算法思想最简单,结合原始论文,本文大概介绍下算法思想和代码...
  • 使用BERT模型进行多标签分类

    千次阅读 2019-12-26 11:47:07
    首先,多标签分类就是将单输出改为输出,最原始的想法是训练个分类模型,每个模型预测不同的输出,比如,在预测顾客对饭店的评价中,第一个模型预测口感如何,第二模型预测交通是否方便,尽管会浪费时间、存储和...
  • multi-class classification problem: 分类问题是相对于二分类问题(典型的0-1分类)来...multi-label classification problem:多标签分类(或者叫标记分类),是指一个样本的标签数量不止一个,即一个样本对...
  • 基于ML-DecisionTree的多标签分类算法

    千次阅读 热门讨论 2018-04-12 11:13:41
    之前有一篇文章介绍了ML-KNN多标签分类算法,这里再介绍另一个算法ML-DT,算法思想比较简单,借鉴了决策树根据信息增益筛选特征生成分类器的思想,标签场景下,信息增益表示的是该特征对所有标签的鉴别能力。...
  • 本文基于sigmoid了一个将一段长文本打上标签的算法模型,首先声明,我的模型最终的效果不好,因为我的文本很长,而且采用的模型很简单,就一层神经网络,权当练手。 数据集文件的格式为每行一个样本,以制表...
  • 补充:(1)、Guide To Multi-Class Multi-Label Classification With Neural Networks In Python(2)、多标签分类(multilabel classification )1、使用caffe训练一个多标签分类/回归模型2、keras解决...
  • 目的: 训练一个分类器来将物品分到不同的类别中,比如一件衣服:可以安照服饰...首先讨论多标签分类数据集(以及如何快速构建自己的数据集)。 之后简要讨论SmallerVGGNet,我们将实现的Keras神经网络架构,并...
  • 最近一直在做多标签分类任务,学习了一种层次注意力模型,基本结构如下: 简单说,就是两层attention机制,一层基于词,一层基于句。 首先是词层面: 输入采用word2vec形成基本语料向量后,采用双向GRU抽特征: 一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 194,142
精华内容 77,656
关键字:

多标签分类怎么做