深度学习模型系列一——多分类模型——Softmax 回归

Softmax 回归

  • 1、概述
  • 2、Softmax回归模型
  • 3、Softmax函数
  • 4、Softmax回归的决策函数
  • 5、参数估计
    • 5.1 损失函数
    • 5.2 梯度估计
      • 5.2.1 Softmax函数的导数
      • 5.2.2 梯度
  • 6、模型预测与评价
  • 7、Softmax回归的从零开始实现

1、概述

\quad \quad Softmax回归(Softmax regression),也称为多项(Multinomial)或多类(Multi-Class)的Logistic回归,是Logistic回归在多分类问题上的推广。

\quad \quad 【关于 logistic 回归可以看我的这篇博客机器学习笔记九——线性模型原理以及python实现案例】

2、Softmax回归模型

\quad \quad Softmax回归跟线性回归一样将输入特征与权重做线性叠加。与线性回归的一个主要不同在于,Softmax回归的输出值个数等于标签里的类别数。比如一共有4种特征和3种输出动物类别(狗、猫、鸡),则权重包含12个标量(带下标的 w w w)、偏差包含3个标量(带下标的 b b b),且对每个输入计算 o 1 , o 2 , o 3 o_1, o_2, o_3 o1,o2,o3这3个输出:

o 1 = x 1 w 11 + x 2 w 21 + x 3 w 31 + x 4 w 41 + b 1 , o 2 = x 1 w 12 + x 2 w 22 + x 3 w 32 + x 4 w 42 + b 2 , o 3 = x 1 w 13 + x 2 w 23 + x 3 w 33 + x 4 w 43 + b 3 . \begin{aligned} o_1 &= x_1 w_{11} + x_2 w_{21} + x_3 w_{31} + x_4 w_{41} + b_1,\\ o_2 &= x_1 w_{12} + x_2 w_{22} + x_3 w_{32} + x_4 w_{42} + b_2,\\ o_3 &= x_1 w_{13} + x_2 w_{23} + x_3 w_{33} + x_4 w_{43} + b_3. \end{aligned} o1o2o3=x1w11+x2w21+x3w31+x4w41+b1,=x1w12+x2w22+x3w32+x4w42+b2,=x1w13+x2w23+x3w33+x4w43+b3.
最后,再对这些输出值进行Softmax函数运算
深度学习模型系列一——多分类模型——Softmax 回归_第1张图片

\quad \quad 图3.2用神经网络图描绘了上面的计算。softmax回归同线性回归一样,也是一个单层神经网络。由于每个输出 o 1 , o 2 , o 3 o_1, o_2, o_3 o1,o2,o3的计算都要依赖于所有的输入 x 1 , x 2 , x 3 , x 4 x_1, x_2, x_3, x_4 x1,x2,x3,x4,所以softmax回归的输出层也是一个全连接层。

3、Softmax函数

\quad \quad Softmax用于多分类过程中,它将多个神经元的输出(比如 o 1 , o 2 , o 3 o_1, o_2, o_3 o1,o2,o3)映射到(0,1)区间内,可以看成概率来理解,从而来进行多分类!它通过下式将输出值变换成值为正且和为1的概率分布:

y ^ 1 , y ^ 2 , y ^ 3 = softmax ( o 1 , o 2 , o 3 ) , \hat{y}_1, \hat{y}_2, \hat{y}_3 = \text{softmax}(o_1, o_2, o_3), y^1,y^2,y^3=softmax(o1,o2,o3),

其中

y ^ 1 = exp ⁡ ( o 1 ) ∑ i = 1 3 exp ⁡ ( o i ) , y ^ 2 = exp ⁡ ( o 2 ) ∑ i = 1 3 exp ⁡ ( o i ) , y ^ 3 = exp ⁡ ( o 3 ) ∑ i = 1 3 exp ⁡ ( o i ) . \hat{y}_1 = \frac{ \exp(o_1)}{\sum_{i=1}^3 \exp(o_i)},\quad \hat{y}_2 = \frac{ \exp(o_2)}{\sum_{i=1}^3 \exp(o_i)},\quad \hat{y}_3 = \frac{ \exp(o_3)}{\sum_{i=1}^3 \exp(o_i)}. y^1=i=13exp(oi)exp(o1),y^2=i=13exp(oi)exp(o2),y^3=i=13exp(oi)exp(o3).

容易看出 y ^ 1 + y ^ 2 + y ^ 3 = 1 \hat{y}_1 + \hat{y}_2 + \hat{y}_3 = 1 y^1+y^2+y^3=1 0 ≤ y ^ 1 , y ^ 2 , y ^ 3 ≤ 1 0 \leq \hat{y}_1, \hat{y}_2, \hat{y}_3 \leq 1 0y^1,y^2,y^31,因此 y ^ 1 , y ^ 2 , y ^ 3 \hat{y}_1, \hat{y}_2, \hat{y}_3 y^1,y^2,y^3是一个合法的概率分布。这时候,如果 y ^ 2 = 0.8 \hat{y}_2=0.8 y^2=0.8,不管 y ^ 1 \hat{y}_1 y^1 y ^ 3 \hat{y}_3 y^3的值是多少,我们都知道图像类别为猫的概率是80%。此外,我们注意到

argmax ⁡ o i = argmax ⁡ y ^ i , \operatorname{argmax} o_i = \operatorname{argmax} \hat y_i, argmaxoi=argmaxy^i,

因此softmax运算不改变预测类别输出。

深度学习模型系列一——多分类模型——Softmax 回归_第2张图片

4、Softmax回归的决策函数

\quad \quad 为了提高计算效率,我们可以将单样本分类通过矢量计算来表达。在上面的图像分类问题中,假设softmax回归的权重和偏差参数分别为

W = [ w 11 w 12 w 13 w 14 w 21 w 22 w 23 w 24 w 31 w 32 w 33 w 34 ] , b = [ b 1 b 2 b 3 ] , \boldsymbol{W} = \begin{bmatrix} w_{11} & w_{12} & w_{13} & w_{14} \\ w_{21} & w_{22} & w_{23}& w_{24} \\ w_{31} & w_{32} & w_{33} & w_{34} \end{bmatrix},\quad \boldsymbol{b} = \begin{bmatrix} b_1 & b_2 & b_3 \end{bmatrix}, W=w11w21w31w12w22w32w13w23w33w14w24w34,b=[b1b2b3],

设高和宽分别为2个像素的图像样本 i i i的特征为

x ( i ) = [ x 1 ( i ) x 2 ( i ) x 3 ( i ) x 4 ( i ) ] , \boldsymbol{x}^{(i)} = \begin{bmatrix}x_1^{(i)} & x_2^{(i)} & x_3^{(i)} & x_4^{(i)}\end{bmatrix}, x(i)=[x1(i)x2(i)x3(i)x4(i)],

输出层的输出为

o ( i ) = [ o 1 ( i ) o 2 ( i ) o 3 ( i ) ] , \boldsymbol{o}^{(i)} = \begin{bmatrix}o_1^{(i)} & o_2^{(i)} & o_3^{(i)}\end{bmatrix}, o(i)=[o1(i)o2(i)o3(i)],

预测为狗、猫或鸡的概率分布为

y ^ ( i ) = [ y ^ 1 ( i ) y ^ 2 ( i ) y ^ 3 ( i ) ] . \boldsymbol{\hat{y}}^{(i)} = \begin{bmatrix}\hat{y}_1^{(i)} & \hat{y}_2^{(i)} & \hat{y}_3^{(i)}\end{bmatrix}. y^(i)=[y^1(i)y^2(i)y^3(i)].

Softmax回归对样本 i i i分类的矢量计算表达式为

o ( i ) = x ( i ) W T + b , y ^ ( i ) = softmax ( o ( i ) ) = exp ⁡ ( o i ) ∑ i = 1 3 exp ⁡ ( o i ) . \begin{aligned} \boldsymbol{o}^{(i)} &= \boldsymbol{x}^{(i)} \boldsymbol{W}^T + \boldsymbol{b},\\ \boldsymbol{\hat{y}}^{(i)} &= \text{softmax}(\boldsymbol{o}^{(i)})= \frac{ \exp(o_i)}{\sum_{i=1}^3 \exp(o_i)}. \end{aligned} o(i)y^(i)=x(i)WT+b,=softmax(o(i))=i=13exp(oi)exp(oi).
则Softmax回归的决策函数可以表示为:

y ^ = a r g m a x y ^ ( i ) \hat{\boldsymbol{y}}=\boldsymbol{argmax}\quad \boldsymbol {\hat{y}}^{(i)} y^=argmaxy^(i)

5、参数估计

5.1 损失函数

\quad \quad 给定N个训练样本 { ( x ( n ) , y ( n ) ) } n = 1 N \{(x^{(n)},y^{(n)})\}_{n=1}^N {(x(n),y(n))}n=1N,样本一共有C个类别,用C维的one-hot向量 y ∈ { 0 , 1 } C y\in\{0,1\}^C y{0,1}C来表示类别标签。【对于类别c,其向量表示为 y c = [ I ( 1 = c ) , I ( 2 = c ) , . . . , I ( C = c ) ] T y_c=[I(1=c),I(2=c),...,I(C=c)]^T yc=[I(1=c),I(2=c),...,I(C=c)]T,其中 I ( . ) I(.) I(.)是指示函数】

\quad \quad 采用交叉熵损失函数,Softmax回归模型的损失函数为:

L ( W , b ) = − 1 N ∑ n = 1 N ∑ c = 1 C y c ( n ) l o g y ^ c ( n ) = − 1 N ∑ n = 1 N ( y ( n ) ) T l o g y ^ ( n ) L(\boldsymbol{W} ,\boldsymbol{b})=-\frac1N\sum_{n=1}^N\sum_{c=1}^C y_c^{(n)}log\hat{y}_c^{(n)}=-\frac1N\sum_{n=1}^N (y^{(n)})^Tlog\hat{y}^{(n)} L(W,b)=N1n=1Nc=1Cyc(n)logy^c(n)=N1n=1N(y(n))Tlogy^(n)
其中, y ^ ( n ) = S o f t m a x ( x ( n ) W T + b ) \hat{y}^{(n)}=Softmax(\boldsymbol{x}^{(n)} \boldsymbol{W}^T + \boldsymbol{b}) y^(n)=Softmax(x(n)WT+b)为样本 x ( n ) x^{(n)} x(n)在每个类别的后验概率。

当样本只有一个标签时,我们可以对损失函数简化,简化如下:

\quad \quad 当每个样本的真实标签 y ( n ) y^{(n)} y(n)只有一个标签,即是一个C维one-hot向量:若样本属于i类,则只有第i维是1,其余都是0( c ∈ [ 1 , C ] ; n ∈ [ 1 , N ] ) c\in[1,C];n\in[1,N]) c[1,C];n[1,N])。所以
L ( W , b ) = − 1 N ∑ n = 1 N ( y ( n ) ) T l o g y ^ ( n ) = − 1 N ∑ n = 1 N l o g y ^ y ( n ) ( n ) L(\boldsymbol{W} ,\boldsymbol{b})=-\frac1N\sum_{n=1}^N (y^{(n)})^Tlog\hat{y}^{(n)}=-\frac1N\sum_{n=1}^N log\hat{y}_{y^{(n)}}^{(n)} L(W,b)=N1n=1N(y(n))Tlogy^(n)=N1n=1Nlogy^y(n)(n)

其中,假设第n个样本的真实标签为第i类即 y ( n ) y^{(n)} y(n)的第i维为1,则 y ^ y ( n ) ( n ) \hat{y}_{y^{(n)}}^{(n)} y^y(n)(n)为样本预测值中第i维的值。

\quad \quad 从另一个角度来看,我们知道最小化损失函数 L ( W , b ) L(W,b) L(W,b)等价于最大化 exp ⁡ ( − n L ( W , b ) ) = ∏ i = 1 n y ^ y ( i ) ( i ) \exp(-nL(W,b))=\prod_{i=1}^n \hat y_{y^{(i)}}^{(i)} exp(nL(W,b))=i=1ny^y(i)(i),即最小化交叉熵损失函数等价于最大化训练数据集所有标签类别的联合预测概率。

5.2 梯度估计

5.2.1 Softmax函数的导数

深度学习模型系列一——多分类模型——Softmax 回归_第3张图片
深度学习模型系列一——多分类模型——Softmax 回归_第4张图片
深度学习模型系列一——多分类模型——Softmax 回归_第5张图片
来源于神经网络与深度学习的附录

5.2.2 梯度

损失函数 L ( W ) L(W) L(W)关于W的梯度为:
∂ L ( W ) ∂ W = − 1 N ∑ n = 1 N x ( n ) ( y ( n ) − y ^ ( n ) ) T \frac{ \partial L(W) }{\partial W}=-\frac 1N\sum_{n=1}^Nx(n)(y^{(n)}-\hat{y}^{(n)})^T WL(W)=N1n=1Nx(n)(y(n)y^(n))T

采用梯度下降法,Softmax回归的训练过程为:

1)初始化 W 0 = 0 W_0=0 W0=0【在神经网络中,不能全部初始化为0,可随机初始化】
2) 迭代更新:
W t + 1 = W t + α ( 1 N ∑ n = 1 N x ( n ) ( y ( n ) − y ^ ( n ) ) T ) W_{t+1}=W_t+\alpha(\frac 1N\sum_{n=1}^Nx(n)(y^{(n)}-\hat{y}^{(n)})^T) Wt+1=Wt+α(N1n=1Nx(n)(y(n)y^(n))T)

6、模型预测与评价

预测
\quad \quad 在训练好softmax回归模型后,给定任一样本特征,就可以预测每个输出类别的概率。通常,我们把预测概率最大的类别作为输出类别。

评价
\quad \quad 如果它与真实类别(标签)一致,说明这次预测是正确的。一般使用准确率(accuracy)来评价模型的表现,它等于正确预测数量与总预测数量之比。

7、Softmax回归的从零开始实现

我们将使用Fashion-MNIST数据集【简介】,进行图像多分类问题。

导入所需的包

import torch
import torchvision
import numpy as np
import sys
sys.path.append('E:\d2lzh_pytorch')#加上d2lzh_pytorch的路径
import d2lzh_pytorch as d2l

1、读取数据集

batch_size = 256#小批量进行读取
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)

2、初始化模型参数

跟线性回归中的例子一样,我们将使用向量表示每个样本。已知每个样本输入是高和宽均为28像素的图像。模型的输入向量的长度是 28 × 28 = 784 28 \times 28 = 784 28×28=784:该向量的每个元素对应图像中每个像素。由于图像有10个类别,单层神经网络输出层的输出个数为10,因此softmax回归的权重和偏差参数分别为 784 × 10 784 \times 10 784×10 1 × 10 1 \times 10 1×10的矩阵。

num_inputs = 784
num_outputs = 10
#随机初始化参数
W = torch.tensor(np.random.normal(0, 0.01, (num_inputs, num_outputs)), dtype=torch.float)
b = torch.zeros(num_outputs, dtype=torch.float)

为模型参数附上梯度。

W.requires_grad_(requires_grad=True)
b.requires_grad_(requires_grad=True)

3、定义Softmax函数

def softmax(X):
    X_exp = X.exp()
    partition = X_exp.sum(dim=1, keepdim=True)#行元素求和
    return X_exp / partition  # 这里应用了广播机制

4、定义Softmax回归模型

def net(X):
    return softmax(torch.mm(X.view((-1, num_inputs)), W) + b)

5、定义损失函数

def cross_entropy(y_hat, y):
    return - torch.log(y_hat.gather(1, y.view(-1, 1)))

6、计算分类准确率

给定一个类别的预测概率分布y_hat,我们把预测概率最大的类别作为输出类别。如果它与真实类别y一致,说明这次预测是正确的。分类准确率即正确预测数量与总预测数量之比。

为了演示准确率的计算,下面定义准确率accuracy函数。其中y_hat.argmax(axis=1)返回矩阵y_hat每行中最大元素的索引,且返回结果与变量y形状相同。我们在“数据操作”一节介绍过,相等条件判别式(y_hat.argmax(axis=1) == y)是一个类型为ByteTensorTensor,我们用float()将其转换为值为0(相等为假)或1(相等为真)的浮点型Tensor

def accuracy(y_hat, y):
    return (y_hat.argmax(dim=1) == y).float().mean().item()

7、评价模型net在数据集data_iter上的准确率。

# 本函数已保存在d2lzh_pytorch包中方便以后使用。该函数将被逐步改进:它的完整实现将在“图像增广”一节中描述
def evaluate_accuracy(data_iter, net):
    acc_sum, n = 0.0, 0
    for X, y in data_iter:
        acc_sum += (net(X).argmax(dim=1) == y).float().sum().item()
        n += y.shape[0]
    return acc_sum / n

8、训练模型

num_epochs, lr = 5, 0.1

# 本函数已保存在d2lzh_pytorch包中方便以后使用
def train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,
              params=None, lr=None, optimizer=None):
    for epoch in range(num_epochs):
        train_l_sum, train_acc_sum, n = 0.0, 0.0, 0
        for X, y in train_iter:
            y_hat = net(X)
            l = loss(y_hat, y).sum()
            
            # 梯度清零
            if optimizer is not None:
                optimizer.zero_grad()
            elif params is not None and params[0].grad is not None:
                for param in params:
                    param.grad.data.zero_()
            
            l.backward()
            if optimizer is None:
                d2l.sgd(params, lr, batch_size)
            else:
                optimizer.step()  # “softmax回归的简洁实现”一节将用到
            
            
            train_l_sum += l.item()
            train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()
            n += y.shape[0]
        test_acc = evaluate_accuracy(test_iter, net)
        print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'
              % (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))

train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, batch_size, [W, b], lr)

epoch 1, loss 0.7852, train acc 0.750, test acc 0.789
epoch 2, loss 0.5707, train acc 0.813, test acc 0.813
epoch 3, loss 0.5258, train acc 0.826, test acc 0.818
epoch 4, loss 0.5008, train acc 0.832, test acc 0.824
epoch 5, loss 0.4843, train acc 0.838, test acc 0.827

9、预测

for X, y in test_iter:
    break

true_labels = d2l.get_fashion_mnist_labels(y.asnumpy())
pred_labels = d2l.get_fashion_mnist_labels(net(X).argmax(axis=1).asnumpy())
titles = [true + '\n' + pred for true, pred in zip(true_labels, pred_labels)]

d2l.show_fashion_mnist(X[0:9], titles[0:9])

深度学习模型系列一——多分类模型——Softmax 回归_第6张图片

参考资料:
1、https://blog.csdn.net/weixin_38169413/article/details/103598534
2、神经网络与深度学习
3、动手学深度学习

你可能感兴趣的:(#,深度学习,机器学习,深度学习,Softmax回归,多分类)