31、神经网络优化:从基础到实践

神经网络优化:从基础到实践

1. 多类 SVM 损失与 Softmax CE 损失

多类 SVM 损失有一个特点,那就是它比较“懒惰”。一旦正确类别的得分超过错误类别得分一定的边界 $m$,损失就不再变化。即使正确类别的得分继续提高,损失也不会改变,这意味着它不会促使模型在这个点之后进一步改进。而 Softmax 交叉熵(CE)损失则不同,它会促使模型为正确类别争取无限高的得分。

2. 神经网络优化基础
  • 损失函数 :神经网络模型定义了一个损失函数,用于估计网络输出的“糟糕程度”。在监督训练中,将特定训练实例的输出与该实例的已知输出(即真实标签,GT)进行比较,两者的差异就是损失。可以将各个训练数据实例的损失相加,得到整个训练数据的总损失。
  • 损失表面 :损失是网络参数 $\vec{w}$ 和 $\vec{b}$ 的函数。可以想象一个维度为 $dim(\vec{w}) + dim(\vec{b})$ 的空间,在这个空间的每一点都对应一个总训练损失值,这样就形成了一个损失表面,其高度表示损失值。
  • 优化目标 :优化的目标就是在这个损失表面上找到最低点。训练时,从网络参数的随机值开始,就像在损失表面上随机选一个点,然后沿着负梯度方向不断局部向下移动,希望最终能到达最小值点或一个足够低的点。
3. 优化的数学表达
  • 参数更新公式 :设 $t$ 表示迭代次数,$\vec{w}_t$ 表示第 $t$ 次迭代的权重值,$\delta \vec{w}_t$ 表示第 $t$ 次迭代的权重更新值,$\vec{b}_t$ 和 $\delta \vec{b}_t$ 同理。参数更新公式如下:
  • $\vec{w}_{t + 1} = \vec{w}_t - \delta \vec{w}_t$
  • $\vec{b}_{t + 1} = \vec{b}_t - \delta \vec{b}_t$
  • 梯度更新公式 :基本的更新是沿着负梯度方向进行的,公式为:
  • $\delta \vec{w} t = \eta \nabla {\vec{w}} L(\vec{w}_t, \vec{b}_t)$
  • $\delta \vec{b} t = \eta \nabla {\vec{b}} L(\vec{w}_t, \vec{b}_t)$
    其中 $L(\vec{w}_t, \vec{b}_t)$ 表示第 $t$ 次迭代的损失,$\eta$ 是学习率(LR)。学习率越大,每次更新时对权重和偏置的调整就越大;反之则越小。通常在训练开始时使用较大的学习率,接近最小值时使用较小的学习率,以避免越过最小值。在随机梯度下降(SGD)中,学习率通常在一个 epoch(即对整个训练数据的一次完整遍历)内保持不变,经过一个或多个 epoch 后再减小,这个过程称为学习率衰减。
4. 随机梯度下降(SGD)
  • 计算梯度的问题 :损失函数在每个训练数据实例上的值都不同,理想情况下应该计算所有实例的损失并求平均,但这意味着每次迭代都要处理整个训练数据集,计算复杂度为 $O(n^2)$($n$ 是训练数据集的大小),对于大规模数据集来说,这种计算是非常昂贵的。
  • SGD 的解决方案 :随机梯度下降不计算整个训练数据集的平均梯度,而是计算一个随机采样的子集(即小批量,minibatch)的平均损失来得到梯度,然后用这个梯度来更新权重和偏置参数。
5. PyTorch 实现 SGD

下面通过一个具体的例子,展示如何在 PyTorch 中实现 SGD。假设我们要构建一个模型,根据身高和体重数据预测 Statsville 居民是男性、女性还是儿童。
- 创建自定义数据集

from torch.utils.data import Dataset, DataLoader

class StatsvilleDataset(Dataset):
    def __init__(self, X, y_gt):
        self.X = X
        self.y_gt = y_gt

    def __len__(self):
        return len(self.X)

    def __getitem__(self, i):
        return self.X[i], self.y_gt[i]

# 假设 X 是包含身高和体重数据的数据集,y_gt 是对应的标签
dataset = StatsvilleDataset(X, y_gt)
data_loader = DataLoader(dataset, batch_size=10, shuffle=True)
  • 创建自定义神经网络模型
import torch
import torch.nn as nn

class Model(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(Model, self).__init__()
        self.linear1 = nn.Linear(input_size, hidden_size)
        self.linear2 = nn.Linear(hidden_size, output_size)
        self.softmax = nn.Softmax(dim=1)

    def forward(self, X):
        scores = self.linear2(self.linear1(X))
        return scores

    def predict(self, X):
        scores = self.forward(X)
        y_pred = torch.argmax(self.softmax(scores), dim=1)
        return y_pred

def initialize_weights(m):
    if isinstance(m, nn.Linear):
        nn.init.xavier_uniform_(m.weight.data)
        nn.init.constant_(m.bias.data, 0)

model = Model(input_size=2, hidden_size=100, output_size=3)
model.apply(initialize_weights)
  • 定义损失函数和优化器
import torch.optim as optim

loss_fn = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.02)
  • 定义训练循环
def train_loop(epoch, data_loader, model, loss_fn, optimizer):
    for X_batch, y_gt_batch in data_loader:
        scores = model(X_batch)
        loss = loss_fn(scores, y_gt_batch)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
  • 运行训练循环
num_epochs = 2
for epoch in range(num_epochs):
    train_loop(epoch, data_loader, model, loss_fn, optimizer)
6. 动量优化
  • 梯度估计的问题 :在高维的实际损失表面上,不同点的梯度估计是有噪声的,并且方向不一致。就像峡谷的墙壁一样,损失表面并不平滑。而且通常是基于小批量进行梯度估计,这使得梯度估计更加嘈杂,方向难以对齐。不过,大多数梯度估计都有一个良好的下降分量,而非下降分量则是随机的。
  • 动量的作用 :动量的思想是对当前迭代计算的梯度和上一次迭代的更新进行加权平均。公式如下:
  • $\delta \vec{w} t = \gamma \delta \vec{w} {t - 1} + \eta \nabla_{\vec{w}} L(\vec{w}_t, \vec{b}_t)$
  • $\delta \vec{b} t = \gamma \delta \vec{b} {t - 1} + \eta \nabla_{\vec{b}} L(\vec{w}_t, \vec{b}_t)$
    其中 $\gamma$ 和 $\eta$ 是小于 1 的正常数。这样做的好处是,如果遇到一个小的平坦区域,普通的梯度下降方法可能会陷入其中,因为该区域梯度为零,但使用动量可以得到非零的更新,从而使优化过程跳出这个局部平坦区域,继续向下进行。
  • 动量公式展开 :将动量公式展开,可以得到:
  • $\delta \vec{w} t = \eta \nabla {\vec{w}} L(\vec{w} t, \vec{b}_t) + \eta \gamma \nabla {\vec{w}} L(\vec{w} {t - 1}, \vec{b} {t - 1}) + \cdots + \eta \gamma^t \nabla_{\vec{w}} L(\vec{w}_0, \vec{b}_0)$
    这实际上是对过去迭代的梯度进行加权求和,且旧的梯度权重随着时间以 $\gamma$ 的幂次减小。不过,这些权重的总和并不等于 1,这是动量梯度下降的一个不太理想的特性,在后续的 Adam 算法中会进行改进。
7. 几何视角:恒定损失轮廓、梯度下降和动量

考虑一个只有两个元素的权重向量 $\vec{w} = \begin{bmatrix} w_0 \ w_1 \end{bmatrix}$ 且无偏置的网络,损失函数为 $L = |\vec{w}|^2 = w_0^2 + w_1^2$。其恒定损失轮廓是以原点为中心的同心圆,圆的半径表示损失大小。
- 梯度方向 :通过计算梯度 $\nabla_{\vec{w}} L = 2\begin{bmatrix} w_0 \ w_1 \end{bmatrix}$ 可知,梯度沿着半径方向,负梯度方向是径向向内的。这意味着沿着半径向内移动时,损失下降最快;沿着圆周移动时,损失保持不变。
- 优化轨迹 :优化过程就是从外圆(大半径,高损失)向里圆(小半径,低损失)移动,理想情况下,当到达原点时,优化停止。图 9.9 展示了有无动量情况下的优化轨迹,可以看到,使用动量的版本能在更少的步骤内到达更小的圆。

下面是一个简单的 mermaid 流程图,展示神经网络优化的基本流程:

graph TD;
    A[初始化网络参数] --> B[计算损失和梯度];
    B --> C{是否达到停止条件};
    C -- 否 --> D[更新参数];
    D --> B;
    C -- 是 --> E[结束优化];

通过上述内容,我们了解了神经网络优化的基本概念、随机梯度下降算法以及如何在 PyTorch 中实现,还介绍了动量优化的原理和几何视角。这些知识对于理解和实现神经网络训练至关重要。在实际应用中,可以根据具体问题选择合适的优化方法和参数,以提高模型的性能。

神经网络优化:从基础到实践

8. 优化过程中的关键要点总结

为了更清晰地理解神经网络优化过程,下面将关键要点总结成表格:
|要点|详情|
| ---- | ---- |
|损失函数|衡量网络输出与真实标签的差异,是优化的目标函数|
|损失表面|由网络参数构成的高维空间中,每个点对应一个总训练损失值|
|优化目标|在损失表面上找到最低点,使网络输出与真实标签的差异最小|
|学习率|控制每次参数更新的步长,开始时可较大,接近最小值时应减小|
|随机梯度下降(SGD)|通过随机采样小批量数据计算梯度,减少计算量|
|动量优化|对当前梯度和上一次更新进行加权平均,帮助跳出局部平坦区域|

9. 不同优化方法的对比

下面对比一下普通梯度下降、随机梯度下降和动量优化三种方法:
|优化方法|优点|缺点|适用场景|
| ---- | ---- | ---- | ---- |
|普通梯度下降|能保证收敛到全局最优解(在凸函数情况下)|计算复杂度高,每次迭代需处理整个数据集|数据集较小的情况|
|随机梯度下降|计算效率高,通过小批量数据更新参数|梯度估计有噪声,收敛过程可能不稳定|大规模数据集|
|动量优化|能减少梯度估计的噪声影响,帮助跳出局部平坦区域|权重总和不为 1,有一定局限性|损失表面复杂,存在局部平坦区域的情况|

10. 优化过程中的注意事项
  • 学习率调整 :学习率的选择对优化过程影响很大。如果学习率过大,可能会导致模型跳过最小值点,无法收敛;如果学习率过小,收敛速度会非常慢。可以采用学习率衰减策略,在训练初期使用较大的学习率,随着训练的进行逐渐减小学习率。
  • 数据随机化 :在每个 epoch 结束后,对训练数据进行随机洗牌是非常重要的。这样可以避免模型对数据的顺序产生依赖,防止过拟合。
  • 梯度清零 :在每次迭代中,需要调用 optimizer.zero_grad() 来清除上一次迭代积累的梯度。否则,梯度会不断累加,导致参数更新异常。
11. 进一步优化思路
  • 自适应学习率方法 :除了学习率衰减策略,还可以使用自适应学习率方法,如 Adagrad、Adadelta、RMSProp 和 Adam 等。这些方法可以根据参数的更新情况自动调整学习率,提高优化效率。
  • 批量归一化(Batch Normalization) :在神经网络中插入批量归一化层,可以加速训练过程,减少梯度消失和梯度爆炸的问题,提高模型的泛化能力。
12. 总结与展望

神经网络优化是一个复杂而关键的过程,涉及到多个方面的知识和技巧。从多类 SVM 损失和 Softmax CE 损失的特点,到随机梯度下降、动量优化等算法的原理和实现,再到优化过程中的关键要点和注意事项,我们对神经网络优化有了更深入的理解。

在未来的研究和实践中,我们可以继续探索更高效、更稳定的优化算法,结合不同的优化策略,进一步提高神经网络模型的性能。同时,随着数据量的不断增加和模型复杂度的提高,优化算法的计算效率和资源利用率也将成为重要的研究方向。

下面是一个 mermaid 流程图,展示优化方法的选择思路:

graph TD;
    A[数据集大小] --> B{小数据集};
    B -- 是 --> C[普通梯度下降];
    B -- 否 --> D{损失表面复杂};
    D -- 是 --> E[动量优化];
    D -- 否 --> F[随机梯度下降];

通过不断学习和实践,我们可以更好地掌握神经网络优化的技术,为解决各种实际问题提供更强大的工具。

内容概要:本文设计了一种基于PLC的全自动洗衣机控制系统内容概要:本文设计了一种,采用三菱FX基于PLC的全自动洗衣机控制系统,采用3U-32MT型PLC作为三菱FX3U核心控制器,替代传统继-32MT电器控制方式,提升了型PLC作为系统的稳定性与自动化核心控制器,替代水平。系统具备传统继电器控制方式高/低水,实现洗衣机工作位选择、柔和过程的自动化控制/标准洗衣模式切换。系统具备高、暂停加衣、低水位选择、手动脱水及和柔和、标准两种蜂鸣提示等功能洗衣模式,支持,通过GX Works2软件编写梯形图程序,实现进洗衣过程中暂停添加水、洗涤、排水衣物,并增加了手动脱水功能和、脱水等工序蜂鸣器提示的自动循环控制功能,提升了使用的,并引入MCGS组便捷性与灵活性态软件实现人机交互界面监控。控制系统通过GX。硬件设计包括 Works2软件进行主电路、PLC接梯形图编程线与关键元,完成了启动、进水器件选型,软件、正反转洗涤部分完成I/O分配、排水、脱、逻辑流程规划水等工序的逻辑及各功能模块梯设计,并实现了大形图编程。循环与小循环的嵌; 适合人群:自动化套控制流程。此外、电气工程及相关,还利用MCGS组态软件构建专业本科学生,具备PL了人机交互C基础知识和梯界面,实现对洗衣机形图编程能力的运行状态的监控与操作。整体设计涵盖了初级工程技术人员。硬件选型、; 使用场景及目标:I/O分配、电路接线、程序逻辑设计及组①掌握PLC在态监控等多个方面家电自动化控制中的应用方法;②学习,体现了PLC在工业自动化控制中的高效全自动洗衣机控制系统的性与可靠性。;软硬件设计流程 适合人群:电气;③实践工程、自动化及相关MCGS组态软件与PLC的专业的本科生、初级通信与联调工程技术人员以及从事;④完成PLC控制系统开发毕业设计或工业的学习者;具备控制类项目开发参考一定PLC基础知识。; 阅读和梯形图建议:建议结合三菱编程能力的人员GX Works2仿真更为适宜。; 使用场景及目标:①应用于环境与MCGS组态平台进行程序高校毕业设计或调试与运行验证课程项目,帮助学生掌握PLC控制系统的设计,重点关注I/O分配逻辑、梯形图与实现方法;②为工业自动化领域互锁机制及循环控制结构的设计中类似家电控制系统的开发提供参考方案;③思路,深入理解PL通过实际案例理解C在实际工程项目PLC在电机中的应用全过程。控制、时间循环、互锁保护、手动干预等方面的应用逻辑。; 阅读建议:建议结合三菱GX Works2编程软件和MCGS组态软件同步实践,重点理解梯形图程序中各环节的时序逻辑与互锁机制,关注I/O分配与硬件接线的对应关系,并尝试在仿真环境中调试程序以加深对全自动洗衣机控制流程的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值