C++元编程——池化层实现

池化层正向都是求区域最大值,反向有两种方法:1、记住最大值位置,将回传值赋值到该位置;2、平均值平均分配到区域中。下面就是实现啦,实现了这两种方法:

#ifndef _POOL_LAYER_HPP_
#define _POOL_LAYER_HPP_
#include "base_logic.hpp"

/* 池化层,对区域内取最大值 */

template<template<int,int,int,int,typename> class update_method_tpl, int input_row, int input_col, int tpl_row, int tpl_col, typename val_t = double>
struct pool_layer 
{
	using input_type = mat<input_row, input_col, val_t>;
	using ret_type = mat<get_ceil_div(input_row, tpl_row), get_ceil_div(input_col, tpl_col), val_t>;
	update_method_tpl<input_row, input_col, tpl_row, tpl_col, val_t>	um;			// 更新算法

	ret_type forward(const input_type& mt) 
	{
		return um.forward(mt);
	}

	input_type backward(const ret_type& mt)
	{
		return um.backward(mt);
	}
};

template<int r, int c, int tpl_row, int tpl_col>
struct region_max_cal
{
	template<int row_num, int col_num, typename val_t, typename omat_p_t>
	inline static val_t cal(const mat<row_num, col_num, val_t>& mt, omat_p_t& p_omt_r, omat_p_t& p_omt_c)
	{
		int i_max_r = 0, i_max_c = 0;
		val_t ret = mt.region_max<r*tpl_row, c*tpl_col, tpl_row, tpl_col>(i_max_r, i_max_c);
		(*p_omt_r).get_val<r, c>() = (i_max_r);
		(*p_omt_c).get_val<r, c>() = (i_max_c);
		return ret;
	}
};

template<int input_row, int input_col, int tpl_row, int tpl_col, typename val_t = double>
struct pool_layer_max 
{
	using input_type = mat<input_row, input_col, val_t>;
	using ret_type = mat<get_ceil_div(input_row, tpl_row), get_ceil_div(input_col, tpl_col), val_t>;

	template<int r, int c>
	struct region_max_local
	{
		template<int row_num, int col_num, typename val_t, typename omat_p_t>
		inline static val_t cal(const mat<row_num, col_num, val_t>& mt, omat_p_t& p_omt_r, omat_p_t& p_omt_c)
		{
			return region_max_cal<r, c, tpl_row, tpl_col>::cal(mt, p_omt_r, p_omt_c);
		}
	};

	mat<get_ceil_div(input_row, tpl_row), get_ceil_div(input_col, tpl_col), int> mt_max_row, mt_max_col;

	ret_type forward(const input_type& mt)
	{
		ret_type ret;
		col_loop<ret_type::c - 1, region_max_local>(ret, mt, &mt_max_row, &mt_max_col);
		return ret;
	}

	input_type backward(const ret_type& mt) 
	{
		input_type ret;
		for (int r = 0; r < ret_type::r; ++r)
		{
			for (int c = 0; c < ret_type::c; ++c) 
			{
				ret.get(mt_max_row.get(r, c), mt_max_col.get(r, c)) = mt.get(r, c);
			}
		}
		return ret;
	}
};

template<int input_row, int input_col, int tpl_row, int tpl_col, typename val_t = double>
struct pool_layer_average
{
	using input_type = mat<input_row, input_col, val_t>;
	using ret_type = mat<get_ceil_div(input_row, tpl_row), get_ceil_div(input_col, tpl_col), val_t>;

	template<int r, int c>
	struct region_max_local
	{
		template<int row_num, int col_num, typename val_t, typename omat_p_t>
		inline static val_t cal(const mat<row_num, col_num, val_t>& mt, omat_p_t& p_omt_r, omat_p_t& p_omt_c)
		{
			return region_max_cal<r, c, tpl_row, tpl_col>::cal(mt, p_omt_r, p_omt_c);
		}
	};

	ret_type forward(const input_type& mt)
	{
		ret_type ret;
		mat<get_ceil_div(input_row, tpl_row), get_ceil_div(input_col, tpl_col), int> mt_max_row, mt_max_col;
		col_loop<ret_type::c - 1, region_max_local>(ret, mt, &mt_max_row, &mt_max_col);
		return ret;
	}

	input_type backward(const ret_type& mt)
	{
		input_type ret;
		for (int r = 0; r < input_type::r; ++r)
		{
			for (int c = 0; c < input_type::c; ++c)
			{
				ret.get(r, c) = mt.get(r/tpl_row, c/tpl_col)/(tpl_row*tpl_col);
			}
		}
		return ret;
	}
};

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

腾昵猫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值