/* * @Author: Weiliang Chen * @Date: 2016-09-29 10:51:07 * @Last Modified by: Weiliang Chen * @Last Modified time: 2016-09-29 10:55:27 */ #include #include #include "ConvLayer.h" #include "Blob.h" #include "common.h" #include "Layer.h" #include "Utils.h" using std::cout; using std::endl; namespace fn { template ConvLayer::ConvLayer() { } template void ConvLayer::LayerSetUp(const Blob & weights, const arma::Col &bias, const int stride_h, const int stride_w, const int pad_h, const int pad_w) { std::vector shape = weights.shape(); kernel_h_ = shape[0]; kernel_w_ = shape[1]; channels_ = shape[2]; number_ = shape[3]; weights_ = weights; bias_ = bias; stride_h_ = stride_h; stride_w_ = stride_w; pad_h_ = pad_h; pad_w_ = pad_w; } template void ConvLayer:: Forward(const std::vector*> &bottom, std::vector*> &top) { if (bottom.size() != 1 ||top.size() != 1 ) { cout << "Error:The dimension of the input data or output data is wrong." << endl; return; } if (bottom[0]->n_rows > 0 && bottom[0]->n_cols > 0 && bottom[0]->n_slices > 0) { arma::Mat feat_mat; arma::Mat weights_mat; bottom[0]->save("input.txt", arma::arma_ascii); im2col(*(bottom[0]), kernel_h_, kernel_w_, pad_h_, pad_w_, stride_h_, stride_w_, feat_mat); feat_mat.save("feat_mat.txt",arma::arma_ascii); filter2col(*(weights_.data_vec()), weights_mat); weights_mat.save("weights_mat.txt", arma::arma_ascii); //conv arma::Mat conv_mat = feat_mat*weights_mat; const int output_h = (bottom[0]->n_rows + 2 * pad_h_ - kernel_h_) / stride_h_ + 1; const int output_w = (bottom[0]->n_cols + 2 * pad_w_ - kernel_w_) / stride_w_ + 1; conv_mat.save("conv1_mat.txt",arma::arma_ascii); col2im(conv_mat, output_h, output_w, *(top[0])); //Add bias for (int channel = 0; channel < top[0]->n_slices; ++channel) { top[0]->slice(channel) += bias_.at(channel); } } } template void ConvLayer::Forward(const arma::Cube& bottom, arma::Cube& top) { if (bottom.n_rows > 0 && bottom.n_cols > 0 && bottom.n_slices > 0) { arma::Mat feat_mat; arma::Mat weights_mat; im2col(bottom, kernel_h_, kernel_w_, pad_h_, pad_w_, stride_h_, stride_w_, feat_mat); filter2col(*(weights_.data_vec()), weights_mat); // printMat(feat_mat, "feat_mat.txt"); // printMat(weights_mat, "weights_mat.txt"); //conv arma::Mat conv_mat = feat_mat*weights_mat; const int output_h = (bottom.n_rows + 2 * pad_h_ - kernel_h_) / stride_h_ + 1; const int output_w = (bottom.n_cols + 2 * pad_w_ - kernel_w_) / stride_w_ + 1; col2im(conv_mat, output_h, output_w, top); //Add bias for (int channel = 0; channel < top.n_slices; ++channel) { top.slice(channel) += bias_.at(channel); } } } template void ConvLayer::CalShape(const arma::Cube& bottom, std::vector& shape) { const int output_h = (bottom.n_rows + 2 * pad_h_ - kernel_h_) / stride_h_ + 1; const int output_w = (bottom.n_cols + 2 * pad_w_ - kernel_w_) / stride_w_ + 1; shape[0] = output_h; shape[1] = output_w; shape[2] = number_; } template ConvLayer::~ConvLayer() { } //Explicit instantiation INSTANTIATE_CLASS(ConvLayer); }