人工神经网络知识点讲解

news2026/5/15 6:12:39
人工神经网络知识点讲解知识导图人工神经网络 ├── 基础认知 │ ├── 神经网络的核心概念 │ ├── 神经元的工作机制 │ └── 网络的层级结构 ├── 激活函数 │ ├── 激活函数的作用 │ ├── 常见激活函数sigmoid/tanh/ReLU/Softmax │ └── 激活函数的选择 ├── 参数初始化 │ ├── 7种初始化方法 │ └── 初始化方法的选择 ├── 损失函数 │ ├── 分类任务损失 │ └── 回归任务损失 ├── 网络优化 │ ├── 优化算法 │ └── 学习率衰减 ├── 正则化方法 │ ├── 正则化的作用 │ ├── Dropout 随机失活 │ └── 批量归一化 └── 实战案例 └── 手机价格分类案例核心名词解释人工神经网络 (ANN)也简称为神经网络 (NN)是一种模仿生物神经网络结构和功能的计算模型用来拟合复杂的非线性关系。神经元神经网络的基本单元接收输入后进行加权求和再通过激活函数输出结果模拟生物神经元的工作方式。输入层 (Input Layer)神经网络的输入层负责接收原始的输入数据每个输入特征对应一个神经元。隐藏层 (Hidden Layers)输入层和输出层之间的层负责对输入数据进行特征提取和变换神经网络的深度由隐藏层的数量决定。输出层 (Output Layer)神经网络的输出层负责生成最终的预测结果根据任务的不同分类 / 回归有不同的设计。全连接层相邻层的所有神经元都相互连接的层也叫稠密层每个连接都有对应的权重和偏置。内部状态值神经元的加权求和结果公式为z W⋅x\b是激活函数的输入。激活值激活函数对内部状态值进行非线性变换后得到的结果是神经元的最终输出。激活函数为神经网络引入非线性因素的函数让网络可以拟合复杂的非线性函数。sigmoid将输入映射到 (0,1) 区间的激活函数常用于二分类的输出层。tanh将输入映射到 (-1,1) 区间的激活函数是 sigmoid 的平移版本解决了 sigmoid 的输出非零均值的问题。ReLU修正线性单元是目前最常用的隐藏层激活函数计算简单缓解了梯度消失问题。Softmax多分类任务的输出激活函数将输出转换为概率所有输出的概率和为 1。参数初始化对神经网络的权重和偏置进行初始赋值的过程合适的初始化可以让网络更快收敛避免梯度消失 / 爆炸。Xavier 初始化也叫 Glorot 初始化用来平衡输入和输出的方差适合 sigmoid、tanh 这类激活函数。Kaiming 初始化也叫 HE 初始化针对 ReLU 这类激活函数设计考虑了 ReLU 的半正则特性让深层网络更容易训练。损失函数用来衡量模型预测值和真实值之间差异的函数是网络训练的优化目标。交叉熵损失分类任务中常用的损失函数衡量预测概率分布和真实分布的差异。MAE 损失也叫 L1 损失回归任务的损失计算预测和真实的绝对误差。MSE 损失也叫 L2 损失回归任务的损失计算预测和真实的均方误差。优化器用来更新神经网络参数最小化损失函数的算法。学习率衰减随着训练进行逐渐降低学习率的策略让模型训练更稳定。Dropout随机失活正则化训练时随机让部分神经元失活防止过拟合。批量归一化 (BN)对批量数据进行标准化和重构的层缓解梯度消失加速训练。正则化用来防止模型过拟合的方法通过限制模型的复杂度提升模型的泛化能力。一、神经网络基础认知本章节学习目标知道什么是人工神经网络了解神经网络的构成理解内部状态和激活值的概念1.1 什么是人工神经网络人工神经网络 Artificial Neural Network 简写为 ANN也简称为神经网络NN是一种模仿生物神经网络结构和功能的计算模型。人脑可以看做是一个生物神经网络由众多的神经元连接而成。各个神经元传递复杂的电信号树突接收到输入信号然后对信号进行处理通过轴突输出信号。当电信号通过树突进入到细胞核时会逐渐聚集电荷。达到一定的电位后细胞就会被激活通过轴突发出电信号。1.2 神经元的工作机制神经网络是由多个神经元组成构建神经网络就是在构建神经元。这个过程就像来源不同树突 (树突都会有不同的权重) 的信息进行的加权计算输入到细胞中做加和再通过激活函数输出细胞值。1.3 神经网络的层级结构神经网络中信息只向一个方向移动即从输入节点向前移动通过隐藏节点再向输出节点移动。其中的基本部分是:输入层Input Layer即输入 x 的那一层如图像、文本、声音等。每个输入特征对应一个神经元。输入层将数据传递给下一层的神经元。输出层Output Layer即输出 y 的那一层。输出层的神经元根据网络的任务回归、分类等生成最终的预测结果。隐藏层Hidden Layers输入层和输出层之间的层负责对输入数据进行特征提取和变换神经网络的深度由隐藏层的数量决定。网络的特点同一层的神经元之间没有连接第 N 层的每个神经元和第 N-1 层 的所有神经元相连这就是全连接神经网络全连接神经网络接收的样本数据是二维的数据在每一层之间需要以二维的形式传递第 N-1 层神经元的输出就是第 N 层神经元的输入每个连接都有一个权重值w 系数和 b 系数1.4 内部状态值和激活值每一个神经元工作时会产生 4 个值:前向传播会产生内部状态值加权求和值和激活值反向传播时会产生激活值梯度和内部状态值梯度。内部状态值:z W⋅x\bW权重矩阵x输入值b偏置激活值:af\(z\)f激活函数z内部状态值二、激活函数本章节学习目标知道常见的激活函数了解激活函数的作用掌握激活函数的选择方法2.1 激活函数的作用激活函数用于对每层的输出数据进行变换进而为整个网络注入了非线性因素。此时神经网络就可以拟合各种曲线。没有引入非线性因素的网络等价于使用一个线性模型来拟合。通过给网络输出增加激活函数实现引入非线性因素使得网络模型可以逼近任意函数提升网络对复杂问题的拟合能力。2.2 常见的激活函数2.2.1 sigmoid 激活函数sigmoid 激活函数可以将输入映射到 (0,1) 的区间它的公式和导数公式如下对应的绘制代码# 解决OMP冲突的代码 import os os.environ[KMP_DUPLICATE_LIB_OK]True # 加这行切换Matplotlib的后端绕过PyCharm的兼容bug import matplotlib matplotlib.use(TkAgg) # 导包 import torch import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [Microsoft YaHei] # 指定用Windows自带的微软雅黑支持中文 plt.rcParams[axes.unicode_minus] False # 顺便解决负号显示成方框的问题 # 准备数据 # 准备 -2020的等差张量1000点 -- x x torch.linspace(start-20,end20,steps1000,requires_gradFalse) print(x.shape,x.ndim) y torch.sigmoid(x) print(y.shape,y.ndim) # 绘制图像 # **todo 为了把值域图像和导数图像画到一张画布上创建一个一行两列的画布** fig,axs plt.subplots(1,2) axs[0].plot(x,y) axs[0].grid() axs[0].set_title(sigmoid 值域图像) # plt.show() print(1) # 准备数据 # # 准备x,y数据 - **todo 注意此处的x开启自动微分y的本质是梯度** x torch.linspace(start-20,end20,steps1000,requires_gradTrue) print(x.shape,x.ndim) torch.sigmoid(x).sum().backward() # - # backward()触发反向传播PyTorch自动帮你计算Sigmoid对x的导数结果会自动存在 x.grad 里 y x.grad print(y.shape,y.ndim) # 绘制图像 axs[1].plot(x.detach(),x.grad) axs[1].grid() axs[1].set_title(Sigmoid 导数图像) plt.show() print(2)2.2.2 tanh 激活函数tanh 激活函数可以将输入映射到 (-1,1) 的区间解决了 sigmoid 输出非零均值的问题它的公式和导数公式如下对应的绘制代码# 创建画布和坐标轴 _, axes plt.subplots(1, 2) # 函数图像 x torch.linspace(-20, 20, 1000) y torch.tanh(x) axes[0].plot(x, y) axes[0].grid() axes[0].set_title(Tanh 函数图像) # 导数图像 x torch.linspace(-20, 20, 1000, requires_gradTrue) torch.tanh(x).sum().backward() axes[1].plot(x.detach(), x.grad) axes[1].grid() axes[1].set_title(Tanh 导数图像) plt.show()2.2.3 ReLU 激活函数ReLU 是修正线性单元是目前最常用的隐藏层激活函数它的公式和导数公式如下对应的绘制代码# 创建画布和坐标轴 _, axes plt.subplots(1, 2) # 函数图像 x torch.linspace(-20, 20, 1000) y torch.relu(x) axes[0].plot(x, y) axes[0].grid() axes[0].set_title(ReLU 函数图像) # 导数图像 x torch.linspace(-20, 20, 1000, requires_gradTrue) torch.relu(x).sum().backward() axes[1].plot(x.detach(), x.grad) axes[1].grid() axes[1].set_title(ReLU 导数图像) plt.show()2.2.4 SoftMax 激活函数softmax 用于多分类过程中它是二分类函数 sigmoid 在多分类上的推广目的是将多分类的结果以概率的形式展现出来。Softmax 就是将网络输出的 logits 通过 softmax 函数就映射成为 (0,1) 的值而这些值的累和为 1满足概率的性质那么我们将它理解成概率选取概率最大也就是值对应最大的节点作为我们的预测目标类别。对应的使用代码import torch scores torch.tensor([0.2, 0.02, 0.15, 0.15, 1.3, 0.5, 0.06, 1.1, 0.05, 3.75]) # dim 0,按行计算 probabilities torch.softmax(scores, dim-1) print(probabilities) # 输出结果: # tensor([0.0212, 0.0177, 0.0202, 0.0202, 0.0638, 0.0287, 0.0185, 0.0522, 0.0183,0.7392])2.3 其他激活函数还有其他的常见激活函数比如 Leaky ReLU、PReLU、ELU 等2.4 激活函数的选择方法隐藏层的选择优先选择 ReLU 激活函数如果 ReLu 效果不好那么尝试其他激活如 Leaky ReLu 等。如果你使用了 ReLU 需要注意一下 Dead ReLU 问题 避免出现 0 梯度从而导致过多的神经元死亡。少用使用 sigmoid 激活函数可以尝试使用 tanh 激活函数输出层的选择二分类问题选择 sigmoid 激活函数多分类问题选择 softmax 激活函数回归问题选择 identity 激活函数激活函数对比辨析激活函数输出区间特点适用场景sigmoid(0, 1)输出非零均值容易梯度消失二分类输出层tanh(-1, 1)输出零均值缓解了 sigmoid 的部分问题隐藏层早期ReLU[0, ∞)计算简单缓解梯度消失可能出现 Dead ReLU隐藏层主流Softmax(0, 1)总和为 1输出概率分布多分类输出层三、参数初始化本章节学习目标了解常见的参数初始化方法掌握初始化方法的选择3.1 常见的初始化方法参数初始化是对神经网络的权重和偏置进行初始赋值的过程常见的 7 种初始化方法如下基础初始化方法均匀分布初始化权重参数初始化从区间均匀随机取值默认区间为01。可以设置为在 (-1/√d,1/√d) 均匀分布中生成当前神经元的权重其中 d 为神经元的输入数量正态分布初始化随机初始化从均值为 0标准差是 1 的高斯分布中取样使用一些很小的值对参数 W 进行初始化全 0 初始化将神经网络中的所有权重参数初始化为 0全 1 初始化将神经网络中的所有权重参数初始化为 1固定值初始化将神经网络中的所有权重参数初始化为某个固定值进阶初始化方法kaiming 初始化HE 初始化HE 初始化分为正态分布的 HE 初始化、均匀分布的 HE 初始化.正态分布的 he 初始化它是从 [0, std] 中抽取样本的std sqrt\(2 / fan\_in\)均匀分布的 he 初始化它从 [-limitlimit] 中的均匀分布中抽取样本limit是 sqrt\(6 / fan\_in\)fan_in输入层神经元的个数xavier 初始化Glorot 初始化该方法也有两种一种是正态分布的 xavier 初始化、一种是均匀分布的 xavier 初始化.正态化的 Xavier 初始化它是从 [0, std] 中抽取样本的std sqrt\(2 / \(fan\_in \ fan\_out\)\)均匀分布的 Xavier 初始化[-limitlimit] 中的均匀分布中抽取样本limit 是 sqrt\(6 / \(fan\_in \ fan\_out\)\)fan_in输入层神经元的个数 fan_out输出层神经元个数3.2 初始化的代码示例import torch import torch.nn.functional as F import torch.nn as nn # 1. 均匀分布随机初始化 def test01(): linear nn.Linear(5, 3) # 从0-1均匀分布产生参数 nn.init.uniform_(linear.weight) print(linear.weight.data) # 2.固定初始化 def test02(): linear nn.Linear(5, 3) nn.init.constant_(linear.weight, 5) print(linear.weight.data) # 3. 全0初始化 def test03(): linear nn.Linear(5, 3) nn.init.zeros_(linear.weight) print(linear.weight.data) # 4. 全1初始化 def test04(): linear nn.Linear(5, 3) nn.init.ones_(linear.weight) print(linear.weight.data) # 5. 正态分布随机初始化 def test05(): linear nn.Linear(5, 3) nn.init.normal_(linear.weight, mean0, std1) print(linear.weight.data) # 6. kaiming 初始化 def test06(): # kaiming 正态分布初始化 linear nn.Linear(5, 3) nn.init.kaiming_normal_(linear.weight) print(linear.weight.data) # kaiming 均匀分布初始化 linear nn.Linear(5, 3) nn.init.kaiming_uniform_(linear.weight) print(linear.weight.data) # 7. xavier 初始化 def test07(): # xavier 正态分布初始化 linear nn.Linear(5, 3) nn.init.xavier_normal_(linear.weight) print(linear.weight.data) # xavier 均匀分布初始化 linear nn.Linear(5, 3) nn.init.xavier_uniform_(linear.weight) print(linear.weight.data)3.3 初始化方法的选择根据激活函数选择Sigmoid/Tanh选择 Xavier 初始化ReLU/Leaky ReLU选择 kaiming 初始化根据网络深度选择浅层网络随机初始化即可深层网络需要考虑方差平衡如 Xavier 或 kaiming 初始化初始化方法对比辨析初始化方法核心特点适用激活函数适用场景均匀 / 正态随机简单随机初始化浅层网络的激活函数简单的浅层网络全 0 / 全 1 / 固定值固定值初始化不推荐容易导致对称问题仅偏置可以使用权重不推荐Xavier 初始化平衡输入输出方差Sigmoid、Tanh早期的深层网络Kaiming 初始化适配 ReLU 的半正则特性ReLU、Leaky ReLU现代深层网络四、神经网络搭建实战我们来构建一个简单的神经网络模型结合我们学到的激活函数和参数初始化搭建步骤在 pytorch 中定义深度神经网络其实就是层堆叠的过程继承自 nn.Module实现两个方法\_\_init\_\_方法中定义网络中的层结构主要是全连接层并进行初始化forward方法在实例化模型的时候底层会自动调用该函数。该函数中为初始化定义的 layer 传入数据进行前向传播等。代码实现from torch.nn import Module, Linear import torch # TODO 1.自定义模型类继承Module类 class My_Model(Module): # TODO 2.重写init魔法方法和forward前向传播方法 def __init__(self, *args, **kwargs): # 1.调用父类的init初始化方法 super().__init__(*args, **kwargs) # TODO 定义神经网络结构 self.linear1 Linear(3, 3) self.linear2 Linear(3, 2) self.out Linear(2, 2) # 3.参数初始化(生成权重矩阵) # 隐藏层初始化权重矩阵 torch.nn.init.xavier_normal_(self.linear1.weight) torch.nn.init.kaiming_normal_(self.linear2.weight) def forward(self, x): # TODO 前向传播计算(每层都是加权求和激活函数) x torch.sigmoid(self.linear1(x)) x torch.relu(self.linear2(x)) # 下面-1代表最后一维, 也就是按照每个样本概率和为1. x torch.softmax(self.out(x), dim-1) return x # TODO 3.创建模型对象并使用模型对象 # 创建模型对象 model My_Model() # 自动调用init魔法方法 # 准备数据集(正态分布数据) torch.manual_seed(66) data torch.randn(5, 3) # 5个样本,3个特征 # 把数据传入模型对象 output model(data) # 自动调用forward方法 print(output)五、损失函数本章节学习目标知道分类任务的损失函数知道回归任务的损失函数5.1 什么是损失函数在深度学习中损失函数是用来衡量模型参数的质量的函数衡量的方式是比较网络输出和真实输出的差异。损失函数在不同的文献中名称是不一样的主要有以下几种命名方式损失函数Loss Function代价函数Cost Function目标函数Objective Function5.2 分类任务的损失函数5.2.1 多分类任务交叉熵损失在多分类任务通常使用 softmax 将 logits 转换为概率的形式所以多分类的交叉熵损失也叫做 softmax 损失它的计算方法是其中:y 是样本 x 属于某一个类别的真实概率而 f (x) 是样本属于某一类别的预测分数S 是 softmax 激活函数将属于某一类别的预测分数转换成概率L 用来衡量真实值 y 和预测值 f (x) 之间差异性的损失结果从概率角度理解我们的目的是最小化正确类别所对应的预测概率的对数的负值 (损失值最小)上图中的交叉熵损失为从概率角度理解我们的目的是最小化正确类别所对应的预测概率的对数的负值(损失值最小)如下图所示在 pytorch 中使用nn\.CrossEntropyLoss\(\)实现代码如下# 分类损失函数交叉熵损失使用nn.CrossEntropyLoss()实现。nn.CrossEntropyLoss()softmax 损失计算 def test01(): # 设置真实值: 可以是热编码后的结果也可以不进行热编码 # y_true torch.tensor([[0, 1, 0], [0, 0, 1]], dtypetorch.float32) # 注意的类型必须是64位整型数据 y_true torch.tensor([1, 2], dtypetorch.int64) y_pred torch.tensor([[0.2, 0.6, 0.2], [0.1, 0.8, 0.1]], requires_gradTrue, dtypetorch.float32) # 实例化交叉熵损失 loss nn.CrossEntropyLoss() # 计算损失结果 my_loss loss(y_pred, y_true).detach().numpy() print(loss:, my_loss)5.2.2 二分类任务二分类交叉熵损失在处理二分类任务时我们不再使用 softmax 激活函数而是使用 sigmoid 激活函数那损失函数也相应的进行调整使用二分类的交叉熵损失函数其中:y 是样本 x 属于某一个类别的真实概率而 y^ 是样本属于某一类别的预测概率L 用来衡量真实值 y 与预测值 y^ 之间差异性的损失结果。在 pytorch 中实现时使用nn\.BCELoss\(\)代码如下def test02(): # 1 设置真实值和预测值 # 预测值是sigmoid输出的结果 y_pred torch.tensor([0.6901, 0.5459], requires_gradTrue) y_true torch.tensor([0, 1], dtypetorch.float32) # 2 实例化二分类交叉熵损失 loss nn.BCELoss() # 3 计算损失 my_loss loss(y_pred, y_true).detach().numpy() print(loss, my_loss)5.3 回归任务的损失函数5.3.1 MAE 损失函数L1 LossMean absolute loss (MAE) 也被称为 L1 Loss是以绝对误差作为距离。损失函数公式:特点是由于 L1 loss 具有稀疏性为了惩罚较大的值因此常常将其作为正则项添加到其他 loss 中作为约束。L1 loss 的最大问题是梯度在零点不平滑导致会跳过极小值。在 pytorch 中使用nn\.L1Loss\(\)实现代码如下# 计算inputs与target之差的绝对值 def test03(): # 1 设置真实值和预测值 y_pred torch.tensor([1.0, 1.0, 1.9], requires_gradTrue) y_true torch.tensor([2.0, 2.0, 2.0], dtypetorch.float32) # 2 实例化MAE损失 loss nn.L1Loss() # 3 计算损失 my_loss loss(y_pred, y_true).detach().numpy() print(loss, my_loss)5.3.2 MSE 损失函数L2 LossMean Squared Loss (MSE) 也被称为 L2 Loss是以均方误差作为距离。损失函数公式:特点是L2 loss 的梯度会随着误差减小而减小因此更容易收敛到最小值。对异常值更敏感因为它会对大的误差进行平方惩罚。在 pytorch 中使用nn\.MSELoss\(\)实现代码如下# 计算inputs与target之差的平方 def test04(): # 1 设置真实值和预测值 y_pred torch.tensor([1.0, 1.0, 1.9], requires_gradTrue) y_true torch.tensor([2.0, 2.0, 2.0], dtypetorch.float32) # 2 实例化MSE损失 loss nn.MSELoss() # 3 计算损失 my_loss loss(y_pred, y_true).detach().numpy() print(loss, my_loss)损失函数对比辨析损失函数适用任务特点适用场景交叉熵损失CrossEntropy多分类衡量预测概率分布和真实分布的差异梯度稳定多分类任务二分类交叉熵损失BCELoss二分类针对二分类的交叉熵配合 sigmoid 使用二分类任务MAE 损失L1 Loss回归对异常值不敏感零点梯度不平滑回归任务对异常值鲁棒的场景MSE 损失L2 Loss回归梯度随误差减小更容易收敛对异常值敏感回归任务数据质量较好的场景六、网络优化方法本章节学习目标了解常见的优化算法掌握学习率的调整方法6.1 梯度下降优化算法梯度下降是神经网络优化的基础算法常见的梯度下降变种有批量梯度下降BGD使用全部样本计算梯度更新稳定但速度慢随机梯度下降SGD使用单个样本计算梯度速度快但波动大小批量梯度下降MBGD使用小批量样本平衡速度和稳定性是目前的主流6.2 带动量的梯度下降动量Momentum是模拟物理中的动量概念积累之前的梯度方向加速收敛减少震荡6.3 自适应学习率算法6.3.1 AdaGrad自适应调整每个参数的学习率对稀疏数据效果好但学习率会单调递减6.3.2 RMSProp解决 AdaGrad 学习率递减的问题使用指数移动平均来累积梯度6.3.3 Adam结合了动量和 RMSProp 的优点是目前最常用的优化算法自适应调整学习率收敛速度快6.4 学习率衰减随着训练的进行逐渐降低学习率让模型在训练后期更稳定避免震荡6.4.1 等间隔学习率衰减每经过固定的轮次就将学习率乘以一个衰减系数def test_StepLR(): # 0.参数初始化 LR 0.1 # 设置学习率初始化值为0.1 iteration 10 max_epoch 200 # 1 初始化参数 y_true torch.tensor([0]) x torch.tensor([1.0]) w torch.tensor([1.0], requires_gradTrue) # 2.优化器 optimizer optim.SGD([w], lrLR, momentum0.9) # 3.设置学习率下降策略 scheduler_lr optim.lr_scheduler.StepLR(optimizer, step_size50, gamma0.5) # 4.获取学习率的值和当前的epoch lr_list, epoch_list list(), list() for epoch in range(max_epoch): lr_list.append(scheduler_lr.get_last_lr()) # 获取当前lr epoch_list.append(epoch) # 获取当前的epoch for i in range(iteration): # 遍历每一个batch数据 loss ((w*x-y_true)**2)/2.0 # 目标函数 optimizer.zero_grad() # 反向传播 loss.backward() optimizer.step() # 更新下一个epoch的学习率 scheduler_lr.step() # 5.绘制学习率变化的曲线 plt.plot(epoch_list, lr_list, labelStep LR Scheduler) plt.xlabel(Epoch) plt.ylabel(Learning rate) plt.legend() plt.show()6.4.2 指定间隔学习率衰减在指定的轮次进行学习率衰减更灵活def test_MultiStepLR(): torch.manual_seed(1) LR 0.1 iteration 10 max_epoch 200 weights torch.randn((1), requires_gradTrue) target torch.zeros((1)) print(weights---, weights, target---, target) optimizer optim.SGD([weights], lrLR, momentum0.9) # 设定调整时刻数 milestones [50, 125, 160] # 设置学习率下降策略 scheduler_lr optim.lr_scheduler.MultiStepLR(optimizer, milestonesmilestones, gamma0.5) lr_list, epoch_list list(), list() for epoch in range(max_epoch): lr_list.append(scheduler_lr.get_last_lr()) epoch_list.append(epoch) for i in range(iteration): loss torch.pow((weights - target), 2) optimizer.zero_grad() # 反向传播 loss.backward() # 参数更新 optimizer.step() # 更新下一个epoch的学习率 scheduler_lr.step() plt.plot(epoch_list, lr_list, labelMulti Step LR Scheduler\nmilestones:{}.format(milestones)) plt.xlabel(Epoch) plt.ylabel(Learning rate) plt.legend() plt.show()6.4.3 按指数学习率衰减学习率按指数规律衰减def test_ExponentialLR(): # 0.参数初始化 LR 0.1 # 设置学习率初始化值为0.1 iteration 10 max_epoch 200 # 1 初始化参数 y_true torch.tensor([0]) x torch.tensor([1.0]) w torch.tensor([1.0], requires_gradTrue) # 2.优化器 optimizer optim.SGD([w], lrLR, momentum0.9) # 3.设置学习率下降策略 gamma 0.95 scheduler_lr optim.lr_scheduler.ExponentialLR(optimizer, gammagamma) # 4.获取学习率的值和当前的epoch lr_list, epoch_list list(), list() for epoch in range(max_epoch): lr_list.append(scheduler_lr.get_last_lr()) epoch_list.append(epoch) for i in range(iteration): # 遍历每一个batch数据 loss ((w*x-y_true)**2)/2.0 optimizer.zero_grad() # 反向传播 loss.backward() optimizer.step() # 更新下一个epoch的学习率 scheduler_lr.step() # 5.绘制学习率变化的曲线 plt.plot(epoch_list, lr_list, labelMulti Step LR Scheduler) plt.xlabel(Epoch) plt.ylabel(Learning rate) plt.legend() plt.show()优化方法对比辨析优化算法核心特点适用场景SGD简单的随机梯度下降收敛慢容易震荡简单任务数据量小SGDMomentum加入动量加速收敛减少震荡大部分任务稳定训练AdaGrad自适应学习率适合稀疏数据稀疏数据NLP 任务RMSProp解决 AdaGrad 学习率递减问题深度学习任务Adam结合动量和自适应学习率收敛快主流深度学习任务默认首选七、正则化方法本章节学习目标知道正则化的作用掌握随机失活 DropOut 策略知道 BN 层的作用7.1 正则化的作用在设计机器学习算法时希望在新样本上的泛化能力强。许多机器学习算法都采用相关的策略来减小测试误差这些策略被统称为正则化。神经网络强大的表示能力经常遇到过拟合所以需要使用不同形式的正则化策略。7.2 Dropout 正则化在练神经网络中模型参数较多在数据量不足的情况下很容易过拟合。Dropout随机失活是一个简单有效的正则化方法。在训练过程中Dropout 的实现是让神经元以超参数 p 的概率停止工作或者激活被置为 0, 未被置为 0 的进行缩放缩放比例为 1/(1-p)。训练过程可以认为是对完整的神经网络的一些子集进行训练每次基于输入数据只更新子网络的参数。在测试过程中随机失活不起作用。代码示例import torch import torch.nn as nn def test(): # 初始化随机失活层 dropout nn.Dropout(p0.4) # 初始化输入数据:表示某一层的weight信息 inputs torch.randint(0, 10, size[1, 4]).float() layer nn.Linear(4,5) y layer(inputs) print(未失活FC层的输出结果\n, y) y dropout(y) print(失活后FC层的输出结果\n, y)输出结果:未失活FC层的输出结果 tensor([[-0.8369, -5.5720, 0.2258, 3.4256, 2.1919]], grad_fnAddmmBackward0) 失活后FC层的输出结果 tensor([[-1.3949, -9.2866, 0.3763, 0.0000, 3.6531]], grad_fnMulBackward0)7.3 批量归一化Batch Normalization批量归一化是对数据标准化再对数据重构缩放 平移如下所示其中λ 和 β 是可学习的参数它相当于对标准化后的值做了一个线性变换λ 为系数β 为偏置eps 通常指为 1e-5避免分母为 0E (x) 表示变量的均值Var (x) 表示变量的方差批量归一化层在计算机视觉领域使用较多它可以缓解梯度消失 / 爆炸问题允许使用更高的学习率降低对初始化的敏感程度有轻微的正则化效果代码示例import torch import torch.nn as nn m nn.BatchNorm2d(2, eps1e-05, momentum0.1, affineTrue) # affine参数设为True表示weight和bias将被使用 input torch.randn(1, 2, 3, 4) print(input--, input) output m(input) print(output--, output) print(output.size()) print(m.weight) print(m.bias)输出结果:input-- tensor([[[[-0.2751, -1.2183, -0.5106, -0.1540], [-0.4585, -0.5989, -0.6063, 0.5986], [-0.4745, 0.1496, -1.1266, -1.2377]], [[ 0.2580, 1.2065, 1.4598, 0.8387], [-0.4586, 0.8938, -0.3328, 0.1192], [-0.3265, -0.6263, 0.0419, -1.2231]]]]) output-- tensor([[[[ 0.4164, -1.3889, -0.0343, 0.6484], [ 0.0655, -0.2032, -0.2175, 2.0889], [ 0.0349, 1.2294, -1.2134, -1.4262]], [[ 0.1340, 1.3582, 1.6853, 0.8835], [-0.7910, 0.9546, -0.6287, -0.0452], [-0.6205, -1.0075, -0.1449, -1.7779]]]], grad_fnNativeBatchNormBackward0) torch.Size([1, 2, 3, 4]) Parameter containing: tensor([1., 1.], requires_gradTrue) Parameter containing: tensor([0., 0.], requires_gradTrue)八、实战案例手机价格分类本章节学习目标掌握构建分类模型的完整流程动手实践整个训练和评估过程8.1 需求分析小明创办了一家手机公司他不知道如何估算手机产品的价格。为了解决这个问题他收集了多家公司的手机销售数据。该数据为二手手机的各个性能的数据最后根据这些性能得到 4 个价格区间作为这些二手手机售出的价格区间。我们需要帮助小明找出手机的功能例如RAM 等与其售价之间的某种关系。我们可以使用机器学习的方法来解决这个问题也可以构建一个全连接的网络。需要注意的是在这个问题中我们不需要预测实际价格而是一个价格范围它的范围使用 0、1、2、3 来表示所以该问题也是一个分类问题。I在这里插入图片描述8.2 完整流程我们按照四个步骤来完成这个任务准备训练集数据构建要使用的模型模型训练模型预测评估8.2.1 导入工具包# 导入相关模块 import torch from torch.utils.data import TensorDataset from torch.utils.data import DataLoader import torch.nn as nn import torch.optim as optim from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt import numpy as np import pandas as pd import time8.2.2 构建数据集数据共有 2000 条其中 1600 条数据作为训练集400 条数据用作测试集。 我们使用 sklearn 的数据集划分工作来完成。并使用 PyTorch 的 TensorDataset 来将数据集构建为 Dataset 对象方便构造数据集加载对象。# 构建数据集 def create_dataset(): # 使用pandas读取数据 data pd.read_csv(data/手机价格预测.csv) # 特征值和目标值 x, y data.iloc[:, :-1], data.iloc[:, -1] # 类型转换特征值目标值 x x.astype(np.float32) y y.astype(np.int64) # 数据集划分 x_train, x_valid, y_train, y_valid train_test_split(x, y, train_size0.8, random_state88) # 构建数据集,转换为pytorch的形式 train_dataset TensorDataset(torch.from_numpy(x_train.values), torch.tensor(y_train.values)) valid_dataset TensorDataset(torch.from_numpy(x_valid.values), torch.tensor(y_valid.values)) # 返回结果 return train_dataset, valid_dataset, x_train.shape[1], len(np.unique(y))输出结果输入特征数 20 分类个数 48.2.3 构建分类网络模型构建全连接神经网络来进行手机价格分类该网络主要由三个线性层来构建使用 relu 激活函数。网络共有 3 个全连接层具体信息如下:第一层输入为维度为 20, 输出维度为: 128第二层输入为维度为 128, 输出维度为: 256第三层输入为维度为 256, 输出维度为: 4# 构建网络模型 class PhonePriceModel(nn.Module): def __init__(self, input_dim, output_dim): super(PhonePriceModel, self).__init__() # 1. 第一层: 输入为维度为 20, 输出维度为: 128 self.linear1 nn.Linear(input_dim, 128) # 2. 第二层: 输入为维度为 128, 输出维度为: 256 self.linear2 nn.Linear(128, 256) # 3. 第三层: 输入为维度为 256, 输出维度为: 4 self.linear3 nn.Linear(256, output_dim) def forward(self, x): # 前向传播过程 x torch.relu(self.linear1(x)) x torch.relu(self.linear2(x)) output self.linear3(x) # 获取数据结果 return output模型实例化的输出8.2.4 模型训练网络编写完成之后我们需要编写训练函数。所谓的训练函数指的是输入数据读取、送入网络、计算损失、更新参数的流程该流程较为固定。我们使用的是多分类交叉生损失函数、使用 SGD 优化方法。最终将训练好的模型持久化到磁盘中。# 模型训练过程 def train(train_dataset,input_dim,class_num,): # 固定随机数种子 torch.manual_seed(0) # 初始化数据加载器 dataloader DataLoader(train_dataset, shuffleTrue, batch_size8) # 初始化模型 model PhonePriceModel(input_dim, class_num) # 损失函数 criterion nn.CrossEntropyLoss() # 优化方法 optimizer optim.SGD(model.parameters(), lr1e-3) # 训练轮数 num_epoch 50 # 遍历每个轮次的数据 for epoch_idx in range(num_epoch): # 训练时间 start time.time() # 计算损失 total_loss 0.0 total_num 0 # 遍历每个batch数据进行处理 for x, y in dataloader: # 将数据送入网络中进行预测 output model(x) # 计算损失 loss criterion(output, y) # 梯度清零 optimizer.zero_grad() # 反向传播 loss.backward() # 参数更新 optimizer.step() # 损失计算 total_num 1 total_loss loss.item() # 打印损失变换结果 print(epoch: %4s loss: %.2f, time: %.2fs %(epoch_idx 1, total_loss / total_num, time.time() - start)) # 模型保存 torch.save(model.state_dict(), model/phone.pth)训练的输出结果8.2.5 模型评估使用训练好的模型对未知的样本的进行预测的过程。我们这里使用前面单独划分出来的验证集来进行评估。def test(valid_dataset,input_dim,class_num): # 加载模型和训练好的网络参数 model PhonePriceModel(input_dim, class_num) model.load_state_dict(torch.load(model/phone.pth)) # 构建加载器 dataloader DataLoader(valid_dataset, batch_size8, shuffleFalse) # 评估测试集 correct 0 # 遍历测试集中的数据 for x, y in dataloader: # 将其送入网络中 output model(x) # 获取类别结果 y_pred torch.argmax(output, dim1) # 获取预测正确的个数 correct (y_pred y).sum() # 求预测精度 print(Acc: %.5f % (correct.item() / len(valid_dataset)))输出结果:Acc: 0.642508.3 调优方向我们前面的网络模型在测试集的准确率为: 0.64250, 我们可以通过以下方面进行调优:优化方法由 SGD 调整为 Adam学习率由 1e-3 调整为 1e-4对数据进行标准化增加网络深度即增加网络参数量调整训练轮次

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2614363.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…