[Caffe]: 关于dropout的实现细节

本文深入解析了Dropout层的工作原理及其实现细节。通过查阅Caffe源码,详细阐述了Dropout层如何在训练阶段利用伯努利分布生成mask矩阵,并应用于前向传播和后向传播的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dropout

关于Dropout的博文网上很多,今晚同学问了我关于Dropout具体是怎么实现的,一时答不出来。
然后就查看了下Caffe的源码,代码思路很清晰,很简洁。

思路

前向: 训练时,利用伯努利分布,随机出一个只包含0,1的mask矩阵,然后利用这个mask去对应乘上每个输入,得到的就是Dropout后的结果;测试时,Dropout并不起作用。
后向:训练时,根据mask来求对应梯度;测试时,与无Dropout一致。

参数

message DropoutParameter {
  // dropouot_ratio 即伯努利分布中p的值,源码中根据1-p的概率选取0,使特征失效
  optional float dropout_ratio = 1 [default = 0.5]; // dropout ratio
}

代码

template <typename Dtype>
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) {
    // Create random numbers
    caffe_rng_bernoulli(count, 1. - threshold_, mask); // Important,
    for (int i = 0; i < count; ++i) {
      top_data[i] = bottom_data[i] * mask[i] * scale_;
    }
  } else {
    caffe_copy(bottom[0]->count(), bottom_data, top_data);
  }
}

template <typename Dtype>
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);
    }
  }
}

反思

Dropout用了这么久,却没有注意到具体是怎么实现的,这是学习上的疏忽。
以后对自己用到的每一种网络层都需要了解原理,明白实现细节。


2017.09.03 记

### Prompt Dropout 的概念及其在自然语言处理中的作用 Prompt Dropout 是一种用于提升模型泛化能力的技术,主要应用于基于提示的学习(Prompt-based Learning)。它通过对输入的提示部分引入随机丢弃机制,使得模型能够在训练过程中适应不同的提示形式,从而提高其鲁棒性和泛化性能[^1]。 #### 提示学习背景 提示学习是一种新兴的范式,特别是在大规模预训练语言模型中得到了广泛应用。在这种方法下,模型通过特定设计的提示(Prompt)来引导生成目标输出。然而,固定的提示可能会导致模型过拟合于特定的形式,降低其在多样场景下的表现。因此,Prompt Dropout 被提出作为一种缓解这一问题的方法[^2]。 #### Prompt Dropout实现方式 Prompt Dropout 的核心思想是在每次前向传播,以一定概率随机移除或替换提示的一部分内容。这种操作可以通过以下几种方式进行: 1. **单词级别的丢弃** 随机选择提示中的某些单词并将其删除,或者替换成特殊的标记符(如 `[MASK]` 或其他占位符),以便模型学会依赖上下文而非固定模式[^3]。 2. **短语级别的扰动** 对提示中的短语结构进行重新排列或替换,增加模型对不同表达形式的理解能力[^4]。 3. **模板多样化** 使用多种模板表示同一任务逻辑,并在训练期间动态切换这些模板,使模型能够更好地捕捉任务的本质特征而不是具体表述[^5]。 以下是 Python 实现 Prompt Dropout 的简单代码示例: ```python import random def apply_prompt_dropout(prompt, dropout_rate=0.2): words = prompt.split() masked_words = [ "[MASK]" if random.random() < dropout_rate else word for word in words ] return " ".join(masked_words) # 示例调用 original_prompt = "The capital of France is Paris" dropped_prompt = apply_prompt_dropout(original_prompt, dropout_rate=0.3) print(dropped_prompt) ``` #### 技术优势与局限性 - **优势** - 增强了模型对于提示变化的容忍度,提高了跨域迁移的能力[^6]。 - 减少了因过度优化单一提示而导致的风险,提升了整体稳定性[^7]。 - **局限性** - 如果参数设置不当,可能导致有效信息丢失过多,影响收敛速度甚至最终效果[^8]。 - 计算开销相对较大,尤其是在复杂提示结构的情况下需要额外的间成本来进行采样和调整[^9]。 ### 总结 Prompt Dropout 是一项重要的技术创新,尤其适合那些高度依赖提示构建的任务环境。尽管存在一些潜在缺陷,但它无疑为当前 NLP 社区提供了一种有效的工具来改善大型语言模型的表现力和适用范围。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值