深度学习基础
概述
深度学习是基于多层神经网络的机器学习方法,通过多层非线性变换自动学习数据的层次特征表示。深度学习基础包括神经网络基本概念、反向传播算法、激活函数、参数初始化、梯度问题和正则化技术等核心内容。
神经网络基础
神经元模型
神经元是神经网络的基本计算单元:
接受多个输入信号
加权求和后通过激活函数产生输出
数学表达式:y = f ( ∑ i = 1 n w i x i + b ) y = f(\sum_{i=1}^n w_i x_i + b) y = f ( ∑ i = 1 n w i x i + b )
每个神经元可以有一个或多个输入,一个或多个输出 ,因此题目中"每个神经元只有一个输入一个输出"的说法错误,实际上各种情况都可能存在。
深层网络的定义
没有严格定义多少层才叫深度模型
一般认为拥有超过2个隐藏层的神经网络就可以称为深度学习模型
前向传播
信号从输入层经过隐藏层逐层计算,最终到达输出层产生预测的过程。
深度学习 vs 传统机器学习
深度学习 传统机器学习 自动特征学习 + 端到端学习 人工特征工程 + 分类/回归 需要大量数据和计算资源 数据量较小时也能工作 端到端优化,泛化能力强 特征工程质量决定上限
反向传播算法
什么是反向传播
反向传播(Backpropagation)是训练神经网络的核心算法,用来计算损失函数对每一层参数的梯度,然后通过梯度下降更新参数。
反向传播的工作流程
前向传播 :输入数据通过网络逐层计算,得到输出值
计算误差 :输出值与真实值计算损失函数
反向传播 :从输出层反向传播到输入层,计算损失对每个参数的偏导(梯度)
参数更新 :使用梯度下降等优化算法更新权重和偏置
为什么需要反向传播
神经网络参数众多,手动计算梯度不可行。反向传播利用链式法则高效计算梯度,使得深层网络训练成为可能。
梯度消失与梯度爆炸
产生原因
根据链式法则,反向传播中梯度是逐层相乘的:
梯度消失 :如果每一层的梯度都小于1,多层相乘后梯度趋近于0,靠近输入层的参数几乎不更新
梯度爆炸 :如果每一层的梯度都大于1,多层相乘后梯度指数增长,变得非常大
在sigmoid激活函数中,饱和区导数最大只有0.25,深层网络很容易发生梯度消失。
梯度消失的表现
靠近输入层的参数更新非常缓慢,模型训练困难
损失下降很慢,甚至不下降
深层网络训练效果不如浅层网络
梯度爆炸的表现
模型不稳定,损失急剧波动
权重变成NaN值
梯度持续超过正常值,参数更新幅度过大
解决方案
问题 解决方案 梯度消失 1. 使用ReLU等非饱和激活函数<br>2. Batch Normalization<br>3. 残差连接(ResNet)<br>4. LSTM结构(序列模型) 梯度爆炸 1. 梯度裁剪(设置梯度范数上限)<br>2. 权重正则化<br>3. Batch Normalization<br>4. LSTM结构
如何检测梯度爆炸
模型不稳定,训练过程中损失出现显著跳变
训练中梯度快速增大
权重更新后变成NaN值
每个节点和层的梯度范数持续超过1.0
激活函数
为什么需要激活函数
如果不使用激活函数,每一层输出都是上层输入的线性组合,无论网络多少层,最终都是线性变换,表达能力有限。引入非线性激活函数后,深度网络可以逼近任意非线性函数。
常见激活函数对比
Sigmoid
公式:σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1+e^{-z}} σ ( z ) = 1 + e − z 1
输出范围:(0, 1),可以表示概率
缺点:饱和区梯度接近0,容易梯度消失;输出不是零均值
Tanh
公式:t a n h ( z ) = e z − e − z e z + e − z tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}} t anh ( z ) = e z + e − z e z − e − z
输出范围:(-1, 1),零均值
缺点:仍然存在梯度消失问题
ReLU
公式:R e L U ( z ) = m a x ( 0 , z ) ReLU(z) = max(0, z) R e LU ( z ) = ma x ( 0 , z )
优点:
计算简单,梯度计算快
不会饱和,缓解梯度消失
稀疏性,缓解过拟合
缺点:
输出不是零均值
Dead ReLU问题:某些神经元可能永远不激活,梯度一直为0
Leaky ReLU / PReLU
公式:y = m a x ( α x , x ) y = max(\alpha x, x) y = ma x ( α x , x ) ,Leaky ReLU中α是小常数,PReLU中α可学习
解决Dead ReLU问题
Softmax
用于多分类输出层,将输出转换为概率分布,所有输出和为1
公式:s o f t m a x ( x i ) = e x i ∑ j e x j softmax(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}} so f t ma x ( x i ) = ∑ j e x j e x i
为什么ReLU比sigmoid好
计算更高效,梯度更容易计算
缓解梯度消失问题
产生稀疏性,减少过拟合
帮助随机梯度下降更快收敛
参数初始化
如果全部初始化为0会发生什么
如果全部初始化为0,每一层所有神经元计算相同,梯度相同,更新相同
最终所有神经元输出都相同,模型无法学习到不同的特征
所有神经元最终都会变成识别相同特征,模型表达能力退化
常见初始化方法
随机初始化 :权重从高斯分布或均匀分布中随机采样,乘以一个很小的系数
Xavier初始化 :
目标:让输入和输出的方差相同
对于激活函数sigmoid/tanh比较合适
权重从N ( 0 , 2 n i n + n o u t ) N(0, \frac{2}{n_{in} + n_{out}}) N ( 0 , n in + n o u t 2 ) 采样
He初始化 :
针对ReLU设计
方差放缩为2 n i n \frac{2}{n_{in}} n in 2
深度学习中推荐使用
初始化太小或太大的问题
初始化太小 :激活值逐渐趋向0,梯度消失,训练困难
初始化太大 :激活值进入饱和区,梯度消失,训练困难
对于sigmoid/tanh,初始化不当很容易导致一开始就梯度消失
正则化技术
Dropout
什么是Dropout :
在训练过程中,以一定概率随机让一部分神经元停止工作
强制模型不依赖于某些特定神经元,减少共适应性,防止过拟合
工作原理 :
训练时:每个神经元以概率p保留,概率(1-p)丢弃
预测时:所有神经元都保留,权重乘以p(或者训练时不缩放,预测时缩放)
Dropout类似于Bagging,训练出多个子网络,预测时集成,减少过拟合
Dropout概率选择 :
输入层:通常0.8(保留概率)
隐藏层:通常0.5(保留概率)
为什么Dropout能防止过拟合 :
减少神经元之间的共适应关系
强制模型学习更鲁棒的特征
类似于集成多个不同网络,降低方差
Batch Normalization (BN)
BN的实现过程 :
对于一个mini-batch:
计算mini-batch的均值:μ B = 1 m ∑ i = 1 m x i \mu_B = \frac{1}{m} \sum_{i=1}^m x_i μ B = m 1 ∑ i = 1 m x i
计算mini-batch的方差:σ B 2 = 1 m ∑ i = 1 m ( x i − μ B ) 2 \sigma_B^2 = \frac{1}{m} \sum_{i=1}^m (x_i - \mu_B)^2 σ B 2 = m 1 ∑ i = 1 m ( x i − μ B ) 2
归一化:x ^ i = x i − μ B σ B 2 + ϵ \hat{x}_i = \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} x ^ i = σ B 2 + ϵ x i − μ B
缩放平移:y i = γ x ^ i + β y_i = \gamma \hat{x}_i + \beta y i = γ x ^ i + β (γ和β是可学习参数)
BN的作用 :
解决内部协变量偏移问题,让每一层输入分布稳定
可以使用更高的学习率,加速收敛
减少梯度消失问题,让训练更稳定
降低对初始化的敏感度
具有一定正则化效果,可以减少Dropout的使用
BN在训练和测试时的区别 :
训练时 :用当前mini-batch的均值和方差做归一化
测试时 :用训练过程中通过滑动平均得到的全局均值和方差
L1/L2正则化
L1正则化 :
在损失函数中加上权重的L1范数:L = L 0 + λ ∑ ∣ w i ∣ L = L_0 + \lambda \sum |w_i| L = L 0 + λ ∑ ∣ w i ∣
产生稀疏解,很多权重变成0,可以用于特征选择
对异常值更鲁棒
L2正则化 :
在损失函数中加上权重的L2范数平方:L = L 0 + λ 2 ∑ w i 2 L = L_0 + \frac{\lambda}{2} \sum w_i^2 L = L 0 + 2 λ ∑ w i 2
限制权重大小,防止权重过大导致过拟合
使权重更平滑,泛化能力更好
对比 :
L1正则化 L2正则化 产生稀疏性,特征选择 不会产生稀疏性 不可导在0点,需要特殊处理 处处可导,容易计算 鲁棒性好,对异常值不敏感 稳定性好,收敛快
其他正则化方法
早停 (Early Stopping) :在验证集性能不再提升时停止训练,防止过拟合
数据增强 (Data Augmentation) :对训练数据做随机变换,增加数据多样性
权重衰减 (Weight Decay) :每次更新乘以一个小于1的系数,限制权重增长
面试常见问题
**什么是梯度消失?为什么会发生梯度消失?
梯度消失是指在反向传播过程中,由于链式法则连乘,靠近输入层的梯度变得非常小,参数几乎不更新的现象。
主要原因:
使用sigmoid/tanh等饱和激活函数,在饱和区导数接近0
网络层数过深,梯度逐层相乘后指数衰减
初始化不当,权重过小
**怎么解决梯度消失和梯度爆炸?
使用ReLU、LeakyReLU等非饱和激活函数
Batch Normalization归一化每一层输出,稳定梯度流
残差连接(ResNet),让梯度可以通过捷径直接传播
梯度裁剪限制梯度最大范数,解决梯度爆炸
LSTM结构解决序列模型中的梯度消失
合理的参数初始化
**为什么要引入非线性激活函数?
如果没有激活函数,不管网络有多少层,每一层都是线性变换,组合后仍然是线性变换,表达能力有限,只能拟合线性关系。引入非线性激活函数后,深度网络可以逼近任意非线性函数,表达能力大大增强。
**Sigmoid和ReLU的优缺点对比?
Sigmoid :输出概率友好,但是容易梯度消失,计算量大,不是零均值
ReLU :计算简单,缓解梯度消失,产生稀疏性,但是存在Dead ReLU问题,输出不是零均值
现代深度学习基本都使用ReLU及其变种
**Dropout为什么能防止过拟合?
Dropout随机失活神经元,迫使网络不依赖某些特定神经元,减少神经元之间的共适应关系
训练过程中实际上隐式集成了多个不同的子网络,类似于Bagging,降低方差
增加了模型的鲁棒性,减少对局部特征的过度依赖
**BN的原理是什么?训练和测试时有什么不同?
BN通过对每一层的激活进行归一化,解决内部协变量偏移问题,让训练更稳定更快。
训练时:使用当前mini-batch的均值和方差进行归一化,同时用滑动平均更新全局统计量
测试时:使用训练阶段得到的全局均值和方差,不使用当前batch的统计量
BN中的γ和β是可学习参数,用来恢复数据的表达能力
**如果把网络权重全部初始化为0,会发生什么?为什么?
网络无法正常训练。因为如果所有初始权重都是0,每一层所有神经元的输入加权和相同,激活值相同,反向传播得到的梯度也相同,参数更新后仍然相同,最终所有神经元都学到相同的特征,网络无法学到多样化的特征,表达能力严重退化。
**Xavier初始化和He初始化的区别?什么时候用哪个?
Xavier初始化:保持输入输出方差一致,适合sigmoid/tanh激活函数
He初始化:考虑ReLU的稀疏性,调整了方差放缩,适合ReLU激活函数
现代深度学习网络大多用ReLU,所以推荐使用He初始化
**BN和Dropout一起使用需要注意什么?
当BN和Dropout一起使用时,需要注意BN在推理时使用的是全局统计量,而Dropout只在训练时生效。一些经验表明,BN已经有一定正则化效果,可以减少Dropout的使用率或降低dropout概率。
**L1正则化为什么能产生稀疏性?
L1正则化在损失函数中加入权重绝对值惩罚,在最优解处,L1正则化会使得很多权重变为0,因为L1在0点处的惩罚是线性的,很多小权重被压缩到0,从而产生稀疏性,这也使得L1可以用于特征选择。
**神经网络中权值共享是什么意思?
权值共享是指在卷积神经网络中,同一个卷积核在整个特征图上使用相同的参数,而不是每个位置使用不同参数。这样大大减少了参数量,并且让网络能够学习到位置不变的特征。LeNet最早提出了权值共享的概念。
**解释一下Dead ReLU问题
Dead ReLU是指某些神经元在训练过程中,权重更新后,对于任何输入都输出0,梯度一直为0,参数不再更新,神经元"死亡"。原因通常是学习率太大,导致一次更新后bias变成很大的负数,使得所有输入都小于0,ReLU输出恒为0。解决方法:使用较小学习率,使用Leaky ReLU/PReLU等变种。