深度学习:激活函数,优化器,学习率,梯度
用于计算一组数值的加权平均,其中最近的数据点被赋予更高的权重。结合了 AdaGrad 算法和 RMSprop 算法的优点,通过计算梯度的一阶矩估计(均值)和二阶矩估计(未中心化的方差)来调整每个参数的学习率,从而实现自适应学习率。这种方式使得算法对最近的梯度给予更多的权重,而对旧的梯度逐渐“遗忘”,从而避免了学习率过快减小的问题。解决AdaGrad算法中学习率单调递减的问题,通过限制累积梯度的窗口
1,激活函数
神经元会对化学物质的刺激进行,当达到一定程度的时候,神经元才会兴奋,并向其他神经元发送信息。神经网络中的激活函数就是用来判断我们所计算的信息是否达到了往后面传输的条件。激活函数的目的主要是为了在神经网络中加入非线性因素,这样就加强了网络的表示能力,获得强大的学习能力和拟合能力。如果神经网络只使用线性激活函数,那么整个网络将只是多个线性操作的组合,无法处理非线性数据或者学习非线性映射。神经网络解决问题的能力与网络所采用的激活函数关系很大。
1.1,Sigmoid
sigmoid 函数的输出是在
开区间,丛神经科学角度来看,中间斜率较大部分即为神经元敏感区,两边斜率较平缓的地方即为抑制区。
输出范围:输出值始终在 (0, 1) 区间内,这使得 sigmoid 函数在输出概率或者用于二分类问题时非常有用。现在使用到 sigmoid 很少,基本上只有在做二分类(0,1)时的输出层才会使用。
平滑连续:sigmoid 函数在整个定义域内都是光滑且连续的,这有助于在优化过程中计算梯度。
中心对称:sigmoid 函数关于直线 y = x 对称,这意味着它能够处理正负输入值。
梯度问题:当输入值 x 非常大或非常小的时候,sigmoid 函数的梯度接近于0,这可能导致梯度消失问题,从而使得在神经网络的深层中梯度难以传播。
非零中心:sigmoid 函数的输出不是以 0 为中心的,这可能会导致网络在优化过程中花费更多的时间和资源来调整权重。
- 计算开销:相比于某些激活函数(如 ReLU),sigmoid 函数的计算复杂度较高,因为它涉及到指数运算。
1.2,tanh
双曲正切函数,tanh 的输出区间是在
之间,而整个函数是以0为中心。
tanh 函数具有良好的求导性质:
sigmoid 和 tanh 都有个问题就是容易导致梯度消失的现象发生,这是由于两者的导数在 x 很大或很小的时候,都容易趋近于 0,从而导致梯度消失的现象发生。但是好在 tanh 是以 0 为中心点,如果使用 tanh 作为激活函数,还能起到归一化(均值为 0)的效果。一般二分类问题中,隐藏层用 tanh 函数,输出层用 sigmod 函数,但是随着 Relu 的出现所有的隐藏层基本上都使用 relu 来作为激活函数了。
1.3,ReLU
【ReLU函数】
稀疏激活:由于 ReLU 在负半轴的输出为 0,这意味着在任何时候,大约有一半的神经元(假设输入是零均值的)不会被激活,这种稀疏性有助于减少计算量和防止过拟合。
非线性:ReLU 引入了非线性,使得神经网络能够学习和模拟复杂的函数。
计算效率高:由于其简单的数学形式,ReLU 的计算非常快速,这有助于加快神经网络的训练和推理速度。
缓解梯度消失问题:相比于 sigmoid 或 tanh 函数,ReLU在正区间的梯度恒定为 1,这有助于缓解梯度消失问题,使得深层网络的训练变得更加可行。
神经元死亡问题:当输入是负数的时,ReLU 是完全不被激活的,会丢失一部分信息,这就意味着在传播过程中,输入负数则梯度为 0,这个和 sigmod 函数、tanh 函数有一样的问题。但是实际的运用中,该缺陷的影响不是很大。
ReLU 在 0 处不可导也可以用于梯度学习,这是因为实际情况中在0处的导数通常会返回左导数或右导数的其中一个,从而避免这个问题。
Leaky ReLU:Leaky ReLU 是对 ReLU 的改进,当输入为负时,Leaky ReLU 引入了一个小的斜率,而不是直接输出 0。这有助于解决 ReLU 在负区间的输出为 0 的问题。
Parametric ReLU (PReLU):PReLU 是 Leaky ReLU 的一种扩展,它引入了一个可学习的参数,用于控制负区间的斜率。这使得神经网络能够自适应地学习负区间的激活函数。
Exponential Linear Unit (ELU):ELU 是一种类似 ReLU 的激活函数,它在负区间引入了一个指数项,使得负区间的输出更加平滑。ELU 在一些情况下可以提供更好的性能。
Scaled Exponential Linear Unit (SELU):SELU 是 ELU 的一种变种,它引入了缩放参数,使得 SELU 在一定条件下能够保持输入的均值和方差不变,从而有助于稳定训练。
GELU:GELU 是一种基于高斯误差线性单元的激活函数,它在一些情况下能够提供更好的性能。GELU 的数学形式是一个带有误差函数的平滑函数。
1.4,Swish
【Swish】
- 非线性:Swish 引入了非线性,使得神经网络能够学习和模拟复杂的函数。
- 平滑性:Swish 函数在整个定义域内都是光滑且连续的,这有助于在优化过程中计算梯度。
- 自适应性:Swish 函数的输出取决于输入值,这使得它能够自适应地调整激活函数的形状。
1.5,GELU
【GELU】输出平滑、近似“软门控”,对小输入抑制、对大输入线性放行,梯度连续稳定。相比 ReLU,训练更稳、收敛更好,尤其适合深层 Transformer。按输入属于“有用信息”的概率来放行信号。
其中
是标准正态分布的累计分布函数。
工程上近似
1.6,SwiGLU
【SwiGLU】SwiGLU 是一种结合了 Swish 和 GLU 的激活函数,它结合了 Swish 的平滑性和 GLU 的门控机制,能够有效地学习输入数据的不同特征。
吸取 GLU 的“门控机制”,增强了模型对信息的筛选能力。
利用 Swish 的“平滑非单调性”,解决了梯度消失并提升了表达力。
通过 增加参数量和升维,在 LLM(大语言模型)这种大数据量场景下展现出了极强的泛化能力。
2,优化器
2.1,SGD,ASGD
【SGD】随机梯度下降在每次迭代中只使用一个或一小批样本来计算梯度,然后更新模型参数。这样做可以减少每次迭代的计算成本,并有助于算法逃离局部最小值。
表示在时间步
的模型参数(可以是权重和偏置);
表示学习率,用于控制参数更新的步长;
表示损失函数
对参数
在样本
处的梯度;
【非凸优化问题】目标函数具有多个局部最小值的情况,这种情况下,SGD 可能会陷入局部最小值,并且很难跳出。这是因为 SGD 在每次迭代中只使用一个或一小批样本来计算梯度,可能导致梯度的方向不准确,从而影响参数更新的方向。
【ASGD】对多个随机梯度进行平均。
- 动量项的计算方式:Momentum 使用指数加权平均来计算动量,而ASGD使用简单算术平均;
- 学习率的调整:在 Momentum 中,学习率是固定的,或者可以随着时间进行调整;而在 ASGD 中,学习率随着迭代次数的增加而自然减小;
- 收敛行为:Momentum 通常在高曲率区域提供更好的加速效果,而 ASGD 则通过平均历史梯度来平滑梯度更新,减少噪声的影响。
2.2,Momentum
【指数加权平均】用于计算一组数值的加权平均,其中最近的数据点被赋予更高的权重。对异常值不太敏感,因为每个数据点的权重都会随着时间的推移而指数级减少。这使得它在处理含有噪声的数据时非常有用。
是在时间点
的指数加权平均值。
是介于 0 和 1 之间的衰减系数(decay factor),决定了历史数据的权重。
是在时间点
的观测值。
【Momentum】通过引入动量项来加速梯度下降算法的收敛并提高其稳定性。
- 加速收敛:通过累积历史梯度,可以在相关方向上加速参数更新;
- 抑制振荡:有助于减少训练过程中的震荡,特别是在目标函数的平坦区域或接近最小值时;
- 跳出局部最小值:在某些情况下,动量可以帮助算法跳出局部最小值,从而找到更好的全局最小值。
是时间步
的动量项,这个动量项是通过指数加权平均的方式计算得到的;
是动量衰减系数,通常设置在
之间,如 0.9 或 0.99;
是学习率;
是在参数
处的损失函数梯度。
2.3,Rprop
【Rprop】仅使用梯度的符号来计算更新,而不是梯度的大小,从而动态地为每个权重独立地调整步长。
- 初始化:为每个权重
初始化学习率
和变化量
(很小的正数)。
- 更新规则:
- 如果
(当前梯度)和
(上一时刻的梯度)同号,则增加学习率:
- 如果
和
异号或
为 0,则减少学习率:
。
- 如果
和
都为 0,则重置学习率:
- 权重更新:
,
是梯度符号。
【特点】
自适应学习率:Rprop 算法为每个权重单独设置学习率,而不是使用全局学习率。这意味着每个权重的学习率可以根据其历史梯度信息进行调整;
快速收敛:由于学习率的自适应调整,Rprop 通常能够更快地收敛;
鲁棒性:Rprop 算法对初始学习率的选择不敏感,这使得它在不同的问题上具有较好的鲁棒性。
2.4,AdaGrad,AdaDelta,RMSprop
【AdaGrad】为每个参数独立地调整学习率,使得不频繁更新的参数可以获得更大的学习率,而频繁更新的参数则获得较小的学习率。
- 初始化:为每个参数
初始化梯度平方和
。
- 梯度计算:在每次迭代中,计算参数
的梯度
。
- 更新梯度平方和:
- 计算自适应学习率:
,
是一个很小的数,用于防止分母为零。
- 参数更新:
【特点】
自适应学习率:Adagrad 为每个参数单独设置学习率,这意味着每个参数的学习率可以根据其历史梯度信息进行调整。
处理稀疏数据:Adagrad 特别适合处理稀疏数据,因为它能够为频繁更新的参数减小学习率,为不常更新的参数增大学习率。
不需要手动调整学习率:Adagrad 不需要手动设置学习率,它会自动根据参数的更新历史来调整学习率。
- 学习率递减,可能导致早期停止,特别是在处理非凸问题时。
- 对于非常大的数据集,累积的梯度平方和可能变得非常大,导致学习率过小。
【AdaDelta】解决 AdaGrad 算法中学习率单调递减的问题,通过限制累积梯度的窗口大小,并且不需要设置全局学习率,因为它会根据之前的参数更新量来自适应地调整学习率。
- 初始化两个状态变量:累积平方梯度的指数加权平均变量
和累积更新量的指数加权平均变量
。
- 在每次迭代中,计算梯度
- 更新累积平方梯度的指数加权平均
,
是计算平方梯度的指数加权平均的系数(通常设为0.9)
- 计算参数更新量
- 更新参数
- 更新累积更新量的指数加权平均
【特点】
- 自适应学习率,不需要手动设置。
- 适合处理稀疏数据。
- 加速模型的收敛过程。
- 对超参数
和
敏感。
- 在某些情况下可能导致不稳定的学习过程
【RMSprop】使用梯度的平方的指数移动平均值来调整每个参数的学习率,从而加快学习速度并减少训练过程中的震荡。这种方法特别适合处理非凸优化问题。
- 初始化参数
,设置学习率
,衰减系数
(通常设为0.9),以及数值稳定性的小常数
;
- 在每次迭代中,计算参数
的梯度
;
- 更新累积平方梯度的指数加权移动平均
- 计算参数更新量:
- 更新参数
【特点】
AdaGrad:累积所有过去的梯度平方(无遗忘因子)。这意味着它会不断地累积梯度信息,导致学习率随着时间逐渐减小,可能在后期变得过小,以至于无法继续有效更新;
RMSprop:使用指数加权平均来累积过去的梯度平方(有遗忘因子)。这种方式使得算法对最近的梯度给予更多的权重,而对旧的梯度逐渐“遗忘”,从而避免了学习率过快减小的问题。
2.5,Adam,Nadam,AdamW,Radam
【Adam】自适应矩估计结合了 AdaGrad 算法和 RMSprop 算法的优点,通过计算梯度的一阶矩估计(均值)和二阶矩估计(未中心化的方差)来调整每个参数的学习率,从而实现自适应学习率。
- 动量:类似于物理中的动量概念,它帮助算法在优化过程中增加稳定性,并减少震荡。
- 自适应学习率:Adam 为每个参数维护自己的学习率,这使得算法能够更加灵活地适应参数的更新需求。
- 偏差修正:由于算法使用了指数加权移动平均来计算梯度的一阶和二阶矩估计,因此在初始阶段会有偏差。Adam 通过偏差修正来调整这一点,使得估计更加准确。
【更新规则】
- 初始化一阶矩估计(动量)
和二阶矩估计(梯度平方的移动平均)
为 0,以及时间步长
;
- 在每次迭代中,计算梯度
;
- 更新一阶矩估计
和二阶矩估计
:
- 计算偏差修正的一阶矩估计
和二阶矩估计
:
- 更新参数:
【Nadam】结合 Nesterov 动量(NAG)和 Adam 优化算法的优化器。它旨在提高优化过程的性能,特别是在深度学习中。
- 同 Adam
- 计算 Nadam 特有的修正动量:
- 更新参数:
【特点】
- 结合 Nesterov 动量和 Adam 算法的优点,既有自适应学习率,又有 Nesterov 动量,可以更快地收敛。对于深度学习模型的优化效果较好。
- 可能会导致优化过程过于复杂,从而增加了计算负担。
【AdamW】
保持动量和自适应学习率的优点:AdamW 保留了 Adam 算法的动量(Momentum)和自适应学习率(AdaGrad)的优点,有助于加速收敛并适应不同的参数更新需求。
改进的权重衰减处理:AdamW 通过将权重衰减应用于参数更新步骤,而不是梯度计算步骤,解决原始 Adam 算法在处理权重衰减时的问题。减少模型的过拟合,提高模型的泛化能力;
超参数调整:AdamW 引入了额外的超参数(如权重衰减系数),这可能需要更多的调参工作来找到最优的超参数组合;
对学习率的敏感性:AdamW 对学习率的选择可能比 SGD 等其他优化器更敏感,不恰当的学习率设置可能导致训练效果不佳。
【Radam】是一种优化算法,它是 Adam 优化器的一个变种,旨在解决 Adam 在不同数据集和任务中性能不一致的问题。Radam 通过动态调整学习率来适应不同的训练阶段,从而提高模型的训练效果。
动态调整学习率:Radam 根据训练的进展动态调整学习率,以适应不同阶段的训练需求。
适应性:Radam 能够根据训练数据的特点自动调整优化策略,提高了对不同数据集和任务的适应性。
简单易用:Radam 的实现与 Adam 类似,易于在现有的深度学习框架中使用。
【更新规则】
- 同 Adam
- 根据训练阶段动态调整学习率:
,
![]()
- 更新参数:
【特点】
- 动态调整学习率,提高了优化的效率。
- 适应性强,适用于多种数据集和任务。
- 相对于原始的 Adam,Radam 的实现稍微复杂一些。
- 需要调整的超参数更多,可能会增加调参的难度。
3,其他问题
3.1,学习率
【问题】批次、泛化、学习率、累计梯度关系?
批次:单次前向传播和反向传播中使用的样本数量。
泛化:模型在未见过的测试数据上的表现能力。最终目标是良好的泛化,而非仅仅在训练集上的低损失。
学习率:优化器(如SGD)更新模型权重时的步长大小。它决定了每次参数更新有多大。
累计梯度:当GPU内存不足以承载大的批次时,将多个小批次(Micro-batch)的前向/反向传播梯度累加求和或求平均,在累积了多个小批次后才执行一次参数更新。这等效于用更大的“有效批次”进行更新。
【批次 & 泛化】
- 小 batch: 梯度噪声大(随机性强),能跳出局部最优,收敛到平坦的最小值,泛化能力强。
- 大 batch: 梯度准、方向稳,容易局部最优,导致测试集表现下降。
【批次 & 学习率】Batch 越大,学习率必须越大。
- 线性放大(主流): Batch 扩大
倍,LR 也扩大
倍(保持 LR/Batch 比例不变)。
- 根号放大(保守): Batch 扩大
倍,LR 扩大
倍(适合超大 Batch 或 Adam 优化器)。
【学习率调度器】带热身的余弦退火
Warmup Phase(预热期):学习率从 0 线性增加到设定的最大值。这能防止模型在微调初期因为梯度过大而产生震荡,有效保护预训练权重。
Cosine Decay Phase(余弦衰减期):学习率按照余弦曲线缓慢下降。相比线性下降,余弦衰减在后期下降更平滑,有助于模型在损失函数表面找到更深、更稳定的局部最优解。
【问题】深度网络中 loss 除以10和学习率除以10等价吗?对于带有自适应学习率的优化器(如 Adam、RMSprop), loss 缩放与学习率调整并不等价。对于经典的 SGD 和 Momentum SGD,将 loss乘以常数等价于将学习率乘以相同的常数。
3.2,梯度检查点
在标准的神经网络反向传播中,为了计算梯度,需要在前向传播阶段把每一层的激活值都保存在显存里。
痛点: 对于深层网络,激活值会占据巨大的显存空间,往往比模型参数本身还要大。
后果: 显存溢出,导致你无法增加 Batch Size 或者训练更深的模型。
【梯度检查点】并不保存所有的激活值,而是只保存其中一部分(即 Checkpoints)。
前向传播时:只记录关键节点的激活值,其他的全部丢弃。
反向传播时:当需要那些被丢弃的激活值来计算梯度时,系统会从最近的一个 Checkpoint 开始,临时重新跑一遍前向计算。
计算完即释放:临时计算出的激活值在用完后立即释放,不常驻显存。
特性 标准训练 梯度检查点 显存占用 极高(随层数线性增加) 极低(降至 级别)
计算速度 快 较慢(增加了约 30% 的前向计算开销) 适用场景 显存充足,追求极致速度 显存告急,想跑大模型或大 Batch
更多推荐






所有评论(0)