pytorch(五)dropout

一、Dropout原理

1.概述
作用:防止过拟合
方法:训练时,随机停止某些神经元的参数训练
2. Dropout工作流程及使用
2.1 Dropout具体工作流程
假设我们要训练这样一个神经网络,如图2所示。

pytorch(五)dropout

图2:标准的神经网络

输入是x输出是y,正常的流程是:我们首先把x通过网络前向传播,然后把误差反向传播以决定如何更新参数让网络进行学习。使用Dropout之后,过程变成如下:

(1)首先随机(临时)删掉网络中一半的隐藏神经元,输入输出神经元保持不变(图3中虚线为部分临时被删除的神经元)

pytorch(五)dropout
图3:部分临时被删除的神经元

(2) 然后把输入x通过修改后的网络前向传播,然后把得到的损失结果通过修改的网络反向传播。一小批训练样本执行完这个过程后,在没有被删除的神经元上按照随机梯度下降法更新对应的参数(w,b)。

(3)然后继续重复这一过程:

. 恢复被删掉的神经元(此时被删除的神经元保持原样,而没有被删除的神经元已经有所更新)

. 从隐藏层神经元中随机选择一个一半大小的子集临时删除掉(备份被删除神经元的参数)。

. 对一小批训练样本,先前向传播然后反向传播损失并根据随机梯度下降法更新参数(w,b) (没有被删除的那一部分参数得到更新,删除的神经元参数保持被删除前的结果)。
2.2 Dropout在神经网络中的使用
Dropout的具体工作流程上面已经详细的介绍过了,但是具体怎么让某些神经元以一定的概率停止工作(就是被删除掉)?代码层面如何实现呢?

下面,我们具体讲解一下Dropout代码层面的一些公式推导及代码实现思路。

(1)在训练模型阶段

无可避免的,在训练网络的每个单元都要添加一道概率流程。
pytorch(五)dropout
图4:标准网络和带有Dropout网络的比较

对应的公式变化如下:

. 没有Dropout的网络计算公式:
pytorch(五)dropout
. 采用Dropout的网络计算公式:
pytorch(五)dropout
上面公式中Bernoulli函数是为了生成概率r向量,也就是随机生成一个0、1的向量。

代码层面实现让某个神经元以概率p停止工作,其实就是让它的激活函数值以概率p变为0。比如我们某一层网络神经元的个数为1000个,其激活函数输出值为y1、y2、y3、…、y1000,我们dropout比率选择0.4,那么这一层神经元经过dropout后,1000个神经元中会有大约400个的值被置为0。

注意: 经过上面屏蔽掉某些神经元,使其激活值为0以后,我们还需要对向量y1……y1000进行缩放,也就是乘以1/(1-p)。如果你在训练的时候,经过置0后,没有对y1……y1000进行缩放(rescale),那么在测试的时候,就需要对权重进行缩放,操作如下。

(2)在测试模型阶段

预测模型的时候,每一个神经单元的权重参数要乘以概率p。
pytorch(五)dropout
图5:预测模型时Dropout的操作
测试阶段Dropout公式:
pytorch(五)dropout
3.通过代码理解

# coding:utf-8
import numpy as np
 
# dropout函数的实现,函数中,x是本层网络的激活值。Level就是dropout就是每个神经元要被丢弃的概率。
def dropout(x, level):
    if level < 0. or level >= 1: #level是概率值,必须在0~1之间
        raise ValueError('Dropout level must be in interval [0, 1[.')
    retain_prob = 1. - level
 
    # 我们通过binomial函数,生成与x一样的维数向量。binomial函数就像抛硬币一样,我们可以把每个神经元当做抛硬币一样
    # 硬币 正面的概率为p,n表示每个神经元试验的次数
    # 因为我们每个神经元只需要抛一次就可以了所以n=1,size参数是我们有多少个硬币。
    random_tensor = np.random.binomial(n=1, p=retain_prob, size=x.shape) #即将生成一个0、1分布的向量,0表示这个神经元被屏蔽,不工作了,也就是dropout了
    print(random_tensor)
 
    x *= random_tensor
    print(x)
    x /= retain_prob
 
    return x
 
#对dropout的测试,大家可以跑一下上面的函数,了解一个输入x向量,经过dropout的结果  
x=np.asarray([1,2,3,4,5,6,7,8,9,10],dtype=np.float32)
dropout(x,0.4)

从论文解读:https://blog.csdn.net/stdcoutzyx/article/details/49022443
在BP网络的实现:https://blog.csdn.net/qq_28888837/article/details/84673884
完整代码:https://github.com/viki6666/Pytorch_learn/blob/master/dropout.ipynb

二、正则化

损失函数:系数选择要使得它们能最小化损失函数。
pytorch(五)dropout
Lasso 回归:L1
pytorch(五)dropout
在MNIST中对loss函数进行修改,添加正则项

#L1
        for param in net.parameters():
            regularization_loss += torch.sum(torch.abs(param))
        classify_loss = criterion(outputs, labels)
        loss = classify_loss + 0.01*regularization_loss

岭回归:L2
pytorch(五)dropout

#L2
        for param in net.parameters():
            regularization_loss += torch.sum((param**2))
        classify_loss = criterion(outputs, labels)
        loss = classify_loss + 0.01*regularization_loss

完整代码:https://github.com/viki6666/Pytorch_learn/blob/master/L1L2.ipynb

上一篇:深度学习中Dropout原理解析


下一篇:深度学习中Dropout原理解析