Dropout[通俗易懂]

Dropout[通俗易懂]参数正则化方法Dropout受人类繁衍后代时男女各一半基因进行组合产生下一代的启发,论文("Dropout:ASimpleWaytoPreventNeuralNetwor

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

参数正则化方法 – Dropout

受人类繁衍后代时男女各一半基因进行组合产生下一代的启发,论文(Dropout: A Simple Way to Prevent Neural Networks from Overfitting)提出了Dropout。

Dropout是一种在深度学习环境中应用的正规化手段。它是这样运作的:在一次循环中我们先随机选择神经层中的一些单元并将其临时隐藏,然后再进行该次循环中神经网络的训练和优化过程。在下一次循环中,我们又将隐藏另外一些神经元,如此直至训练结束。
在训练时,每个神经单元以概率p被保留(dropout丢弃率为1-p);在测试阶段,每个神经单元都是存在的,权重参数w要乘以p,成为:pw。测试时需要乘上p的原因:考虑第一隐藏层的一个神经元在dropout之前的输出是x,那么dropout之后的期望值是\(E=px + (1-p)0\) ,在测试时该神经元总是激活,为了保持同样的输出期望值并使下一层也得到同样的结果,需要调整\(x \rightarrow px\). 其中p是Bernoulli分布(0-1分布)中值为1的概率。示意图如下:

dropout train/test nooverfit.com/wp/wp-content/uploads/2016/07/QQ%E6%88%AA%E5%9B%BE20160729103207.png

inverted dropout

在训练时由于舍弃了一些神经元,因此在测试时需要在激励的结果中乘上因子p进行缩放.但是这样需要需要对测试的代码进行更改并增加了测试时的计算量,非常影响测试性能。通常为了提高测试的性能(减少测试时的运算时间),可以将缩放的工作转移到训练阶段,而测试阶段与不使用dropout时相同,称为 **inverted dropout **:将前向传播dropout时保留下来的神经元的权重乘上1/p(看做惩罚项,使权重扩大为原来的1/p倍,这样测试时不用再缩小权重),代码参考这里。
在架构中添加inverted Dropout这一改动仅会影响训练过程,而并不影响测试过程。

drop的比例常用值是p=0.5 .
Dropout率和正规化有什么关系?我们定义Dropout率为保留一个神经元为激活状态的概率.Dropout率越高,意味着更多神经元是激活的,正规化程度越低.

dropout

Dropout可以与Max-norm regularization,较大的初始学习率和较高的动量(momentum)等结合获得比单独使用Dropout更好的效果。由于Max-norm regularization的应用,设置较大的学习率不至于发生梯度爆炸。

Dropout对于循环层效果并不理想,你可能需要稍微修改一下dropout技术来得到良好的结果。

在dropout的过程中,神经元被失活,在dropconnect的过程中,失活的是神经元之间的连接。所以dropout会使输入和输出权重都变为无效,而在dropconnect中,只有其中一种会被失活。

Dropout可以看作是Bagging的极限形式,每个模型都在当一种情况训练,同时模型的每个参数都经过与其他模型共享参数,从而高度正则化。

AlphaDropout

Alpha Dropout是一种保持输入均值和方差不变的Dropout,该层的作用是通过缩放和平移使得在dropout时也保持数据的自规范性。Alpha Dropout与SELU激活函数配合较好。更多细节参考论文Self-Normalizing Neural Networks.

代码实现

caffe dropout_layer 代码如下:

// LayerSetUp
DCHECK(threshold_ > 0.);
DCHECK(threshold_ < 1.);
scale_ = 1. / (1. - threshold_);
// forward
void DropoutLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
    const vector<Blob<Dtype>*>& top) {
  const Dtype* bottom_data = bottom[0]->cpu_data();
  Dtype* top_data = top[0]->mutable_cpu_data();
  unsigned int* mask = rand_vec_.mutable_cpu_data();
  const int count = bottom[0]->count();
  if (this->phase_ == TRAIN) {
    // 产生01掩码,伯努利随机数
    caffe_rng_bernoulli(count, 1. - threshold_, mask);
    for (int i = 0; i < count; ++i) {
      // 丢弃部分置0,保留部分按inverted dropout需要放大scale_倍
      top_data[i] = bottom_data[i] * mask[i] * scale_;
    }
  } else { // 测试阶段原样输出
    caffe_copy(bottom[0]->count(), bottom_data, top_data);
  }
}

//backward
void DropoutLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
    const vector<bool>& propagate_down,
    const vector<Blob<Dtype>*>& bottom) {
  if (propagate_down[0]) {
    const Dtype* top_diff = top[0]->cpu_diff();
    Dtype* bottom_diff = bottom[0]->mutable_cpu_diff();
    if (this->phase_ == TRAIN) {
      const unsigned int* mask = rand_vec_.cpu_data();
      const int count = bottom[0]->count();
      for (int i = 0; i < count; ++i) {
        bottom_diff[i] = top_diff[i] * mask[i] * scale_;
      }
    } else {
      caffe_copy(top[0]->count(), top_diff, bottom_diff);
    }
  }
}

可以进一步阅读的论文有:

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

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

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


相关推荐

  • java中Scanner类用法的详解[通俗易懂]

    java中Scanner类用法的详解[通俗易懂] 一  java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入。首先要导入包  import java.util.Scanner;Scanner类的创建对象:   Scanner S=newScanner(System.in);   方法基本格式  hasNextXxx()  判断是否还有下一个输入项,其中Xxx可以是Int,…

    2022年7月7日
  • CoInitialize浅析一

    CoInitialize浅析一大家都知道程序中若要使用COM组件则必需要先调用CoInitialize,该函数主要是用来初始化COM执行环境。但这个函数的作用域是以线程为单位还是以进程为单位呢?或许大家已经通过測试程序摸索出答案,

    2022年7月3日
  • 阿里云服务器中了挖矿程序应该如何清除「建议收藏」

    阿里云服务器中了挖矿程序应该如何清除「建议收藏」阿里云服务器中了挖矿程序如何处理?云安全中心安全告警短信提醒云服务器中了挖矿程序怎么处理?护云盾来详细说下阿里云服务器挖矿程序的解决方法,一种是使用云安全中心自动处理,另一种方式是自行手动清除。阿里云服务器挖矿程序解决方法如果你的阿里云服务器中了挖矿程序,你有两种处理方式,一种是使用云安全中心自动清理,另一种是手动清除:云安全中心处理挖矿程序1、登录到云安全中心控制台2、左侧栏,选择“威胁检测”–“安全告警处理”在安全告警处理列表中,找到挖矿程序,然后点“处理”云安全中心安

    2022年6月22日
  • pip怎么卸载安装包_python pip升级

    pip怎么卸载安装包_python pip升级pip卸载安装的所有python包

    2022年10月19日
  • JavaScript 时间戳格式化日期

    JavaScript 时间戳格式化日期JavaScript时间戳格式化日期项目中从后台获取接口数据时常需要按自己的需求将时间戳转化为对应的日期格式。//时间戳格式化为日期functionformatDate(timestamp,fmt){//这里传入的timestamp应该是Number数值,如果是字符串,需要先转换为Number//vartimestamp=parseInt(timestamp)vardate=newDate(timestamp)if(/(y+)/.tes

    2022年10月27日
  • java实现闰年判断

    java实现闰年判断要求:给定一个年份,判断这一年是不是闰年。当以下情况之一满足时,这一年是闰年:1、年份是4的倍数而不是100的倍数;2、年份是400的倍数。其他的年份都不是闰年。输入:输入包含一个整数y,表示当前的年份。输出:输出一行,如果给定的年份是闰年,则输出yes,否则输出no。importjava.util.Scanner;publicclassMain{ publicstaticvoidmain(String[]args){ Scanneri..

    2022年7月17日

发表回复

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

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