Pytorch中的序列化容器-度消失和梯度爆炸-nn.Sequential-nn.BatchNorm1d-nn.Dropout

Pytorch中的序列化容器-度消失和梯度爆炸-nn.Sequential-nn.BatchNorm1d-nn.Dropout

1. 梯度消失和梯度爆炸

在使用pytorch中的序列化 容器之前,我们先来了解一下常见的梯度消失和梯度爆炸的问题

1.1 梯度消失    【梯度太小,无法进行参数的更新,梯度小到数据类型无法表示时出现NAN】

假设我们有四层极简神经网络:每层只有一个神经元

获取w1的梯度有:▽w1 = x1f(a1)’w2f(b1)’w3*▽out

假设我们使用sigmoid激活函数,即f为sigmoid函数,sigmoid的导数如下图

假设每层都取得sigmoid导函数的最大值1/4,那么在反向传播时,X1=0.5,w1=w2=w3=0.5​

\nabla w1< \frac{1}{2} * \frac{1}{4}* \frac{1}{2}* \frac{1}{4}\frac{1}{2}\nabla out == \frac{1}{2^7} \nabla out

当权重初始过小或使用易饱和神经元(sigmoid,tanh,) sigmoid在y=0,1处梯度接近0,而无法更新参数,时神经网络在反向传播时也会呈现指数倍缩小,产生“消失”现象。

 

1.2 梯度爆炸    【梯度太大,大到数据类型无法表示,出现NAN】

假设X2=2,w1=w2=w3=2​

\nabla w1 = f'{a}2f‘{a}*x2\nabla out = 2^3f'(a)^2 \nabla out

当权重初始过大时,梯度神经网络在反向传播时也会呈现指数倍放大,产生“爆炸”现象。

1.3 解决梯度消失或者梯度爆炸的经验   【1.使用更加容易计算梯度的激活函数 2.使用改进的优化算法 3.使用batch Normalization】

  1. 替换易训练神经元

  1. 改进梯度优化算法:使用adam等算法

  2. 使用batch normalization

 

2. nn.Sequential

nn.Sequential是一个有序的容器,其中传入的是构造器类(各种用来处理input的类),最终input会被Sequential中的构造器类依次执行

例如:

layer = nn.Sequential(
            nn.Linear(input_dim, n_hidden_1), 
            nn.ReLU(True), #inplace=False 是否对输入进行就地修改,默认为False
            nn.Linear(n_hidden_1, n_hidden_2),
            nn.ReLU(True),
            nn.Linear(n_hidden_2, output_dim) # 最后一层不需要添加激活函数
             )

在上述过程中,可以直接调用layer(x),得到输出

x的被执行顺序就是Sequential中定义的顺序:

  1. 被隐层1执行,形状变为[batch_size,n_hidden_1]

  2. 被relu执行,形状不变

  3. 被隐层2执行,形状变为[batch_size,n_hidden_2]

  4. 被relu执行,形状不变

  5. 被最后一层执行,形状变为[batch_size,output_dim]

 

3. nn.BatchNorm1d  【加速模型的训练,把参数进行规范化的处理,让参数计算的梯度不会太小】

batch normalization 翻译成中文就是批规范化,即在每个batch训练的过程中,对参数进行归一化的处理,从而达到加快训练速度的效果。

以sigmoid激活函数为例,他在反向传播的过程中,在值为0,1的时候,梯度接近0,导致参数被更新的幅度很小,训练速度慢。但是如果对数据进行归一化之后,就会尽可能的把数据拉倒[0-1]的范围,从而让参数更新的幅度变大,提高训练的速度。

batchNorm一般会放到激活函数之后,即对输入进行激活处理之后再进入batchNorm

layer = nn.Sequential(
            nn.Linear(input_dim, n_hidden_1),
    		
            nn.ReLU(True), 
    		nn.BatchNorm1d(n_hidden_1)
    
            nn.Linear(n_hidden_1, n_hidden_2),
            nn.ReLU(True),
    		nn.BatchNorm1d(n_hidden_2)

            nn.Linear(n_hidden_2, output_dim) 
             )

4. nn.Dropout

dropout在前面已经介绍过,可以理解为对参数的随机失活

  1. 增加模型的稳健性

  2. 可以解决过拟合的问题(增加模型的泛化能力)

  3. 可以理解为训练后的模型是多个模型的组合之后的结果,类似随机森林。

layer = nn.Sequential(
            nn.Linear(input_dim, n_hidden_1),
            nn.ReLU(True), 
    		nn.BatchNorm1d(n_hidden_1)
    		nn.Dropout(0.3) #0.3 为dropout的比例,默认值为0.5
    
            nn.Linear(n_hidden_1, n_hidden_2),
            nn.ReLU(True),
    		nn.BatchNorm1d(n_hidden_2)
    		nn.Dropout(0.3)
    
            nn.Linear(n_hidden_2, output_dim) 
             )

 

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这些代码定义了一个名为`CNN`的神经网络类,这个类继承自PyTorch的`nn.Module`类。这个类包含了四个卷积层和一个全连接层。 - `layer1`是一个由三个子层组成的序列,它的输入大小为`(batch_size, 1, seq_len)`,输出大小为`(batch_size, 4, seq_len)`。 - `layer2`是一个由三个子层组成的序列,它的输入大小为`(batch_size, 4, seq_len)`,输出大小为`(batch_size, 8, seq_len)`。 - `layer3`是一个由三个子层组成的序列,它的输入大小为`(batch_size, 8, seq_len)`,输出大小为`(batch_size, 8, seq_len)`。 - `layer4`是一个由四个子层组成的序列,它的输入大小为`(batch_size, 16, seq_len)`,输出大小为`(batch_size, 32, seq_len/2)`。 这些卷积层的输出都是1维张量。其,`nn.Conv1d`表示1维卷积层,`nn.BatchNorm1d`表示1维批量归一化层,`nn.ReLU`表示ReLU激活函数层,`nn.Dropout`表示随机失活层,`nn.MaxPool1d`表示1维最大池化层。这些层的作用分别是提取特征、标准化特征、引入非线性、随机失活以防止过拟合和下采样。 接下来,`conv_last`定义了一个1维卷积层,它的输入大小为`(batch_size, 8, seq_len/2)`,输出大小为`(batch_size, 1, seq_len/2)`。这个层用于将卷积层的输出转化为一个单一的值。 最后,`fc`定义了一个全连接层,它的输入大小为10,输出大小为1。`gamma`是一个可学习的参数,用于控制模型的输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值