机器学习:分类器介绍

目录

一 softmax 简介

计算loss时,预测值要与真实值分布在相同的数据区间内,例如真实值在[0,1]区间内,那么神经网络的预测值最好也要在相同的区间(0,1)内;这样在计算loss是才会有较好的效果。

在做二分类时,可在网络的输出层使用激活函数sigmoid(),将输出压缩在(0,1)区间,

softmax可看做是对sigmoid的扩展,是用于多分类的激活函数,softmax就是将网络的输出转化成对应类别的概率值;

二 cross_entropy

交叉熵(KL散度)是统计学中两个数据分布差异的一直度量;

其中p(x)是labels,q(x)是logits

三 tensorflow中计算cross_entropy的方式

目前主流的深度学习开发框架为Tensorflow,这一节将对如何在tensorflow中使用上述方法作一个简短的介绍。

(1)自己使用公式计算

soft_max = tf.nn.softmax(logits)

cross_entropy = -tf.reduce_sum(labels*tf.log(soft_max),1)

loss = tf.reduce_mean(cross_entropy)

上面,cross_entropy是一个shape是[batch_size]的tensor,而loss是shape是1的数值,需要使用tf.reduce_sum()或者tf.reduce_mean()计算当前batch_size的总交叉熵loss,或者平均交叉熵loss;

或者不指定tf.reduce_sum()的axis,直接求当前batch的交叉熵总和作为loss

soft_max = tf.nn.softmax(logits)

loss = -tf.reduce_sum(labels*tf.log(soft_max))

tips:tf.reduce_sum()默认是计算输入tensor的总和,指定axis时,会按照指定的轴进行求和;

(2)Softmax交叉熵,label使用one_hot编码

使用tf.nn.softmax_cross_entropy_with_logits(logits,onehot_labels,name=None)

适用于每个类别独立并且相互排斥,也就是每张图片自能属于一种类别

输入:logits和labels必须具有相同的shape,和dtype。labels必须是one-hot编码形式。

输出:shape=[batch_size]的交叉熵cross_entropy

此函数会做两件事:

对网络输出使用softmax,转化成总和为1,对应于各个类别的概率值
使用交叉熵公式计算cross_entropy,此时cross_entropy是shape=[batch_size],可以认为是batch中每个图片的交叉熵的值;

同时要注意与tf.losses.softmax_cross_entropy(logits,onehot_labels)的区别, tf.losses.softmax_cross_entropy()返回的是平均交叉熵的值,相当于在tf.nn.softmax_cross_entropy_with_logits()后加上tf.reduce_mean()对交叉熵求平均,

此函数会做三件事:

对网络输出使用softmax,转化成总和为1,对应于各个类别的概率值
使用交叉熵公式计算cross_entropy,此时cross_entropy是shape=[batch_size],可以认为是batch中每个图片的交叉熵的值;
使用tf.reduce_mean(cross_entropy)计算平均交叉熵

(3)Softmax交叉熵,labels不使用one_hot编码

使用tf.nn.sparse_softmax_cross_entropy_with_logits(logits,labels,name=None)

适用于每个类别独立并且相互排斥

输入:logits[batch_size,num_classes],label是从0开始代表类别的整形数组,必须是非one-hot编码

输入:shape=[batch_size]的交叉熵cross_entropy

tf.losses.sparse_softmax_cross_entropy()也是相当于在tf.nn.sparse_softmax_cross_entropy_with_logits后加上tf.reduce_mean对列表求均值;

(4)sigmoid交叉熵,激活函数使用sigmoid

使用tf.nn.sigmoid_cross_entropy_with_logits(logits,labels,name=None)

适用于每个类别相互独立,并且不相互排斥,也就是说每个图片可以属于多个类别;

输入:logits,labels 必须具有相同的shape和type

输出:shape=[batch_size,num_classes]当前batch中网络输出节点每个节点的cross_entropy

用sigmoid做分类原本只能用于二分类,例如,网络输出节点1个,使用sigmoid函数将网络输出压缩至(0,1)范围内,用0和1代表两个类别;

将sigmoid扩展至多分类,例如假设num_classes=10,对一张图片中包含的数字(0~9)做分类(一张图片可能包含多种数字),标签label可能是(1,0,1,1,0,0,1,0,1,0)(图片包含0,2,3,6,8,数字),那么将网络的输出节点设置为10,对于每个节点使用都sigmoid激活函数来做二分类,判断是/不是当前类别;如第一个输出节点判别是否包含数字1,第二个判别是否包含数字2…

loss使用交叉熵cross_entropy=-labels(tf.log(sigmoid(logits)))-(1-labels(tf.log(1-sigmoid(logits))))

或者使用tf.nn.sigmoid_cross_entropy_with_logits(logits,labels,name=None)

loss = tf.reduce_mean(cross_entropy)

或者使用tf.losses.sigmoid_cross_entropy()直接求平均交叉熵loss。

tips:softmax激活函数会使用所用的输出节点一起来计算属于每个类别的概率,而sigmoid激活函数只针对当前节点,返回包含当前节点类别的概率,

此函数会做两件事:

对网络输出使用sigmoid,
使用交叉熵公式计算cross_entropy

没有更多推荐了,返回首页