摘要:池化层的主要目的是降维,通过滤波器映射区域内取最大值、平均值等操作。

均值池化:tf.nn.avg_pool(input,ksize,strides,padding)

最大池化:tf.nn.max_pool(input,ksize,strides,padding)

input:通常情况下是卷积层输出的featuremap,shape=[batch,height,width,channels]

               

  假定这个矩阵就是卷积层输出的featuremap(2通道输出)  他的shape=[1,4,4,2]

ksize:池化窗口大小    shape=[batch,height,width,channels]    比如[1,2,2,1]

strides: 窗口在每一个维度上的移动步长 shape=[batch,stride,stride,channel]  比如[1,2,2,1]

padding:“VALID”不填充  “SAME”填充0

返回:tensor        shape=[batch,height,width,channels]

上图是采用的最大池化,取红色框内最大的一个数。

import tensorflow as tf
feature_map = tf.constant([
[[0.0,4.0],[0.0,4.0],[0.0,4.0],[0.0,4.0]],
[[1.0,5.0],[1.0,5.0],[1.0,5.0],[1.0,5.0]],
[[2.0,6.0],[2.0,6.0],[2.0,6.0],[2.0,6.0]] ,
[[3.0,7.0],[3.0,7.0],[3.0,7.0],[3.0,7.0]]
])
feature_map = tf.reshape(feature_map,[1,4,4,2])##两通道featuremap输入 ##定义池化层
pooling = tf.nn.max_pool(feature_map,[1,2,2,1],[1,2,2,1],padding='VALID')##池化窗口2*2,高宽方向步长都为2,不填充
pooling1 = tf.nn.max_pool(feature_map,[1,2,2,1],[1,1,1,1],padding='VALID')##池化窗口2*2,高宽方向步长都为1,不填充
pooling2 = tf.nn.avg_pool(feature_map,[1,4,4,1],[1,1,1,1],padding='SAME')##池化窗口4*4,高宽方向步长都为1,填充
pooling3 = tf.nn.avg_pool(feature_map,[1,4,4,1],[1,4,4,1],padding='SAME')##池化窗口4*4,高宽方向步长都为4,填充
##转置变形(详细解释参考另一篇博文)
tran_reshape = tf.reshape(tf.transpose(feature_map),[-1,16])
pooling4 = tf.reduce_mean(tran_reshape,1) ###对行值求平均
with tf.Session() as sess:
print('featuremap:\n',sess.run(feature_map))
print('*'*30)
print('pooling:\n',sess.run(pooling))
print('*'*30)
print('pooling1:\n',sess.run(pooling1))
print('*'*30)
print('pooling2:\n',sess.run(pooling2))
print('*'*30)
print('pooling3:\n',sess.run(pooling3))
print('*'*30)
print('pooling4:\n',sess.run(pooling4))
'''
输出结果:
featuremap:
[[[[ 0. 4.]
[ 0. 4.]
[ 0. 4.]
[ 0. 4.]] [[ 1. 5.]
[ 1. 5.]
[ 1. 5.]
[ 1. 5.]] [[ 2. 6.]
[ 2. 6.]
[ 2. 6.]
[ 2. 6.]] [[ 3. 7.]
[ 3. 7.]
[ 3. 7.]
[ 3. 7.]]]]
******************************
pooling:
[[[[ 1. 5.]
[ 1. 5.]] [[ 3. 7.]
[ 3. 7.]]]]
******************************
pooling1:
[[[[ 1. 5.]
[ 1. 5.]
[ 1. 5.]] [[ 2. 6.]
[ 2. 6.]
[ 2. 6.]] [[ 3. 7.]
[ 3. 7.]
[ 3. 7.]]]]
******************************
pooling2:
[[[[ 1. 5. ]
[ 1. 5. ]
[ 1. 5. ]
[ 1. 5. ]] [[ 1.5 5.5]
[ 1.5 5.5]
[ 1.5 5.5]
[ 1.5 5.5]] [[ 2. 6. ]
[ 2. 6. ]
[ 2. 6. ]
[ 2. 6. ]] [[ 2.5 6.5]
[ 2.5 6.5]
[ 2.5 6.5]
[ 2.5 6.5]]]]
******************************
pooling3:
[[[[ 1.5 5.5]]]]
******************************
pooling4:
[ 1.5 5.5] '''

池化层常用函数及参数

现在我们对代码中的内容加以解释:

padding的规则

  •   padding=‘VALID’时,输出的宽度和高度的计算公式(下图gif为例)

         

    输出宽度:output_width = (in_width-filter_width+1)/strides_width  =(5-3+1)/2=1.5【向上取整=2】

    输出高度:output_height = (in_height-filter_height+1)/strides_height  =(5-3+1)/2=1.5【向上取整=2】

    输出的形状[1,2,2,1]

        

    

import tensorflow as tf
image = [0,1.0,1,2,2,0,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,2,0,1,0]
input = tf.Variable(tf.constant(image,shape=[1,5,5,1])) ##1通道输入
fil1 = [-1.0,0,1,-2,0,2,-1,0,1]
filter = tf.Variable(tf.constant(fil1,shape=[3,3,1,1])) ##1个卷积核对应1个featuremap输出 op = tf.nn.conv2d(input,filter,strides=[1,2,2,1],padding='VALID') ##步长2,VALID不补0操作 init = tf.global_variables_initializer() with tf.Session() as sess:
sess.run(init)
# print('input:\n', sess.run(input))
# print('filter:\n', sess.run(filter))
print('op:\n',sess.run(op)) ##输出结果
'''
[[[[ 2.]
[-1.]] [[-1.]
[ 0.]]]]
'''

tensorflow中实现(步长2)

    如果strides=[1,3,3,1]的情况又是如何呢?   

    输出宽度:output_width  = (in_width-filter_width+1)/strides_width  =(5-3+1)/3=1

    输出高度:output_height = (in_height-filter_height+1)/strides_height  =(5-3+1)/3=1

    输出的形状[1,1,1,1],因此输出的结果只有一个

    

    

import tensorflow as tf
image = [0,1.0,1,2,2,0,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,2,0,1,0]
input = tf.Variable(tf.constant(image,shape=[1,5,5,1])) ##1通道输入
fil1 = [-1.0,0,1,-2,0,2,-1,0,1]
filter = tf.Variable(tf.constant(fil1,shape=[3,3,1,1])) ##1个卷积核对应1个featuremap输出 op = tf.nn.conv2d(input,filter,strides=[1,3,3,1],padding='VALID') ##步长2,VALID不补0操作 init = tf.global_variables_initializer() with tf.Session() as sess:
sess.run(init)
# print('input:\n', sess.run(input))
# print('filter:\n', sess.run(filter))
print('op:\n',sess.run(op)) ##输出结果
'''
op:
[[[[ 2.]]]]
'''

tensorflow中实现(步长3)

    padding=‘SAME’时,输出的宽度和高度的计算公式(下图gif为例)

    

    输出宽度:output_width  = in_width/strides_width=5/2=2.5【向上取整3】

    输出高度:output_height = in_height/strides_height=5/2=2.5【向上取整3】

    则输出的形状:[1,3,3,1]

    那么padding补0的规则又是如何的呢?【先确定输出形状,再计算补多少0】

    pad_width = max((out_width-1)*strides_width+filter_width-in_width,0)=max((3-1)*2+3-5,0)=2

    pad_height = max((out_height-1)*strides_height+filter_height-in_height,0)=max((3-1)*2+3-5,0)=2

    pad_top = pad_height/2=1

    pad_bottom = pad_height-pad_top=1

    pad_left = pad_width/2=1

    pad_right = pad_width-pad_left=1

    

    

import tensorflow as tf
image = [0,1.0,1,2,2,0,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,2,0,1,0]
input = tf.Variable(tf.constant(image,shape=[1,5,5,1])) ##1通道输入
fil1 = [-1.0,0,1,-2,0,2,-1,0,1]
filter = tf.Variable(tf.constant(fil1,shape=[3,3,1,1])) ##1个卷积核对应1个featuremap输出 op = tf.nn.conv2d(input,filter,strides=[1,2,2,1],padding='SAME') ##步长2,VALID不补0操作 init = tf.global_variables_initializer() with tf.Session() as sess:
sess.run(init)
# print('input:\n', sess.run(input))
# print('filter:\n', sess.run(filter))
print('op:\n',sess.run(op)) ##输出结果
'''
op:
[[[[ 3.]
[ 1.]
[-4.]] [[ 3.]
[ 0.]
[-3.]] [[ 4.]
[-1.]
[-3.]]]]
'''

SAME步长2

    如果步长为3呢?补0的规则又如何?

    输出宽度:output_width  = in_width/strides_width=5/3=2

    输出高度:output_height = in_height/strides_height=5/3=2

    则输出的形状:[1,2,2,1]

    那么padding补0的规则又是如何的呢?【先确定输出形状,再计算补多少0】

    pad_width = max((out_width-1)*strides_width+filter_width-in_width,0)=max((2-1)*3+3-5,0)=1

    pad_height = max((out_height-1)*strides_height+filter_height-in_height,0)=max((2-1)*3+3-5,0)=1

    pad_top = pad_height/2=0【向下取整】

    pad_bottom = pad_height-pad_top=1

    pad_left = pad_width/2=0【向下取整】

    pad_right = pad_width-pad_left=1

        

    

import tensorflow as tf
print(3/2)
image = [0,1.0,1,2,2,0,1,1,0,0,1,1,0,1,0,1,0,1,1,1,0,2,0,1,0]
input = tf.Variable(tf.constant(image,shape=[1,5,5,1])) ##1通道输入
fil1 = [-1.0,0,1,-2,0,2,-1,0,1]
filter = tf.Variable(tf.constant(fil1,shape=[3,3,1,1])) ##1个卷积核对应1个featuremap输出 op = tf.nn.conv2d(input,filter,strides=[1,3,3,1],padding='SAME') ##步长2,VALID不补0操作 init = tf.global_variables_initializer() with tf.Session() as sess:
sess.run(init)
# print('input:\n', sess.run(input))
# print('filter:\n', sess.run(filter))
print('op:\n',sess.run(op)) ##输出结果
'''
op:
[[[[ 2.]
[-3.]] [[ 0.]
[-3.]]]]
'''

SAME步长3

    这里借用的卷积中的padding规则,在池化层中的padding规则与卷积中的padding规则一致   

CNN之池化层tf.nn.max_pool | tf.nn.avg_pool | tf.reduce_mean | padding的规则解释的更多相关文章

  1. 深入解析CNN pooling 池化层原理及其作用

    原文地址:https://blog.csdn.net/CVSvsvsvsvs/article/details/90477062 池化层作用机理我们以最简单的最常用的max pooling最大池化层为例 ...

  2. tensorflow的卷积和池化层(二):记实践之cifar10

    在tensorflow中的卷积和池化层(一)和各种卷积类型Convolution这两篇博客中,主要讲解了卷积神经网络的核心层,同时也结合当下流行的Caffe和tf框架做了介绍,本篇博客将接着tenso ...

  3. TensorFlow 池化层

    在 TensorFlow 中使用池化层 在下面的练习中,你需要设定池化层的大小,strides,以及相应的 padding.你可以参考 tf.nn.max_pool().Padding 与卷积 pad ...

  4. 【深度学习篇】--神经网络中的池化层和CNN架构模型

    一.前述 本文讲述池化层和经典神经网络中的架构模型. 二.池化Pooling 1.目标 降采样subsample,shrink(浓缩),减少计算负荷,减少内存使用,参数数量减少(也可防止过拟合)减少输 ...

  5. tensorflow CNN 卷积神经网络中的卷积层和池化层的代码和效果图

    tensorflow CNN 卷积神经网络中的卷积层和池化层的代码和效果图 因为很多 demo 都比较复杂,专门抽出这两个函数,写的 demo. 更多教程:http://www.tensorflown ...

  6. 第十三节,使用带有全局平均池化层的CNN对CIFAR10数据集分类

    这里使用的数据集仍然是CIFAR-10,由于之前写过一篇使用AlexNet对CIFAR数据集进行分类的文章,已经详细介绍了这个数据集,当时我们是直接把这些图片的数据文件下载下来,然后使用pickle进 ...

  7. CNN学习笔记:池化层

    CNN学习笔记:池化层 池化 池化(Pooling)是卷积神经网络中另一个重要的概念,它实际上是一种形式的降采样.有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见 ...

  8. ubuntu之路——day17.3 简单的CNN和CNN的常用结构池化层

    来看上图的简单CNN: 从39x39x3的原始图像 不填充且步长为1的情况下经过3x3的10个filter卷积后 得到了 37x37x10的数据 不填充且步长为2的情况下经过5x5的20个filter ...

  9. CNN中卷积层 池化层反向传播

    参考:https://blog.csdn.net/kyang624823/article/details/78633897 卷积层 池化层反向传播: 1,CNN的前向传播 a)对于卷积层,卷积核与输入 ...

随机推荐

  1. XMLHttpRequest.setRequestHeader()

    在AJAX中,如果需要像 HTML 表单那样 POST 数据,需要使用 setRequestHeader() 方法来添加 HTTP 头. 然后在 send() 方法中规定需要希望发送的数据: setR ...

  2. vue实现搜索功能

    vue实现搜索功能 template 部分 <!-- 搜索页面 --> <template> <div> <div class="goback&qu ...

  3. Solr的学习使用之(十)数据库(Oracle、SqlServer)原有的全文索引功能和Solr对比?

    本人有个问题一直不解,既然solr的全文索引功能这么强大,而且效果也不错,那为什么那些数据库厂商比如Oracle.SqlServer,不把solr的功能集成进去呢,或者说把全文索引的功能做好点,做到和 ...

  4. 微信小程序倒计时实现功能

    onLoad: function () {    var that=this;    this.data.intervarID= setInterval(function () {      var ...

  5. Redis的客户端Jedis

    1. Redis支持消息的订阅与发布 Redis的消息订阅支持:先订阅后发布 订阅:subscribe c1 c2 发布:publish c2 hello-redis 支持通配符的订阅:psubscr ...

  6. 洛谷 P2783 有机化学之神偶尔会做作弊(Tarjan,LCA)

    题目背景 LS中学化学竞赛组教练是一个酷爱炉石的人. 有一天他一边搓炉石一边监考,而你作为一个信息竞赛的大神也来凑热闹. 然而你的化竞基友却向你求助了. “第1354题怎么做”<--手语 他问道 ...

  7. Tenka1 Programmer Contest C - Align

    链接 Tenka1 Programmer Contest C - Align 给定一个序列,要求重新排列最大化\(\sum_{i=2}^{i=n} |a_i-a_{i-1}|\),\(n\leq 10 ...

  8. bzoj4940 [Ynoi2016]这是我自己的发明 莫队+dfs序

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4940 题解 对于换根操作,处理方法就很套路了. 首先先假定以 \(1\) 为根做一遍 dfs, ...

  9. UVa 1009 Sharing Chocolate (数位dp)

    题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...

  10. C++遍历循环多维数组

    #include <iostream> using namespace std; int main() { int arr[2][2][2] = {0}; for(auto&&am ...