dropout函数详解及反向传播中的梯度求导

摘要

本文给出 dropout 函数的定义, 并求解其在反向传播中的梯度

相关

配套代码, 请参考文章 :

Python和PyTorch对比实现dropout函数及反向传播

系列文章索引 :
https://blog.youkuaiyun.com/oBrightLamp/article/details/85067981

正文

1. dropout 的概念

深度神经网络结构的过拟合是指 : 在训练集上的正确率很高, 但在测试集上的准确率很低.
为了缓解网络过拟合的问题, 其中一种常见的办法是使用 dropout 函数.

dropout 是指在深度网络的训练中, 以一定的概率随机地 “临时丢弃” 一部分神经元节点. 具体来讲, dropout 作用于每份小批量训练数据, 由于其随机丢弃部分神经元的机制, 相当于每次迭代都在训练不同结构的神经网络.

– 摘抄自 <百面机器学习>

dropout 前网络结构示意 :
在这里插入图片描述
图片来源 : https://www.jianshu.com/p/2c6978b4bf74

dropout 后网络结构示意 :
在这里插入图片描述
图片来源 : https://www.jianshu.com/p/2c6978b4bf74

2. dropout 的作用

dropout 最直接的作用就是可以提升模型的泛化能力, 提高模型的健壮性, 提高通用性.

如何理解 ?

假设某公司存在一个职能稳定, 合理分工团队.

因为某些不可避免的原因, 该团队的成员每天都有 50% 概率不能参与工作.

为了完成任务, 需要其他同事加班完成缺席员工任务.

一段时间后, 该团队的成员普遍学会了其他同事的相关工作技能.

于是, 该团队拥有了更好的泛化能力.

3. 训练过程中的 dropout

为了定义 dropout, 我们需要一个随机数生成函数 rand(), 每一次调用都会重新生成一个0~1之间的小数 :
0 ⩽ r a n d ( ) &lt; 1 &ThickSpace; 0\leqslant rand() &lt; 1 \;\\ 0rand()<1

假设每一次 dropout 都以 p 的概率随机丢弃一个节点 :
0 ⩽ p &lt; 1 0\leqslant p &lt; 1 0p<1

则 dropout 函数的定义为 :
r = r a n d ( ) &ThickSpace; d r o p o u t ( x ) = { 0 , r &lt; p x / ( 1 − p ) , r ⩾ p r = rand()\\ \;\\ dropout(x) = \left\{ \begin{array}{rr} 0, &amp; r &lt; p\\ x / (1 - p), &amp; r \geqslant p \end{array} \right. r=rand()dropout(x)={ 0,x/(1p),r<prp

将通过的信号被放大 1 / ( 1 − p ) 1/(1 - p) 1/(1p) 倍, 保证总体信号强度不变 (加班).

dropout函数是逐个元素处理的, 并不需要写成向量的形式.
但为了方便编程实现, 这里将其进行改编成向量的形式.

考虑一个输入向量 x, 同时定义一个随机掩码函数和一个随机掩码向量 m :
x = ( x 1 , x 2 , x 3 , ⋯ &ThinSpace; , x k ) &ThickSpace; r i = r a n d ( ) &ThickSpace; r a n d o m M a s k ( x i ) = { 0 , r i &lt; p 1 / ( 1 − p ) , r i ⩾ p &ThickSpace; m i = r a n d o m M a s k ( x i ) x = (x_1,x_2,x_3,\cdots,x_k)\\ \;\\ r_i

<think>好的,用户现在想了解人工神经网络(ANN)模型的训练过程和步骤。之前我已经给出过关于ANN解决二分类问题的步骤,现在需要根据用户的新提问,结合提供的引用资料,整理出更通用的训练流程。 首先,用户引用了四篇资料,其中[1]和[4]详细介绍了ANN的基本结构和BP算法,[2]提到了前向传播、反向传播和学习率的作用,而[3]虽然关于大模型,但可能关联性不大。需要重点参考[1]、[2]、[4]的内容。 回顾之前的回答,我已经覆盖了数据准备、网络结构、损失函数、训练步骤、评估调优等。现在需要将这些内容更系统地组织成训练过程的步骤,并确保符合引用中的信息。 用户可能希望了解从初始化到参数更新的整个流程,包括前向传播、损失计算、反向传播梯度下降等。需要明确每个步骤的细节,如参数初始化方法、激活函数的选择、优化器的使用等。 同时,用户可能对BP算法特别感兴趣,因为引用[4]提到了BP算法。需要详细解释反向传播梯度计算的过程,结合链式法则,如引用[4]中的内容。 另外,引用[2]提到从零开始构建神经网络,可能需要强调参数初始化和手动实现梯度计算的部分,但考虑到用户可能需要实际应用,可能更倾向于使用框架(如PyTorch)的示例,但需平衡理论和实践。 需要检查是否有遗漏的关键步骤,比如数据分批(batch)、学习率调整、正则化等,这些在之前的回答中已经提到,但需要整合到训练流程中。 还要注意引用文献的正确标注,确保每个关键点都有对应的引用支持,比如前向传播和反向传播引用[2]和[4],激活函数引用[4],优化器引用[2]等。 最后,用户可能需要清晰的步骤划分,每个步骤的输入输出,以及算法流程的总结。可能需要用公式展示关键计算,如梯度更新公式,损失函数等,符合之前设定的LaTeX格式要求。 总结,需要将训练过程分为初始化、前向传播、损失计算、反向传播、参数更新、迭代优化等步骤,结合引用资料,详细说明每个步骤,并给出代码示例和常见问题。</think>### 人工神经网络(ANN)模型的训练过程与步骤详解 --- #### **1. 训练流程概述** 人工神经网络的训练过程是**通过迭代优化网络参数(权重与偏置)**,使模型能够从输入数据中学习特征与规律,最终最小化预测误差。整个过程可分为以下核心步骤: 1. 网络初始化 → 2. 前向传播 → 3. 损失计算 → 4. 反向传播 → 5. 参数更新 → 6. 迭代优化[^1][^4]。 --- #### **2. 详细训练步骤** ##### **2.1 网络结构与参数初始化** - **网络架构设计**: - 输入层:神经元数量与输入特征维度一致(如特征向量长度为$d$,则输入层为$d$个神经元)。 - 隐藏层:通常为全连接层,层数与神经元数量根据任务复杂度调整(浅层网络SNN vs. 深层网络DNN)[^4]。 - 输出层:根据任务类型设计(如二分类任务使用1个神经元+Sigmoid,多分类任务使用Softmax)。 - **参数初始化**: - 权重矩阵$W$:常用Xavier或He初始化方法,避免梯度消失或爆炸。例如: $$W \sim \text{Uniform}\left(-\sqrt{\frac{6}{n_{\text{in}} + n_{\text{out}}}}, \sqrt{\frac{6}{n_{\text{in}} + n_{\text{out}}}}\right)$$ 其中$n_{\text{in}}$和$n_{\text{out}}$为相邻层的神经元数量。 - 偏置$b$:通常初始化为0或小随机数。 ##### **2.2 前向传播(Forward Propagation)** - **输入数据逐层计算**: 对于第$l$层,计算加权和并应用激活函数: $$ z^{(l)} = W^{(l)} a^{(l-1)} + b^{(l)} \\ a^{(l)} = \sigma(z^{(l)}) $$ 其中: - $a^{(l-1)}$为前一层输出(输入层$a^{(0)} = x$) - $\sigma$为激活函数(如ReLU、Sigmoid) - **输出层结果**: 最终输出$\hat{y} = a^{(L)}$,与真实标签$y$对比计算误差。 ##### **2.3 损失函数计算** - **定义损失函数**:根据任务类型选择: - **均方误差(MSE)**:回归任务 $$L = \frac{1}{N} \sum_{i=1}^N (\hat{y}^{(i)} - y^{(i)})^2$$ - **交叉熵损失(Cross-Entropy)**:分类任务 $$L = -\frac{1}{N} \sum_{i=1}^N \left[ y^{(i)} \log(\hat{y}^{(i)}) + (1 - y^{(i)}) \log(1 - \hat{y}^{(i)}) \right]$$ [^1][^4] ##### **2.4 反向传播(Backpropagation)** 通过链式法则计算梯度,从输出层向输入层逐层传递误差信号[^2]: 1. **输出层梯度**: - 对于交叉熵损失+Sigmoid激活的组合,梯度简化为: $$\frac{\partial L}{\partial z^{(L)}} = \hat{y} - y$$ ($z^{(L)}$为输出层的未激活值) 2. **隐藏层梯度**: - 计算当前层误差$\delta^{(l)}$: $$\delta^{(l)} = \left( W^{(l+1)T} \delta^{(l+1)} \right) \odot \sigma'(z^{(l)})$$ 其中$\odot$表示逐元素相乘,$\sigma'$为激活函数导数。 3. **参数梯度**: - 权重梯度: $$\frac{\partial L}{\partial W^{(l)}} = \delta^{(l)} a^{(l-1)T}$$ - 偏置梯度: $$\frac{\partial L}{\partial b^{(l)}} = \delta^{(l)}$$ ##### **2.5 参数更新** 使用优化算法调整权重与偏置,常见方法包括: - **随机梯度下降(SGD)**: $$W^{(l)} \gets W^{(l)} - \eta \cdot \frac{\partial L}{\partial W^{(l)}}$$ $$b^{(l)} \gets b^{(l)} - \eta \cdot \frac{\partial L}{\partial b^{(l)}}$$ 其中$\eta$为学习率。 - **自适应优化器**:如Adam、RMSProp,动态调整学习率以加速收敛[^2]。 ##### **2.6 迭代优化** 重复以下步骤直至收敛: 1. 将训练数据分为小批量(Mini-Batch)。 2. 前向传播计算预测值。 3. 反向传播计算梯度。 4. 更新网络参数。 5. 周期性验证模型性能,防止过拟合。 --- #### **3. 关键算法:反向传播(BP算法)** 反向传播是ANN训练的核心,其数学本质是**复合函数的链式求导法则**。以下以单隐藏层网络为例说明流程: 1. **前向传播**: $$z^{(1)} = W^{(1)}x + b^{(1)}, \quad a^{(1)} = \text{ReLU}(z^{(1)})$$ $$z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}, \quad \hat{y} = \sigma(z^{(2)})$$ 2. **计算损失**: $$L = -y \log(\hat{y}) - (1 - y) \log(1 - \hat{y})$$ 3. **反向传播梯度**: - 输出层: $$\frac{\partial L}{\partial z^{(2)}} = \hat{y} - y$$ $$\frac{\partial L}{\partial W^{(2)}} = \frac{\partial L}{\partial z^{(2)}} \cdot a^{(1)T}$$ - 隐藏层: $$\delta^{(1)} = (W^{(2)T} \cdot \frac{\partial L}{\partial z^{(2)}}) \odot \text{ReLU}'(z^{(1)})$$ $$\frac{\partial L}{\partial W^{(1)}} = \delta^{(1)} \cdot x^T$$ 4. **更新参数**: $$W^{(2)} \gets W^{(2)} - \eta \cdot \frac{\partial L}{\partial W^{(2)}}$$ $$W^{(1)} \gets W^{(1)} - \eta \cdot \frac{\partial L}{\partial W^{(1)}}$$ --- #### **4. 训练优化技巧** - **学习率调度**: 使用余弦退火或指数衰减动态调整学习率,平衡收敛速度与稳定性。 - **正则化**: - L2正则化:向损失函数添加权重惩罚项: $$L_{\text{total}} = L + \frac{\lambda}{2} \sum_{l} \|W^{(l)}\|_F^2$$ - Dropout:训练时随机屏蔽部分神经元,增强泛化能力。 - **批量归一化(BatchNorm)**: 在隐藏层后添加归一化层,加速训练并缓解梯度问题: $$x_{\text{norm}} = \frac{x - \mu_{\text{batch}}}{\sqrt{\sigma_{\text{batch}}^2 + \epsilon}}$$ [^4] --- #### **5. 代码示例(PyTorch实现)** ```python import torch import torch.nn as nn # 定义网络结构 class ANN(nn.Module): def __init__(self, input_dim): super().__init__() self.fc1 = nn.Linear(input_dim, 64) self.fc2 = nn.Linear(64, 1) self.relu = nn.ReLU() self.sigmoid = nn.Sigmoid() def forward(self, x): x = self.relu(self.fc1(x)) x = self.sigmoid(self.fc2(x)) return x # 初始化模型、损失函数与优化器 model = ANN(input_dim=10) criterion = nn.BCELoss() # 二元交叉熵 optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 训练循环 for epoch in range(100): for batch_x, batch_y in dataloader: # 分批次加载数据 optimizer.zero_grad() outputs = model(batch_x) loss = criterion(outputs, batch_y) loss.backward() # 反向传播计算梯度 optimizer.step() # 参数更新 ``` --- ### 关键问题解答 1. **为何反向传播需要从输出层开始计算梯度?** 链式法则要求按计算图的逆序求导,输出层的梯度可直接通过预测误差计算,随后逐层传递至输入层[^4]。 2. **如何选择批量大小(Batch Size)?** 较小批量(如32/64)适合数据量大的场景,能提供更多更新次数;大批量(如256)训练更稳定,但可能陷入局部最优。 3. **梯度消失/爆炸的解决方法?** - 使用ReLU激活函数代替Sigmoid。 - 应用批量归一化或残差连接(ResNet)。 - 采用梯度裁剪(Gradient Clipping)[^4]。 --- ### 相关问题 1. 如何通过可视化工具(如TensorBoard)监控训练过程? 2. 卷积神经网络(CNN)与全连接ANN在训练流程上有何异同? 3. 如何解释神经网络中的权重与特征重要性? 4. 分布式训练如何加速大规模ANN模型的训练? --- **参考文献** [^1]: 神经网络算法--一文搞懂ANN(人工神经网络) [^2]: 神经网络训练与优化方法 [^4]: 人工神经网络(ANN)及BP算法详解
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值