SoftMax回归详解

SoftMax 回归

推导

数据说明

  • 数据集: { ( x i , y i ) } i = 1 m \{(x_i, y_i)\}_{i=1}^m {(xi,yi)}i=1m m m m 个样本)
  • x i x_i xi 可能是多维(假设有 d d d 维)
  • y i y_i yi 是类别 { 0 , 1 , 2 , . . . , k } \{0,1,2,...,k\} {0,1,2,...,k}(分为 k + 1 k+1 k+1 类)的 O n e H o t OneHot OneHot 编码
  • y i = j y_i=j yi=j(属于第 j j j 类)简称 y i j y_i^j yij,且 y i j = [ 0 , 0 , . . . , 1 , . . . , 0 ] y_i^j=[0,0,...,1,...,0] yij=[0,0,...,1,...,0](下标 j j j 的位置为 1 1 1

本质

  • 使用归一化 S o f t M a x SoftMax SoftMax 函数: p = e − ( ω T x + b ) ∑ j = 0 k e − ( ω j T x + b j ) = e − y ∑ j = 0 k e − y j p=\frac{e^{-(\omega^Tx+b)}}{\sum_{j=0}^k e^{-(\omega_j^Tx+b_j)}}=\frac{e^{-y}}{\sum_{j=0}^ke^{-y^j}} p=j=0ke(ωjTx+bj)e(ωTx+b)=j=0keyjey,将线性回归 y = ω T x + b y=\omega^Tx+b y=ωTx+b 与多分类任务 { 0 , 1 , 2 , . . . , k } \{0,1,2,...,k\} {0,1,2,...,k} 联系起来,得到了 p = e − y ∑ j = 0 k e − y j p=\frac{e^{-y}}{\sum_{j=0}^ke^{-y^j}} p=j=0keyjey
  • 通过梯度下降法得到参数 ω \omega ω b b b(每一类对应一组参数,总共 k + 1 k+1 k+1 ω \omega ω b b b),代入要分类的样本 x x x,计算出对应的 y y y 值(相当于该样本的类后验概率 p ( y ∣ x ) p(y|x) p(yx),简称属于第 j j j 类的后验概率 p ( y = j ∣ x ) p(y=j|x) p(y=jx) p j p^j pj),并与多个阈值比较,完成分类
与 Logistic 回归的关系(重点)
关系
  • Logistic 回归是 SoftMax 回归的特殊形式
  • y ∈ { 0 , 1 } y\in\{0,1\} y{0,1},则 S o f t M a x SoftMax SoftMax 函数计算类后验概率 p ( y = 0 ∣ x ) = e − y 0 e − y 0 + e − y 1 = 1 1 + e − y 1 p(y=0|x)=\frac{e^{-y^0}}{e^{-y^0}+e^{-y^1}}=\frac{1}{1+e^{-y^1}} p(y=0x)=ey0+ey1ey0=1+ey11,即 Logistic 回归的形式
求导的关系(重点)
  • 便于推导,令 θ = ( b , ω ) \theta=(b,\omega) θ=(b,ω) d + 1 d+1 d+1 维),对应的 x = ( 1 , x ) x=(1,x) x=(1,x),(也就是增广)
  • 在 Logistic 回归中,我们实际是对 p 0 = 1 1 + e − y 1 = e − y 0 e − y 0 + e − y 1 p^0=\frac{1}{1+e^{-y^1}}=\frac{e^{-y^0}}{e^{-y^0}+e^{-y^1}} p0=1+ey11=ey0+ey1ey0 中的 θ = ( θ 0 , θ 1 ) \theta=(\theta_0,\theta_1) θ=(θ0,θ1) 求导,即对每个类对应的一组 θ \theta θ 求导,结果再求和,如下
  • ∂ p 0 ∂ θ = ∂ p 0 ∂ θ 0 + ∂ p 0 ∂ θ 1 = p 0 ( 1 − p 0 ) + 0 = p 0 ( 1 − p 0 ) \frac{\partial p^0}{\partial\theta}=\frac{\partial p^0}{\partial\theta_0}+\frac{\partial p^0}{\partial\theta_1}=p^0(1-p^0)+0=p^0(1-p^0) θp0=θ0p0+θ1p0=p0(1p0)+0=p0(1p0)
  • 于是求导的情况就分为两类:
    • 要计算类后验概率 p a p^a pa,对类 a a a 对应的参数 θ a \theta_a θa 求导(如上面的 ∂ p 0 ∂ θ 0 \frac{\partial p^0}{\partial\theta_0} θ0p0
    • 要计算类后验概率 p a p^a pa,却对类 b b b 对应的参数 θ b \theta_b θb 求导(如上面的 ∂ p 0 ∂ θ 1 \frac{\partial p^0}{\partial\theta_1} θ1p0

损失函数

  • 由于预测结果是多类概率,这里 p = [ p 0 , p 1 , . . . , p k ] p=[p^0,p^1,...,p^k] p=[p0,p1,...,pk]
  • 交叉熵损失函数: J ( θ ) = − 1 m ∑ i = 1 m ∑ j = 0 k [ y i j l n p i ] J(\theta)=-\frac{1}{m}\sum_{i=1}^m\sum_{j=0}^k[y_i^jlnp_i] J(θ)=m1i=1mj=0k[yijlnpi]

梯度下降法求参数 ω \omega ω, b b b

  • S o f t M a x SoftMax SoftMax 函数求导性质:对于 p a = e − y a ∑ j = 0 k e − y j p^a=\frac{e^{-y^a}}{\sum_{j=0}^ke^{-y^j}} pa=j=0keyjeya,有 ∂ p a ∂ y = { p a ( 1 − p a ) , y = y a − p a p b , y = y b \frac{\partial p^a}{\partial y}=\left\{ \begin{aligned} p^a(1-p^a), && y=y^a\\ -p^ap^b, && y=y^b \end{aligned} \right. ypa={pa(1pa),papb,y=yay=yb(对应上面求导的两类情况)
  • 求偏导: ∂ J ( θ ) ∂ θ = − 1 m ∑ i = 1 m [ y i p i a ( 1 − p i a ) x i p i a + ∑ j = 0 , j ≠ a k y i j ( − p i a p i j ) x i p i j ] \frac{\partial J(\theta)}{\partial\theta}=-\frac{1}{m}\sum_{i=1}^m[\frac{y_ip_i^a(1-p_i^a)x_i}{p_i^a}+\sum_{j=0,j\not=a}^k\frac{y_i^j(-p_i^ap_i^j)x_i}{p_i^j}] θJ(θ)=m1i=1m[piayipia(1pia)xi+j=0,j=akpijyij(piapij)xi]
  • 继续: = − 1 m ∑ i = 1 m [ y i a ( 1 − p i a ) + ∑ j = 0 , j ≠ a k y i j ( − p i a ) ] x i =-\frac{1}{m}\sum_{i=1}^m[y_i^a(1-p_i^a)+\sum_{j=0,j\not=a}^ky_i^j(-p_i^a)]x_i =m1i=1m[yia(1pia)+j=0,j=akyij(pia)]xi
  • 继续: = − 1 m ∑ i = 1 m [ y i a ∑ j = 0 , j ≠ a k p i j − p i a ∑ j = 0 , j ≠ a k y i j ] x i =-\frac{1}{m}\sum_{i=1}^m[y_i^a\sum_{j=0,j\not=a}^kp_i^j-p_i^a\sum_{j=0,j\not=a}^ky_i^j]x_i =m1i=1m[yiaj=0,j=akpijpiaj=0,j=akyij]xi ,(注意 1 − p i a = ∑ j = 0 , j ≠ a k p i j 1-p_i^a=\sum_{j=0,j\not=a}^kp_i^j 1pia=j=0,j=akpij
  • 得到: = 1 m ∑ i = 1 m [ p i − y i j ] x i =\frac{1}{m}\sum_{i=1}^m[p_i-y_i^j]x_i =m1i=1m[piyij]xi(与 Logistic 完全一样)

实现

  • 在 jupyter notebook 中代码均可运行

读取鸢尾花数据集

from sklearn import datasets
import numpy as np

iris = datasets.load_iris()    #加载鸢尾花数据集

X = iris["data"][:, (2, 3)]     #花瓣的长,宽
y = iris["target"]

X_with_bias = np.c_[np.ones([len(X), 1]), X]    #增广矩阵

切分数据集

test_ratio = 0.2
validation_ratio = 0.2
total_size = len(X_with_bias)

test_size = int(total_size * test_ratio)
validation_size = int(total_size * validation_ratio)
train_size = total_size - test_size - validation_size

rnd_indices = np.random.permutation(total_size)

X_train = X_with_bias[rnd_indices[:train_size]]
y_train = y[rnd_indices[:train_size]]
X_valid = X_with_bias[rnd_indices[train_size:-test_size]]
y_valid = y[rnd_indices[train_size:-test_size]]
X_test = X_with_bias[rnd_indices[-test_size:]]
y_test = y[rnd_indices[-test_size:]]

O n e H o t OneHot OneHot 编码

def to_one_hot(y):    #类索引转换为矩阵,例如 0,1,2 类中属于 1 类,则 [0,1,0]
    n_classes = y.max() + 1
    m = len(y)
    Y_one_hot = np.zeros((m, n_classes))    #全 0 向量
    Y_one_hot[np.arange(m), y] = 1
    return Y_one_hot

Y_train_one_hot = to_one_hot(y_train)    #转换
Y_valid_one_hot = to_one_hot(y_valid)
Y_test_one_hot = to_one_hot(y_test)

S o f t M a x SoftMax SoftMax 函数

def softmax(logits):    #与 Logistic 函数完全一样
    exps = np.exp(logits)
    exp_sums = np.sum(exps, axis=1, keepdims=True)
    return exps / exp_sums

梯度下降法求参数

eta = 0.01    #学习率
n_iterations = 5001    #迭代次数
m = len(X_train)    #训练样本数
epsilon = 1e-7    #平滑,为了防止 log(0) 出错

Theta = np.random.randn(n_inputs, n_outputs)    #随便生成 3 个 3 维的 theta

for iteration in range(n_iterations):
    logits = X_train.dot(Theta)
    Y_proba = softmax(logits)
    
    loss = -np.mean(np.sum(Y_train_one_hot * np.log(Y_proba + epsilon), axis=1))    #计算损失
    
    error = Y_proba - Y_train_one_hot
    
    # if iteration % 500 == 0:    #输出损失测试一下
    #    print(iteration, loss)
        
    gradients = 1/m * X_train.T.dot(error)    #偏导数
    Theta = Theta - eta * gradients

验证精度

logits = X_valid.dot(Theta)
Y_proba = softmax(logits)
y_predict = np.argmax(Y_proba, axis=1)

accuracy_score = np.mean(y_predict == y_valid)
  • 可以看到精度达到了 0.966666... 0.966666... 0.966666...,至于如何再提高精度,可以逐步减小步长,或者提前停止,这里就暂不讨论了
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值