dropout理解「建议收藏」

dropout理解「建议收藏」1.dropout解决的问题深度神经网络的训练是一件非常困难的事,涉及到很多因素,比如损失函数的非凸性导致的局部最优值、计算过程中的数值稳定性、训练过程中的过拟合等。过拟合是指模型训练到一定程度后,在测试集上得到的测试误差远大于在训练集上得到的误差。导致过拟合的主要原因有: 1.训练数据集太小 2.模型太复杂 3.过度训练2.dropoutdropout是指在训练一…

大家好,又见面了,我是你们的朋友全栈君。

1.dropout解决的问题

深度神经网络的训练是一件非常困难的事,涉及到很多因素,比如损失函数的非凸性导致的局部最优值、计算过程中的数值稳定性、训练过程中的过拟合等。

过拟合是指模型训练到一定程度后,在测试集上得到的测试误差远大于在训练集上得到的误差。

导致过拟合的主要原因有: 
1. 训练数据集太小 
2. 模型太复杂 
3. 过度训练

2.dropout

dropout是指在训练一个很大的神经网络时,它在每次迭代的过程中随机“关闭”一些神经元,被关闭的神经元在前向和反向传播中都不贡献作用,英文即是“dropout”的意思。如下图所示: 
dropout示意图 
我们看到图中打叉的神经元就是被“dropout”掉的神经元,和这些个神经元相连接的权重值也一并被“抹去”,不参与本次训练。不参与本次训练是说在当前的batch中,不参与训练,每个batch都会随机挑选神经元做dropout。

dropout为什么可以防止过拟合
dropout的解决方案,在每一次迭代的过程中,我们会随机dropout掉一些神经元(至于在那一层做dropout,需要看不同的情况),如果设置的dropout的值为0.8,则表示每个神经元有80%的概率被留下来,20%的概率被”抹去“。这就相当于我们从原来的神经网络中随机采样了80%的节点,组成了一个新的神经网络,这个是原来的神经网络的一个子网络,但是规模要比原来的神经网络小很多,并且训练代价也比较小。我们多次迭代优化,每次迭代优化都会做这样的”随机采样“,从原来的网络中构造一个子网络(sub-network),而每次构造的网络也都不尽相同,这样每个神经元对另一个特定神经元的激活很不敏感。这样参数就不会过分依赖于训练数据,增加了模型的泛化能力。

只在训练过程中使用dropout,在测试期间不使用dropout。因为在测试阶段,我们不期望输出结果是随机的,如果测试阶段应用了dropout,预测会受到干扰。

inverted dropout函数做法:举例神经网络 训练阶段前向传播第一层dropout

Z1=np.dot(W1,X)+b1  
A1=relu(Z1)
D1=np.random.rand(A1.shape[0],A2.shape[1]) 
D1=D1<keep_prop
A1=np.multiply(A1,D1) 
A1=A1/keep_prop #确保A1期望不变,这样测试阶段,没有dropout也没有影响
Z2=np.dot(A1,X)+b2
import numpy as np

def relu(x):

    s = np.maximum(0,x)
    
    return s

w1=[[1,2,3],[1,2,3],[4,5,6],[4,5,6]]
x=[[1,2],[1,2],[1,2]]
b=1
z1=np.dot(w1,x)+b
print(z1)

[[ 7 13]
 [ 7 13]
 [16 31]
 [16 31]]

a1=relu(z1)
d1=np.random.rand(a1.shape[0],a1.shape[1])
print(d1)

[[0.58695556 0.41508454]
 [0.16031604 0.24994934]
 [0.10260241 0.8237806 ]
 [0.28117361 0.8992166 ]]

d1=d1<0.8
print(d1)
[[ True  True]
 [ True  True]
 [ True False]
 [ True False]]

a1=np.multiply(a1,d1)
print(a1)
[[ 7 13]
 [ 7 13]
 [16  0]
 [16  0]]

a1=a1/0.8
print(a1)
[[ 8.75 16.25]
 [ 8.75 16.25]
 [20.    0.  ]
 [20.    0.  ]]

train 和 test 的时候,dropout的概率怎么设置:按照原始的论文中,假设dropout的值是 p%,原始神经网络的神经元个数是N,因为在训练的过程中只有 p% 的神经元被保留下来,相应也只有p%的需要被优化的权值保留下来,这导致dropout后sub-network的输出也是整个原始神经网络的输出值的p%。所以,在测试的是时候使用的整个神经网络,我们只需要将每一层的权值矩阵乘以p%就可以保证测试网络的输出期望和训练网络的输出期望值大小一致了。 

注意,如果你使用了tensorflow,则在测试的时候要保持dropout的值为1,即不”抹去“任何神经元。

为什么很少见CNN层加dropout: 这种情况确实不多见,典型的TextCNN模型,就是没有在卷积层加dropout。但是原始论文中确实又指出可以在卷积层做dropout ,只是收益并不是太明显。另外,dropout对于具有大量参数的全连接效果最好,而CNN的卷积层不是全连接,参数不是很多,所以效果不明显。论文还建议如果在CNN中加,最好是在开始的层加dropout,越往后的层,越是要小心加dropout。

神经网络加上dropout后,test loss 比 train loss还要小:正常,在不考虑测试集采样偏差的情况下,这种情况的解释是:每次train loss是在一个batch上计算的,而单个batch又是在一个通过dropout得到的sub-network计算得到的,即相当于在单颗树上得到的train loss;而测试的时候,用的整个神经网络,即相当于在整个”森林“上做预测,结果当然会好一下。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/133117.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • cmd下出现找不到或无法加载主类的问题

    cmd下出现找不到或无法加载主类的问题之前安装过 jdk 安装另一个版本的 jdk 配置环境后出现了找不到或无法加载主类的问题 经过相关资料查询 整理后有如下情况 其实这些情况都不是我遇到的 我遇到的写在最后 1 环境变量配置错误 如果 java 和 javac 指定能够顺利运行 cmd 中没有出现无法识别相关指令之类的提示 说明 path 路径配置正确 此时 运行 javac 后成功生成 class 文件 运行 java 类名时出现提示找不到或无法加载主类 说明 classpath 路径错误 classpath 是运行时搜索类的路径 包括 jdk 中的类的路径

    2025年12月7日
    6
  • 利用iframe技巧获取訪问者qq

    利用iframe技巧获取訪问者qq

    2021年12月9日
    58
  • JVM进阶(十一):JAVA G1收集器

    JVM进阶(十一):JAVA G1收集器JVM进阶(十一)——JAVAG1收集器  在前两篇博文中讲解了新生代和年老代的收集器,在本篇博文中介绍一个收集范围涵盖整个堆的收集器——G1收集器。先讲讲G1收集器的特点,他也是个多线程的收集器,能够充分利用多个CPU进行工作,收集方式也与CMS收集器类似,因此不会有太久的停顿。  虽然回收的范围是整个堆,但还是有分代回收的回收方式。在年轻代依然采用复制算法;年老代也同样采用“标记-清除

    2022年6月13日
    27
  • 如何简单运行Java程序

    如何简单运行Java程序本章开始,我们需要下苦功打基础,目标是完成一个会员管理系统哦!如何运行Java程序,用java命令即可,一定不要忘了写main方法哦,一个java文件里面可以写很多个class。步骤1java文件等于java类吗问大家一个问题,你认为java文件是java类吗?你可以用记事本写一个Demo.java的文本文件,编码是ansi,如果你的windows系统是简体中文的,那么所谓的ansi,其实就和GBK是一样的。在这个文件里,你可以写很多的class,但是声明为public的class只能有一个。

    2022年7月7日
    32
  • JS开发引用HTML DOM的location和document对象[通俗易懂]

    JS开发引用HTML DOM的location和document对象[通俗易懂]本文主要介绍报表软件FineReport的JavaScript开发中,可以访问并处理的HTMLDOM的location、document两种对象。

    2022年7月19日
    19
  • JS高级拖动技术 setCapture,releaseCapture

    JS高级拖动技术 setCapture,releaseCapture代码如下: window.onload=function(){ objDiv=document.getElementById(‘drag’); drag(objDiv); }; functiondrag(dv){ dv.onmousedown=function(e){ vard=document; e=e||window.event;

    2022年5月3日
    62

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号