1 #ifndef LAYER_CONVOLUTIONAL_H_ 2 #define LAYER_CONVOLUTIONAL_H_ 9 #include "../Utils/Convolution.h" 10 #include "../Utils/Random.h" 22 template <
typename Activation>
26 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> Matrix;
27 typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1> Vector;
28 typedef Matrix::ConstAlignedMapType ConstAlignedMapMat;
29 typedef Vector::ConstAlignedMapType ConstAlignedMapVec;
30 typedef Vector::AlignedMapType AlignedMapVec;
32 const internal::ConvDims m_dim;
60 const int in_channels,
const int out_channels,
61 const int window_width,
const int window_height) :
62 Layer(in_width * in_height * in_channels,
63 (in_width - window_width + 1) * (in_height - window_height + 1) * out_channels),
64 m_dim(in_channels, out_channels, in_height, in_width, window_height, window_width)
67 void init(
const Scalar& mu,
const Scalar& sigma,
RNG& rng)
70 const int filter_data_size = m_dim.in_channels * m_dim.out_channels * m_dim.filter_rows * m_dim.filter_cols;
71 m_filter_data.resize(filter_data_size);
72 m_df_data.resize(filter_data_size);
75 internal::set_normal_random(m_filter_data.data(), filter_data_size, rng, mu, sigma);
78 m_bias.resize(m_dim.out_channels);
79 m_db.resize(m_dim.out_channels);
80 internal::set_normal_random(m_bias.data(), m_dim.out_channels, rng, mu, sigma);
84 void forward(
const Matrix& prev_layer_data)
87 const int nobs = prev_layer_data.cols();
90 m_z.resize(this->m_out_size, nobs);
92 internal::convolve_valid(m_dim, prev_layer_data.data(),
true, nobs,
93 m_filter_data.data(), m_z.data()
98 int channel_start_row = 0;
99 const int channel_nelem = m_dim.conv_rows * m_dim.conv_cols;
100 for(
int i = 0; i < m_dim.out_channels; i++, channel_start_row += channel_nelem)
102 m_z.block(channel_start_row, 0, channel_nelem, nobs).array() += m_bias[i];
106 m_a.resize(this->m_out_size, nobs);
107 Activation::activate(m_z, m_a);
118 void backprop(
const Matrix& prev_layer_data,
const Matrix& next_layer_data)
120 const int nobs = prev_layer_data.cols();
127 Activation::apply_jacobian(m_z, m_a, next_layer_data, dLz);
143 internal::ConvDims back_conv_dim(nobs, m_dim.out_channels, m_dim.channel_rows, m_dim.channel_cols,
144 m_dim.conv_rows, m_dim.conv_cols);
145 internal::convolve_valid(back_conv_dim, prev_layer_data.data(),
false, m_dim.in_channels,
146 dLz.data(), m_df_data.data()
152 ConstAlignedMapMat dLz_by_channel(dLz.data(), m_dim.conv_rows * m_dim.conv_cols, m_dim.out_channels * nobs);
153 Vector dLb = dLz_by_channel.colwise().sum();
155 ConstAlignedMapMat dLb_by_obs(dLb.data(), m_dim.out_channels, nobs);
156 m_db.noalias() = dLb_by_obs.rowwise().mean();
159 m_din.resize(this->m_in_size, nobs);
160 internal::ConvDims conv_full_dim(m_dim.out_channels, m_dim.in_channels, m_dim.conv_rows, m_dim.conv_cols, m_dim.filter_rows, m_dim.filter_cols);
161 internal::convolve_full(conv_full_dim, dLz.data(), nobs,
162 m_filter_data.data(), m_din.data()
173 ConstAlignedMapVec dw(m_df_data.data(), m_df_data.size());
174 ConstAlignedMapVec db(m_db.data(), m_db.size());
175 AlignedMapVec w(m_filter_data.data(), m_filter_data.size());
176 AlignedMapVec b(m_bias.data(), m_bias.size());
184 std::vector<Scalar> res(m_filter_data.size() + m_bias.size());
186 std::copy(m_filter_data.data(), m_filter_data.data() + m_filter_data.size(), res.begin());
187 std::copy(m_bias.data(), m_bias.data() + m_bias.size(), res.begin() + m_filter_data.size());
194 if(static_cast<int>(param.size()) != m_filter_data.size() + m_bias.size())
195 throw std::invalid_argument(
"Parameter size does not match");
197 std::copy(param.begin(), param.begin() + m_filter_data.size(), m_filter_data.data());
198 std::copy(param.begin() + m_filter_data.size(), param.end(), m_bias.data());
203 std::vector<Scalar> res(m_df_data.size() + m_db.size());
205 std::copy(m_df_data.data(), m_df_data.data() + m_df_data.size(), res.begin());
206 std::copy(m_db.data(), m_db.data() + m_db.size(), res.begin() + m_df_data.size());
void init(const Scalar &mu, const Scalar &sigma, RNG &rng)
std::vector< Scalar > get_parameters() const
void set_parameters(const std::vector< Scalar > ¶m)
const Matrix & output() const
void update(Optimizer &opt)
Convolutional(const int in_width, const int in_height, const int in_channels, const int out_channels, const int window_width, const int window_height)
std::vector< Scalar > get_derivatives() const
void backprop(const Matrix &prev_layer_data, const Matrix &next_layer_data)
const Matrix & backprop_data() const
virtual void update(ConstAlignedMapVec &dvec, AlignedMapVec &vec)=0
void forward(const Matrix &prev_layer_data)