| Id |
Title |
Content |
Published |
Framework Id |
User Id |
Created |
Modified |
Actions |
| 35 |
激活函数介绍 |
<p> 激活函数的目的:</p>
<p> 给模型增加非线性功能, 让模型(神经元)既可以做分类, 还可以做回归问题.</p>
<p> 激活函数的分类:</p>
<p> Sigmoid:</p>
<p> ReLU:</p>
<p> Tanh:</p>
<p> Softmax:</p>
<p> </p>
<p> Sigmoid激活函数:</p>
<p> 主要应用于 二分类的输出层, 且适用于 浅层神经网络(不超过5层).</p>
<p> 数据在 [-6, 6]之间有效果, 在[-3, 3]之间效果明显, 会将数据值映射到: [0, 1]</p>
<p> 求导后范围在 [0, 0.25]</p>
<p> </p>
<p> Tanh:</p>
<p> 主要应用于 隐藏层, 且适用于 浅层神经网络(不超过5层).</p>
<p> 数据在 [-3, 3]之间有效果, 在[-1, 1]之间效果明显, 会将数据值映射到: [-1, 1]</p>
<p> 求导后范围在 [0, 1], 较之于Sigmoid, 收敛速度快.</p>
<p> </p>
<p> ReLU:</p>
<p> 计算公式为: max(0, x), 计算量相对较小, 训练成本低. 多应用于 隐藏层, 且适合 深层神经网络.</p>
<p> 求导后, 值要么是0, 要么是1, 较之于Tanh, 收敛速度更快.</p>
<p> 默认情况下ReLU只考虑 正样本, 可以使用LeakyReLU, PReLU 来考虑 正负样本.</p>
<p> </p>
<p> </p>
<p> Softmax:</p>
<p> 将多分类的结果以概率的形式展示, 且概率和相加为1, 最终选取概率值最大的分类 作为最终结果.</p>
<p> </p>
<p>记忆: 如何选择激活函数</p>
<p> 隐藏层:</p>
<p> ReLU > Leaky ReLU > PReLU > Tanh > Sigmoid</p>
<p> 输出层:</p>
<p> 二分类: Sigmoid</p>
<p> 多分类: Softmax</p>
<p> 回归问题: identity</p> |
1 |
1 |
1 |
1/31/26, 6:01 PM |
1/31/26, 6:01 PM |
View Edit Delete |
| 36 |
Pytorch神经网络参数初始化方式 |
<p>参数初始化的目的:</p>
<p> 1. 防止梯度消失 或者 梯度爆炸.</p>
<p> 2. 提高收敛速度.</p>
<p> 3. 打破对称性.</p>
<p> </p>
<p>参数初始化的方式:</p>
<p> 无法打破对称性的:</p>
<p> 全0, 全1, 固定值</p>
<p> 可以打破对称性的:</p>
<p> 随机初始化, 正态分布初始化, kaiming初始化, xavier初始化</p>
<p> </p>
<p>总结:</p>
<p> 1. 记忆 kaiming初始化, xavier初始化, 全0初始化.</p>
<p> 2. 关于初始化的选择上:</p>
<p> 激活函数ReLU及其系列: 优先用 kaiming</p>
<p> 激活函数非ReLU: 优先用 xavier</p>
<p> 如果是浅层网络: 可以考虑使用 随机初始化</p>
<pre class=""><code class="language-python hljs"># 导包
import torch.nn as nn # neural network: 神经网络
import torch.nn as nn
# 1. 均匀分布随机初始化
def dm01():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行随机初始化, 从0-1均匀分布产生参数
nn.init.uniform_(linear.weight)
# 3. 对偏置(b)进行随机初始化, 从0-1均匀分布产生参数
nn.init.uniform_(linear.bias)
# 4. 打印生成结果.
print(linear.weight.data)
print(linear.bias.data)
# 2. 固定初始化
def dm02():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 设置固定值为: 3
nn.init.constant_(linear.weight, 3)
# 3. 对偏置(b)进行初始化, 设置固定值为: 3
nn.init.constant_(linear.bias, 3)
# 4. 打印生成结果.
print(linear.weight.data)
print(linear.bias.data)
# 3. 全0初始化
def dm03():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 全0初始化
nn.init.zeros_(linear.weight)
# 3. 对偏置(b)进行初始化, 全0初始化
nn.init.zeros_(linear.bias)
# 4. 打印生成结果.
print(linear.weight.data)
print(linear.bias.data)
# 4. 全1初始化
def dm04():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 全1初始化
nn.init.ones_(linear.weight)
# 3. 打印生成结果.
print(linear.weight.data)
# 5. 正态分布随机初始化
def dm05():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 正态分布初始化(均值为0, 标准差为1)
nn.init.normal_(linear.weight)
# 3. 打印生成结果.
print(linear.weight.data)
# 6. kaiming 初始化
def dm06():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 正态分布初始化(均值为0, 标准差为1)
# kaiming 正态分布初始化
# nn.init.kaiming_normal_(linear.weight)
# kaiming 均匀分布初始化
nn.init.kaiming_uniform_(linear.weight)
# 3. 打印生成结果.
print(linear.weight.data)
# 7. xavier 初始化
def dm07():
# 1. 创建1个线性层, 输入维度5, 输出维度3
linear = nn.Linear(5, 3)
# 2. 对权重(w)进行初始化, 正态分布初始化(均值为0, 标准差为1)
# xavier 正态分布初始化
# nn.init.xavier_normal_(linear.weight)
# xavier 均匀分布初始化
nn.init.xavier_uniform_(linear.weight)
# 3. 打印生成结果.
print(linear.weight.data)
# 测试
if __name__ == '__main__':
# dm01() # 均匀分布随机初始化
# dm02() # 固定初始化
# dm03() # 全0初始化
# dm04() # 全1初始化
# dm05() # 正态分布
# dm06() # kaiming初始化
dm07() # xavier初始化</code></pre> |
1 |
1 |
1 |
2/1/26, 8:05 AM |
2/4/26, 3:33 PM |
View Edit Delete |
| 37 |
Pytorch常用损失函数 |
<p>损失函数介绍:</p>
<p> 概述:</p>
<p> 损失函数也叫成本函数, 目标函数, 代价函数, 误差函数, 就是用来衡量 模型好坏(模型拟合情况)的.</p>
<p> 分类:</p>
<p> 分类问题:</p>
<p> <strong>多分类交叉熵损失: CrossEntropyLoss </strong>【实际情况可替代BCELoss】</p>
<p> 二分类交叉熵损失: BCELoss</p>
<p> 回归问题:</p>
<p> MAE: Mean Absolute Error, 平均绝对误差.</p>
<p> MSE: Mean Squared Error, 均方误差.</p>
<p> <strong> Smooth L1: 结合上述两个的特点做的升级, 优化.</strong>【实际情况可替代MAE和MSE】</p>
<p> </p>
<p>多分类交叉熵损失: CrossEntropyLoss</p>
<p> 设计思路:</p>
<p> Loss = - Σylog(S(f(x)))</p>
<p> 简单记忆:</p>
<p> x: 样本</p>
<p> f(x): 加权求和</p>
<p> S(f(x)): 处理后的概率</p>
<p> y: 样本x属于某一个类别的 真实概率.</p>
<p> 大白话解释:</p>
<p> 损失函数结果 = 最小化 正确类别所对应的 预测概率的对数的 负值(损失值最小)...</p>
<p> 细节:</p>
<p> CrossEntropyLoss = Softmax() + 损失计算, 后续如果用这个损失函数, 则: 输出层就不用额外调用 softmax()激活函数了.</p>
<pre class=""><code class="language-python hljs"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 演示: 多分类交叉熵损失.
def dm01():
# 1. 手动创建样本的真实值 -> 就是上述公式中的 y
y_true = torch.tensor([[0, 1, 0], [1, 0, 0]], dtype=torch.float)
# y_true = torch.tensor([1, 2])
# 2. 手动创建样本的预测值 -> 就是上述公式中的 f(x)
y_pred = torch.tensor([[0.1, 0.8, 0.1], [0.7, 0.2, 0.1]], requires_grad=True, dtype=torch.float)
# 3. 创建多分类交叉熵损失函数.
criterion = nn.CrossEntropyLoss() # 平均损失, 来源于参数: reduction: str = "mean",
# 4. 计算损失值.
loss = criterion(y_pred, y_true)
print(f'损失值: {loss}')
# 2. 测试
if __name__ == '__main__':
dm01()</code></pre>
<p> </p>
<p>二分类任务的损失函数(BCELoss):</p>
<p> 公式:</p>
<p> Loss = -ylog(预测值) - (1 - y)log(1 - 预测值)</p>
<p> 细节:</p>
<p> 因为公式中没有包含Sigmoid激活函数, 所以使用BCELoss的时候, 还需要手动指定 Sigmoid.</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 演示: 二分类任务的损失函数.
def dm01():
# 1. 设置真实值.
y_true = torch.tensor([0, 1, 0], dtype=torch.float)
# 2. 设置预测值(概率)
y_pred = torch.tensor([0.6901, 0.5423, 0.2639])
# 3. 创建二分类交叉熵损失函数.
criterion = nn.BCELoss() # reduction: str = "mean" -> 均值
# 4. 计算损失值.
loss = criterion(y_pred, y_true)
print(f'损失值: {loss}')
# 2. 测试
if __name__ == '__main__':
dm01()</code></pre>
<p> </p>
<p>回归任务常用损失函数如下:</p>
<p> MAE: Mean Absolute Error, 平均绝对误差.</p>
<p> 公式:</p>
<p> 误差绝对值之和 / 样本总数</p>
<p> 类似于L1正则化, 权重可以降维0, 数据会变得稀疏.</p>
<p> </p>
<p> 弊端:</p>
<p> 在0点不平滑, 可能错过最小值.</p>
<p> </p>
<p> MSE: Mean Squared Error, 均方误差.</p>
<p> 公式:</p>
<p> 误差平方之和 / 样本总数</p>
<p> 弊端:</p>
<p> 如果差值过大, 可能存在梯度爆炸的情况.</p>
<p> </p>
<p> Smooth L1:</p>
<p> 就是基于MAE 和 MSE做的综合, 在 [-1, 1]是 L2(MSE), 其它段时L1.</p>
<p> 这样即解决了L1不平滑的问题(0点不可导, 可能错过最小值)</p>
<p> 又解决了L2(MSE)的 梯度爆炸的问题.</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 演示: MAE 损失函数.
def dm01():
# 1. 定义变量, 记录: 真实值.
y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)
# 2. 定义变量, 记录: 预测值.
y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)
# 3. 创建MAE损失函数对象.
criterion = nn.L1Loss()
# 4. 计算损失.
loss = criterion(y_pred, y_true)
# 5. 输出损失.
print(f'MAE: {loss}')
# 2. 定义函数, 演示: MSE 损失函数.
def dm02():
# 1. 定义变量, 记录: 真实值.
y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)
# 2. 定义变量, 记录: 预测值.
y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)
# 3. 创建MSE损失函数对象.
criterion = nn.MSELoss()
# 4. 计算损失.
loss = criterion(y_pred, y_true)
# 5. 输出损失.
print(f'MSE: {loss}')
# 3. 定义函数, 演示: Smooth L1 损失函数.
def dm03():
# 1. 定义变量, 记录: 真实值.
y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)
# 2. 定义变量, 记录: 预测值.
y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)
# 3. 创建Smooth L1损失函数对象.
criterion = nn.SmoothL1Loss()
# 4. 计算损失.
loss = criterion(y_pred, y_true)
# 5. 输出损失.
print(f'Smooth L1: {loss}')
# 4. 测试
if __name__ == '__main__':
# dm01() # 0.699999988079071
# dm02() # 0.6700000166893005
dm03() # 0.33500000834465027</code></pre> |
1 |
1 |
1 |
2/2/26, 3:48 AM |
2/4/26, 3:33 PM |
View Edit Delete |
| 38 |
导数计算 |
<p><strong>幂函数求导</strong><br />公式:<img src="data:image/png;base64,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" alt="" /></p>
<p>例如 :x<sup>2</sup>; 求导则等于2x<br /><br /></p>
<p><strong>复合函数求导<br /></strong>公式:<img src="data:image/png;base64,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" alt="" /></p>
<p>例如:(3-x)<sup>2</sup>求导</p>
<p>要算要外层乘以内层,</p>
<p>设内层 3-x 等于 u</p>
<p>然后外层u<sup>2</sup>对u求导 、内层u对x求导,并相乘</p>
<p>得出外层2u = 2(3-x) 和 内层(0-1) = -1 相乘</p>
<p>得到2x-6</p> |
1 |
1 |
1 |
2/3/26, 7:36 PM |
2/4/26, 4:48 AM |
View Edit Delete |
| 39 |
Pytorch常用优化器 |
<p>梯度下降相关介绍:</p>
<p> 概述:</p>
<p> 梯度下降是结合 本次损失函数的导数(作为梯度) 基于学习率 来更新权重的.</p>
<p> 公式:</p>
<p> W新 = W旧 - 学习率 * (本次的)梯度</p>
<p> 存在的问题:</p>
<p> 1. 遇到平缓区域, 梯度下降(权重更新)可能会慢.</p>
<p> 2. 可能会遇到 鞍点(梯度为0)</p>
<p> 3. 可能会遇到 局部最小值.</p>
<p> 解决思路:</p>
<p> 从上述的 学习率 或者 梯度入手, 进行优化, 于是有了: 动量法Momentum, 自适应学习率AdaGrad, RMSProp, 综合衡量: Adam</p>
<p> </p>
<p> 动量法Momentum:</p>
<p> 动量法公式:</p>
<p> St = β * St-1 + (1 - β) * Gt</p>
<p> 解释:</p>
<p> St: 本次的指数移动加权平均结果.</p>
<p> β: 调节权重系数, 越大, 数据越平缓, 历史指数移动加权平均 比重越大, 本次梯度权重越小.</p>
<p> St-1: 历史的指数移动加权平均结果.</p>
<p> Gt: 本次计算出的梯度(不考虑历史梯度).</p>
<p> 加入动量法后的 梯度更新公式:</p>
<p> W新 = W旧 - 学习率 * St</p>
<p> </p>
<p> 自适应学习率: AdaGrad(Adaptive Gradient Estimation)</p>
<p> 公式:</p>
<p> 累计平方梯度:</p>
<p> St = St-1 + Gt * Gt</p>
<p> 解释:</p>
<p> St: 累计平方梯度</p>
<p> St-1: 历史累计平方梯度.</p>
<p> Gt: 本次的梯度.</p>
<p> 学习率:</p>
<p> 学习率 = 学习率 / (sqrt(St) + 小常数)</p>
<p> 解释:</p>
<p> 小常数: 1e-10, 目的: 防止分母变为0</p>
<p> 梯度下降公式:</p>
<p> W新 = W旧 - 调整后的学习率 * Gt</p>
<p> 缺点:</p>
<p> 可能会导致学习率过早, 过量的降低, 导致模型后期学习率太小, 较难找到最优解.</p>
<p> </p>
<p> </p>
<p> 自适应学习率: RMSProp(Root Mean Square Propagation) -> 可以看做是 对AdaGrad做的优化, 加入 调和权重系数.</p>
<p> 公式:</p>
<p> 指数加权平均 累计历史平方梯度:</p>
<p> St = β * St-1 + (1 - β) * Gt * Gt</p>
<p> 解释:</p>
<p> St: 累计平方梯度</p>
<p> St-1: 历史累计平方梯度.</p>
<p> Gt: 本次的梯度.</p>
<p> β: 调和权重系数.</p>
<p> 学习率:</p>
<p> 学习率 = 学习率 / (sqrt(St) + 小常数)</p>
<p> 解释:</p>
<p> 小常数: 1e-10, 目的: 防止分母变为0</p>
<p> 梯度下降公式:</p>
<p> W新 = W旧 - 调整后的学习率 * Gt</p>
<p> 优点:</p>
<p> RMSProp通过引入 衰减系数β, 控制历史梯度 对 历史梯度信息获取的多少.</p>
<p> </p>
<p> 自适应矩估计: Adam(Adaptive Moment Estimation)</p>
<p> 思路:</p>
<p> 即优化学习率, 又优化梯度.</p>
<p> 公式:</p>
<p> 一阶矩: 算均值.</p>
<p> Mt = β1 * Mt-1 + (1 - β1) * Gt 充当: 梯度</p>
<p> St = β2 * St-1 + (1 - β2) * Gt * Gt 充当: 学习率</p>
<p> 二阶矩: 梯度的方差.</p>
<p> Mt^ = Mt / (1 - β1 ^ t)</p>
<p> St^ = St / (1 - β2 ^ t)</p>
<p> 权重更新公式:</p>
<p> W新 = W旧 - 学习率 / (sqrt(St^) + 小常数) * Mt^</p>
<p> 大白话翻译:</p>
<p> Adam = RMSProp + Momentum</p>
<p> </p>
<p>总结: 如何选择梯度下降优化方法</p>
<p> 简单任务和较小的模型:</p>
<p> SGD, 动量法</p>
<p> 复杂任务或者有大量数据:</p>
<p> Adam</p>
<p> 需要处理稀疏数据或者文本数据:</p>
<p> AdaGrad, RMSProp</p>
<pre class=""><code class="language-python hljs"># 导包
import torch
import torch.nn as nn
import torch.optim as optim
# 1. 定义函数, 演示: 梯度下降优化方法 -> 动量法(Momentum)
def dm01_momentum():
# 1. 初始化权重参数.
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 2. 定义损失函数
criterion = ((w ** 2) / 2.0)
# 3. 创建优化器(函数对象) -> 基于SGD(随机梯度下降), 加入参数 momentum, 就是 动量法.
# 参1: (待优化的)参数列表, 参2: 学习率, 参3: 动量参数.
optimizer = optim.SGD(params=[w], lr=0.01, momentum=0.9) # 细节: momentum=0(默认), 只考虑: 本次梯度.
# 4. 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
print(f'w: {w}, w.grad: {w.grad}')
# 5.重复上述的步骤, 第2次 更新权重参数.
# 5.1 定义损失函数.
criterion = ((w ** 2) / 2.0)
# 5.2 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
# 5.3 打印结果.
print(f'w: {w}, w.grad: {w.grad}')
# 2. 定义函数, 演示: 梯度下降优化方法 -> 自适应学习率(AdaGrad)
def dm02_adagrad():
# 1. 初始化权重参数.
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 2. 定义损失函数
criterion = ((w ** 2) / 2.0)
# 3. 创建优化器(函数对象)
# 思路1: 基于SGD(随机梯度下降), 加入参数 momentum, 就是 动量法.
# 参1: (待优化的)参数列表, 参2: 学习率, 参3: 动量参数.
# optimizer = optim.SGD(params=[w], lr=0.01, momentum=0.9) # 细节: momentum=0(默认), 只考虑: 本次梯度.
# 思路2: 基于AdaGrad(自适应学习率).
optimizer = optim.Adagrad(params=[w], lr=0.01)
# 4. 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
print(f'w: {w}, w.grad: {w.grad}')
# 5.重复上述的步骤, 第2次 更新权重参数.
# 5.1 定义损失函数.
criterion = ((w ** 2) / 2.0)
# 5.2 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
# 5.3 打印结果.
print(f'w: {w}, w.grad: {w.grad}')
# 3. 定义函数, 演示: 梯度下降优化方法 -> 自适应学习率(RMSProp)
def dm03_rmsprop():
# 1. 初始化权重参数.
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 2. 定义损失函数
criterion = ((w ** 2) / 2.0)
# 3. 创建优化器(函数对象)
# 思路1: 基于SGD(随机梯度下降), 加入参数 momentum, 就是 动量法.
# 参1: (待优化的)参数列表, 参2: 学习率, 参3: 动量参数.
# optimizer = optim.SGD(params=[w], lr=0.01, momentum=0.9) # 细节: momentum=0(默认), 只考虑: 本次梯度.
# 思路2: 基于AdaGrad(自适应学习率).
# optimizer = optim.Adagrad(params=[w], lr=0.01)
# 思路3: 基于RMSProp(自适应学习率).
optimizer = optim.RMSprop(params=[w], lr=0.01, alpha=0.99)
# 4. 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
print(f'w: {w}, w.grad: {w.grad}')
# 5.重复上述的步骤, 第2次 更新权重参数.
# 5.1 定义损失函数.
criterion = ((w ** 2) / 2.0)
# 5.2 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
# 5.3 打印结果.
print(f'w: {w}, w.grad: {w.grad}')
# 4. 定义函数, 演示: 梯度下降优化方法 -> 自适应矩估计(Adam)
def dm04_adam():
# 1. 初始化权重参数.
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 2. 定义损失函数
criterion = ((w ** 2) / 2.0)
# 3. 创建优化器(函数对象)
# 思路1: 基于SGD(随机梯度下降), 加入参数 momentum, 就是 动量法.
# 参1: (待优化的)参数列表, 参2: 学习率, 参3: 动量参数.
# optimizer = optim.SGD(params=[w], lr=0.01, momentum=0.9) # 细节: momentum=0(默认), 只考虑: 本次梯度.
# 思路2: 基于AdaGrad(自适应学习率).
# optimizer = optim.Adagrad(params=[w], lr=0.01)
# 思路3: 基于RMSProp(自适应学习率).
# optimizer = optim.RMSprop(params=[w], lr=0.01, alpha=0.99)
# 思路4: 基于Adam(自适应矩估计).
optimizer = optim.Adam(params=[w], lr=0.01, betas=(0.9, 0.999)) # betas=(梯度用的 衰减系数, 学习率用的 衰减系数)
# 4. 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
print(f'w: {w}, w.grad: {w.grad}')
# 5.重复上述的步骤, 第2次 更新权重参数.
# 5.1 定义损失函数.
criterion = ((w ** 2) / 2.0)
# 5.2 计算梯度值: 梯度清零 + 反向传播 + 参数更新
optimizer.zero_grad()
criterion.sum().backward()
optimizer.step()
# 5.3 打印结果.
print(f'w: {w}, w.grad: {w.grad}')
# 5. 测试
if __name__ == '__main__':
dm01_momentum()
# dm02_adagrad()
# dm03_rmsprop()
# dm04_adam()</code></pre> |
1 |
1 |
1 |
2/4/26, 2:20 PM |
2/4/26, 3:33 PM |
View Edit Delete |
| 40 |
Pytorch手动调整学习率衰减间隔 |
<p>学习率衰减策略介绍:</p>
<p> 目的:</p>
<p> 较之于AdaGrad, RMSProp, Adam方式, 我们可以通过 等间隔, 指定间隔, 指数等方式, 来手动控制学习率的调整.</p>
<p> </p>
<p> 分类:</p>
<p> 等间隔学习率衰减</p>
<p> 指定间隔学习率衰减</p>
<p> 指数学习率衰减</p>
<p> </p>
<p>等间隔学习率衰减:</p>
<p> step_size: 间隔的轮数, 即: 多少轮调整一次学习率.</p>
<p> gamma: 学习率衰减系数, 即: lr新 = lr旧 * gamma</p>
<p> </p>
<p>指定间隔学习率衰减:</p>
<p> milestones = [50, 125, 160] 里边定义的是要调整学习率的 轮数.</p>
<p> gamma: 学习率衰减系数, 即: lr新 = lr旧 * gamma</p>
<p> </p>
<p>指数间隔学习率衰减:</p>
<p> 前期学习率衰减快, 中期慢, 后期更慢, 更符合梯度下降规律.</p>
<p> 公式:</p>
<p> lr新 = lr旧 * gamma ** epoch</p>
<p> </p>
<p>总结:</p>
<p> 等间隔学习率衰减:</p>
<p> 优点:</p>
<p> 直观, 易于调试, 适用于 大批量数据.</p>
<p> 缺点:</p>
<p> 学习率变化较大, 可能跳过最优解.</p>
<p> 应用场景:</p>
<p> 大型数据集, 较为简单的任务.</p>
<p> </p>
<p> 指定间学习率衰减:</p>
<p> 优点:</p>
<p> 易于调试, 稳定训练过程.</p>
<p> 缺点:</p>
<p> 在某些情况下可能衰减过快, 导致优化提前停滞.</p>
<p> 应用场景:</p>
<p> 对训练平稳性要求较高的任务.</p>
<p> 指数学习率衰减:</p>
<p> 优点:</p>
<p> 平滑, 且考虑历史更新, 收敛稳定性较强.</p>
<p> 缺点:</p>
<p> 超参调节较为复杂, 可能需要更多的资源.</p>
<p> 应用场景:</p>
<p> 高精度训练, 避免过快收敛.</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
from torch import optim
import matplotlib.pyplot as plt
# 1. 定义函数, 演示: 等间隔学习率衰减
def dm01():
# 1. 定义变量, 记录初始的 学习率, 训练的轮数, 每轮训练的批次数.
lr, epochs, iteration = 0.1, 200, 10
# 2. 创建数据集. y_true, x, w
# 真实值.
y_true = torch.tensor([0])
# 输入特征
x = torch.tensor([1.0], dtype=torch.float32)
# 权重参数w, 需要自动微分(求导)
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 3. 创建优化器对象, 动量法 -> 加速模型的收敛, 减少震荡.
# 参1: 待优化的参数, 参2: 学习率, 参3: 动量系数
optimizer = optim.SGD([w], lr=lr, momentum=0.9)
# 4. 创建学习率衰减对象.
# 思路1: 创建等间隔学习率衰减对象.
# 参1: 优化器对象, 参2: 间隔的轮数(多少轮调整一次学习率), 参3: 学习率衰减系数.
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5) # [0.1, 0.1, 0.1... 0.05...]
# 5. 创建两个列表, 分别表示: 训练轮数, 每轮训练用的学习率
# epoch_list = [0, 1, 2, 3.... 50, 51, 52...100, 101, 101... 150, 151...199]
# lr_list = [0.1, 0.1, 0.1, 0.05........,0.025........., 0.0125...]
lr_list, epoch_list = [], []
# 6. 循环遍历训练轮数, 进行具体的训练.
for epoch in range(epochs): # epoch: 0 ~ 199
# 7. 获取当前轮数 和 学习率, 并保存到列表中.
epoch_list.append(epoch)
lr_list.append(scheduler.get_last_lr()) # 获取最后的lr(learning rate, 学习率)
# 8. 循环遍历, 每轮每批次进行训练.
for batch in range(iteration):
# 9. 先计算预测值, 然后基于损失函数计算损失.
y_pred = w * x
# 10. 计算损失, 最小二乘法.
loss = (y_pred - y_true) ** 2
# 11. 梯度清零 + 反向传播 + 优化器更新参数.
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 12. 更新学习率.
scheduler.step()
# 13. 打印结果:
print(f'lr_list: {lr_list}') # [0.1, 0.1, 0.1..., 0.05........,0.025........., 0.0125...]
# 14. 可视化.
# x轴: 训练的轮数, y轴: 每轮训练用的学习率
plt.plot(epoch_list, lr_list)
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.show()
# 2. 定义函数, 演示: 指定间隔学习率衰减
def dm02():
# 1. 定义变量, 记录初始的 学习率, 训练的轮数, 每轮训练的批次数.
lr, epochs, iteration = 0.1, 200, 10
# 2. 创建数据集. y_true, x, w
# 真实值.
y_true = torch.tensor([0])
# 输入特征
x = torch.tensor([1.0], dtype=torch.float32)
# 权重参数w, 需要自动微分(求导)
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 3. 创建优化器对象, 动量法 -> 加速模型的收敛, 减少震荡.
# 参1: 待优化的参数, 参2: 学习率, 参3: 动量系数
optimizer = optim.SGD([w], lr=lr, momentum=0.9)
# 4. 创建学习率衰减对象.
# 思路1: 创建等间隔学习率衰减对象.
# 参1: 优化器对象, 参2: 间隔的轮数(多少轮调整一次学习率), 参3: 学习率衰减系数.
# scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5) # [0.1, 0.1, 0.1... 0.05...]
# 思路2: 创建指定间隔学习率衰减对象.
# 定义变量, 记录要修改学习率的轮数.
milestones = [50, 125, 160]
scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=milestones, gamma=0.5)
# 5. 创建两个列表, 分别表示: 训练轮数, 每轮训练用的学习率
# epoch_list = [0, 1, 2, 3.... 50, 51, 52...100, 101, 101... 150, 151...199]
# lr_list = [0.1, 0.1, 0.1, 0.05........,0.025........., 0.0125...]
lr_list, epoch_list = [], []
# 6. 循环遍历训练轮数, 进行具体的训练.
for epoch in range(epochs): # epoch: 0 ~ 199
# 7. 获取当前轮数 和 学习率, 并保存到列表中.
epoch_list.append(epoch)
lr_list.append(scheduler.get_last_lr()) # 获取最后的lr(learning rate, 学习率)
# 8. 循环遍历, 每轮每批次进行训练.
for batch in range(iteration):
# 9. 先计算预测值, 然后基于损失函数计算损失.
y_pred = w * x
# 10. 计算损失, 最小二乘法.
loss = (y_pred - y_true) ** 2
# 11. 梯度清零 + 反向传播 + 优化器更新参数.
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 12. 更新学习率.
scheduler.step()
# 13. 打印结果:
print(f'lr_list: {lr_list}') # [0.1, 0.1, 0.1..., 0.05........,0.025........., 0.0125...]
# 14. 可视化.
# x轴: 训练的轮数, y轴: 每轮训练用的学习率
plt.plot(epoch_list, lr_list)
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.show()
# 3. 定义函数, 演示: 指数学习率衰减
def dm03():
# 1. 定义变量, 记录初始的 学习率, 训练的轮数, 每轮训练的批次数.
lr, epochs, iteration = 0.1, 200, 10
# 2. 创建数据集. y_true, x, w
# 真实值.
y_true = torch.tensor([0])
# 输入特征
x = torch.tensor([1.0], dtype=torch.float32)
# 权重参数w, 需要自动微分(求导)
w = torch.tensor([1.0], requires_grad=True, dtype=torch.float32)
# 3. 创建优化器对象, 动量法 -> 加速模型的收敛, 减少震荡.
# 参1: 待优化的参数, 参2: 学习率, 参3: 动量系数
optimizer = optim.SGD([w], lr=lr, momentum=0.9)
# 4. 创建学习率衰减对象.
# 思路1: 创建等间隔学习率衰减对象.
# 参1: 优化器对象, 参2: 间隔的轮数(多少轮调整一次学习率), 参3: 学习率衰减系数.
# scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=50, gamma=0.5) # [0.1, 0.1, 0.1... 0.05...]
# 思路2: 创建指定间隔学习率衰减对象.
# 定义变量, 记录要修改学习率的轮数.
# milestones = [50, 125, 160]
# scheduler = optim.lr_scheduler.MultiStepLR(optimizer, milestones=milestones, gamma=0.5)
# 思路3: 创建指数学习率衰减对象.
scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.95)
# 5. 创建两个列表, 分别表示: 训练轮数, 每轮训练用的学习率
# epoch_list = [0, 1, 2, 3.... 50, 51, 52...100, 101, 101... 150, 151...199]
# lr_list = [0.1, 0.1, 0.1, 0.05........,0.025........., 0.0125...]
lr_list, epoch_list = [], []
# 6. 循环遍历训练轮数, 进行具体的训练.
for epoch in range(epochs): # epoch: 0 ~ 199
# 7. 获取当前轮数 和 学习率, 并保存到列表中.
epoch_list.append(epoch)
lr_list.append(scheduler.get_last_lr()) # 获取最后的lr(learning rate, 学习率)
# 8. 循环遍历, 每轮每批次进行训练.
for batch in range(iteration):
# 9. 先计算预测值, 然后基于损失函数计算损失.
y_pred = w * x
# 10. 计算损失, 最小二乘法.
loss = (y_pred - y_true) ** 2
# 11. 梯度清零 + 反向传播 + 优化器更新参数.
optimizer.zero_grad()
loss.backward()
optimizer.step()
# 12. 更新学习率.
scheduler.step()
# 13. 打印结果:
print(f'lr_list: {lr_list}') # [0.1, 0.1, 0.1..., 0.05........,0.025........., 0.0125...]
# 14. 可视化.
# x轴: 训练的轮数, y轴: 每轮训练用的学习率
plt.plot(epoch_list, lr_list)
plt.xlabel('Epoch')
plt.ylabel('Learning Rate')
plt.show()
# 4. 测试
if __name__ == '__main__':
# dm01()
# dm02()
dm03()</code></pre> |
1 |
1 |
1 |
2/4/26, 3:32 PM |
2/4/26, 3:32 PM |
View Edit Delete |
| 41 |
Pytorch正则化 |
<p>正则化的作用:</p>
<p> 缓解模型的过拟合情况.</p>
<p>正则化的方式:</p>
<p> L1正则化: 权重可以变为0, 相当于: 降维.</p>
<p> L2正则化: 权重可以无限接近0</p>
<p> DropOut: 随机失活, 每批次样本训练时, 随机让一部分神经元死亡, 防止一些特征对结果的影响较大(防止过拟合)</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 演示: 随机失活(DropOut)
def dm01():
# 1. 创建隐藏层输出结果.
t1 = torch.randint(0, 10, size=(1, 4)).float()
print(f't1: {t1}') # t1: tensor([[0., 5., 6., 3.]])
# 2. 进行下一层 加权求和 和 激活函数计算.
# 2.1 创建全连接层(充当线性层)
# 参1: 输入特征维度, 参2: 输出特征维度.
linear1 = nn.Linear(4, 5)
# 2.2 加权求和.
l1 = linear1(t1)
print(f'l1: {l1}')
# 2.3 激活函数.
output = torch.relu(l1)
print(f'output: {output}')
# 3. 对激活值进行随机失活dropout处理 -> 只有训练阶段有, 测试阶段没有.
dropout = nn.Dropout(p=0.5) # 每个神经元都有50%的概率被 kill.
# 具体的 随机失活动作.
d1 = dropout(output)
print(f'd1(随机失活后的数据): {d1}') # 未被失活的进行缩放, 缩放比例为: 1 / (1 - p) = 2
# 2. 测试
if __name__ == '__main__':
dm01()</code></pre>
<p> BN(批量归一化): 先对数据做标准化(会丢失一些信息), 然后再对数据做 缩放(λ, 理解为: w权重) 和 平移(β, 理解为: b偏置), 再找补回一些信息.</p>
<p> BatchNorm1d:主要应用于全连接层或处理一维数据的网络,例如文本处理。它接收形状为 (N, num_features) 的张量作为输入。</p>
<p> BatchNorm2d:主要应用于卷积神经网络,处理二维图像数据或特征图。它接收形状为 (N, C, H, W) 的张量作为输入。</p>
<p> BatchNorm3d:主要用于三维卷积神经网络 (3D CNN),处理三维数据,例如视频或医学图像。它接收形状为 (N, C, D, H, W) 的张量作为输入。</p>
<pre class=""><code class="hljs language-python"># 导包
import torch
import torch.nn as nn
# 1. 定义函数, 处理 二维数据.
def dm01():
# 1. 创建图像样本数据.
# 1张图片, 2个通道, 3行4列(像素点)
input_2d = torch.randn(size=(1, 2, 3, 4))
print(f'input_2d: {input_2d}')
# 2. 创建批量归一化层(BN层)
# 参1: 输入特征数 = 图片的通道数.
# 参2: 噪声值(小常数), 默认为1e-5.
# 参3: 动量值, 用于计算移动平局统计量的 动量值.
# 参4: 表示使用可学习的变换参数(λ, β) 对归一化(标准化)后的数据进行 缩放和平移.
bn2d = nn.BatchNorm2d(num_features=2, eps=1e-5, momentum=0.1, affine=True)
# 3. 对数据进行 批量归一化处理.
output_2d = bn2d(input_2d)
print(f'output_2d: {output_2d}')
# 2. 定义函数, 处理: 一维数据.
def dm02():
# 1. 创建样本数据.
# 2行2列, 2条样本, 每个样本有2个特征
input_1d = torch.randn(size=(2, 2))
print(f'input_1d: {input_1d}')
# 2. 创建线性层.
linear1 = nn.Linear(2, 4)
# 3. 对数据进行 线性变换.
l1 = linear1(input_1d)
print(f'l1: {l1}')
# 4. 创建批量归一化层.
bn1d = nn.BatchNorm1d(num_features=4)
# 5. 对线性处理结果l1 进行 批量归一化处理.
output_1d = bn1d(l1)
print(f'output_1d: {output_1d}')
# 3. 测试
if __name__ == '__main__':
# dm01()
dm02()</code></pre> |
1 |
1 |
1 |
2/4/26, 4:47 PM |
2/4/26, 6:21 PM |
View Edit Delete |
| 42 |
Pytorch实现基础的价格分类模型 |
<p>背景:</p>
<p> 基于手机的20列特征 -> 预测手机的价格区间(4个区间), 可以用机器学习做, 也可以用 深度学习做(推荐)</p>
<p> </p>
<p>ANN案例的实现步骤:</p>
<p> 1. 构建数据集.</p>
<p> 2. 搭建神经网络.</p>
<p> 3. 模型训练.</p>
<p> 4. 模型测试.</p>
<pre class=""><code class="hljs language-python">import torch
import torch.nn as nn
import pandas as pd
from sklearn.model_selection import train_test_split
from torch.utils.data import TensorDataset
from torch.utils.data import DataLoader
import torch.optim as optim
import numpy as np
import time
from sklearn.preprocessing import StandardScaler
# 构建数据集
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_size=0.8, random_state=88, stratify=y)
# 优化①:数据标准化
transfer = StandardScaler()
x_train = transfer.fit_transform(x_train)
x_valid = transfer.transform(x_valid)
# 构建数据集,转换为pytorch的形式
train_dataset = TensorDataset(torch.from_numpy(x_train), torch.tensor(y_train.values))
valid_dataset = TensorDataset(torch.from_numpy(x_valid), torch.tensor(y_valid.values))
# 返回结果
return train_dataset, valid_dataset, x_train.shape[1], len(np.unique(y))
# 构建网络模型
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, 输出维度为: 512
self.linear3 = nn.Linear(256, 512)
# 4. 第四层: 输入为维度为 512, 输出维度为: 128
self.linear4 = nn.Linear(512, 128)
# 5. 输出层: 输入为维度为 128, 输出维度为: 4
self.linear5 = nn.Linear(128, output_dim)
def forward(self, x):
# 前向传播过程
x = torch.relu(self.linear1(x))
x = torch.relu(self.linear2(x))
x = torch.relu(self.linear3(x))
x = torch.relu(self.linear4(x))
# 后续CrossEntropyLoss损失函数中包含softmax过程, 所以当前步骤不进行softmax操作
output = self.linear5(x)
# 获取数据结果
return output
# 编写训练函数
def train(train_dataset, input_dim, class_num):
# 固定随机数种子
torch.manual_seed(0)
# 初始化数据加载器
dataloader = DataLoader(train_dataset, shuffle=True, batch_size=8)
# 初始化模型
model = PhonePriceModel(input_dim, class_num)
# 损失函数 CrossEntropyLoss = softmax + 损失计算
criterion = nn.CrossEntropyLoss()
# 优化③:使用Adam优化方法, 优化④:学习率变为1e-4
optimizer = optim.Adam(model.parameters(), lr=1e-4)
# 遍历每个轮次的数据
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:
model.train()
output = model(x)
# 计算损失
loss = criterion(output, y)
# 梯度清零
optimizer.zero_grad()
# 反向传播
loss.backward()
# 参数更新
optimizer.step()
# 损失计算
total_num += len(y)
total_loss += loss.item() * len(y)
# 打印损失变换结果
print('epoch: %4s loss: %.2f, time: %.2fs' %
(epoch_idx + 1, total_loss / total_num, time.time() - start))
# 模型保存
torch.save(model.state_dict(), './model/phone-price-model2.pth')
def evaluate(valid_dataset, input_dim, class_num):
# 加载模型和训练好的网络参数
model = PhonePriceModel(input_dim, class_num)
# load_state_dict:将加载的参数字典应用到模型上
# load:加载用来保存模型参数的文件
model.load_state_dict(torch.load('./model/phone-price-model2.pth'))
# 构建加载器
dataloader = DataLoader(valid_dataset, batch_size=8, shuffle=False)
# 评估测试集
correct = 0
# 遍历测试集中的数据
for x, y in dataloader:
# 将其送入网络中
# model.eval()
output = model(x)
# 获取预测类别结果
y_pred = torch.argmax(output, dim=1)
# 获取预测正确的个数
correct += (y_pred == y).sum()
# 求预测精度
print('Acc: %.5f' % (correct / len(valid_dataset)))
if __name__ == '__main__':
train_dataset, valid_dataset, input_dim, class_num = create_dataset()
train(train_dataset, input_dim, class_num)
evaluate(valid_dataset, input_dim, class_num)</code></pre> |
1 |
1 |
1 |
2/4/26, 6:21 PM |
2/4/26, 6:22 PM |
View Edit Delete |
| 43 |
Pytorch实现卷积神经网络(CNN)案例 |
<p>深度学习项目的步骤</p>
<p> 1. 准备数据集.</p>
<p> 这里我们用的时候 计算机视觉模块 torchvision自带的 CIFAR10数据集, 包含6W张 (32,32,3)的图片, 5W张训练集, 1W张测试集, 10个分类, 每个分类6K张图片.</p>
<p> 需要单独安装一下 torchvision包, 即: pip install torchvision</p>
<p> 2. 搭建(卷积)神经网络</p>
<p> 3. 模型训练.</p>
<p> 4. 模型测试.</p>
<p> </p>
<p>卷积层:</p>
<p> 提取图像的局部特征 -> 特征图(Feature Map), 计算方式: N = (W - F + 2P) // S + 1</p>
<p> 每个卷积核都是1个神经元.</p>
<p> </p>
<p>池化层:</p>
<p> 降维, 有最大池化 和 平均池化.</p>
<p> 池化只在HW上做调整, 通道上不改变.</p>
<p> </p>
<p>案例的优化思路:</p>
<p> 1. 增加卷积核的输出通道数(大白话: 卷积核的数量)</p>
<p> 2. 增加全连接层的参数量.</p>
<p> 3. 调整学习率</p>
<p> 4. 调整优化方法(optimizer...)</p>
<p> 5. 调整激活函数...</p>
<p> 6. ...</p>
<pre class=""><code class="language-python hljs">import torch
import torch.nn as nn
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor
import torch.optim as optim
from torch.utils.data import DataLoader
import time
import matplotlib.pyplot as plt
from torchinfo import summary
import os
# ===== 超参数集中管理(最佳实践)=====
BATCH_SIZE = 128 # 增大提升训练速度
LR = 1e-4
EPOCHS = 50
WEIGHT_DECAY = 1e-5
NUM_WORKERS = 4 # 利用多核CPU加速数据加载
MODEL_PATH = './model/image_model.pth'
# 1、准备数据集
def create_dataset():
# 1。获取训练集
# 参1:数据集路径。 参2:是否训练集,参 3数据预处理 --> 张量数据, 参4?:是否联网下载
train_dataset = CIFAR10(root='./data', train=True, transform=ToTensor(), download=True)
test_dataset = CIFAR10(root='./data', train=False, transform=ToTensor(),download=True)
return train_dataset, test_dataset
# 2、搭建卷积神经网络
class ImageModel(nn.Module):
# 1、初始化父类成员,搭建神经网络
def __init__(self):
# 初始化父类成员
super().__init__()
# 第一个卷积层,输入3通道,输出32通道,卷积核大小3*3,步长1,填充1
self.conv1 = nn.Conv2d(3,32,3,1,1)
self.bn1 = nn.BatchNorm2d(32)
# 第一个池化层
# 窗口大小2*2,步长1,填充0
self.pool1 = nn.MaxPool2d(2,2,0)
# 第2个卷积层 输入32通道,输出128通道,卷积核大小3*3,步长1,填充0
self.conv2 = nn.Conv2d(32,64,3,1,1)
self.bn2 = nn.BatchNorm2d(64)
# 第2个池化层
self.pool2 = nn.MaxPool2d(2,2,0)
# 第一个人隐藏层(全连接层),自动计算卷积输入数量,输出512,
self.fc1 = nn.LazyLinear(512)
self.bn3 = nn.BatchNorm1d(512)
# 第一个人隐藏层(全连接层),512,输出256
self.fc2 = nn.Linear(512,256)
self.bn4= nn.BatchNorm1d(256)
# 第一个人隐藏层(全连接层),256,输出10
self.output = nn.Linear(256,10)
# 添加dropout层
self.dropout = nn.Dropout(0.5)
# 定义前向传播
def forward(self,x):
# 第一层:卷积层(加权求和) + 激励层(激活函数)+池化层(降维)
x = self.pool1(torch.relu(self.bn1(self.conv1(x))))
# 第二层:卷积层(加权求和) + 激励层(激活函数)+池化层(降维)
x = self.pool2(torch.relu(self.bn2(self.conv2(x))))
# 第三层: 全连接层(加权求和)+激励层(激活函数)
# 全连接层只能处理二维数据,所以要将数据进行拉平(8,16,6,6) -> (8,576)
# 参1:样本数(行数),参2是列数(特征数)。-1表示自动计算
# 这里的size(0)是x的总长度,8、因为批次是8,不能用x[0],不然会出现形状为 [16, 6, 6] 的张量
x = x.reshape(x.size(0), -1)
# print(x.shape)
x = torch.relu(self.bn3(self.fc1(x)))
# 添加dropout层
x = self.dropout(x)
# 第四层: 全连接层(加权求和)+激励层(激活函数)
x = torch.relu(self.bn4(self.fc2(x)))
# 添加dropout层
x = self.dropout(x)
# 输出层
return self.output(x) # 后期用多分类交叉熵函数CrossEntropyLoss = Softmax()激活函数+损失计算
# 3、模型训练
def train(train_dataset):
# 1、创建数据加载器
train_dataloader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True)
# 2、创建模型对象
model = ImageModel().to(device)
# 3、创建损失函数
criterion = nn.CrossEntropyLoss()
# 4、创建优化器
optimizer = optim.Adam(model.parameters(), lr=LR, weight_decay=WEIGHT_DECAY)
# ✅ 优化2: 自动创建模型保存目录
os.makedirs(os.path.dirname(MODEL_PATH), exist_ok=True)
# 5、开始训练
for epoch in range(EPOCHS):
# 总损失
total_loss = 0.0
# 总样本数
total_sample =0.0
# 预测总正确数
total_correct = 0
# 训练开始时间
start_time = time.time()
for i, (x, y) in enumerate(train_dataloader):
# 1、将数据移动到GPU
x = x.to(device)
y = y.to(device)
model.train()
# 2、前向传播
y_pred = model(x)
# 3、计算损失
loss = criterion(y_pred, y)
# 4、梯度清零
optimizer.zero_grad()
# 5、反向传播
loss.backward()
# 6、梯度更新
optimizer.step()
# 统计预测正确的个数
# total_correct += (y_pred.argmax(dim=1) == y).sum().item()
# print('#' * 30)
# print(y_pred)
# print(y)
# print(torch.argmax(y_pred,dim=-1))
# print((torch.argmax(y_pred,dim=-1) ==y))
# print('#' * 30)
# 预测总正确数
total_correct += (torch.argmax(y_pred, dim=-1) == y).sum()
# print(total_correct)
# 统计总损失
# loss.item() 返回单个批次的平均损失 乘以批次数,获取总损失
total_loss += loss.item() * len(y)
# 统计总样本数
total_sample += len(y)
# 打印训练结果
print(f'轮数:{epoch + 1}, 训练总损失:{total_loss / total_sample}, 训练准确率:{total_correct / total_sample}, 训练时间:{time.time() - start_time}')
# 保存模型
torch.save(model.state_dict(), './model/image_model.pth')
# 4、模型测试
def evaluate(test_dataset):
# 1、创建数据加载器
test_dataloader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False)
# 2、创建模型对象
model = ImageModel().to(device)
# 3、加载模型参数
model.load_state_dict(torch.load('./model/image_model.pth'))
# 4、定义变量统计 预测正确的样本数,总样本数
total_correct = 0
total_samples = 0
model.eval()
# 遍历数据加载器,获取到每批次的数量
for x, y in test_dataloader:
# 1、将数据移动到GPU
x = x.to(device)
y = y.to(device)
# 2、前向传播
y_pred = model(x)
# 3、统计预测正确的样本数
total_correct += (torch.argmax(y_pred, dim=-1) == y).sum()
# 4、统计总样本数
total_samples += len(y)
# 打印测试结果
print(f'测试准确率:{total_correct / total_samples}')
if __name__ == '__main__':
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print(torch.cuda.get_device_name(0))
train_dataset, test_dataset = create_dataset()
# print(train_dataset,train_dataset.data.shape) #(5000,32,32,3)
# print(test_dataset, test_dataset.data.shape) #(10000,32,32,3)
#
# plt.figure(figsize=(2,2))
# plt.imshow(train_dataset.data[111])
# plt.show()
model = ImageModel().to(device)
# 查看模型参数,参1:模型,参2 (批次,通道,高,宽),参3 设备
# 卷积层参数计算公式 = 输入通道数*卷积核尺寸*卷积核数量+卷积核数量
summary(model,input_size=(BATCH_SIZE, 3,32,32),device=device)
# 模型训练
train(train_dataset)
# 模型测试
evaluate(test_dataset)
</code></pre> |
1 |
1 |
1 |
2/8/26, 9:03 PM |
2/9/26, 6:49 AM |
View Edit Delete |
| 47 |
余弦相似度公式cosθ |
<p>余弦相似度 = 看两个东西“朝向”是否一致,不管它们“长短”如何。</p>
<p><strong>公式:两个向量的点积 除以 两个向量模长的乘积</strong></p>
<p><img src="data:image/png;base64,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" alt="" /></p>
<p> </p>
<p><strong>情况1:完全相同方向 → 相似度 = 1</strong></p>
<p><img src="data:image/png;base64,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" alt="" /></p>
<p>分子:点积1×2 + 1×2 = 2 + 2 =4</p>
<p>分母:长度乘积:√(1²+1²) × √(2²+2²) = 1.41 × 2.83≈4</p>
<p>相似度:4 ÷ 4=1.0</p>
<p> </p>
<p><strong>情况2:垂直(90°)→ 相似度 = 0</strong></p>
<p><img src="data:image/png;base64,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" alt="" /></p>
<p>分子:点积0×2 + 2×0 = 0 + 0 =0</p>
<p>分母:长度乘积:√(0²+2²) × √(2²+0²) = 2 × 2 = 4</p>
<p>相似度:0 ÷ 4 = 0</p>
<p> </p>
<p><strong>情况3:完全相反 → 相似度 = -1</strong></p>
<p><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAPwAAAC+CAIAAACeWfVXAAAQAElEQVR4AexdX0gc2Zo/3AenJ2g7arQzQrpzr6Hp3jFBJGTYEALGB6EJ+DAvvsgIgllkXeJDgouXDVluWDEPHdZd2Q4EhDysL/sQkAYfHCFIlpEgkvSs0qSX6Q6YUaMmrSQ9woX7nVNV/UdPVXf96/rTX6iUVafqfN93fudXp746fb5z/tDREcQNEagpBP5A8B8iUGMIIOlrrMKxuIQg6ZEFNYcAkr7mqhwLjKTXxAHM5GQEkPROrj20XRMCSHpNsGEmJyOApHdy7aHtmhBA0muCDTM5GQEkvZNrz2m228ReJL1NKgLNqB4CSPrqYY2abIKAnUgfHp68E7EJLmiGixFQIH1kNBqbejAcqlLpI6MjVxsC/aO9VdKHamoWARnS996binbur2WrhUvnwIN+kk7R7dajgXC11KKemkSAS/rI6I29ufHpdT2I0MfmXk9ewonTfLpw0BvpeDsz+wZOErNPNjv65J0cuAU3REAfAlzSx2fvP93UJ5csJTKkIyz5Kj2XOkg6sSwnc2n64bOEeHHj6cPHcfEY/yACJiDAJb0heuI/rWX9l4Q2OxIOZNcXkcqGAItC9CJgHunJ5qvNw0An9XB6O/3p5fkNvbZifkTAEARMJD3Z+DmVpR4O+DaZN9jMG1JfKMQABMwkPUnMv0j5bzy61rT605IBtqIIzQhgxmIEuKSHDsTYVDQ21O0l3qtDenrr4XPW6yVvf9b7WVxsMh4jAvoQ4JI+MX//9sR40aarMyebeiX1zCjbujQ9gf02yhDhVSMQ4JLeCMFMRs+dfvyEZUjgzkYImEX6njvUQeprWp3DxttG1Y2mUATMIv3yY+Yd6fKLqH34HxEwHIGKSW+4ZhSICFiEgFmkv3bt7y0qEapFBMogYBbpy6jFy4iAdQgg6a3DHjVbhICdSN97bwojpyziQU2ptRPp3Qg8lsmGCMiQ3hO4cPl6kG3nGm1oNpqECGhHgEv6M83+1mxyJfl6JZk+8AauNHu0K8CciIDdEOCS/vN+8tV+jpn6aTdLPHVfsWPcIQKuQIBLeleUDAuBCMggUIb09f6gN/du/5NMbkxGBExBwFyhSqSv811p/+ZgK5k+NtcGlI4IVBUBWdID4y/4yIfkL0dVtQeVIQKmI8AnvcR46XPWdDNQASJQPQS4pG9r9kEnpedsUOyqDwYDddUzCTUhAuYiwCX9zm/QQ1+8oVtvbi2g9KoiwCV9VS0wSRmKRQTkEEDSyyGD6a5FwE6kx9kQXEszexXMTqS3FzJojWsRMIv0L1/+r2sxw4I5HAGzSO9wWGrW/JooOJK+JqoZC1mMgJ1Ij+GCxTWDx6YhYCfSm1ZIFIwIFCPAJ329XxqAcPm69nDB8PBklE7uNxWN4ZqBxaDjsbUI8El/lGGxgq9Xksl3Ho3hgp0DA6HUEza530LKj2sGWlvPqL0IAT7pCzfkvghhg4WUckfS9cT8/bvikjtLiQzxNrdLV/AvImApAuVI39jqze0eaSW+pUVD5YgAHwE50p9pFsYVB5qy23ojp+gs9VlcgYdfAZhafQTkSP95X5gC5PXase/6Bd8ZzZaFBh/1BVKLOGe3ZgQxo9EIyJE+r+fz0adc3Vf1+XNVB8D4oW6y/mRadtlkVeLwZkTACATKkp5GUWU/7WjQJTFe+pzVIKKGsmBRq4cAl/SSQ0+n9QuS9MpvWqYAidzs9hLi7RoRu+qnHgyHqlcu1IQIyCLAJX3eoV9JvtbGeNAXny1enxCO0a0HVHCzAQJc0tvALjQBETANASS9adCiYLsiYCfSY7igXVliX7s0WWYn0msqAGZCBNQigKRXixje73gEkPSOr0IsgFoEkPRqEcP7HY+AnUiP4YKOp5MzCmAn0luDGGqtOQQUSe8J0DUGdU1ZHBmNxnAAQs3Ryt4FViD9mWb/+dzHA+32g7sS7dxfy2qXgDkRARMQkCV9ne/vzpJ3Olabioze2Jsbn143wWgUiQjoQUCG9J5Au498yOiJmYrP4ggzPTWDeU1DgE/6+rbzZPv/xKVkTdONgh2MgJNN55G+8bt2z7ut7c9OLhfajgjIIsAhfX1jE/Gcp/02l68HA+LxuUZZEXgBEXAWAhzSF2Z6er2STB+Q3LtftYeSOAsNtLYmEOCQ3qBydw48oIGCQ91e4r06hL31BsGKYvQjUI70n35JalxaMDF/n83pNy7tsTNHf3WhBCMQKEd6I3TIyMBkRMAaBJD01uCOWi1EwE6kx3BBC4lQS6rtRPpawh3LaiECZpH+3Pk/WVgqVI0IKCBgFukVVOIlXQhgZt0IIOl1Q4gCnIaAnUjfe2/qTsRpAKK9zkPATqR3HnposSMR4JO+zncleNmIBQYdiQka7XIE+KSHQh9vryVf01mLYa9pqm6QgRsiYBcEiu2QJX3xTXiMCLgJASS9m2oTy1IRArKkr/N1i269v60iSXgTIuAQBPikP95+Ba4829Y+eIJB5L1DqhPNrAQBPumLctLVBYtO8RARcDwC5UhP5wLxaFtd0PHYnCgAnroFAS7pi1YXDLZmk5rXWnMLSFgOdyHAJf3n/aTYQ598/Qpnv3FXjWNpCJf0iAsi4GYEkPRurl0sGxcBO5EewwW5VeTwRBuabyfS2xAeNMmNCCDp3VirWCZFBJD0ivDgRTcigKR3Y61imRQRQNIrwoMX3YiAE0jvRtyxTBYioED6tnNSxCBOTm9hDaFqwxGQIb0ncOFykKTFwQgYLmg47ijQQgT4pK9vO59LV3ucWWjwkUNXnO25E5uK3usRqjE8PBmNTQ52Cme4tyECXNK31X+TO/Z8J0ZOXf6u3oaGV9Ek4PRor5K+5ccz69mOPjppT+fAwFWyNvPwWUIpA16zFAEe6T1fe4jn7Fe7LHJqZetjU7uuRcMtLZ8RyoHT+zdiihNRJebvP88EegYGI11k9X/swXgjiu5OGTzS05IebGV26F9CjnbeHXvq64QTM/bMH5iKxgoL9URj9/8lCimntv86lQJ+xX/8JQr7k9u/8RIf8hJ5MmNTf/n3ovSxLi8hgX5F7ys+u7Db1d26Pv900wyUUKZxCPBIn/uSI1/XeYxToixp4+lDtkTP3FqWZFfn2PGDfx2fYAel+38oPRUW9vnHP3PuvP3PvMRJXiJP5u2JP/9TUfrMepaQ9PMJhRWE4NG9RRaB9yOSc69carxqHQI80pOdo4+es23iJAjwUVv3cffIOhMt19xzZ6z5xe2Jx3F5SwRXPr68NL2YFpx7+XvxitUIcElPjjJsEgTWT99OkknJ1bHaWmv0Lz++PbukoLpz4MFY3pVfXlw9BEeIftQqZMFLViLAJz0hRRGD1WL85rO7Sv6DlSgp64av2NsFywVvTem1oCwNr5qOgBzpmWLcIQJuRABJ78ZaxTIpIoCkV4QHL7oRASS9G2sVy6SIAJJeER686EYEkPTG1ypKtDkCSHqbVxCaZzwCSHrjMUWJNkcASW/zCkLzjEeAR3oaNlVYWjB4+XrQ9KHF8Eu+NExS8w/4YRq9oTgAWAE+AwwIDT6aisaUR97LWiAYzwaBapQgKxovnESAR/pc+ldpXcHk65Wtj4TkvhyfzGjkeWjwx463M2xU4/NMoH9SfdhRCAg3QFJpjVb13BnrOniuwwD6zPxANjMa9XcODIRST9ig0YWU/9ajgbBGQU7OVj3beaQv0U6jqD7s7JSkGX2y+eyuFGoU30iThha/Og3h4R9alifuP91Wl026Ozx8LZBdXxQGUcZ/Wss2XPw+JF2s5C88tM0vbj989r6Sm3n3JObv353fYFeWEhnibW5nx7gzB4EypK/z+b0fM3afon7j6UM9A7zaWxqym+sC53rvsViWlm/VwA0PreIwTDWy8F7zEVAmfVuzj5jdzJeUsfdeX6HRLbli+ongVd8ii+PPM6TVZ5GD0XOn359d/UlpJLPpSLhegRLpaTOf2z3KGQsCdX/hg0/YRosDroF2tzoyC9KLXkZtD516QPzqnVTv/fOleq8OjbS8pHFV08vhb5vI7rbQ8PPvNis1NPioL5BaVIjPMktzbclVID00857sdtroT1jwX9kXG2VYUXAGMH6EziNQ1k9YflzILn0J6Kuzrb1Dkl1/Mr0siKHezp5m91yQoWEPjB/qJgUzNIjALJUhIEt61sy/2/9UmRidd0mM10lijVZs/JzKersGhtnHa+fAjY7Dtz9XObhbYnyZt5zGAmK2UgRkSO8JtPvMaOZLlUtnPX1XGwhp6B4TfJ6pqNo+u8go6+HuC7A5C+BYXWc/vHxm1snVIcgYHYPOU9XPXu89Znk/9Dr5b1HXq8Rtk4op/zdys9tLiLdrhOaloh4IT6B8DryiAwEZ0rOu+qrN5lfssbDOcrUNXnyWOUssL3N+VHfmAO9ZxnHoeVQ/T9PSdEE1s6Ssk1ZaZafsR7e+FCBjz2RIb6wSlIYI2AkBJL2dagNtqQoCSPqqwGxrJTVnHJK+5qocC4ykRw7UHAJI+pqrciwwkh45UHMIIOlrrsqxwMaQ3rU4ij+1wg+lan8kVguJ+KMy/Byr8tdctYpscH+YxbjR37+1BppxCqECQDnSt+WXFgzW+PI74pT55X8kDg1WGC5YqJ7JwihR4UfZGToRPqdG3ZeUWjz103WoWgBySX+mOVhYWpAuv+MX56p3H/YGlYiOl64sXBDu7G9aY7GRT1ZJ95j72/WKIAZYYlUDkEv6+jpP7vh30djj3w0eUC/KLf0jPOXwcldc4qY0j9IZBbGUT9C+muWihAZ/rDRcsDfS5U29FBal2nj6Mk38lyJK5dB5reCeGbM+Ss+dEwsnnsZZi8VVBpBLerYSSZAtKigMt/y0o6UoFecJDT6iQXrC/d6rQ4UxhoCpGqaCsyjmTWwfkKb2Kq1rWXm4YKi9laQTwsB9KDUdFtr0LRvSLBTe0D0w/laHJLGjL7/oJ0sC7ZMF54olye6gvRCfmfd7WdURzLJiCxeqDCCX9OQos5JMk3Y6+UdrNmn2grKdXRe9BQDgyBvqChMCDI6ONb8o70xDDnHbePrwRcsQG5kM1cMS4bFhX0tK8VBQqfCpWrSJTw4TYMYO6BiNDV3cnHuyeuhVF49buTk9l/KMFzJ1hIvi1IBnL1vGKnuvxmef7F1js5tsbu0KsqQm39/sze5vCWkn93APfXWzD1Z2oKb9Oims9FwfgHzS1/uvB31HdCKQ9JezwesXfGdKdZp/1nVvaoQOsheGpzPIgJRie1OqvpSytG2jA9NvntltaPGT8PfNBykiNPlZFg9FnyUQRTfJ/xE+IsWhxXSQsNLIXvoUSfawx6nUmvJngf6pG3t0PTnQUuUorYvCuH9adigCfc/Ae7X0DSDZX1LMfF1Mhv56SF9NkTBJHQC89O58aKVQEYU60j1inErn/NcNII/0nsDZb3IfMixQ8NMvyfRBne+P9RzlRiUl1t9mS2RlN9f/e3oCWkFCMgtFXByXIvpK7i6l7EKKv0eExQAABkRJREFU0Ni/27Mv9qB6eq6EyJv4fsv3IaDXwXsaDwVvA9ZvMLeWlfxpobZEKgAbFNu/wsh7eDxUjpsnrKUsRMFSb0ewqqRExpwsvwEoikWlNmIl4/4X0wDV6hwf1ZJi5uvi4X9uHHhbvu3tbNqLb5DOHnh/Ck0JAQz7ydrqYZFCM1p6QwDkkZ7a7an7iv6B//WNTSR3ZHSkLAgubPCqBQqK59BFCE0gnFB2zuzfUPNOhFacNqIFj8jXsruxlNgmoZuXWg/3iuZiCg//0O3NvBHnujkZgyIYADbo39iLuDDvGp3WJr/8IA2YkmzQr+mUhKXpCdoECOnQRVjSZIQGH13bm5moqKSRURY1n3/Cfe0k9Srxfq813NfSID60tOmZfSXoEvfGtPQmAMgjfS79a/rAG7hOJ/S7fL3d8+7XJGv1xbKY8gd4Dw0n3UqqAdqbAoPLK4bnJJ994/2B92oXScBX4/KbXX/Ae7AlhkRBfU+N0BnF8rVYXrLyHULFRHnhgpTlhFCXQBAB5KCzuNH3SbSfLBSFxgvXjd0D79lrbeJUcw6AVxwVCTbnH5jMfraj6+Le+gbZfLXZFOgoaUo0G19dAHmkB9PBq3m9khQ28xkPCk3YoKqkxV9Z3YsUF6ZzEgNSCw6oLgOYfPrEigwrpjKwhBCxORSUMMPYnaJJQrIz9tAMSUspQhNTiK5k3wAj8BkG3UTqP3VUAUj0AihDemdUgCYrS/DNN2CaRJXLRF8p0TE6S6bqmN1yom13nT0M7EmGh9+oh9kkAGuP9GrpQvs34BtXzaeFpAJcCGDAREWMhw9B0DLWVdp5K0ly31/6QgAfT+pA4xfQJACR9Hy4xdTCa0HNp4WYWdUfva9sVcosvpn5RbQ5GC/2A3UapQJAJL1OrDG78xCwnvTnzv+pcthU3Vy5WLyzphCwnvRWwI06axoBJH1NV39tFh5JX5v1XtOlRtKrr37x58PYlNmDMdWbhjkqQUCO9IVwQQuGWFZiuK57WKd4CWVZijgItvAzLftxBLrPYcsnRkZvta7TRdHoRMc3iwbr6rIIM1cRAS7pzzQHg57tNTYMIZnzdZ9rrKJFZqui7XTn/lq2SA/8hE6HwQg9x4tpaUAYHbCwK4Ry0kThIaHjCoUFqujg0KrFqRRZa92hWzTzSN/4x7Oegw/bn1kZd/a3c95G18TIRkbpMMzpdVY2aecvjoQoRJ/c6Dhciy+zm5YXVw+F0BY6jo3FuBAa+5IfxMbuwp0zEOCRHiwvGkt8nPtCPF/XQaK9N3BFJsvHv8Vn88MwC8WJb6S9XSPMgSkMOaZPQuqVMDAzMkqHUgkrXcZnF3bZ6gl0UE1Fg0zCw5PCW6KgEY+sRIBH+k+7Wc/5ZtGlaTsXaLLSwIp0g38SG2pZrnis7EmhdOT3AukDn/7kkGMqeYqNAV5MS0G3+bEJFQ2qIQR+dZeCGE8qxnMrEOCRnuz8VhhP33qUPiC5L6YGkegrOHyDsnFagf4pYK20KY9kOqGRxvhQt+f2BGvFpTcGNP9jzS9o6NbsUqeviahxZsAq+PyVNimIUZVVJ4zEU6MQ4JKekMJ4+l+OPV8f/35klD4T5MRnx2foHEnp58KXqLCvyPEQrBFWDJ9/ugmn0IovpBq6Iz2EjoM/XJuR5FBvRy4CGvKd2sAq+rQIxrAIpiz0+UjSTt2OCVVEQIb0kgV1visXGne3xI9aKVX7X5Ny0sHcc3s9UgutQYvgr9OMdBIBGvdJO2caun8cCNPE0GCPPyt02tBTdf/Bp6evEbPHaaozqpbv5pL+THNQjBW88FUm6ZDIqc1ndyvw6QUfPTbU7SXCQHn4xASfeyGVn3ahr2l1jn3sgsC5NcK+WWNDFzeFRC1cAflMoJa8mMcEBLik/7yflGIFMzsmKLVQJH0niC6HEOYj0BG8GuEU9kIKsxF4L95clMiu4M7BCHBJ7+DyoOmIQFkEkPRlIcIb3IYAkt4JNYo2GooAkt5QOFGYExAwi/S/vfv/Cotf+Z0gUNXNcD9uiMBpBMwi/WlNmIII2AQBJL1NKgLNqB4CSPrqYY2aqoyAnDokvRwymO5aBJD0rq1aLJgcAkh6OWQw3bUIIOldW7VYMDkEkPRyyGC6axFA0itWLV50IwJ/AwAA//+u5UeFAAAABklEQVQDABx4vFTSOc74AAAAAElFTkSuQmCC" alt="" /></p>
<p>分子:1×(-1) + 0×0 = -1 + 0 = -1</p>
<p>分母:长度乘积:√(1²+0²) × √((-1)²+0²) = 1 × 1 = 1</p>
<p>相似度:-1 ÷ 1 = -1.0</p> |
1 |
1 |
1 |
2/13/26, 8:52 PM |
2/17/26, 9:02 PM |
View Edit Delete |