softmax回归总结(动手深度学习)-5

本文介绍了Softmax回归的基本原理,包括其与线性回归的区别、模型公式、损失函数的选择及计算方式,并提供了两种MXNet实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

  1. softmax回归与线性回归
  2. softmax回归模型
  3. 如何计算softmax回归模型
  4. softmax回归的代码实现

1. softmax回归与线性回归

相比于线性回归输出一个连续的值,softmax回归则输出一系列离散的值。线性回归适合解决回归问题,如房价的预测问题。而softmax回归适合做分类问题,如识别一张图片中是猫,狗还是鸡。相比于线性回归输出单元仅一个,softmax回归有更多的输出单元。

2. softmax回归模型

O=XW+b,O=XW+b,O=XW+b,

Y^=softmax(O),\hat{Y}=softmax(O),Y^=softmax(O),

上式中的X为数据集,X∈Rn∗dX{\in}{\mathbb{R}^{n*d}}XRnd,n表示样本批量大小,d表示输入个数(特征数)。
W为权重,W∈Rd∗qW{\in}{\mathbb{R}^{d*q}}WRdq,q表示输出个数(类别数)。
O和Y^\hat{Y}Y^∈Rn∗q{\in}{\mathbb{R}^{n*q}}Rnq为输出的预测标签。其中Y^\hat{Y}Y^为n*d的矩阵,每一行表示一个样本的预测,一行包含d个元素,这是对每一类别进行的预测值,一行中最大的值对应的下标为预测的标签。

3. 如何计算softmax回归模型

由于softmax回归输出的值与线性回归输出的不同。对于每一个样本,softmax会输出一个1*q的向量,我们仅需确认向量中那个元素最大即可。这时使用平方损失将不适合。
我们使用交叉熵损失函数来计算softmax回归,下式为单个样本对应的损失值:

H(y(i),y^(i))=−∑j=1nyj(i)logy^j(i),H(y^{(i)},\hat{y}^{(i)})=-\sum_{j=1}^{n}y^{(i)}_jlog\hat{y}^{(i)}_j,H(y(i),y^(i))=j=1nyj(i)logy^j(i),

从上面可以看到,其实H(y(i),y^(i))=−logy^y(i)(i)H(y^{(i)},\hat{y}^{(i)})=-log\hat{y}^{(i)}_{y^{(i)}}H(y(i),y^(i))=logy^y(i)(i),其中下标y(i)y^{(i)}y(i)表示这个样本中正确的标签下标。当y^y(i)(i)\hat{y}^{(i)}_{y^{(i)}}y^y(i)(i)的值越接近1,也就是概率越大时,loss越小。当这个值越接近0,也就是概率越接近0时,loss越大,并且是接近正无穷。

假设训练数据集的样本数为n,交叉熵损失函数定义为:

l(Θ)=1n∑i=1nH(y(i),y^(i))l(\Theta)=\frac{1}{n}\sum_{i=1}^{n}H(y^{(i)},\hat{y}^{(i)})l(Θ)=n1i=1nH(y(i),y^(i))

根据上式,我们能够使用梯度下降、随机梯度下降等优化算法进行求解。

4. softmax回归的代码实现

1 获取数据集

import d2lzh as d2l
from mxnet import autograd,nd
# 1. 获取数据集
batch_size=256
train_iter,test_iter=d2l.load_data_fashion_mnist(batch_size)

2 初始化模型参数

num_inputs=784
num_outputs=10

W=nd.random.normal(scale=0.01,shape=(num_inputs,num_outputs))
b=nd.zeros(num_outputs)

W.attach_grad()
b.attach_grad()

3 实现softmax运算

def softmax(X):
    '''
    softmax函数
    :param X: X为输出层的输出,大小为batch_size*q,其中q为类别数,batch_size为批量大小
    :return:返回预测的概率分布
    '''
    X_exp=X.exp()#对每个元素做指数运算
    partition=X_exp.sum(axis=1,keepdims=True)#将X_exp中每行所有元素加起来形成batch_size*1的矩阵
    return X_exp/partition

4 定义模型

def net(X):
    return softmax(nd.dot(X.reshape((-1,num_inputs)),W)+b)

5 定义损失函数

def cross_entropy(y_hat,y):
    return -nd.pick(y_hat,y).log()

6 计算分类准确度

def accuracy(y_hat,y):
    '''训练时计算当前预测的准确度'''
    return (y_hat.argmax(axis=1)==y.astype('float32')).mean().asscalar()

def evaluate_accuracy(data_iter,net):
    '''通常输入测试数据集计算准确度'''
    acc_sum,n=0.0,0
    for X,y in data_iter:
        y=y.astype('float32')
        acc_sum+=(net(X).argmax(axis=1)==y).sum().asscalar()
        n+=y.size
    return acc_sum/n

7 训练模型

num_epochs,lr=5,0.1
def train_ch3(net,train_iter,test_iter,loss,num_epochs,batch_size,
              params=None,lr=None,trainer=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:
            with autograd.record():
                y_hat=net(X)
                l=loss(y_hat,y).sum()
            l.backward()
            if trainer is None:
                d2l.sgd(params,lr,batch_size)
            else:
                trainer.step(batch_size)
            y=y.astype('float32')
            train_l_sum+=l.asscalar()
            train_acc_sum+=(y_hat.argmax(axis=1)==y).sum().asscalar()
            n+=y.size
        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)

8 输出

epoch 1,loss 0.7874,train acc 0.748,test acc 0.804
epoch 2,loss 0.5727,train acc 0.811,test acc 0.823
epoch 3,loss 0.5284,train acc 0.824,test acc 0.829
epoch 4,loss 0.5054,train acc 0.829,test acc 0.836
epoch 5,loss 0.4897,train acc 0.835,test acc 0.838

更简洁的方式softmax回归

import d2lzh as d2l
from mxnet import gluon,init
from mxnet.gluon import loss as gloss,nn

# 1. 获取和读取数据
batch_size=256
train_iter,test_iter=d2l.load_data_fashion_mnist(batch_size)

# 2. 定义和初始化模型
net=nn.Sequential()
net.add(nn.Dense(10))
net.initialize(init.Normal(sigma=0.01))

# 3. softmax和交叉熵损失函数
loss=gloss.SoftmaxCrossEntropyLoss()

# 4.定义优化算法
trainer=gluon.Trainer(net.collect_params(),'sgd',{'learning_rate':0.1})

# 5. 训练模型
num_epochs=5
d2l.train_ch3(net,train_iter,test_iter,loss,num_epochs,batch_size,None,
              None,trainer)

输出:

epoch 1, loss 0.7851, train acc 0.751, test acc 0.796
epoch 2, loss 0.5740, train acc 0.811, test acc 0.820
epoch 3, loss 0.5285, train acc 0.824, test acc 0.826
epoch 4, loss 0.5052, train acc 0.831, test acc 0.836
epoch 5, loss 0.4895, train acc 0.834, test acc 0.839
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值