[开发技巧]·AdaptivePooling与Max/AvgPooling相互转换

个人网站--> http://www.yansongsong.cn/

1.问题描述

自适应池化Adaptive Pooling是PyTorch的一种池化层,根据1D,2D,3D以及Max与Avg可分为六种形式。

自适应池化Adaptive Pooling与标准的Max/AvgPooling区别在于,自适应池化Adaptive Pooling会根据输入的参数来控制输出output_size,而标准的Max/AvgPooling是通过kernel_size,stride与padding来计算output_size:

                        output_size = ceil ( (input_size+2∗padding−kernel_size)/stride)+1

Adaptive Pooling仅存在与PyTorch,如果需要将包含Adaptive Pooling的代码移植到Keras或者TensorFlow就会遇到问题。

本文将提供一个公式,可以简便的将AdaptivePooling准换为Max/AvgPooling,便于大家移植使用。

2.原理讲解

我们已经知道了普通Max/AvgPooling计算公式为:output_size = ceil ( (input_size+2∗padding−kernel_size)/stride)+1 

当我们使用Adaptive Pooling时,这个问题就变成了由已知量input_size,output_size求解kernel_size与stride

为了简化问题,我们将padding设为0(后面我们可以发现源码里也是这样操作的c++源码部分)

stride = floor ( (input_size / (output_size) )

kernel_size = input_size − (output_size−1) * stride

3.实战演示

下面我们通过一个实战来操作一下,验证公式的正确性

import torch as t
import math
import numpy as np alist = t.randn(2,6,7) inputsz = np.array(alist.shape[1:])
outputsz = np.array([2,3]) stridesz = np.floor(inputsz/outputsz).astype(np.int32) kernelsz = inputsz-(outputsz-1)*stridesz adp = t.nn.AdaptiveAvgPool2d(list(outputsz))
avg = t.nn.AvgPool2d(kernel_size=list(kernelsz),stride=list(stridesz))
adplist = adp(alist)
avglist = avg(alist) print(alist)
print(adplist)
print(avglist)

输出结果

tensor([[[ 0.9095,  0.8043,  0.4052,  0.3410,  1.8831,  0.8703, -0.0839],
[ 0.3300, -1.2951, -1.8148, -1.1118, -1.1091, 1.5657, 0.7093],
[-0.6788, -1.2790, -0.6456, 1.9085, 0.8627, 1.1711, 0.5614],
[-0.0129, -0.6447, -0.6685, -1.2087, 0.8535, -1.4802, 0.5274],
[ 0.7347, 0.0374, -1.7286, -0.7225, -0.4257, -0.0819, -0.9878],
[-1.2553, -1.0774, -0.1936, -1.4741, -0.9028, -0.1584, -0.6612]], [[-0.3473, 1.0599, -1.5744, -0.2023, -0.5336, 0.5512, -0.3200],
[-0.2518, 0.1714, 0.6862, 0.3334, -1.2693, -1.3348, -0.0878],
[ 1.0515, 0.1385, 0.4050, 0.8554, 1.0170, -2.6985, 0.3586],
[-0.1977, 0.8298, 1.6110, -0.9102, 0.7129, 0.2088, 0.9553],
[-0.2218, -0.7234, -0.4407, 1.0369, -0.8884, 0.3684, 1.2134],
[ 0.5812, 1.1974, -0.1584, -0.0903, -0.0628, 3.3684, 2.0330]]]) tensor([[[-0.3627, 0.0799, 0.7145],
[-0.5343, -0.7190, -0.3686]], [[ 0.1488, -0.0314, -0.4797],
[ 0.2753, 0.0900, 0.8788]]]) tensor([[[-0.3627, 0.0799, 0.7145],
[-0.5343, -0.7190, -0.3686]], [[ 0.1488, -0.0314, -0.4797],
[ 0.2753, 0.0900, 0.8788]]])

可以发现adp = t.nn.AdaptiveAvgPool2d(list(outputsz))与avg = t.nn.AvgPool2d(kernel_size=list(kernelsz),stride=list(stridesz))结果一致

为了防止这是偶然现象,修改参数,使用AdaptiveAvgPool1d进行试验

import torch as t
import math
import numpy as np alist = t.randn(2,3,9) inputsz = np.array(alist.shape[2:])
outputsz = np.array([4]) stridesz = np.floor(inputsz/outputsz).astype(np.int32) kernelsz = inputsz-(outputsz-1)*stridesz adp = t.nn.AdaptiveAvgPool1d(list(outputsz))
avg = t.nn.AvgPool1d(kernel_size=list(kernelsz),stride=list(stridesz))
adplist = adp(alist)
avglist = avg(alist) print(alist)
print(adplist)
print(avglist)

  

输出结果

tensor([[[ 1.3405,  0.3509, -1.5119, -0.1730,  0.6971,  0.3399, -0.0874,
-1.2417, 0.6564],
[ 2.0482, 0.3528, 0.0703, 1.2012, -0.8829, -0.3156, 1.0603,
-0.7722, -0.6086],
[ 1.0470, -0.9374, 0.3594, -0.8068, 0.5126, 1.4135, 0.3538,
-1.0973, 0.3046]], [[-0.1688, 0.7300, -0.3457, 0.5645, -1.2507, -1.9724, 0.4469,
-0.3362, 0.7910],
[ 0.5676, -0.0614, -0.0243, 0.1529, 0.8276, 0.2452, -0.1783,
0.7460, 0.2577],
[-0.1433, -0.7047, -0.4883, 1.2414, -1.4316, 0.9704, -1.7088,
-0.0094, -0.3739]]]) tensor([[[ 0.0598, -0.3293, 0.3165, -0.2242],
[ 0.8237, 0.1295, -0.0461, -0.1069],
[ 0.1563, 0.0217, 0.7600, -0.1463]], [[ 0.0718, -0.3440, -0.9254, 0.3006],
[ 0.1606, 0.3187, 0.2982, 0.2751],
[-0.4454, -0.2262, -0.7233, -0.6973]]]) tensor([[[ 0.0598, -0.3293, 0.3165, -0.2242],
[ 0.8237, 0.1295, -0.0461, -0.1069],
[ 0.1563, 0.0217, 0.7600, -0.1463]], [[ 0.0718, -0.3440, -0.9254, 0.3006],
[ 0.1606, 0.3187, 0.2982, 0.2751],
[-0.4454, -0.2262, -0.7233, -0.6973]]])

可以发现adp = t.nn.AdaptiveAvgPool1d(list(outputsz))与avg = t.nn.AvgPool1d(kernel_size=list(kernelsz),stride=list(stridesz))结果也是相同的。

4.总结分析

在以后遇到别人代码使用Adaptive Pooling,可以通过这两个公式转换为标准的Max/AvgPooling,从而应用到不同的学习框架中

stride = floor ( (input_size / (output_size) )

kernel_size = input_size − (output_size−1) * stride

只需要知道输入的input_size ,就可以推导出stride 与kernel_size ,从而替换为标准的Max/AvgPooling

Hope this helps

[开发技巧]·AdaptivePooling与Max/AvgPooling相互转换的更多相关文章

  1. iOS开发技巧系列---详解KVC(我告诉你KVC的一切)

    KVC(Key-value coding)键值编码,单看这个名字可能不太好理解.其实翻译一下就很简单了,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值.而不需 ...

  2. Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机

    Unity 游戏开发技巧集锦之制作一个望远镜与查看器摄像机 Unity中制作一个望远镜 本节制作的望远镜,在鼠标左键按下时,看到的视图会变大:当不再按下的时候,会慢慢缩小成原来的视图.游戏中时常出现的 ...

  3. [开发技巧]·Python极简实现滑动平均滤波(基于Numpy.convolve)

    [开发技巧]·Python极简实现滑动平均滤波(基于Numpy.convolve) ​ 1.滑动平均概念 滑动平均滤波法(又称递推平均滤波法),时把连续取N个采样值看成一个队列 ,队列的长度固定为N ...

  4. Mysql - 开发技巧(二)

    本文中的涉及到的表在https://github.com/YangBaohust/my_sql中 本文衔接Mysql - 巧用join来优化sql(https://www.cnblogs.com/dd ...

  5. javascript的10个开发技巧

    总结10个提高开发效率的JavaScript开发技巧. 1.生成随机的uid. const genUid = () => { var length = 20; var soupLength = ...

  6. SQL开发技巧(二)

    本系列文章旨在收集在开发过程中遇到的一些常用的SQL语句,然后整理归档,本系列文章基于SQLServer系列,且版本为SQLServer2005及以上-- 文章系列目录 SQL开发技巧(一) SQL开 ...

  7. DelphiXE2 DataSnap开发技巧收集

    DelphiXE2 DataSnap开发技巧收集 作者:  2012-08-07 09:12:52     分类:Delphi     标签: 作为DelphiXE2 DataSnap开发的私家锦囊, ...

  8. delphi XE5下安卓开发技巧

    delphi XE5下安卓开发技巧 一.手机快捷方式显示中文名称 project->options->Version Info-label(改成需要显示的中文名即可),但是需要安装到安卓手 ...

  9. 经典收藏 50个jQuery Mobile开发技巧集萃

    http://www.cnblogs.com/chu888chu888/archive/2011/11/10/2244181.html 1.Backbone移动实例 这是在Safari中运行的一款Ba ...

随机推荐

  1. 【cogs 775】山海经 ——Segment Tree

    题目链接:      TP 题解:   我数据结构真心是弱啊= =. 线段树好厉害啊,一直不会区间最大连续和,今天刚学习了一下233. 维护前缀最大和后缀最大,越界最大(?),再维护一个区间最大,瞎搞 ...

  2. BZOJ_4726_[POI2017]Sabota?_树形DP

    BZOJ_4726_[POI2017]Sabota?_树形DP Description 某个公司有n个人, 上下级关系构成了一个有根树.其中有个人是叛徒(这个人不知道是谁).对于一个人, 如果他 下属 ...

  3. js操作中要去注意的一些问题

    1.js中注意问题 font-size 改成fontSize padding-top 改成paddingTop js中不认识-,所以要以小驼峰方式操作属性或者以[" "]方式,例[ ...

  4. 2D图形如何运动模拟出3D效果

    一.先看看实现效果图 (左边的2d图片如何运动出右边3d的效果)                                      引言: 对于这个题目,真的很尴尬,不知道取啥,就想了这个题目 ...

  5. 说说new 和 malloc()

    熟悉c++的朋友应该都知道,c++提供给了程序员与硬件打交道的可能性,比如说内存管理.一个高水平的c++程序员可以将c++程序的性能优化到极致,榨干硬件资源.而现在我想说说与内存管理有关的new 和 ...

  6. MIP 内容声明

    从搜索结果页点出的 MIP 页面,其页面上的任何内容(包括但不限于广告.在线咨询.统计等组件)均视为在原站点上的投放和使用. MIP (Mobile Instant Pages - 移动网页加速器), ...

  7. Bootstrap优秀模板-ColorAdmin.4.3.0

    老牌的Bootstrap商业模板,提供HTML.AngularJS.AngularJS5.Vue.React多种环境,风格覆盖Flat.Material.Apple.Transparent甚至Face ...

  8. Azure Devops/Tfs 编译的时候自动修改版本号

    看到阿迪王那边出品了一个基于Azure Devops自增版本号  链接 http://edi.wang/post/2019/3/1/incremental-build-number-for-net-c ...

  9. 面试前必须知道的MySQL命令【explain】

    前言 只有光头才能变强 刷面试题的时候,不知道你们有没有见过MySQL这两个命令:explain和profile(反正我就见过了).. 之前虽然知道这两个命令大概什么意思,但一直没有去做笔记.今天发现 ...

  10. cocos creator主程入门教程(四)—— 网络通信

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 前面已经介绍怎样加载资源.管理弹窗.开发一个网络游戏,难免要处理网络通信.有几点问题需要注意: 1.服务 ...