Dropout层到底在干些什么(Pytorch实现)

2023-10-26

一、基本概念

1.正则化(Regularization):通过对问题的求解目标增加一定的先验限制或约束,引导问题的求解。
2.过拟合(Overfitting):指所得网络泛化能力差,表现为网络训练误差小,测试误差大,网络在训练集上表现极好,而在测试集上表现一般甚至很差。
3.伯努利分布(Bernoulli distribution):对于随机变量X,有参数p(0<p<1),分别以概率p、1-p取1、0为值。记为X~B(1,p),表示一次伯努利实验中X为1的概率为p。
4.Dropout通过对其输入进行一定概率的“舍弃”起到一种正则化的作用,可有效缓解网络过拟合。

二、Dropout工作原理

1.Dropout工作流程

在这里插入图片描述
对于一个正常的全连接网络而言,当前层每个神经元的值由前一层所有神经元共同决定,对于输入X,沿着网络前向传播,然后将误差回传,以此更新神经元之间的权重以及偏置参数。
当我们对其中的隐藏层使用Dropout后,隐藏层中的神经元以一定概率“睡眠”,通过对其随机置零实现,其更新参数的过程也发生了一些改变,具体地,过程如下:
(1)网络首先按照一定概率将隐藏层中的部分神经元随机置零,此时这些神经元将暂时处于“睡眠”状态;
(2)输入X沿着网络前向传播,然后通过误差回传更新神经元参数,需要注意的是此时只有未被“置零”的神经元参数被更新,处于“睡眠”状态的神经元参数与上一次参数更新的结果保持一致;
(3)将隐藏层所有神经元激活,此时之前未被“睡眠”的部分神经元参数得到更新,“睡眠”状态的神经元参数与上一次更新结果保持一致,然后重复(1)、(2)步骤;

2.Dropout如何缓解过拟合

之前在解决过拟合问题时,一般会采用“模型集成”的方法,在训练数据上训练多个模型,然后在测试数据上对这些模型采用一定的策略(投票法、平均法等)进行组合集成,以此对训练好的多个模型“取长补短”,使得最终模型拥有更好的泛化能力,缓解过拟合情况的发生。但是模型集成带来很直接的缺陷就是极其耗时以及过高的算力需求。
《Improving neural networks by preventing co-adaptation of feature detectors》一文中提出Dropout通过对隐藏层部分神经元随机置零的方式去缓解过拟合,并且也不用进行耗时的模型集成。正如这篇文章题目中所提到的“通过防止特征检测器之间的协同适应去改进神经网络”,Dropout可以从两个方面去缓解过拟合:
1)防止特征检测器之间的共适应关系:在隐藏层之间利用Dropout操作可使不同隐藏层之间的部分神经元之间断开连接,在每一批次数据进行训练的时候这些神经元不一定会同时激活。如此操作可使网络参数的更新不必完全依赖标准网络中存在特定连接关系的神经元之间的共同作用,以此使网络学习更鲁棒的特征。比如在标准全连接网络中判断一个物品是否是西瓜时,必须同时具备球体、绿色、有瓜蒂等特征,而采用Dropout操作训练的网络可以在缺失某些特征时也能准确预测结果。
2)类似采用平均法进行模型集成:Dropout操作对隐藏层中的神经元随机“丢弃”,每批次数据Dropout丢弃的神经元并不固定,这就导致此时的网络结构是不同的,所以进行网络训练时其实就相当于在训练不同的网络,整个网络训练过程就好比对不同的网络模型进行平均法集成,以此得到更好的泛化能力,有效缓解过拟合。

3.Dropout实际实现

在进行代码实现时,实际是通过控制神经元的激活值是否置零实现,而置零操作通过伯努利分布随机生成0或1向量,将此向量与标准网络的神经元输出相乘,此时部分神经元的输出则被成功置零。比如,原始输出为y1=1,y2=2,此时与之对应生成向量r1=1,r2=0,将他们对应相乘则得到此时的输出y1’=1,y2’=0。
在这里插入图片描述
图中分别展示有无Dropout时对于黄色神经元输出结果的变化:
1)无dropout
z1=w1y1+w2y2
2)有dropout

  • 利用伯努利分布以一定概率随机生成0、1向量:r1、r2;
  • 随机置零操作:y1’=y1*r1、y2’=y2*r2;
  • z1=w1y1’+w2y2’;

三、Pytorch实现

1.实际实现方式(训练模式下)

1)以概率p随机将输入张量中的元素置零,并且对于多通道输入,每个通道的置零操作是独立的;
在这里插入图片描述
2)然后对其输出结果乘以1/(1-p)进行缩放;
在这里插入图片描述
这里对为什么要对Dropout的输出还要进行缩放进行解释:
首先需要明确在Pytorch实现Dropout时,其参数p是对部分神经元输出值进行置零的概率。因为Dropout在网络训练和评估时表现是不一样的,其在网络训练模式下以概率p对隐藏层部分神经元的输出随机置零,而在网络评估时是直接进行一致性映射,也就是直接对输入进行输出,不做操作,所以为了保证隐藏层神经元在训练和评估模式下输出结果的期望是一致的,我们需要在训练时对Dropout的输出结果进行缩放,并且缩放因子必须是1/(1-p)(后面的代码示例也证实了这一点)
假设标准网络中隐藏层神经元输出为Y,故期望为E(Y)=Y,
在采用Dropout之后,若不进行缩放,则期望变为:
在这里插入图片描述
要想采用Dropout前后,神经元输出结果的期望保持不变,则需要对其输出进行缩放,如此期望即可保持不变:
在这里插入图片描述

2.调用方式

  • 输入为任意形状的数据,输出形状与输入保持一致;
torch.nn.Dropout(p=0.5, inplace=False)

3.参数解析

参数名 含义
p 以概率p随机将输入张量中元素置零,通常取p=0.5效果最好
inplace 默认inplace=False,当inplace=True时表示使用Dropout层的输出结果替换原本输入张量在内存中位置处存储的数据(其实就是使用输出结果在内存中覆盖输入)。

1)关于参数p
在这里插入图片描述
此处的p与伯努利分布中的参数p是有区别的:此处p是指以p概率将部分元素随机置零;而伯努利分布中随机变量以概率p取1为值。
2)关于inplace
在这里插入图片描述
可使用函数id(x)查看inplace在不同设置下,其输入和输出变量在内存中的地址是否一致验证inplace的作用,测试代码:
在执行Dropout之前以及之后均打印输入张量以及其对应的内存地址:

import torch
import torch.nn as nn


inp=torch.ones(size=(1,10),dtype=torch.float32)
print(id(inp))
print(inp)
print(inp.shape)
print('-'*25)


class TestDemo(nn.Module):
    def __init__(self):
        super(TestDemo, self).__init__()
        self.drop=nn.Dropout(p=0.5,inplace=False)

    def forward(self,x):
        return self.drop(x)


out=TestDemo()(inp)
print(out)
print(out.shape)
print(id(out))
print('-'*25)
print(id(inp))
print(inp)
print(inp.shape)
print('-'*25)
inplace=True
2566402092704
tensor([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
torch.Size([1, 10])
-------------------------
tensor([[0., 0., 0., 0., 2., 2., 0., 2., 0., 2.]])
torch.Size([1, 10])
2566402092704
-------------------------
2566402092704
tensor([[0., 0., 0., 0., 2., 2., 0., 2., 0., 2.]])
torch.Size([1, 10])
-------------------------
inplace=False
2107016691504
tensor([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
torch.Size([1, 10])
-------------------------
tensor([[0., 0., 2., 2., 0., 2., 0., 0., 2., 0.]])
torch.Size([1, 10])
2107016690640
-------------------------
2107016691504
tensor([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
torch.Size([1, 10])
-------------------------

上面的测试结果可看到,当inplace=True时,输出向量直接原地替换原始输入,这样做可以节省内存,而当inplace=False时,输出变量和输入变量均有自己的一块内存存储数据。

4.实例

在这里插入图片描述
注意Dropout在网络处于训练还是评估模式下,执行结果是有区别的:训练时,Dropout会以p概率对部分神经元值置零;评估时,Dropout不会对神经元进行操作,可以忽略。

inp=torch.ones(size=(1,10),dtype=torch.float32)
print(inp)
print(inp.shape)
print('-'*25)


class TestDemo(nn.Module):
    def __init__(self):
        super(TestDemo, self).__init__()
        self.drop=nn.Dropout(p=0.5,inplace=False)

    def forward(self,x):
        return self.drop(x)


model=TestDemo()
model.train()   # 设置网络为训练模式
out=model(inp)
print(out)
print(out.shape)
print('-'*25)

model.eval()   # 设置网络为评估模式
out=model(inp)
print(out)
print(out.shape)
tensor([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
torch.Size([1, 10])
-------------------------
model.train():训练模式
tensor([[0., 0., 0., 2., 0., 2., 2., 2., 2., 2.]])
torch.Size([1, 10])
-------------------------
model.eval():评估模式
tensor([[1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
torch.Size([1, 10])
-------------------------

由上面测试结果可证实:Dropout层在网络训练模式和评估模式下表现不同,当处于评估模式时,Dropout不会对输入进行操作,直接输出一个一致性映射结果。此外,可以观察一下训练模式下的输出结果,Dropout首先对其输入进行部分置零,得到由0,1构成的输出;然后对该输出进行缩放因子为1/(1-p)=1/(1-0.5)=2的缩放得到由0,2构成的最终输出

5.Dropout1d和Dropout2d

除了上面的nn.Dropout,Pytorch针对不同维度的张量分别更细致地实现了对应的Dropout1d和Dropout2d,在这里我也简单说一下:
1)nn.Dropout1d通常接在nn.Conv1d后面,用于一维张量的处理;输入形状为(N,C,L)或(C,L),输出结果与之对应。
2)nn.Dropout2d通常接在nn.Conv2d后面,用于二维张量的处理;输入形状为(N,C,H,W)或(N,C,L),输出结果与之对应)。
nn.Dropout2d为啥不支持(C,H,W)这是版本迭代中的历史遗留问题,更多参见Pytorch官网:https://pytorch.org/docs/stable/nn.html,不过我们进行网络训练时图像数据形状一般都是(N,C,H,W),所以也可以忽略这个点。

参考:

(1)https://zhuanlan.zhihu.com/p/38200980
(2)《Improving neural networks by preventing
co-adaptation of feature detectors》:https://arxiv.org/pdf/1207.0580.pdf

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Dropout层到底在干些什么(Pytorch实现) 的相关文章

随机推荐

  • SQL IF语句实际应用--返回输出

    SQL IF语句输出 SQL IF语句我们有时会用到用到这个通常是对某个属性进行判断操作 类似我们编程那种三元表达式一样 但有时候业务上不会让你去简简单单去判断操作 还会让你把结果返回过去 通过接口展示出去在前端 你写一个带有if的查询结果
  • B tree、B- tree、B+ tree、B*tree

    目录 1 B tree B tree 2 B tree B 树 2 1为什么需要B 树 B 树比B树更好呢 2 1数据库索引采用B 树的主要原因 3 B tree B 树 4 小结 1 B tree B tree B树 B tree 是一种
  • Pytorch-GPU配置

    自己电脑Window 10下pytorch GPU的配置 CUDA 10 1 cuDNN v7 6 4 pytorch 1 4 参考 1 Windows10安装cuda cudnn pytorch jupyter fastai 2 wind
  • C#系列-基础

  • 理解广度优先遍历(持续更新)

    文章的目录如下方便翻阅 广度优先搜索 BFS 如何实现广度优先搜索 简单的描述广度优先搜索的大致过程 下面结合例题理解广度优先搜索 广度优先遍历在树中的应用 广度优先遍历在数组中的应用 last 广度优先搜索 BFS 如何理解广度优先搜索
  • 传统图像处理算法总结

    1 图像滤波 目的 保证图像细节特征的条件下抑制图像噪声 1 1 线性滤波 1 11 方框滤波 原图像与内核的系数加权求和 方框滤波的核 normalize true 时 方框滤波就变成了均值滤波 也就是说 均值滤波是方框滤波归一化 nor
  • 【Java】【排序算法】【冒泡排序】(代码示例)

    文章目录 冒泡排序概念 冒泡排序的实现步骤如下 以下是冒泡排序的Java实现代码 总结 冒泡排序概念 冒泡排序 Bubble Sort 是一种简单的排序算法 它重复地遍历待排序的列表 每次比较相邻的两个元素 并交换它们的位置 直到整个列表排
  • Docker 如何保存对容器的修改

    1 docker ps 查看正在运行的容器 2 docker exec it d81abcfd2e3b bash 进入正在运行的容器内 3 进入容器后 就可以修改镜像了 比如修改镜像中已经部署的代码或者安装新的软件或包等 修改完成之后 ex
  • 【Hibernate】Hibernate.cfg.xml配置文件详解

    Hibernate配置文件主要用于配置数据库连接和Hibernate运行时所需的各种属性 这个配置文件应该位于应用程序或Web程序的类文件夹 classes中 Hibernate配置文件支持两种形式 一种是xml格式的配置文件 另一种是Ja
  • linux下安装Tkinter及python升级

    1 首先安装Tkinter模块 yum y install tkinter 在python下运行import Tkinter发现正确 但是使用的是默认版的python2 4 3 5 再次运行import Tkinter后报错 Type he
  • java中的输入输出

    java与C语言和C 不同 java的输入输出比较复杂 下面我将来介绍一下java的输入输出 输出 java中有三种方法进行输出 class Main public static void main String args System o
  • iview table使用自定义按钮取消某个选中的单项

    实现效果 选中选项后然后弹出选中的选项框 点击删除按钮删除某一个选项 table中的选中状态也随之变化 ivew坑 给data设置 checked其实对table上的checkBox并没有作用 用js给data数据设置该属性并没有作用 具体
  • 标准的遗传算法求函数最大值

    最近看了下遗传算法 刚看了一点 就觉得手痒 非要把程序编制出来看看效果 我现在总认为那些理论再高深 无法用计算机实现就是空话 呵呵 下面是我调试了好久的代码 无赖没有学过数据结构 算法 程序写的很差 单效果还是出来了 高兴 和大家共同分享下
  • ipmitool工具的安装遇到的问题

    1 从https gitee com mirrors ipmitool git下载ipmitool源码 https gitee com mirrors ipmitool git 因为官网的下载速度比较慢 推荐使用gitee下载 2 进行编译
  • python练习题之

    本文来源于公众号 csdn2299 喜欢可以关注公众号 程序员学府 安装Tornado 省事点可以直接用grequests库 下面用的是tornado的异步client 异步用到了tornado 根据官方文档的例子修改得到一个简单的异步爬虫
  • android 打砖块教程,少儿编程教程:设计打砖块游戏。

    凤县微课堂 你我共成长 愿以此小小的平台 助你成就更好的自己 第二百零七期 少儿编程教程 第5讲 设计打砖块游戏 创建一个小球的角色 在运动选项中选择 碰到边缘就反弹 当角色运动到窗口的边缘 就会反弹运动 在控制选项中选择重复执行 并在运动
  • 五线谱音名和组别对照表_五线谱简谱对照表

    五线谱与钢琴对照表 五线谱与钢琴对照表 一 以下图示五条线 就是五线谱 分一 二 三 四 五条线 二 五条线中间的空白处为间 共有四间 三 放在五线谱开头 分别为高音谱号和低音谱号 四 五线谱 简谱音阶对照示意图 五 简谱唱法与五线谱的音名
  • 网页搜索指定网站内容site

    查询资料时指定查询某一个网站使用 site 参数site空格 指定网站域名 搜索内容 例如 site csdn php
  • 华为OD机试 - 两数之和绝对值最小(Java)

    题目描述 给定一个从小到大的有序整数序列 存在正整数和负整数 数组 nums 请你在该数组中找出两个数 其和的绝对值 nums x nums y 为最小值 并返回这个绝对值 每种输入只会对应一个答案 但是 数组中同一个元素不能使用两遍 输入
  • Dropout层到底在干些什么(Pytorch实现)

    Dropout 一 基本概念 二 Dropout工作原理 1 Dropout工作流程 2 Dropout如何缓解过拟合 3 Dropout实际实现 三 Pytorch实现 1 实际实现方式 训练模式下 2 调用方式 3 参数解析 4 实例