1 #ifndef LAYER_MAXPOOLING_H_ 2 #define LAYER_MAXPOOLING_H_ 9 #include "../Utils/FindMax.h" 21 template <
typename Activation>
25 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> Matrix;
26 typedef Eigen::MatrixXi IntMatrix;
28 const int m_channel_rows;
29 const int m_channel_cols;
30 const int m_in_channels;
31 const int m_pool_rows;
32 const int m_pool_cols;
55 MaxPooling(
const int in_width,
const int in_height,
const int in_channels,
56 const int pooling_width,
const int pooling_height) :
57 Layer(in_width * in_height * in_channels,
58 (in_width / pooling_width) * (in_height / pooling_height) * in_channels),
59 m_channel_rows(in_height), m_channel_cols(in_width), m_in_channels(in_channels),
60 m_pool_rows(pooling_height), m_pool_cols(pooling_width),
61 m_out_rows(m_channel_rows / m_pool_rows), m_out_cols(m_channel_cols / m_pool_cols)
64 void init(
const Scalar& mu,
const Scalar& sigma,
RNG& rng) {}
66 void forward(
const Matrix& prev_layer_data)
69 const int nobs = prev_layer_data.cols();
70 m_loc.resize(this->m_out_size, nobs);
71 m_z.resize(this->m_out_size, nobs);
74 int* loc_data = m_loc.data();
75 const int channel_end = prev_layer_data.size();
76 const int channel_stride = m_channel_rows * m_channel_cols;
77 const int col_end_gap = m_channel_rows * m_pool_cols * m_out_cols;
78 const int col_stride = m_channel_rows * m_pool_cols;
79 const int row_end_gap = m_out_rows * m_pool_rows;
80 for(
int channel_start = 0; channel_start < channel_end; channel_start += channel_stride)
82 const int col_end = channel_start + col_end_gap;
83 for(
int col_start = channel_start; col_start < col_end; col_start += col_stride)
85 const int row_end = col_start + row_end_gap;
86 for(
int row_start = col_start; row_start < row_end; row_start += m_pool_rows, loc_data++)
87 *loc_data = row_start;
92 loc_data = m_loc.data();
93 const int*
const loc_end = loc_data + m_loc.size();
94 Scalar* z_data = m_z.data();
95 const Scalar* src = prev_layer_data.data();
96 for(; loc_data < loc_end; loc_data++, z_data++)
98 const int offset = *loc_data;
99 *z_data = internal::find_block_max(src + offset, m_pool_rows, m_pool_cols, m_channel_rows, *loc_data);
104 m_a.resize(this->m_out_size, nobs);
105 Activation::activate(m_z, m_a);
108 const Matrix&
output()
const {
return m_a; }
112 void backprop(
const Matrix& prev_layer_data,
const Matrix& next_layer_data)
114 const int nobs = prev_layer_data.cols();
121 Activation::apply_jacobian(m_z, m_a, next_layer_data, dLz);
126 m_din.resize(this->m_in_size, nobs);
128 const int dLz_size = dLz.size();
130 const Scalar* dLz_data = dLz.data();
131 const int* loc_data = m_loc.data();
132 Scalar* din_data = m_din.data();
133 for(
int i = 0; i < dLz_size; i++)
134 din_data[loc_data[i]] += dLz_data[i];
void update(Optimizer &opt)
const Matrix & backprop_data() const
MaxPooling(const int in_width, const int in_height, const int in_channels, const int pooling_width, const int pooling_height)
std::vector< Scalar > get_derivatives() const
void init(const Scalar &mu, const Scalar &sigma, RNG &rng)
void set_parameters(const std::vector< Scalar > ¶m)
std::vector< Scalar > get_parameters() const
const Matrix & output() const
void forward(const Matrix &prev_layer_data)
void backprop(const Matrix &prev_layer_data, const Matrix &next_layer_data)