如何仅使用Numpy实现2x2窗口的最大池化(Maxpooling)操作
纯Numpy实现2x2池化(最大/平均)
核心实现思路
用Numpy的np.lib.stride_tricks.as_strided方法把原矩阵切分为连续的2x2非重叠子块,无需手动写循环遍历,计算效率远高于逐块遍历实现,兼容任意行/列为偶数的输入矩阵(包括8x8、16x16等更大尺寸)。
完整实现代码
import numpy as np def max_pooling_2x2(mat): # 校验输入矩阵行列数为偶数,奇数尺寸可先做padding再传入 assert mat.shape[0] % 2 == 0 and mat.shape[1] % 2 == 0, "输入矩阵行列数需为偶数" m, n = mat.shape # 切分2x2子块 blocks = np.lib.stride_tricks.as_strided( mat, shape=(m//2, n//2, 2, 2), strides=(mat.strides[0]*2, mat.strides[1]*2, mat.strides[0], mat.strides[1]) ) # 每个子块取最大值 return blocks.max(axis=(2,3)) def avg_pooling_2x2(mat): assert mat.shape[0] % 2 == 0 and mat.shape[1] % 2 == 0, "输入矩阵行列数需为偶数" m, n = mat.shape blocks = np.lib.stride_tricks.as_strided( mat, shape=(m//2, n//2, 2, 2), strides=(mat.strides[0]*2, mat.strides[1]*2, mat.strides[0], mat.strides[1]) ) # 每个子块取平均值 return blocks.mean(axis=(2,3)) # 你的测试用例 k = np.random.randint(1,64,64).reshape(8,8) print("原8x8矩阵:\n", k) print("\n2x2最大池化结果(4x4):\n", max_pooling_2x2(k)) print("\n2x2平均池化结果(4x4):\n", avg_pooling_2x2(k))
预期效果示例
以4x4小矩阵验证逻辑正确性:
输入矩阵:
[[ 1 2 3 4] [ 5 6 7 8] [ 9 10 11 12] [13 14 15 16]]2x2最大池化输出:
[[ 6 8] [14 16]]2x2平均池化输出:
[[ 3.5 5.5] [11.5 13.5]]
注意事项
- 若输入矩阵行列数为奇数,可先通过
np.pad方法补0/补边缘值到偶数尺寸再传入函数 as_strided生成的块是原矩阵的视图,不要直接修改块数组避免影响原矩阵,需要修改可先调用.copy()生成独立副本
内容的提问来源于stack exchange,提问作者Arockia Jegan
相关产品推荐
相关产品推荐

