代码先锋网 代码片段及技术文章聚合

max pooling in caffe

技术标签: caffe  pooling

我们来看max pooling 在caffe 中怎么实现的吧

reshape

首先 reshap的时候:

  // If max pooling, we will initialize the vector index part.
  if (this->layer_param_.pooling_param().pool() ==
      PoolingParameter_PoolMethod_MAX && top.size() == 1) {
    max_idx_.Reshape(bottom[0]->num(), channels_, pooled_height_,
        pooled_width_);
  }

如是max pooling 则需要reshape max_idx 用来记录每次max pooling是 提取哪个地方的位置。
大小为num×channel×pooled_height×pooled_width

forward

再看forward:

case PoolingParameter_PoolMethod_MAX:
    // Initialize 如果top有两个分支,就有top_mask 没研究这个。遇到再说,目前是进else分支
    if (use_top_mask) {
      top_mask = top[1]->mutable_cpu_data();
      caffe_set(top_count, Dtype(-1), top_mask);
    } else {
    //get 到 max_idx_的指针
      mask = max_idx_.mutable_cpu_data();
      caffe_set(top_count, -1, mask);
    }
    //top_data 全部变成大浮点数的相反数。方便后面的取max运算
    caffe_set(top_count, Dtype(-FLT_MAX), top_data);
    // The main loop 找最大值
    for (int n = 0; n < bottom[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < pooled_height_; ++ph) {
          for (int pw = 0; pw < pooled_width_; ++pw) {
            int hstart = ph * stride_h_ - pad_h_;
            int wstart = pw * stride_w_ - pad_w_;
            int hend = min(hstart + kernel_h_, height_);
            int wend = min(wstart + kernel_w_, width_);
            hstart = max(hstart, 0);
            wstart = max(wstart, 0);
            const int pool_index = ph * pooled_width_ + pw;
            for (int h = hstart; h < hend; ++h) {
              for (int w = wstart; w < wend; ++w) {
                const int index = h * width_ + w;
                if (bottom_data[index] > top_data[pool_index]) {
                  top_data[pool_index] = bottom_data[index];
                  if (use_top_mask) {
                    top_mask[pool_index] = static_cast<Dtype>(index);
                  } else {
                    mask[pool_index] = index;
                  }
                }
              }
            }
          }
        }
        // compute offset 移动指针位置
        bottom_data += bottom[0]->offset(0, 1);
        top_data += top[0]->offset(0, 1);
        if (use_top_mask) {
          top_mask += top[0]->offset(0, 1);
        } else {
          mask += top[0]->offset(0, 1);
        }
      }
    }
    break;

其中offset函数是这样定义的:

  inline int offset(const int n, const int c = 0, const int h = 0,
      const int w = 0) const {
    CHECK_GE(n, 0);
    CHECK_LE(n, num());
    CHECK_GE(channels(), 0);
    CHECK_LE(c, channels());
    CHECK_GE(height(), 0);
    CHECK_LE(h, height());
    CHECK_GE(width(), 0);
    CHECK_LE(w, width());
    return ((n * channels() + c) * height() + h) * width() + w;
  }

带入的都是0,1 也就是 平移height timeswidth大小

backward

case PoolingParameter_PoolMethod_MAX:
    // The main loop
    if (use_top_mask) {
      top_mask = top[1]->cpu_data();
    } else {
      mask = max_idx_.cpu_data();
    }
    for (int n = 0; n < top[0]->num(); ++n) {
      for (int c = 0; c < channels_; ++c) {
        for (int ph = 0; ph < pooled_height_; ++ph) {
          for (int pw = 0; pw < pooled_width_; ++pw) {
            const int index = ph * pooled_width_ + pw;
            //找到对应位置 把上层的梯度加上去就好了
            const int bottom_index =
                use_top_mask ? top_mask[index] : mask[index];
            bottom_diff[bottom_index] += top_diff[index];
          }
        }
        bottom_diff += bottom[0]->offset(0, 1);
        top_diff += top[0]->offset(0, 1);
        if (use_top_mask) {
          top_mask += top[0]->offset(0, 1);
        } else {
          mask += top[0]->offset(0, 1);
        }
      }
    }
    break;
版权声明:本文为Love_wanling原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Love_wanling/article/details/78588898

智能推荐

矩阵max_pooling 二维矩阵滑动窗口

题目链接 题目大意 给定M×N矩阵,求经过给定size为A×B的最大池化处理后结果 M, N <= 2e3, A <= M, B <= N 直接上二维线段树可能被卡常了。 这里用滑动窗口,先对每行使用滑动窗口,再对得到的数组的每列使用滑动窗口即可。...

笔试题——max pooling滑动窗口实现(python 代码)

题目 输入:从控制台获取n,m,a,b;其中n*m为矩阵大小,a*b为滑动窗口大小 矩阵中的值,通过(i*j)mod 10 得到, 在滑动过程中,需要获得每次滑动窗口中的最大值,并存储下来 输出:所有最大值的和 要求及思路 纯暴力求解法,时间复杂度过高,需要使用滑动窗口方法求解 题目为2维矩阵,所以需要对行和列依次使用滑动窗口方法即可 不了解滑动窗口的可以参考一维滑动窗口这篇文章 源码  ...

tensorflow 池化操作实例 tf.nn.max_pooling

输出: The shape of x: (1, 4, 4, 1) [[ 4.  3.  1.  8.]  [ 7.  2.  6.  3.]  [ 2.  0.  1.  1.]  [ 3.  4.  2.  5.]] The shape pf y:...

category-wise max-pooling 操作案例理解

案例: 输出结果:...

Caffe源码精读 - 4 - Caffe Layers之pooling_layer(池化层)

Class_4 Caffe Layers之pooling_layer(池化层)   1. 概述 池化是卷积神经网络中较为常用的一种操作,根本目的是实现降采样,简化计算。 目前池化层从作用面区分,可分为全局池化和局部池化。全局池化是相当于在整张图上做池化,每一张特征图最终得到一个池化值,即H*W*C的特征层,经过全局池化以后得到的是1*1*C的池化输出。局部池化就是指定Feature ma...

猜你喜欢

dynamic k-max pooling 动态k-max 池化

最近老师让做一个比较多个池化操作的作业。其中包含了max,min,avg,k-max, dynamic k-max。 前面四种还好说,max和avg在pytorch.nn.functional里面就有,min只需要给输入值加个负号,然后在外面加个负号会正即可。k-max也是网上有很多的实现方式。但是关于dynamic k-max的资料在百度里面实在太少。谷歌里面也都是一些tf,或者别的实现方式的,...

Install caffe in Ubuntu

Author: Zongwei Zhou | 周纵苇 Weibo: @MrGiovanni Email: [email protected] Overview System: Ubuntu 16.04 LTS Graphics: GeForce GTX 960M/PCIe/SSE2 OS type: 64-bit Python: 2.7.12 Downloads CUDA Linux x86_64 ...

lstm in caffe

参考文献: https://blog.csdn.net/mounty_fsc/article/details/53114698 [(Caffe)LSTM层分析] https://stackoverflow.com/questions/32225388/lstm-module-for-caffe# [代码来自于该网址]...

Normalize Layer in Caffe

下面进行实验,主要检查三个参数的具体含义,即across_spatial , scale_filler ,channel_shared。 across_spatial: 对于每个样本,其到达norm层的张量形状表示为(1,c,h,w),那么across_spatial用来指示标准化是否要跨空间位置 (即(h,w))。如果across_spatial=False,则表示分别对(h,w)空间中的每个位...

caffe in python ---Classification

参考官方文档:http://nbviewer.jupyter.org/github/BVLC/caffe/blob/master/examples/00-classification.ipynb...