zoukankan      html  css  js  c++  java
  • CNN基础

    CNN一般结构

    卷积层作用:

    1. 提取不同维度的特征,组合不同维度特征,其本质是卷积核,因此,学习一个有效的总卷积核是训练卷积层主要工作
      2)寻找不同位置,不同大小的特征
    2. 根据卷积核参数计算上下层blob之前维度关系
    input => conv => output:
    out = (W-F+2*P)/S + 1
    W:input的尺寸
    F:kernel的尺寸
    S:步长
    P:padding的数量
    

    非线性层

    控制对不同特征特征信号所应当作出的反应
    如,RELU:

    [f(x)=max(0,x) ]

    1. 对低强度特征信息不做反应,超过阈值后,强度越大,反应相应越大
    2. 阈值一般为0,因此样本数据与特征也尽量零均值,这可能是训练数据归一化及batchnormalization的原因

    池化层

    1. 降采样:将高维特征稀疏为低维特征
      2)可以增强模型对特征畸变的鲁棒性,如手写数字笔记不工整

    dropout:

    打破网络的对称性,使网络结构不断重构,防止网络过拟合;
    具体实现直接看源码dropout_layer.cppdropout_layer.hpp
    前传过程中,bottom计算出的部分特征不参与前传过程的计算

    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();    //从cpu中取一段可读写的内存,返回指针mask
      const int count = bottom[0]->count();                               //mutable_cpu_data表示可读写的内存,而cpu_data表示只读内存
      if (this->phase_ == TRAIN) {
        // Create random numbers
        caffe_rng_bernoulli(count, 1. - threshold_, mask);    //将mask内容部分以伯努利概率置为0,置0的概率与threshold有关
        for (int i = 0; i < count; ++i) {
          top_data[i] = bottom_data[i] * mask[i] * scale_;    //用mask掩码将bottom_data中部分特征设为死结点,不参与前传中loss的计算
        }
      } else {
        caffe_copy(bottom[0]->count(), bottom_data, top_data);
      }
    }
    

    在反传过程中,上层梯度回传时至下层时,同样会一部分被mask屏蔽,而且这个maskg前传一致,保证了前传与反传过程看到的网络结构是一致的

    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();    //将前传时写入mask内容重新赋值mask指针
          const int count = bottom[0]->count();
          for (int i = 0; i < count; ++i) {
            bottom_diff[i] = top_diff[i] * mask[i] * scale_;    //同样,反传过程也屏蔽了部分梯度,这样在一次前传与反传过程中所看见的网络结构实际就相同了,                                                                              
          }                                                                         //得到bottom梯度后会给cpu或gpu进行solver的update
        } else {
          caffe_copy(top[0]->count(), top_diff, bottom_diff);
        }
      }
    }
    

    其中,mask初始化用到了一个 caffe_rng_bernoulli,在这篇文章中提到,其实它主要调用了boost::bernoulli_distribution,将向量初始化为一定比例的1其余为0

    参考

    dropout_layer

  • 相关阅读:
    298. Binary Tree Longest Consecutive Sequence
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    163. Missing Ranges
    336. Palindrome Pairs
    727. Minimum Window Subsequence
    211. Add and Search Word
    年底购物狂欢,移动支付安全不容忽视
    成为程序员前需要做的10件事
    全球首推iOS应用防破解技术!
  • 原文地址:https://www.cnblogs.com/fariver/p/6839665.html
Copyright © 2011-2022 走看看