当前位置: 首页 > web >正文

动手学深度学习(pytorch版):第三章节—线性神经网络(4)softmax回归

Softmax回归是一种广泛使用的多类分类算法,适用于将输入数据映射到多个离散类别。它是逻辑回归的扩展,常用于图像识别、自然语言处理等领域。其核心是通过softmax函数将线性模型的输出转换为概率分布,从而预测每个类别的可能性。

1. 简介与目的

Softmax回归的目标是解决多类分类问题(例如,将图像分为“猫”、“狗”或“鸟”)。给定输入特征向量$x$,模型输出一个概率向量$p$,其中每个元素$p_i$表示输入属于第$i$个类别的概率。

        概率总和为1,即 $\sum_{i} p_i = 1$。这使得模型能直观地表示分类不确定性。

2. 数学基础

Softmax回归的核心是softmax函数和交叉熵损失函数。

  • Softmax函数:该函数将线性模型的原始输出(称为logits)转换为概率。假设有$K$ 个类别,对于输入 $x$,模型首先计算logits向量 $z$$ z = Wx + b $其中:

    • $W$ 是权重矩阵(维度为 $K \times d$$d$是特征维度),
    • $b$是偏置向量(维度为 $K \times 1$)。 然后,softmax函数将$z$ 转换为概率$p$$ p_i = \frac{e^{z_i}}{\sum_{j=1}^{K} e^{z_j}} \quad \text{for} \quad i = 1, 2, \ldots, K $这里,$e^{z_i}$是指数函数,确保输出为正数,且分母归一化使概率和为1。
  • 损失函数:使用交叉熵损失来衡量预测概率 $p$ 与真实标签$y$(one-hot编码)的差异。损失函数定义为: $ L = -\sum_{i=1}^{K} y_i \log(p_i) $ 其中 $y_i$ 是真实标签的第$i$ 个元素(如果类别正确则为1,否则为0)。最小化该损失可优化模型参数。

3. 训练过程

训练Softmax回归涉及优化参数$W$$b$ 以最小化损失函数$L$。常用方法是梯度下降:

  1. 初始化参数:随机设置 $W$$b$
  2. 前向传播:对每个输入$x$计算 $z = Wx + b$,然后应用softmax得到$p$
  3. 计算梯度:使用链式法则计算损失对参数的梯度。例如,损失对权重 $W$的梯度为: $ \frac{\partial L}{\partial W} = (p - y) x^T $其中$y$是真实标签。
  4. 更新参数:用梯度下降更新参数,例如 $W \leftarrow W - \alpha \frac{\partial L}{\partial W}$,其中 $\alpha$ 是学习率。
  5. 迭代:重复上述步骤直到损失收敛或达到预设的迭代次数。

训练后,模型能预测新样本的类别:选择概率最高的$p_i$对应的类别。

4. 应用场景

Softmax回归简单高效,常用于:

  • 图像分类(如MNIST手写数字识别)。
  • 文本分类(如情感分析)。
  • 作为神经网络输出层(例如,在卷积神经网络后接softmax层)。

5. 代码示例

以下是一个简单的Python实现,使用NumPy库进行数值计算。代码包括模型定义、训练和预测功能。

import numpy as npclass SoftmaxRegression:def __init__(self, num_classes, input_dim, learning_rate=0.01, max_iter=1000):self.num_classes = num_classesself.input_dim = input_dimself.learning_rate = learning_rateself.max_iter = max_iterself.W = np.random.randn(num_classes, input_dim) * 0.01  # 初始化权重self.b = np.zeros((num_classes, 1))  # 初始化偏置def softmax(self, z):# 计算softmax概率exp_z = np.exp(z - np.max(z, axis=0, keepdims=True))  # 避免数值溢出return exp_z / np.sum(exp_z, axis=0, keepdims=True)def fit(self, X, y):# 训练模型:X是特征矩阵(N x d), y是标签向量(N,),每个元素是类别索引N = X.shape[0]y_one_hot = np.eye(self.num_classes)[y]  # 转换为one-hot编码 (N x K)for _ in range(self.max_iter):# 前向传播z = self.W @ X.T + self.b  # 计算logits (K x N)p = self.softmax(z)  # 概率矩阵 (K x N)# 计算损失(交叉熵)loss = -np.mean(np.log(p[y_one_hot.T == 1] + 1e-8))  # 加小值防log(0)# 反向传播:计算梯度grad_z = p - y_one_hot.T  # 梯度对z (K x N)grad_W = grad_z @ X / N  # 平均梯度 (K x d)grad_b = np.mean(grad_z, axis=1, keepdims=True)  # 平均梯度 (K x 1)# 更新参数self.W -= self.learning_rate * grad_Wself.b -= self.learning_rate * grad_breturn lossdef predict(self, X):# 预测类别:返回概率最高的索引z = self.W @ X.T + self.bp = self.softmax(z)return np.argmax(p, axis=0)# 示例使用
if __name__ == "__main__":# 假设有简单数据集:2个特征,3个类别X_train = np.array([[1.0, 2.0], [2.0, 3.0], [3.0, 1.0]])  # 训练特征y_train = np.array([0, 1, 2])  # 训练标签(类别索引)# 创建并训练模型model = SoftmaxRegression(num_classes=3, input_dim=2, learning_rate=0.1, max_iter=1000)loss = model.fit(X_train, y_train)print(f"训练损失: {loss:.4f}")# 预测新样本X_test = np.array([[1.5, 1.5]])pred = model.predict(X_test)print(f"预测类别: {pred[0]}")

http://www.xdnf.cn/news/17969.html

相关文章:

  • strlen与传值传址调用
  • 设计模式(Design Patterns)
  • C++:stl-> list的模拟实现
  • 条件变量的基本介绍与有界缓冲区问题
  • 异步开发:协程、线程、Unitask
  • C语言——深入理解指针(四)
  • 获取农历日期
  • Jeecg后端经验汇总
  • strings命令和findstr命令验证iso文件中ntkrnlmp.exe系统版本
  • 如何避免网盘中资源被和谐?
  • LeetCode算法日记 - Day 12: 寻找旋转排序数组中的最小值、点名
  • Erlang notes[2]
  • Vue 侦听器(watch 与 watchEffect)全解析1
  • 图解软件知识库体系
  • GaussDB 常用数值类型
  • 分布式锁:从理论到实战的深度指南
  • python自学笔记8 二维和三维可视化
  • 深入解析Prompt缓存机制:原理、优化与实践经验
  • 云原生俱乐部-杂谈1
  • CVE-2014-6271(bash破壳漏洞 )
  • Android数据缓存目录context.getCacheDir与Environment.getExternalStorageDirectory
  • Git 中切换到指定 tag
  • 会议系统进程池管理:初始化、通信与状态同步详解
  • Fiddler抓包
  • 【FreeRTOS】刨根问底4: 优先级反转是啥?咋解决?
  • 为什么Integer缓存-128 ~ 127
  • 学习设计模式《二十二》——职责链模式
  • 搭建 Docker 私有仓库
  • springboot项目不同平台项目通过http接口AES加密传输
  • UE5配置MRQ编解码器输出MP4视频