keras解决多标签分类问题(附python代码)

multi-class classification problem: 多分类问题是相对于二分类问题(典型的0-1分类)来说的,意思是类别总数超过两个的分类问题,比如手写数字识别mnist的label总数有10个,每一个样本的标签在这10个中取一个。

multi-label classification problem:多标签分类(或者叫多标记分类),是指一个样本的标签数量不止一个,即一个样本对应多个标签。

一般问题定义
一般情况下,假设我们的分类问题有5个标签,样本数量为n,数学表示为: 
X={x1,x2,...,xn}Y={y1,y2,y3,y4,y5},其中yi∈{1,2,3,4,5}
X={x1,x2,...,xn}Y={y1,y2,y3,y4,y5},其中yi∈{1,2,3,4,5}

我们用神经网络模型对样本建模,计算P(cj|xi)P(cj|xi) :样本xixi 的标签为cjcj的概率。模型的输出为: 
y^i=argmaxj∈{1,2,3,4,5}P(cj|xi)
y^i=arg⁡maxj∈{1,2,3,4,5}P(cj|xi)

现在我们用keras的Sequential 模型建立一个简单的模型:
from keras.layers import Input,Dense
from keras.models import Sequential

model = Sequential()
model.add(Dense(10, activation="relu", input_shape=(10,)))
model.add(Dense(5))


multi-class classification
对于多分类问题,接下来要做的是输出层的设计。在多分类中,最常用的就是softmax层。

softmax层中的softmax 函数是logistic函数在多分类问题上的推广,它将一个N维的实数向量压缩成一个满足特定条件的N维实数向。压缩后的向量满足两个条件:

像两种的每个元素的大小都在[0,1]
所有向量元素的和为1
因此,softmax适用于多分类问题中对每一个类别的概率判断,softmax计算公式: 
Softmax(xi)=exi∑niexi
Softmax(xi)=exi∑inexi

python 代码示例:
import numpy as np

def Softmax_sim(x):
    y = np.exp(x)
    return y/np.sum(y)

x = np.array([1.0,2.0,3.0,4.0,1.0])
print(Softmax_sim(x))
#输出:[ 0.03106277  0.08443737  0.22952458  0.6239125   0.03106277]

假设隐藏层的输出为[1.0,2.0,3.0,4.0,1.0],我们可以根据softmax函数判断属于标签4

所以,利用keras的函数式定义多分类的模型:

from keras.layers import Input,Dense
from keras.models import Model

inputs = Input(shape=(10,))
hidden = Dense(units=10,activation='relu')(inputs)
output = Dense(units=5,activation='softmax')(hidden)

 


mulit-label classification
在预测多标签分类问题时,假设隐藏层的输出是[-1.0, 5.0, -0.5, 5.0, -0.5 ],如果用softmax函数的话,那么输出为:

z = np.array([-1.0, 5.0, -0.5, 5.0, -0.5 ])
print(Softmax_sim(z))
# 输出为[ 0.00123281  0.49735104  0.00203256  0.49735104  0.00203256]


通过使用softmax,我们可以清楚地选择标签2和标签4。但我们必须知道每个样本需要多少个标签,或者为概率选择一个阈值。这显然不是我们想要的,因为样本属于每个标签的概率应该是独立的。

对于一个二分类问题,常用的激活函数是sigmoid函数: 
σ(x)=11+e−x
σ(x)=11+e−x

ps: sigmoid函数之所以在之前很长一段时间作为神经网络激活函数(现在大家基本都用Relu了),一个很重要的原因是sigmoid函数的导数很容易计算,可以用自身表示: 
σ′(x)=σ(x)(1−σ(x))
σ′(x)=σ(x)(1−σ(x))

python 代码为:
import numpy as np

def Sigmoid_sim(x):
    return  1 /(1+np.exp(-x))

a = np.array([-1.0, 5.0, -0.5, 5.0, -0.5])
print(Sigmoid_sim(a))
#输出为: [ 0.26894142  0.99330715  0.37754067  0.99330715  0.37754067]

此时,每个标签的概率即是独立的。完整整个模型构建之后,最后一步中最重要的是为模型的编译选择损失函数。在多标签分类中,大多使用binary_crossentropy损失而不是通常在多类分类中使用的categorical_crossentropy损失函数。这可能看起来不合理,但因为每个输出节点都是独立的,选择二元损失,并将网络输出建模为每个标签独立的bernoulli分布。整个多标签分类的模型为:

from keras.models import Model
from keras.layers import Input,Dense

inputs = Input(shape=(10,))
hidden = Dense(units=10,activation='relu')(inputs)
output = Dense(units=5,activation='sigmoid')(hidden)
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

 


参考
Guide To Multi-Class Multi-Label Classification With Neural Networks In Python

keras实践(一): multi-label神经网络

Softmax回归
--------------------- 
作者:somTian 
来源:CSDN 
原文:https://blog.csdn.net/somTian/article/details/79614570 
版权声明:本文为博主原创文章,转载请附上博文链接!

你可能感兴趣的:(python)