Multi Class Classfication - Softmax

Multi Class Classification

在二分类任务中,y只可能取两个值,通常表示为0/1。

而在多分类任务中,y可能取不止两个离散值,例如预测所有的手写数字,则y可以取0123456789,就是一个多分类任务。一个多分类任务的数据图示可能类似于下图

在这里插入图片描述

Softmax

Equation

Softmax算法是Logistic算法的推广(generalization),在logistic regression中,我们使用表达式
S i g m o i d ( z ) = 1 1 + e − z Sigmoid(z) = \frac 1 {1 + e^{-z}} Sigmoid(z)=1+ez1

而对于softmax regression,其表达式为
S o f t m a x ( z ⃗ ) j = e z j ∑ k = 1 N e z k Softmax(\vec z)_j = \frac {e^{z_j}}{\sum_{k = 1}^N e^{z_k}} Softmax(z )j=k=1Nezkezj

softmax实际所做的事情是将包含k个实数的向量,转换为同样包含k个实数,但实数和为1的向量。

与sigmoid不同,softmax计算的对象是向量(vector),而sigmoid计算的对象是标量(scalar)

当只有两个分类器的时候,设输入向量为 [ z , 0 ] [z, 0] [z,0],则有
S o f t m a x ( [ z , 0 ] ) 1 = e z e z + e 0 = e z e z + 1 Softmax([z, 0])_1 = \frac {e^z} {e^z + e^0} = \frac {e^z} {e^z + 1} Softmax([z,0])1=ez+e0ez=ez+1ez
上下同除 e z e^z ez,得
S o f t m a x ( [ z , 0 ] ) 1 = 1 1 + e − z Softmax([z, 0])_1 = \frac 1 {1 + e^{-z}} Softmax([z,0])1=1+ez1

输入可以是+/-/0,输出范围[0, 1]。当输入很小或者为负的时候,输出逼近0;当输入很大的时候,输出逼近1;综合这两个特性,可以将输出解释为概率。

使用Softmax作为分类器的一个前提是类别之间互斥(mutually exclusive)。如果存在某些样例可以同时是多个类别的成员,则不可以使用Softmax,而应该使用多个logistic(拆分成多个二分类)。

使用NumPy表示:

def softmax(z):
	'''
	convert vector values to probability
	Args:
		z (ndarray (N,)) : inputs, N features from linear function
	Returns:
		a (ndarray (N,)) : softmax of z
	'''
    ez = np.exp(z)
    a = ez / ez.sum()
    return a

在softmax中,指数会对最大值产生放大效应,这也是为什么它叫“softmax",我们可以从一下几个示例中观察到这个性质

在这里插入图片描述

在这里插入图片描述

Loss & Cost

在前一篇我们讨论了交叉熵法。复习一下,对于对率回归,其loss为
l o s s = − y log ⁡ f ( x ) − ( 1 − y ) log ⁡ ( 1 − f ( x ) ) loss = -y\log f(x) - (1-y) \log (1 - f(x)) loss=ylogf(x)(1y)log(1f(x))
cost取所有loss的均值,等价于求交叉熵
c o s t = − P ( y = 1 ) log ⁡ f ( x ) − [ 1 − P ( y = 1 ) log ⁡ [ 1 − f ( x ) ] cost = -P(y = 1) \log f(x) - [1-P(y = 1)\log[1-f(x)] cost=P(y=1)logf(x)[1P(y=1)log[1f(x)]

同理可知,Softmax函数的cost为
c o s t = E x ∼ P ( − log ⁡ f ( x ) ) cost = \mathrm{E}_{x \sim P}(-\log f(x)) cost=ExP(logf(x))
其中,P是观测数据的分布,f是模型函数。

可推得loss
a j = e z j ∑ k = 1 N e z k = P ( y = j ) l o s s = − log ⁡ a j \begin{array}{l} a_j = \frac {e^{z_j}}{\sum_{k = 1}^N e^{z_k}} = P(y = j) \newline loss = -\log a_j \end{array} aj=k=1Nezkezj=P(y=j)loss=logaj

在这里插入图片描述

从图像可以看出,当 a j a_j aj接近1的时候,loss下降减慢,当 a j a_j aj逼近0的时候,loss下降加快。

Neural Network with Softmax output

还是识别手写体的例子,假设要识别手写体0~9,则输出层应该有10个units,并选用Softmax作为激活函数。

因为手写体的数字都是互斥的,所以可以用Softmax

在这里插入图片描述

Softmax的输入是整个向量,计算单个结果需要依赖所有的向量元素。

代码

import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.deras.layers import Dense
# 设置模型
model = Sequential([
    Dense(units = 25, activation = 'relu'),
    Dense(units = 15, activation = 'relu'),
    Dense(units = 10, activation = 'softmax')
])
# 指定loss
from tensorflow.keras.losses import SparseCategoricalCrossentropy
model.compile(loss = SparseCategoricalCrossentropy)
# 训练
model.fit(X, Y, epochs = 100)

SparseCategoricalCrossentropy是label和prediction之间的交叉熵,也就是前面的公式

这部分代码可以运行,但不是效率最好的,只是为了整理前面所学的知识,后面会给出更推荐的写法。

Improved Implements

Round out Errors

设以下两个等价的运算
x = 2 10000 x = ( 1 + 1 10000 ) − ( 1 − 1 10000 ) x = \frac 2 {10000} \newline x = (1 + \frac 1 {10000}) - (1 - \frac 1 {10000}) x=100002x=(1+100001)(1100001)

如果在计算机中运行的话,可能出现舍入错误

>>> x = 2.0 / 10000.0
>>> print(f'{x:.18f}')
0.000200000000000000
>>> x = 1 + 1.0/10000.0 - (1 - 1.0/10000.0)
>>> print(f'{x:.18f}')
0.000199999999999978

在logistic和softmax算法中,同样存在这种舍入问题。我们需要选择更为合理的计算方法,来减少舍入误差。

More numerically accurate implement of logistic loss

首先讨论如何更精确计算logistic loss,只需要将输出层的激活函数改为linear,并设置loss的from_logit属性为True即可

model = Sequential([
    Dense(units = 25, activation = 'relu'),
    Dense(units = 15, activation = 'relu'),
    # Dense(units = 10, activation = 'sigmoid')
    Dense(units = 10, activation = 'linear') # 这里改用linear
])

# model.compile(loss = BinaryCrossEntropy())
model.compile(loss = BinaryCrossEntropy(from_logits = True))

logit是logistic函数的反函数,因此数学定义为
l o g i t   p = ln ⁡ p 1 − p \mathrm{logit}\ p = \ln \frac p {1 - p} logit p=ln1pp
因此也被称为对数几率(log-odds)。应用from_logit意味着传递logit而不是probability,在logistic regression中,这个值就是 z z z。TensorFlow源码中也推荐使用from_logits = True

当设置from_logits = false的时候,首先会计算f = \frac 1 {1 + e{-x*w + b}},再将这个值带入cost表达式;而当设置from_logits = True的时候,会直接将f先带入cost表达式,再进行计算,这样就能减少舍入,并且让tensorflow重新排列各项,提高运算的精度。

这种运算方式在logistic regression中提升不明显,但在softmax regression中提升非常显著

More numerically accurate implement of softmax

softmax的loss表达式为
l o s s = − log ⁡ e z j ∑ k = 1 N e z k loss = -\log \frac {e^{z_j}}{\sum_{k = 1}^N e^{z_k}} loss=logk=1Nezkezj
直觉上,可能存在某些极端大或极端小的 e z j e^{z_j} ezj,使得计算的精度变差;而通过设置from_logits = True,TensorFlow可以重新排列部分表达式,避免极端值的出现。

代码

model = Sequential([
    Dense(units = 25, activation = 'relu'),
    Dense(units = 15, activation = 'relu'),
    Dense(units = 10, activation = 'linear')
])

model.compile(loss = SparseCategoricalCrossEntropy(from_logits = True))

当然,因为输出层变成了linear,predict的输出会变成z而不是概率,需要再用对应的函数求一次概率

# in logistic regression
predict = tf.nn.sigmoid(model(X))

# in softmax
predict = tf.nn.softmax(model(X))

Multi Label Classification

Multi Class 和 Multi Label是经常容易混淆的两个概念。在前面我们讨论了Multi Class Classification,输出label可能是多个label中的一个(多个中的一个);而对于Multi Label Classification问题,同一个输入可能对应着多个label

例如,在道路目标检测的问题中,同一张图像中可能既有car,也有person,也有bus。如下面一组图所示。

在这里插入图片描述

解决这类问题,需要输出层输出多个输出结果,例如可以用一个0/1数组,其中的每一项都表示场景中是否存在对应的label

在这里插入图片描述

Adaptive Moment estimation

简称Adam算法,该算法能够自动调整学习率 α \alpha α的大小,并作出调整

  • 当学习率较低,持续向同一个方向下降时,算法会增大学习率
  • 当学习率过高,发生振荡的时候,算法会减小学习率

在这里插入图片描述

使用示例:在MNIST模型上应用

# model
model = Sequential([
    tf.keras.layers.Dense(25, activation = 'sigmoid'),
    tf.keras.layers.Dense(15, activation = 'sigmoid'),
    tf.keras.layers.Dense(10, activation = 'linear'),
])
# compile
model.compile(optimizer = tf.keras.optimizers.Adam(learning_rate = 1e-3),
             loss = tf.keras.SparseCategoricalCrossentropy(from_logits = True))
# fit
model.fit(X, Y, epochs = 100)

Adam需要提供一个初始学习率,可以像之前梯度下降中所做的那样,尝试不同数量级的学习率,选择训练速度最快的那个。

为了细微调节,不同层的学习率会有不同。

Adam通常是比较推荐的优化算法。

Additional Layer Types

到现在为止,我们使用的都是Dense类型的层,在这里讨论其他的常用层类型。

Convolutional Layer

卷积层的每个神经元只能看到前一个层输出数据的一部分,这样做有两个优势

  • 计算更快
  • 不易过拟合,需要的训练数据更少

使用至少一层卷积层的神经网络称为Convolutional Neural Network(CNN,卷积神经网络),以心电图信号分类为例子进行说明,如图所示,该神经网络处理心电图的时间序列,包含两个卷积层。

在这里插入图片描述

机器学习这门课不会过多深入CNN,知道layer不只有Dense就可以了。

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Recitative

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值