MaxPooling实现by C++
实现思路
输入:
feature: 二维特征图
k_h和k_w: kernel_size的高和宽
s_h和s_w: row和col上的步长
输出:
maxpooling后的二维特征图
算法流程
- 计算出输出feature map的尺寸
- 对输入feature map进行右侧和下侧的填充
- 遍历输出特征图,找到每个点在输入特征图上对应的滑动窗口
- 找到窗口中最大的值,赋值给输出特征图上的点
实现细节
- 输出特征图的尺寸:
int out_row = (row - k_h) / s_h + 1;
int out_col = (col - k_w) / s_w + 1;
- 如果stride无法被 row / col 整除,out_row / out_col需要++,因为最后一个stride会只覆盖住一部分,这个边角料也需要进行maxpooling操作
int mod_row = row % s_h, mod_col = col % s_w;
if(mod_row !=0) ++out_row;
if(mod_col !=0) ++out_col;
代码
#include<iostream>
#include<vector>
#include<algorithm>
#include<math.h>
using namespace std;
vector<vector<int>> maxpooling(vector<vector<int>> feature, int k_h, int k_w, int s_h, int s_w){
int row = feature.size(), col = feature.size();
int out_row = (row - k_h) / s_h + 1, out_col = (col - k_w) / s_w + 1;
int mod_row = row % s_h, mod_col = col % s_w;
if(mod_row !=0) ++out_row;
if(mod_col !=0) ++out_col;
vector<vector<int>> res(out_row, vector<int>(out_col, 0));
vector<vector<int>> pad_map(feature);
for(int i=0;i<row;++i){
for(int j=0;j<k_w-mod_col;++j){ //j代表向右填充次数
pad_map[i].push_back(feature[i][col-1]);
}
}
for(int i=0;i<k_h-mod_row;++i){ //j代表填向下充次数
pad_map.push_back(pad_map[row-1]);
}
for(int i=0;i<out_row;++i){
for(int j=0;j<out_col;++j){
int start_x = j*s_w;
int start_y = i*s_h;
vector<int> temp;
for(int ii=start_y;ii<start_y+k_h;++ii){
for(int jj=start_x;jj<start_x+k_w;++jj){
temp.push_back(pad_map[ii][jj]);
}
}
sort(temp.begin(), temp.end());
res[i][j] = temp[temp.size()-1];
}
}
return res;
}
int main()
{
vector<vector<int>> f_map = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};
//maxpooling(f_map, k_h, k_w, s_h, s_w);
auto res = maxpooling(f_map, 2, 2, 2, 2);
for (auto l : res)
{
for (auto ll : l)
{
cout << ll << " ";
}
cout << endl;
}
system("pause");
return 0;
}