第二周
- 一、深度学习步骤:
-
-
- [1. 选定模型结构](#1. 选定模型结构)
- [2. 模型参数随机初始化](#2. 模型参数随机初始化)
- [3. 构造模型损失函数](#3. 构造模型损失函数)
- [4. 选择优化算法并设置超参数](#4. 选择优化算法并设置超参数)
- [5. 数据准备与预处理](#5. 数据准备与预处理)
- [6. 训练模型](#6. 训练模型)
- [7. 模型评估](#7. 模型评估)
- [8. 测试模型](#8. 测试模型)
- [9. 应用模型](#9. 应用模型)
- 损失函数极小值、导向
- 超参数的影响
-
- 迭代次数epoch
- [批次量大小batch size](#批次量大小batch size)
- [学习率 lr](#学习率 lr)
- 模型问题
-
- 二、神经网络结构-全连接层
-
- 激活函数
-
- [1. Sigmoid](#1. Sigmoid)
- [2. Tanh](#2. Tanh)
- [3. ReLU (Rectified Linear Unit)](#3. ReLU (Rectified Linear Unit))
- [4. Leaky ReLU](#4. Leaky ReLU)
- [5. ELU (Exponential Linear Unit)](#5. ELU (Exponential Linear Unit))
- [6. Softmax](#6. Softmax)
- [7. Swish](#7. Swish)
- [8. GELU (Gaussian Error Linear Unit)](#8. GELU (Gaussian Error Linear Unit))
- 损失函数
-
- 均方差
- [交叉熵(Cross Entropy)](#交叉熵(Cross Entropy))
- 作业
一、深度学习步骤:
1. 选定模型结构
首先选择适合任务需求的模型架构 。在这个例子中,我们选择了二次函数作为模型结构,它可以表示为:
[ y = w_1x^2 + w_2x + w_3 ]
这里 (w_1, w_2, w_3) 是待学习的参数。
2. 模型参数随机初始化
在开始训练之前,需要对模型的所有权重(或参数)进行初始化 。通常我们会使用小的随机值来初始化这些参数,目的是打破对称性并且确保梯度的有效传播。对于我们的二次函数模型,这意味着给 (w_1, w_2, w_3) 分配随机初始值。
3. 构造模型损失函数
接下来定义一个损失函数(或成本函数),用来衡量模型预测输出与真实标签之间的差异。在本例中,均方误差(MSE)被用作损失函数 :
Loss = 1 N ∑ i = 1 N ( y pred , i − y true , i ) 2 \text{Loss} = \frac{1}{N}\sum_{i=1}^{N}(y_{\text{pred},i} - y_{\text{true},i})^2 Loss=N1i=1∑N(ypred,i−ytrue,i)2
其中 (N) 是样本数量,(ypred,i) 是模型预测值,而 (yture,i) 是真实值。
对损失函数中的权重求导实际上是,一个复合函数求导。首先损失函数是一个关于w的多元复合函数。对损失函数的W求导,就使用链式求导法则。以二元一次函数为例对W1求导结果如下:
∂ w 1 ∂ L = 2 ( y p r e d − y t r u e ) ⋅ x 2 ∂w1∂L=2(ypred−ytrue)⋅x2 ∂w1∂L=2(ypred−ytrue)⋅x2
4. 选择优化算法并设置超参数
选择适当的优化算法 来最小化损失函数,比如梯度下降法及其变种(如SGD、Adam等)。同时设定**必要的超参数,如学习率(lr)、批量大小(batch size)、迭代次数(epochs)**等。
5. 数据准备与预处理
将原始数据集划分为训练集、验证集和测试集,并进行必要的预处理步骤,例如标准化、归一化等。
6. 训练模型
使用训练数据集来进行模型训练,在每次迭代中执行以下子步骤:
- 前向传播:计算输入数据通过当前模型参数后的预测结果。
- 计算损失:根据预测结果和实际标签计算损失值。
- 反向传播:计算损失相对于每个参数的梯度。
- 更新参数:利用优化算法调整模型参数以减少损失。
7. 模型评估
在独立的验证集上评估模型性能,检查是否过拟合或欠拟合,并据此调整模型配置或超参数。
8. 测试模型
一旦模型训练完成且经过调优,最后一步是在完全未见过的测试集上评估其泛化能力。
9. 应用模型
如果模型表现良好,则可以将其部署到生产环境中,用于解决实际问题。
损失函数极小值、导向
损失函数越小,模型越好;
损失函数最小化;
模型权重影响损失函数值;
通过梯度下降来找到最优权重
梯度:多元函数导数,是个向量
梯度下降法:
-
根据梯度,更新权重。
-
w′=w−α ∂w/∂L
-
其中:w′ 是更新后的权重。w 是当前的权重。α 是学习率,决定了我们沿着梯度方向移动的步伐大小。偏导数也称为梯度。
意义
- 最小化损失 :梯度下降的目标是找到使损失函数最小化的模型参数。通过计算损失函数相对于每个参数的梯度,并在每次迭代中调整参数值以减小损失,我们可以逐渐接近全局最小点或局部最小点(对于非凸问题)。
- 优化方向:梯度给出了损失函数增长最快的方向,而负梯度则指向了减少最快的方向。因此,当我们用负梯度乘以一个小的学习率并从当前参数中减去它时,我们实际上是在尝试"下坡",即朝向更低损失的方向前进。
- 收敛速度与稳定性:学习率 α 控制着更新步骤的大小。如果 α 设置得太小,那么算法可能会非常慢才能收敛;如果太大,则可能导致算法无法稳定地收敛,甚至发散。选择合适的学习率对于确保有效和稳定的训练至关重要。
- 泛化能力 :通过最小化训练数据上的损失,我们希望模型能够很好地泛化到未见过的数据。虽然这并不是梯度下降直接保证的,但一个训练良好的模型通常也会在新数据上有较好的表现。
- 自适应调整 :在某些高级变体中,如Adam、RMSprop等优化器,它们不仅考虑了梯度的一阶信息(即平均梯度) ,还考虑了二阶信息(例如梯度的方差) 。这可以帮助加速收敛 并在不同类型的损失表面上提供更好的性能。
总结来说,通过应用梯度下降来更新权重,我们可以在损失空间中导航,寻找使得预测输出尽可能接近真实标签的模型参数。这是一个基础但极其重要的概念,在机器学习和深度学习领域被广泛使用。
-
-
学习率控制权重更新的幅度
-
损失函数变种SGD(Stochastic gradient descent)
超参数的影响
迭代次数epoch
- 过少的 Epochs
- 欠拟合(Underfitting) :如果
epoch
数量过少,模型可能没有充分学习到数据中的特征和模式,导致训练不足。这可能会使得模型性能较差,无法很好地捕捉输入数据与输出之间的关系。 - 低准确度:模型在训练集上的表现不佳,同时也会在验证集和测试集上表现出较低的准确性。
- 过多的 Epochs
- 过拟合(Overfitting) :当
epoch
数量过多时,模型可能会过度适应训练数据,以至于它不仅学到了数据中的有用信息,还记住了噪声或不相关的细节 。这样的模型在训练集上的表现会非常好,但在未见过的数据(如验证集和测试集)上的泛化能力差。 - 资源浪费:额外的训练时间增加了计算成本,并且不会带来性能上的显著提升,甚至可能导致性能下降。
- 合适数量的 Epochs
- 最佳性能 :找到一个恰当的
epoch
数量可以保证模型既能从数据中学习到足够的信息,又不会陷入过拟合的状态。通常,我们会通过监控验证集上的损失或准确率来确定这个点。 - 早停法(Early Stopping):一种常用的策略是在验证集上的性能不再改善时提前停止训练。这种方法可以帮助我们避免不必要的训练迭代,从而节省时间和资源。
实践建议:
- 交叉验证 :使用交叉验证技术可以在多个子集上评估模型性能,帮助更可靠地估计模型的最佳
epoch
数。 - 学习曲线 :绘制训练集和验证集的学习曲线(即随着
epoch
的增加,损失或准确性的变化),有助于直观地观察是否存在过拟合或欠拟合现象。 - 动态调整 :某些高级优化器具有自适应学习率 的能力,可以根据训练进度自动调整学习率,这也间接影响了
epoch
的效果。
批次量大小batch size
批次量(Batch Size)是深度学习模型训练中的一个重要超参数,它决定了在每次迭代中用于更新模型权重的样本数量。批次量的选择对模型训练的效果、速度以及最终性能有着显著的影响。以下是批次量对深度学习模型可能造成的影响:
- 训练稳定性
-
小批次量 :使用较小的批次量(如1或2),即所谓的随机梯度下降(SGD),可以引入更多的噪声 到梯度估计中。这有助于跳出局部极小值和鞍点 ,但同时也可能导致训练过程更加不稳定 ,损失函数值波动较大。
-
大批次量 :较大的批次量通常会提供更稳定和准确的梯度估计,因为它们平均了更多样例的信息。然而,过大的批次量可能会使模型收敛于次优解 ,尤其是在复杂的非凸优化问题中。
- 内存占用
-
小批次量:较小的批次量需要较少的内存来存储中间计算结果和梯度信息,因此更适合资源受限的环境,如移动设备或嵌入式系统。
-
大批次量:较大的批次量需要更多的内存,这可能限制了可以在单个GPU上训练的最大模型规模或者迫使你使用分布式训练。
- 训练速度
-
小批次量:虽然每次迭代的速度较快,但由于每轮epoch内需要进行更多次的权重更新,总体训练时间可能不会明显减少。此外,由于频繁的参数更新,通信开销(特别是在分布式训练环境中)也会增加。
-
大批次量:每次迭代处理的数据更多,理论上可以在更少的迭代次数下完成训练,但这取决于硬件是否能够高效地并行处理这些数据。
- 泛化能力
-
小批次量:研究表明,适当的小批次量可以帮助提高模型的泛化能力,因为它引入了一定程度的正则化效果,使得模型不易过拟合训练数据。
-
大批次量:非常大的批次量可能会导致模型过拟合训练数据,因为它减少了训练过程中参数空间探索的机会,使得模型更容易找到与训练集吻合得非常好的解决方案,但未必是对测试集表现最佳的解。
- 优化路径
-
小批次量:由于其固有的随机性和不稳定性,小批次量倾向于探索更广泛的参数空间,有时能找到更好的全局最小值。
-
大批次量:较大批次量提供的平滑梯度可能导致优化路径更加直接地指向某个局部最优解,而忽略了其他潜在的更优解。
实践建议
选择合适的批次量通常是一个实验性的过程,并且依赖于具体的应用场景和可用资源。一些常见的策略包括:
- 从一个合理的默认值开始:例如32、64或128,然后根据实际情况调整。
- 尝试不同的批次量组合:结合学习率和其他超参数一起调优。
- 考虑使用动态批次量:在训练初期使用较小的批次量以促进更好的探索,随着训练进程逐渐增大批次量以加快收敛。
总之,批次量的选择对于确保模型的有效训练和良好的泛化性能至关重要。通过实验和分析,可以找到最适合特定任务的最佳批次量。
学习率 lr
学习率(Learning Rate, LR)是深度学习模型训练过程中一个至关重要的超参数,它决定了在每次迭代中权重更新的步长。学习率的选择对模型训练的效果和效率有着直接的影响。以下是学习率对深度学习模型可能造成的影响:
- 过大的学习率
- 不稳定训练:如果学习率设置得过大,可能会导致损失函数值剧烈波动,无法稳定收敛,甚至发散。这是因为每一步的更新幅度过大,使得权重跳跃式变化,从而错过损失函数的最小值。
- 难以找到最优解:由于每次更新都跨越了较大的距离,模型可能会跳过全局最小点或陷入局部极小值附近,而不能精确地定位到最佳参数位置。
- 过小的学习率
- 训练速度慢:较小的学习率意味着每次权重更新都非常微小,因此需要更多的迭代次数才能达到收敛状态,这会导致训练时间显著增加。
- 容易陷入局部极小值或鞍点:当学习率非常小时,模型可能会被困在局部极小值、鞍点或者平坦区域,难以逃脱并继续向更好的解决方案前进。
- 合适的学习率
- 有效且快速的收敛:一个适当的学习率可以使模型既不会因为步子太大而错过最优点,也不会因为步子太小而导致训练过程漫长无果。它可以确保损失函数值逐渐下降,并最终稳定在一个较低水平,表示模型找到了较好的参数组合。
- 动态调整学习率
为了克服固定学习率带来的问题,实践中经常采用自适应学习率的方法,例如:
- 学习率衰减:随着训练的进行逐渐降低学习率。
- 循环学习率:周期性地改变学习率,在一定范围内上下浮动。
- 基于性能的学习率调整:根据验证集上的表现自动调整学习率,如当验证误差不再改善时降低学习率。
总之,选择合适的学习率对于确保模型能够有效地学习数据中的模式至关重要。通常情况下,通过实验来寻找最佳学习率范围,或者使用自动化工具和技术来优化这个过程。
模型问题
业内有固定模型(CNN、Transformer)
打乱样本顺序
梯度爆炸
梯度计算求和,是一个差的平方和,但是没有取平方;导致梯度值越来越大
或者是初始权重值特别大
梯度消失
过拟合
二、神经网络结构-全连接层
- 又叫线性层
- y = w * x + b
- w b 是参与训练的参数
- x 是 一个矩阵或者是转置矩阵
- W维度决定了隐含层输出的维度,一般称为隐单元个数(hidden size)
激活函数
1. Sigmoid
-
函数:
σ(x)=11+e−xσ (x )=1+e −x1
-
导数:
σ′(x)=σ(x)⋅(1−σ(x))σ ′(x )=σ (x )⋅(1−σ (x))
2. Tanh
-
函数:
tanh(x)=ex−e−xex+e−xtanh(x )=e**x +e −xex −e −x
-
导数:
tanh′(x)=1−tanh2(x)tanh′(x )=1−tanh2(x)
3. ReLU (Rectified Linear Unit)
-
函数:
ReLU(x)=max(0,x)ReLU(x )=max(0,x)
-
导数:
ReLU′(x)={1if x>00if x≤0ReLU′(x )={10if x >0if x≤0
4. Leaky ReLU
-
函数:
Leaky ReLU(x)={xif x>0αxif x≤0Leaky ReLU(x )={x**αx if x >0if x≤0
(αα 是一个小的正数,如 0.01)
-
导数:
Leaky ReLU′(x)={1if x>0αif x≤0Leaky ReLU′(x )={1α if x >0if x≤0
5. ELU (Exponential Linear Unit)
-
函数:
ELU(x)={xif x>0α(ex−1)if x≤0ELU(x )={x**α (e**x −1)if x >0if x≤0
(αα 是一个超参数)
-
导数:
ELU′(x)={1if x>0αexif x≤0ELU′(x )={1αex if x >0if x≤0
6. Softmax
-
函数:
Softmax(xi)=exi∑jexjSoftmax(x**i )=∑je xj exi
(通常用于多分类问题的输出层)
-
导数:
Softmax′(xi)=Softmax(xi)⋅(1−Softmax(xi))Softmax′(x**i )=Softmax(x**i )⋅(1−Softmax(x**i))
7. Swish
-
函数:
Swish(x)=x⋅σ(x)=x⋅11+e−xSwish(x )=x ⋅σ (x )=x ⋅1+e −x1
-
导数:
Swish′(x)=σ(x)+x⋅σ(x)⋅(1−σ(x))Swish′(x )=σ (x )+x ⋅σ (x )⋅(1−σ (x))
8. GELU (Gaussian Error Linear Unit)
-
函数:
GELU(x)=x⋅Φ(x)GELU(x )=x ⋅Φ(x)
其中 Φ(x)Φ(x) 是标准正态分布的累积分布函数。
-
导数:
GELU′(x)=Φ(x)+x⋅ϕ(x)GELU′(x )=Φ(x )+x ⋅ϕ (x)
其中 ϕ(x)ϕ (x) 是标准正态分布的概率密度函数。
损失函数
均方差
交叉熵(Cross Entropy)
常用于分类任务
分类任务中,网络输出经常是所有类别上的概率分布
torch会对你的预测值进行softmax归一化再用交叉熵运算
可能会用到真实标签转换为onehot编码
python
import numpy as np
# 真实值转换为one_hot编码
def to_one_hot(target, num_classes):
"""
将真实标签转换为One-Hot编码
参数:
target (list or array-like): 真实标签列表或数组
num_classes (int): 类别总数
返回:
numpy.ndarray: One-Hot编码后的矩阵
"""
# 创建一个全零的矩阵,形状为 (len(target), num_classes)
one_hot_target = np.zeros((len(target), num_classes))
# 遍历每个目标标签,并将其对应的索引位置设为1
for i, t in enumerate(target):
if 0 <= t < num_classes:
one_hot_target[i][t] = 1
else:
raise ValueError(f"Target value {t} is out of bounds for num_classes {num_classes}")
return one_hot_target
# 示例数据
target = [0, 1, 2, 1]
num_classes = 3
one_hot_encoded = to_one_hot(target, num_classes)
print("Original target:", target)
print("One-Hot encoded:\n", one_hot_encoded)