深度学习——激活函数、损失函数、优化器、参数显存占用分析

深度学习——激活函数、损失函数、优化器、参数显存占用分析

1、激活函数

激活函数将非线性引入到网络中,没有激活函数相当于原始的感知机,只有线性操作,近似为矩阵相乘操作,加入激活函数后可以更好地拟合非线性函数。

1.1、一些常见的激活函数

1.1.1、sigmoid

σ ( x ) = 1 1 + e − x \sigma(x) = \frac{1}{1+e^{-x}} σ(x)=1+ex1
特点:将负无穷到正无穷的输入映射到0-1,处处连续可导,可以用于二分类,导数为 σ ′ ( x ) = σ ( x ) ( 1 − σ ( x ) ) \sigma'(x)=\sigma(x)(1-\sigma(x)) σ(x)=σ(x)(1σ(x))
缺点:在输出值接近0或1时会出现饱和现象,在反向传播时梯度较小,容易梯度消失,从而无法完成深层网络的训练。输出不是0均值的,会导致后层的神经元的输入是非0均值的信号,这会对梯度产生影响。并且计算复杂度较高,因为涉及到指数。

1.1.2、softmax

S o f t m a x ( x i ) = e x i Σ j e x j Softmax(x_i)=\frac{e^{x_i}}{\Sigma_j{e^{x_j}}} Softmax(xi)=Σjexjexi
softmax可以将上一层的原始数据进行归一化,转化为一个(0,1)之间的数值,这些数值可以被当作概率分布,用来作为多分类的目标预测值,一般作为神经网络的最后一层,接收上一层网络的输入值,然后将其转化为概率。sigmoid是softmax的一个特例,sigmoid函数只能用于预测值为0或1的二元分类。

1.1.3、tanh

σ ( x ) = e x − e − x e x + e − x \sigma(x) = \frac{e^x-e^{-x}}{e^x+e^{-x}} σ(x)=ex+exexex
输出范围在-1~1,相比sigmoid函数,是0均值,会比sigmoid函数要好一些,但是仍然会存在容易梯度消失的问题。并且计算复杂度仍然较高。

1.1.4、ReLU

σ ( x ) = { 0 x < 0 x x ⩾ 0 \sigma(x) = \begin{cases} 0 & x<0 \\ x & x \geqslant 0 \end{cases} σ(x)={ 0xx<0x0
或者 σ ( x ) = m a x ( 0 , x ) \sigma(x) = max(0,x) σ(x)=max(0,x)
整流线性单元,使用ReLU的SGD算法收敛速度比sigmoid和tanh快,在x>0时不会出现梯度消失问题,在x<0时,梯度为0,无法传播到前一层。计算复杂度低。
缺点:输出不是0均值的,并且在x<0时会存在神经元坏死问题,梯度无法传播,其后面的神经元梯度都为0,无法更新参数。

1.1.5、Leaky ReLU

σ ( x ) = { α x x < 0 x x > 0 \sigma(x) = \begin{cases} \alpha x & x<0 \\ x & x>0 \\ \end{cases} σ(x)={ αxxx<0x>0
alpha默认0.01;为解决ReLU神经元坏死的问题,引入了LeakReLU,使得激活函数在负数区域也存在微小的梯度,而梯度是固定的斜率。

1.1.6、PReLU

σ ( x ) = { a x x < 0 x x > 0 \sigma(x) = \begin{cases} ax & x<0 \\ x & x>0 \\ \end{cases} σ(x)={ axxx<0x>0
和LeakReLU不同的是这里的参数 a a a是可学习的

1.1.7、GeLU

σ ( x ) = 1 1 + e − 1.702 x \sigma(x) = \frac{1}{1+e^{-1.702x}} σ(x)=1+e1.702x1
在Transformer里面用的多一些

1.1.8、ELU

σ ( x ) = { α ( e x − 1 ) x < 0 x x > 0 \sigma(x) = \begin{cases} \alpha(e^x-1) & x<0 \\ x & x>0 \\ \end{cases} σ(x)={ α(ex1)xx<0x>0
有负数饱和区域,从而对噪声有一些鲁棒性。可以看做是介于ReLU和Leaky ReLU之间的一个函数。当然,这个函数也需要计算exp,从而计算量上更大一些。

1.1.9、Swish

f ( x ) = x ⋅ σ ( β ⋅ x ) f(x) = x \cdot \sigma(\beta \cdot x) f(x)=xσ(βx)
其中 σ \sigma σ是Sigmoid激活函数。 σ ( x ) = 1 1 + e − x \sigma(x)=\frac{1}{1+e^{-x}} σ(x)=1+ex1
特点:和ReLU一样没有上边界,因此不会出现梯度饱和的现象;有下边界,可以产生更强的正则化效果(x左半轴慢慢趋近于0),非单调,处处连续可导,更容易训练。

1.1.10、GLU

GLU(Gated Linear Units)其实不算是一种激活函数,而是一种神经网络层,是一个线性变换后面接门控机制的结构。门控机制是一个sigmoid函数用来控制信息能够通过多少。
G L U ( x , W , V , b , c ) = σ ( x W + b ) ⊗ ( x V + c ) GLU(x, W, V, b, c)=\sigma(xW+b) \otimes (xV+c) GLU(x,W,V,b,c)=σ(xW+b)(xV+c)
其中 σ \sigma σ是Sigmoid激活函数, ⊗ \otimes 是逐元素乘法,通过使用其他激活函数,就可以得到各种GLU的变体。

1.1.11、SwiGLU

采用Swish作为激活函数的GLU变体。
S w i G L U ( x , W , V , b , c ) = S w i s h ( x W + b ) ⊗ ( x V + c ) SwiGLU(x, W, V, b, c)=Swish(xW+b) \otimes (xV+c) SwiGLU(x,W,V,b,c)=Swish(xW+b)(xV+c)

1.2、激活函数的特点

1.2.1、非线性

即导数不能是常数,来保证多层网络不退化成单层线性网络

1.2.2、几乎处处可微

几乎处处可微保证了在优化中梯度的可计算性,ReLU仅在有限个点处不可微。有限个不可微的点对优化结果不会有很大的影响。

1.2.3、计算简单

因为每一个神经元的输出都需要经过激活函数,简单的函数像是ReLU更适合做激活函数。

1.2.4、非饱和性

Sigmoid在正负区域都有饱和区,ReLU在负半轴有饱和区,饱和区参数无法得到有效更新,leakyReLU就是为了解决这个问题。

1.2.5、单调性、输出范围有限

2、损失函数

2.1、深度估计回归损失

2.1.1、L1损失函数

L1损失函数:最小绝对值偏差、最小绝对值误差:是目标值与估计值的绝对差值的总和。缺点:不稳定。收敛速度慢。优点:对离群点异常值更具有鲁棒性。
L 1 ( y ^ − y ) = ∑ i = 0 m ∣ y ( i ) − y ^ ( i ) ∣ L_1(\hat{y}-y)=\sum_{i=0}^m\left|y^{(i)}-\hat{y}^{(i)}\right| L1(y^y)=i=0m y(i)y^(i)
torch.nn.L1Loss(size_average=None, reduce=None, reduction='sum') # size_average与reduce已经被弃用,具体功能可由reduction替代。

l1_loss = torch.nn.L1Loss(size_average=None, reduce=None, reduction='sum') # 创建实例
loss = l1_loss(src,tgt)

L 1 ( y ^ − y ) = 1 N ∑ i = 0 m ∣ y ( i ) − y ^ ( i ) ∣ L_1\left(\hat{y}-y\right)=\frac1N\sum_{i=0}^m\left|y^{(i)}-\hat{y}^{(i)}\right| L1(y^y)=N1i=0m y(i)y^(i)
torch.nn.L1Loss(size_average=None, reduce=None, reduction='mean'),相当于MAE平均绝对误差。
torch.nn.functional.l1_loss(src, tgt, reduction='mean')
torch.mean(torch.abs(src-tgt))
(src-tgt).abs().mean()
如果是np.ndarray的话
np.mean(np.abs(src-tgt)) np.ndarray没有.abs()方法,只有类np.abs()函数

2.1.2、L2损失函数

L2损失函数:均方误差:是目标值与估计值的差值的平方和。缺点:对异常值更敏感。梯度更新方向容易受离群点主导。
L 2 ( y ^ , y ) = ∑ i = 0 m ( y ( i ) − y ^ ( i ) ) 2 L_2(\hat{y},y)=\sum_{i=0}^m(y^{(i)}-\hat{y}^{(i)})^2 L2(y^,y)=i=0m(y(i)y^(i))2
torch.nn.MSELoss(size_average=None, reduce=None, reduction='sum')
torch.sum(torch.pow(src-tgt,2))
np.sum(np.power(src-tgt,2))
L 2 ( y ^ , y ) = 1 N ∑ i = 0 m ( y ( i ) − y ^ ( i ) ) 2 L_2(\hat{y},y)=\frac1N\sum_{i=0}^m(y^{(i)}-\hat{y}^{(i)})^2 L2(y^,y)=N1i=0m(y(i)y^(i))2
torch.nn.MSELoss(size_average=None, reduce=None, reduction='mean'),相当于MSE均方误差。
torch.mean(torch.pow(src-tgt,2))
np.mean(np.power(src-tgt,2))

2.1.3、smooth L1损失函数

smooth L1损失函数:平滑之后的L1损失函数:分段函数,来消除L1的折点不光滑问题。当误差的绝对值较小时采用MSE,当误差的绝对值较大时采用MAE。
S m o o t h L 1 = 0.5 x 2 , ∣ x ∣ < 1 ∣ x ∣ − 0.5 , x < − 1 或者 x > 1 SmoothL_1=\begin{aligned}

### 构建基于深度学习的手写数字识别系统的概述 构建一个基于深度学习的手写数字识别系统通常涉及多个阶段,包括数据准备、模型设计、训练以及评估。卷积神经网络(CNN)由于其优秀的特征提取能力,在图像处理领域表现尤为出色[^1]。 #### 数据集的选择与预处理 对于手写数字识别任务而言,MNIST数据库是一个广泛使用的标准测试平台。该数据集中包含了大量已经标注好的灰度手写体图片,每张图像是28×28像素大小。为了提高模型性能,可以对原始输入做一定的变换操作,比如标准化或者增强等方法来扩充样本数量并改善泛化效果。 #### 卷积神经网络架构的设计 CNN由多层组成,其中最核心的部分就是卷积层(Convolutional Layer),它能够自动捕捉到局部区域内的空间关系;池化层(Pooling Layer)用于降低维度的同时保留重要信息;最后通过全连接层(Fully Connected Layers, FCs)完成分类工作。具体来说: - **卷积层**:利用滤波器扫描整个图像矩阵,生成一系列激活映射(Feature Maps)。 - **ReLU激活函数**:引入非线性因素,使得网络具备更强表达力。 - **最大池化(Max Pooling)**:减少计算量和过拟合风险。 - **Dropout正则项**:随机丢弃部分节点防止过拟合现象发生。 - **Softmax回归**:输出各个类别的概率分布情况。 ```python import torch.nn as nn class CNN(nn.Module): def __init__(self): super(CNN, self).__init__() # 定义两组卷积+池化的结构 self.conv_layer = nn.Sequential( nn.Conv2d(in_channels=1, out_channels=16, kernel_size=(3, 3), padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=(2, 2)), nn.Conv2d(in_channels=16, out_channels=32, kernel_size=(3, 3), padding=1), nn.ReLU(), nn.MaxPool2d(kernel_size=(2, 2)) ) # 全连接层 self.fc_layer = nn.Sequential( nn.Linear(32 * 7 * 7, 128), nn.Dropout(p=0.5), nn.Linear(128, 10) ) def forward(self, x): conv_out = self.conv_layer(x) flatten = conv_out.view(-1, 32*7*7) fc_out = self.fc_layer(flatten) return fc_out ``` 上述代码展示了如何定义一个简单的CNN模型框架,适用于解决二值化后的黑白手写字母或阿拉伯数字符号的辨识问题。 #### 训练过程中的注意事项 当采用PyTorch框架来进行实际编程实践时,除了搭建合适的网络拓扑之外,还需要关注以下几个方面: - 设置合理的损失函数(Loss Function),如交叉熵误差; - 使用高效的优化算法(Optimizer),例如AdamOptimizer; - 调整批量尺寸(Batch Size)以平衡内存占用与收敛速度之间的矛盾; - 对于大规模的数据集考虑分批次读取方式加载至GPU显存中加快运算效率。 综上所述,借助于强大的开源工具包——PyTorch,按照以上指导原则精心调参之后便能成功建立起一套高效稳定的手写数字识别解决方案[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值