void MaskingLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { bias_term_ = this->layer_param_.masking_param().bias_term(); if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { // initialize weights (and bias), adjust parameter blob shape(s) and fill the values if (bias_term_) { this->blobs_.resize(2); this->blobs_[1].reset(new Blob<Dtype>(bottom[0]->shape())); } else { this->blobs_.resize(1); } this->blobs_[0].reset(new Blob<Dtype>(bottom[0]->shape())); if (bias_term_) { shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>(this->layer_param_.masking_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>(this->layer_param_.masking_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); } stable_prod_grad_ = this->layer_param_.masking_param().stable_prod_grad(); }
void InnerProductLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term(); N_ = num_output; K_ = bottom[0]->count() / bottom[0]->num(); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight this->blobs_[0].reset(new Blob<Dtype>(1, 1, N_, K_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, N_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization this->param_propagate_down_.resize(this->blobs_.size(), true); }
void InnerProductLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term(); transpose_ = this->layer_param_.inner_product_param().transpose(); N_ = num_output; const int axis = bottom[0]->CanonicalAxisIndex( this->layer_param_.inner_product_param().axis()); // Dimensions starting from "axis" are "flattened" into a single // length K_ vector. For example, if bottom[0]'s shape is (N, C, H, W), // and axis == 1, N inner products with dimension CHW are performed. K_ = bottom[0]->count(axis); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize the weights vector<int> weight_shape(2); if (transpose_) { weight_shape[0] = K_; weight_shape[1] = N_; } else { weight_shape[0] = N_; weight_shape[1] = K_; } this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization this->param_propagate_down_.resize(this->blobs_.size(), true); //add by zhaoyang 4.18 this->has_backward_filter = this->layer_param_.inner_product_param().has_backward_filter(); if (this->has_backward_filter) { string backward_filter_path = this->layer_param_.inner_product_param().backward_filter_path(); FILE *f = fopen(backward_filter_path.c_str(), "r"); int temp; while (fscanf(f, "%d", &temp) != EOF) { this->filter.push_back((bool)temp); } } //---- }
void LocalLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { CHECK_EQ(bottom.size(), 1) << "Conv Layer takes a single blob as input."; CHECK_EQ(top.size(), 1) << "Conv Layer takes a single blob as output."; kernel_size_ = this->layer_param_.local_param().kernel_size(); stride_ = this->layer_param_.local_param().stride(); pad_ = this->layer_param_.local_param().pad(); num_ = bottom[0]->num(); channels_ = bottom[0]->channels(); height_ = bottom[0]->height(); width_ = bottom[0]->width(); num_output_ = this->layer_param_.local_param().num_output(); height_out_ = (height_ + 2 * pad_ - kernel_size_) / stride_ + 1; width_out_ = (width_ + 2 * pad_ - kernel_size_) / stride_ + 1; M_ = num_output_; K_ = channels_ * kernel_size_ * kernel_size_; N_ = height_out_ * width_out_; CHECK_GT(kernel_size_, 0); CHECK_GT(num_output_, 0); CHECK_GE(height_, kernel_size_) << "height smaller than kernel size"; CHECK_GE(width_, kernel_size_) << "width smaller than kernel size"; // Set the parameters bias_term_ = this->layer_param_.local_param().bias_term(); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight this->blobs_[0].reset(new Blob<Dtype>( num_output_, 1, K_, N_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.local_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, M_, N_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.local_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } }
void CCCPPoolingLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, //vector<Blob<Dtype>*>* top) { const vector<Blob<Dtype>*>& top) { CHECK_EQ(bottom.size(), 1) << "CCCP Pooling Layer takes a single blob as input."; CHECK_EQ(top.size(), 1) << "CCCP Pooling Layer takes a single blob as output."; NUM_OUTPUT_ = this->layer_param_.cccp_param().num_output(); GROUP_ = this->layer_param_.cccp_param().group(); biasterm_ = this->layer_param_.cccp_param().biasterm(); // Figure out the dimensions CHANNEL_ = bottom[0]->channels(); REST_ = bottom[0]->height() * bottom[0]->width(); NUM_ = bottom[0]->num(); CHECK_EQ(CHANNEL_%GROUP_, 0) << "CCCP Pooling input channel number is not divisible by group number."; //top[0]->Reshape(bottom[0]->num(), GROUP_*NUM_OUTPUT_, bottom[0]->height(), bottom[0]->width()); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (biasterm_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight this->blobs_[0].reset(new Blob<Dtype>(1, 1, GROUP_*NUM_OUTPUT_, CHANNEL_/GROUP_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler( GetFiller<Dtype>(this->layer_param_.cccp_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (biasterm_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, GROUP_*NUM_OUTPUT_)); shared_ptr<Filler<Dtype> > bias_filler( GetFiller<Dtype>(this->layer_param_.cccp_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization // Setting up the bias multiplier if (biasterm_) { bias_multiplier_.reset(new SyncedMemory(REST_ * sizeof(Dtype))); Dtype* bias_multiplier_data = reinterpret_cast<Dtype*>(bias_multiplier_->mutable_cpu_data()); for (int i = 0; i < REST_; ++i) { bias_multiplier_data[i] = 1.; } } }
void TopologyLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int num_output = this->layer_param_.topology_param().num_output(); bias_term_ = this->layer_param_.topology_param().bias_term(); N_ = num_output; weighted_bottom_.Reshape(bottom[0]->shape()); const int axis = bottom[0]->CanonicalAxisIndex(this->layer_param_.topology_param().axis()); // Dimensions starting from "axis" are "flattened" into a single // length K_ vector. For example, if bottom[0]'s shape is (N, C, H, W), // and axis == 1, N inner products with dimension CHW are performed. K_ = bottom[0]->count(axis); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight vector<int> weight_shape(2); weight_shape[0] = N_; weight_shape[1] = K_; this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); // Fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>(this->layer_param_.topology_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>(this->layer_param_.topology_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } this->param_propagate_down_.resize(this->blobs_.size(), true); ConstructWeightMask(); }
void InnerProductDataLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term(); N_ = num_output; const int axis = bottom[0]->CanonicalAxisIndex( this->layer_param_.inner_product_param().axis()); // Dimensions starting from "axis" are "flattened" into a single // length K_ vector. For example, if bottom[0]'s shape is (N, C, H, W), // and axis == 1, N inner products with dimension CHW are performed. K_ = bottom[0]->count(axis); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight vector<int> weight_shape(2); weight_shape[0] = N_; weight_shape[1] = K_; this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); // fill the weights if (Caffe::getThreadId() == 0) { shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); } Dtype* weight = this->blobs_[0]->mutable_cpu_data(); MPI_Bcast(weight, this->blobs_[0]->count(), MPI_FLOAT, 0, MPI_COMM_WORLD); // If necessary, intiialize and fill the bias term if (bias_term_) { vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); if (Caffe::getThreadId() == 0) { shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } Dtype* bias = this->blobs_[1]->mutable_cpu_data(); MPI_Bcast(bias, this->blobs_[1]->count(), MPI_FLOAT, 0, MPI_COMM_WORLD); } } // parameter initialization this->param_propagate_down_.resize(this->blobs_.size(), true); }
void InnerProductLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term();//bool bias_term transpose_ = this->layer_param_.inner_product_param().transpose();//bool transpose_if true, transposed weights N_ = num_output;//表示全连接层输出神经元的个数 const int axis = bottom[0]->CanonicalAxisIndex( this->layer_param_.inner_product_param().axis()); // Dimensions starting from "axis" are "flattened" into a single // length K_ vector. For example, if bottom[0]'s shape is (N, C, H, W), // and axis == 1, N inner products with dimension CHW are performed. K_ = bottom[0]->count(axis);//表示单个样本特征向量长度 // Check if we need to set up the weights if (this->blobs_.size() > 0) { //为什么blob_.size大于0就跳过参数初始化 LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) {//w blob和b blob this->blobs_.resize(2); } else { //否则只有w blob this->blobs_.resize(1); } // Initialize the weights vector<int> weight_shape(2); if (transpose_) {//如果权重被转置了 weight_shape[0] = K_; weight_shape[1] = N_; } else { weight_shape[0] = N_; weight_shape[1] = K_; } this->blobs_[0].reset(new Blob<Dtype>(weight_shape));//根据是否转置调整权重W维度 // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); //权重过滤器填充W过滤器 // If necessary, intiialize and fill the bias term if (bias_term_) {//有偏置项 vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape));//b blob重新调整维度 shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler()));//得到偏置过滤器 bias_filler->Fill(this->blobs_[1].get());//权重过滤器填充 } } // parameter initialization //vector< bool > param_propagate_down_ this->param_propagate_down_.resize(this->blobs_.size(), true);//? }
void InnerProductLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) { CHECK_EQ(bottom.size(), 1) << "IP Layer takes a single blob as input."; CHECK_EQ(top->size(), 1) << "IP Layer takes a single blob as output."; const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term(); // Figure out the dimensions M_ = bottom[0]->num(); K_ = bottom[0]->count() / bottom[0]->num(); N_ = num_output; (*top)[0]->Reshape(bottom[0]->num(), num_output, 1, 1, 1); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize the weight this->blobs_[0].reset(new Blob<Dtype>(1, 1, 1, N_, K_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, 1, N_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization // Setting up the bias multiplier if (bias_term_) { bias_multiplier_.reset(new SyncedMemory(M_ * sizeof(Dtype))); Dtype* bias_multiplier_data = reinterpret_cast<Dtype*>(bias_multiplier_->mutable_cpu_data()); for (int i = 0; i < M_; ++i) { bias_multiplier_data[i] = 1.; } } }
void SparseInnerProductLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { // three bottom blobs are: value, indices and ptr M_ = bottom[2]->count() - 1; K_ = this->layer_param_.sparse_inner_product_param().input_dim(); N_ = this->layer_param_.sparse_inner_product_param().num_output(); bias_term_ = this->layer_param_.sparse_inner_product_param().bias_term(); transpose_ = this->layer_param_.sparse_inner_product_param().transpose(); if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize the weights vector<int> weight_shape(2); if (transpose_) { weight_shape[0] = K_; weight_shape[1] = N_; } else { weight_shape[0] = N_; weight_shape[1] = K_; } this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.sparse_inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.sparse_inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization this->param_propagate_down_.resize(this->blobs_.size(), true); }
void BNLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { frozen_ = this->layer_param_.bn_param().frozen(); moving_average_ = this->layer_param_.bn_param().moving_average(); bn_momentum_ = this->layer_param_.bn_param().momentum(); bn_eps_ = this->layer_param_.bn_param().eps(); // Initialize parameters if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (moving_average_) { this->blobs_.resize(4); } else { this->blobs_.resize(2); } vector<int> shape; shape.push_back(1); shape.push_back(bottom[0]->channels()); // slope this->blobs_[0].reset(new Blob<Dtype>(shape)); shared_ptr<Filler<Dtype> > slope_filler(GetFiller<Dtype>( this->layer_param_.bn_param().slope_filler())); slope_filler->Fill(this->blobs_[0].get()); // bias this->blobs_[1].reset(new Blob<Dtype>(shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.bn_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); if (this->blobs_.size() > 2) { // moving average mean this->blobs_[2].reset(new Blob<Dtype>(shape)); caffe_set(this->blobs_[2]->count(), Dtype(0), this->blobs_[2]->mutable_cpu_data()); // moving average variance this->blobs_[3].reset(new Blob<Dtype>(shape)); caffe_set(this->blobs_[3]->count(), Dtype(1), this->blobs_[3]->mutable_cpu_data()); } } this->param_propagate_down_.resize(this->blobs_.size(), true); }
void InnerProductLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) { Layer<Dtype>::SetUp(bottom, top); const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term(); // Figure out the dimensions M_ = bottom[0]->num(); K_ = bottom[0]->count() / bottom[0]->num(); N_ = num_output; (*top)[0]->Reshape(bottom[0]->num(), num_output, 1, 1); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight this->blobs_[0].reset(new Blob<Dtype>(1, 1, N_, K_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, N_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization // Setting up the bias multiplier if (bias_term_) { bias_multiplier_.Reshape(1, 1, 1, M_); caffe_set(M_, Dtype(1), bias_multiplier_.mutable_cpu_data()); } this->param_propagate_down_.resize(this->blobs_.size(), true); }
void EmbedLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { N_ = this->layer_param_.embed_param().num_output(); CHECK_GT(N_, 0) << "EmbedLayer num_output must be positive."; K_ = this->layer_param_.embed_param().input_dim(); CHECK_GT(K_, 0) << "EmbedLayer input_dim must be positive."; bias_term_ = this->layer_param_.embed_param().bias_term(); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize the weights -- // transposed from InnerProductLayer for spatial locality. vector<int> weight_shape(2); weight_shape[0] = K_; weight_shape[1] = N_; this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.embed_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, initialize and fill the bias term if (bias_term_) { vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.embed_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization this->param_propagate_down_.resize(this->blobs_.size(), true); }
void BaseConvolutionLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { // Configure the kernel size, padding, stride, and inputs. ConvolutionParameter conv_param = this->layer_param_.convolution_param(); force_nd_im2col_ = conv_param.force_nd_im2col(); channel_axis_ = bottom[0]->CanonicalAxisIndex(conv_param.axis()); const int num_axes = bottom[0]->num_axes(); if (num_axes == 5 && channel_axis_ == 1 && bottom[0]->shape(2) == 1) { forced_3d_ = true; } else { forced_3d_ = false; } const int first_spatial_axis = channel_axis_ + 1 + forced_3d_; num_spatial_axes_ = num_axes - first_spatial_axis; CHECK_GE(num_spatial_axes_, 0); vector<int> spatial_dim_blob_shape(1, std::max(num_spatial_axes_, 1)); // Setup filter kernel dimensions (kernel_shape_). kernel_shape_.Reshape(spatial_dim_blob_shape); int* kernel_shape_data = kernel_shape_.mutable_cpu_data(); if (conv_param.has_kernel_h() || conv_param.has_kernel_w()) { CHECK_EQ(num_spatial_axes_, 2) << "kernel_h & kernel_w can only be used for 2D convolution."; CHECK_EQ(0, conv_param.kernel_size_size()) << "Either kernel_size or kernel_h/w should be specified; not both."; kernel_shape_data[0] = conv_param.kernel_h(); kernel_shape_data[1] = conv_param.kernel_w(); } else { const int num_kernel_dims = conv_param.kernel_size_size(); CHECK(num_kernel_dims == 1 || num_kernel_dims == num_spatial_axes_) << "kernel_size must be specified once, or once per spatial dimension " << "(kernel_size specified " << num_kernel_dims << " times; " << num_spatial_axes_ << " spatial dims)."; for (int i = 0; i < num_spatial_axes_; ++i) { kernel_shape_data[i] = conv_param.kernel_size((num_kernel_dims == 1) ? 0 : i); } } for (int i = 0; i < num_spatial_axes_; ++i) { CHECK_GT(kernel_shape_data[i], 0) << "Filter dimensions must be nonzero."; } // Setup stride dimensions (stride_). stride_.Reshape(spatial_dim_blob_shape); int* stride_data = stride_.mutable_cpu_data(); if (conv_param.has_stride_h() || conv_param.has_stride_w()) { CHECK_EQ(num_spatial_axes_, 2) << "stride_h & stride_w can only be used for 2D convolution."; CHECK_EQ(0, conv_param.stride_size()) << "Either stride or stride_h/w should be specified; not both."; stride_data[0] = conv_param.stride_h(); stride_data[1] = conv_param.stride_w(); } else { const int num_stride_dims = conv_param.stride_size(); CHECK(num_stride_dims == 0 || num_stride_dims == 1 || num_stride_dims == num_spatial_axes_) << "stride must be specified once, or once per spatial dimension " << "(stride specified " << num_stride_dims << " times; " << num_spatial_axes_ << " spatial dims)."; const int kDefaultStride = 1; for (int i = 0; i < num_spatial_axes_; ++i) { stride_data[i] = (num_stride_dims == 0) ? kDefaultStride : conv_param.stride((num_stride_dims == 1) ? 0 : i); CHECK_GT(stride_data[i], 0) << "Stride dimensions must be nonzero."; } } // Setup pad dimensions (pad_). pad_.Reshape(spatial_dim_blob_shape); int* pad_data = pad_.mutable_cpu_data(); if (conv_param.has_pad_h() || conv_param.has_pad_w()) { CHECK_EQ(num_spatial_axes_, 2) << "pad_h & pad_w can only be used for 2D convolution."; CHECK_EQ(0, conv_param.pad_size()) << "Either pad or pad_h/w should be specified; not both."; pad_data[0] = conv_param.pad_h(); pad_data[1] = conv_param.pad_w(); } else { const int num_pad_dims = conv_param.pad_size(); CHECK(num_pad_dims == 0 || num_pad_dims == 1 || num_pad_dims == num_spatial_axes_) << "pad must be specified once, or once per spatial dimension " << "(pad specified " << num_pad_dims << " times; " << num_spatial_axes_ << " spatial dims)."; const int kDefaultPad = 0; for (int i = 0; i < num_spatial_axes_; ++i) { pad_data[i] = (num_pad_dims == 0) ? kDefaultPad : conv_param.pad((num_pad_dims == 1) ? 0 : i); } } // Setup dilation dimensions (dilation_). dilation_.Reshape(spatial_dim_blob_shape); int* dilation_data = dilation_.mutable_cpu_data(); const int num_dilation_dims = conv_param.dilation_size(); CHECK(num_dilation_dims == 0 || num_dilation_dims == 1 || num_dilation_dims == num_spatial_axes_) << "dilation must be specified once, or once per spatial dimension " << "(dilation specified " << num_dilation_dims << " times; " << num_spatial_axes_ << " spatial dims)."; const int kDefaultDilation = 1; for (int i = 0; i < num_spatial_axes_; ++i) { dilation_data[i] = (num_dilation_dims == 0) ? kDefaultDilation : conv_param.dilation((num_dilation_dims == 1) ? 0 : i); } // Special case: im2col is the identity for 1x1 convolution with stride 1 // and no padding, so flag for skipping the buffer and transformation. is_1x1_ = true; for (int i = 0; i < num_spatial_axes_; ++i) { is_1x1_ &= kernel_shape_data[i] == 1 && stride_data[i] == 1 && pad_data[i] == 0; if (!is_1x1_) { break; } } // Configure output channels and groups. channels_ = bottom[0]->shape(channel_axis_); num_output_ = this->layer_param_.convolution_param().num_output(); CHECK_GT(num_output_, 0); group_ = this->layer_param_.convolution_param().group(); CHECK_EQ(channels_ % group_, 0); CHECK_EQ(num_output_ % group_, 0) << "Number of output should be multiples of group."; if (reverse_dimensions()) { conv_out_channels_ = channels_; conv_in_channels_ = num_output_; } else { conv_out_channels_ = num_output_; conv_in_channels_ = channels_; } // Handle the parameters: weights and biases. // - blobs_[0] holds the filter weights // - blobs_[1] holds the biases (optional) vector<int> weight_shape(2); weight_shape[0] = conv_out_channels_; weight_shape[1] = conv_in_channels_ / group_; for (int i = 0; i < num_spatial_axes_; ++i) { weight_shape.push_back(kernel_shape_data[i]); } bias_term_ = this->layer_param_.convolution_param().bias_term(); vector<int> bias_shape(bias_term_, num_output_); if (this->blobs_.size() > 0) { CHECK_EQ(1 + bias_term_, this->blobs_.size()) << "Incorrect number of weight blobs."; // true_blob_shape is original blob_shape (n,c,h,w) in case of forced_3d_ // where blob_shape is expanded to (n,c,1,h,w) vector<int> true_blob_shape = this->blobs_[0]->shape(); if (forced_3d_) true_blob_shape.erase(true_blob_shape.begin()+2); if (weight_shape != true_blob_shape) { Blob<Dtype> weight_shaped_blob(weight_shape); LOG(FATAL) << "Incorrect weight shape: expected shape " << weight_shaped_blob.shape_string() << "; instead, shape was " << this->blobs_[0]->shape_string(); } if (bias_term_ && bias_shape != this->blobs_[1]->shape()) { Blob<Dtype> bias_shaped_blob(bias_shape); LOG(FATAL) << "Incorrect bias shape: expected shape " << bias_shaped_blob.shape_string() << "; instead, shape was " << this->blobs_[1]->shape_string(); } LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize and fill the weights: // output channels x input channels per-group x kernel height x kernel width this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, initialize and fill the biases. if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } kernel_dim_ = this->blobs_[0]->count(1); weight_offset_ = conv_out_channels_ * kernel_dim_ / group_; // Propagate gradients to the parameters (as directed by backward pass). this->param_propagate_down_.resize(this->blobs_.size(), true); }
void DeconvNormLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { CHECK_EQ(4, bottom[0]->num_axes()) << "Input must have 4 axes, " << "corresponding to (num, channels, height, width)"; LayerParameter deconv_param(this->layer_param()); deconv_param.mutable_convolution_param()->set_bias_term(false); deconv_param.mutable_convolution_param()->mutable_weight_filler()->set_type("constant"); deconv_param.mutable_convolution_param()->mutable_weight_filler()->set_value(0); deconv1_layer.reset(new DeconvolutionLayer<Dtype>(deconv_param)); deconv1_bottom_vec.clear(); deconv1_top_vec.clear(); deconv1_bottom_vec.push_back(&constant1); //constant1.Reshape(1, 1, 1, 1); constant1.Reshape(1, 1, bottom[0]->height(), bottom[0]->width()); deconv1_top_vec.push_back(&coef_norm); deconv1_layer->SetUp(deconv1_bottom_vec, deconv1_top_vec); deconv_param = LayerParameter(this->layer_param()); deconv_param.mutable_convolution_param()->set_bias_term(false); deconv2_layer.reset(new DeconvolutionLayer<Dtype>(deconv_param)); deconv2_top_vec.clear(); deconv2_top_vec.push_back(&deconv_val); deconv2_layer->SetUp(bottom, deconv2_top_vec); // Handle the parameters: weights and biases. // - blobs_[0] holds the filter weights // - blobs_[1] holds the biases (optional) bias_term_ = this->layer_param_.convolution_param().bias_term(); if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(3); } else { this->blobs_.resize(2); } // Initialize and fill the weights: // output channels x input channels per-group x kernel height x kernel width this->blobs_[0].reset(new Blob<Dtype>(deconv2_layer->blobs()[0]->shape())); this->blobs_[1].reset(new Blob<Dtype>(deconv1_layer->blobs()[0]->shape())); this->blobs_[0]->CopyFrom(*deconv2_layer->blobs()[0]); //this->blobs_[1]->CopyFrom(*deconv1_layer->blobs()[0]); shared_ptr<Filler<Dtype>> alpha_filler(GetFiller<Dtype>( this->layer_param_.deconvolution_param().alpha_filler())); alpha_filler->Fill(this->blobs_[1].get()); weights_alphas.reset(new Blob<Dtype>(deconv2_layer->blobs()[0]->shape())); alphas.reset(new Blob<Dtype>(deconv1_layer->blobs()[0]->shape())); Blob<Dtype> *alpha = alphas.get(); Blob<Dtype> *wa = weights_alphas.get(); deconv1_layer->blobs()[0]->ShareData(*alpha); deconv2_layer->blobs()[0]->ShareData(*wa); deconv1_layer->blobs()[0]->ShareDiff(*alpha); deconv2_layer->blobs()[0]->ShareDiff(*wa); // If necessary, initialize and fill the biases. if (bias_term_) { vector<int> bias_shape(1, this->layer_param_.convolution_param().num_output()); this->blobs_[2].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[2].get()); } } LayerParameter exp_param; exp_top_vec.clear(); exp_bottom_vec.clear(); exp_bottom_vec.push_back(this->blobs_[1].get()); exp_top_vec.push_back(alphas.get()); exp_layer.reset(new ExpLayer<Dtype>(exp_param)); exp_layer->SetUp(exp_bottom_vec, exp_top_vec); // Propagate gradients to the parameters (as directed by backward pass). this->param_propagate_down_.resize(this->blobs_.size(), true); average_train = true; if (this->layer_param_.has_deconvolution_param() && !this->layer_param_.deconvolution_param().average_train()) { this->param_propagate_down_[1] = false; average_train = false; } }
void ConvolutionPerforatedLayer<Dtype>::LayerSetUp( const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { // Configure the kernel size, padding, stride, and inputs. ConvolutionParameter conv_param = this->layer_param_.convolution_param(); if (conv_param.has_kernel_h() || conv_param.has_kernel_w()) { CHECK_EQ(0, conv_param.kernel_size_size()) << "Either kernel_size or kernel_h/w should be specified; not both."; kernel_h_ = conv_param.kernel_h(); kernel_w_ = conv_param.kernel_w(); } else { const int num_kernel_dims = conv_param.kernel_size_size(); CHECK(num_kernel_dims == 1 || num_kernel_dims == 2) << "kernel_size must be specified once, or once per spatial dimension "; kernel_h_ = conv_param.kernel_size(0); kernel_w_ = conv_param.kernel_size((num_kernel_dims == 1) ? 0 : 1); } CHECK_GT(kernel_h_, 0) << "Filter dimensions cannot be zero."; CHECK_GT(kernel_w_, 0) << "Filter dimensions cannot be zero."; // Setup stride dimensions (stride_). if (conv_param.has_stride_h() || conv_param.has_stride_w()) { CHECK_EQ(0, conv_param.stride_size()) << "Either stride or stride_h/w should be specified; not both."; stride_h_ = conv_param.stride_h(); stride_w_ = conv_param.stride_w(); } else { const int num_stride_dims = conv_param.stride_size(); CHECK(num_stride_dims == 0 || num_stride_dims == 1 || num_stride_dims == 2) << "stride must be specified once, or once per spatial dimension "; const int kDefaultStride = 1; stride_h_ = (num_stride_dims == 0) ? kDefaultStride : conv_param.stride(0); stride_w_ = (num_stride_dims == 0) ? kDefaultStride : conv_param.stride((num_stride_dims == 1) ? 0 : 1); } CHECK_GT(stride_h_, 0) << "Stride dimensions must be nonzero."; CHECK_GT(stride_w_, 0) << "Stride dimensions must be nonzero."; // Setup pad dimensions (pad_). if (conv_param.has_pad_h() || conv_param.has_pad_w()) { CHECK_EQ(0, conv_param.pad_size()) << "Either pad or pad_h/w should be specified; not both."; pad_h_ = conv_param.pad_h(); pad_w_ = conv_param.pad_w(); } else { const int num_pad_dims = conv_param.pad_size(); CHECK(num_pad_dims == 0 || num_pad_dims == 1 || num_pad_dims == 2) << "pad must be specified once, or once per spatial dimension "; const int kDefaultPad = 0; pad_h_ = (num_pad_dims == 0) ? kDefaultPad : conv_param.pad(0); pad_w_ = (num_pad_dims == 0) ? kDefaultPad : conv_param.pad((num_pad_dims == 1) ? 0 : 1); } // Configure output channels and groups. channels_ = bottom[0]->channels(); num_output_ = this->layer_param_.convolution_param().num_output(); CHECK_GT(num_output_, 0); group_ = this->layer_param_.convolution_param().group(); CHECK_EQ(channels_ % group_, 0); CHECK_EQ(num_output_ % group_, 0) << "Number of output should be multiples of group."; // Handle the parameters: weights and biases. // - blobs_[0] holds the filter weights // - blobs_[1] holds the biases (optional) vector<int> weight_shape(4); weight_shape[0] = num_output_; weight_shape[1] = channels_ / group_; weight_shape[2] = kernel_h_; weight_shape[3] = kernel_w_; bias_term_ = this->layer_param_.convolution_param().bias_term(); vector<int> bias_shape(bias_term_, num_output_); if (this->blobs_.size() > 0) { CHECK_EQ(1 + bias_term_, this->blobs_.size()) << "Incorrect number of weight blobs."; if (weight_shape != this->blobs_[0]->shape()) { Blob<Dtype> weight_shaped_blob(weight_shape); LOG(FATAL) << "Incorrect weight shape: expected shape " << weight_shaped_blob.shape_string() << "; instead, shape was " << this->blobs_[0]->shape_string(); } if (bias_term_ && bias_shape != this->blobs_[1]->shape()) { Blob<Dtype> bias_shaped_blob(bias_shape); LOG(FATAL) << "Incorrect bias shape: expected shape " << bias_shaped_blob.shape_string() << "; instead, shape was " << this->blobs_[1]->shape_string(); } LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize and fill the weights: // output channels x input channels per-group x kernel height x kernel width this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, initialize and fill the biases. if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Propagate gradients to the parameters (as directed by backward pass). this->param_propagate_down_.resize(this->blobs_.size(), true); }
void ConvolutionLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) { Layer<Dtype>::SetUp(bottom, top); kernel_size_ = this->layer_param_.convolution_param().kernel_size(); stride_ = this->layer_param_.convolution_param().stride(); group_ = this->layer_param_.convolution_param().group(); pad_ = this->layer_param_.convolution_param().pad(); num_ = bottom[0]->num(); channels_ = bottom[0]->channels(); height_ = bottom[0]->height(); width_ = bottom[0]->width(); num_output_ = this->layer_param_.convolution_param().num_output(); CHECK_GT(num_output_, 0); CHECK_EQ(channels_ % group_, 0); // The im2col result buffer would only hold one image at a time to avoid // overly large memory usage. int height_out = (height_ + 2 * pad_ - kernel_size_) / stride_ + 1; int width_out = (width_ + 2 * pad_ - kernel_size_) / stride_ + 1; col_buffer_.Reshape( 1, channels_ * kernel_size_ * kernel_size_, height_out, width_out); // Set the parameters CHECK_EQ(num_output_ % group_, 0) << "Number of output should be multiples of group."; bias_term_ = this->layer_param_.convolution_param().bias_term(); // Figure out the dimensions for individual gemms. M_ = num_output_ / group_; K_ = channels_ * kernel_size_ * kernel_size_ / group_; N_ = height_out * width_out; (*top)[0]->Reshape(bottom[0]->num(), num_output_, height_out, width_out); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight this->blobs_[0].reset(new Blob<Dtype>( num_output_, channels_ / group_, kernel_size_, kernel_size_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, num_output_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Set up the bias filler if (bias_term_) { bias_multiplier_.reset(new SyncedMemory(N_ * sizeof(Dtype))); Dtype* bias_multiplier_data = reinterpret_cast<Dtype*>(bias_multiplier_->mutable_cpu_data()); for (int i = 0; i < N_; ++i) { bias_multiplier_data[i] = 1.; } } }
void ConvolutionLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) { Layer<Dtype>::SetUp(bottom, top); LOG(INFO)<<"start setup conv layer"; //kernel_size_ = this->layer_param_.convolution_param().kernel_size(); if(this->layer_param_.convolution_param().has_kernel_size()){ kernel_h_=kernel_w_=kernel_d_=this->layer_param_.convolution_param().kernel_size(); }else{ kernel_h_=this->layer_param_.convolution_param().kernel_h(); kernel_w_=this->layer_param_.convolution_param().kernel_w(); kernel_d_=this->layer_param_.convolution_param().kernel_d(); } if(this->layer_param_.convolution_param().has_stride()){ stride_h_=stride_w_=stride_d_=this->layer_param_.convolution_param().stride(); }else{ stride_h_=this->layer_param_.convolution_param().stride_h(); stride_w_=this->layer_param_.convolution_param().stride_w(); stride_d_=this->layer_param_.convolution_param().stride_d(); } if(this->layer_param_.convolution_param().has_pad()){ pad_h_=pad_w_=pad_d_=this->layer_param_.convolution_param().pad(); }else{ pad_h_=this->layer_param_.convolution_param().pad_h(); pad_w_=this->layer_param_.convolution_param().pad_w(); pad_d_=this->layer_param_.convolution_param().pad_d(); } //stride_ = this->layer_param_.convolution_param().stride(); group_ = this->layer_param_.convolution_param().group(); // pad_ = this->layer_param_.convolution_param().pad(); num_ = bottom[0]->num(); channels_ = bottom[0]->channels(); height_ = bottom[0]->height(); width_ = bottom[0]->width(); depth_ = bottom[0]->depth(); // TODO: generalize to handle inputs of different shapes. for (int bottom_id = 1; bottom_id < bottom.size(); ++bottom_id) { CHECK_EQ(num_, bottom[bottom_id]->num()) << "Inputs must have same num."; CHECK_EQ(channels_, bottom[bottom_id]->channels()) << "Inputs must have same channels."; CHECK_EQ(height_, bottom[bottom_id]->height()) << "Inputs must have same height."; CHECK_EQ(width_, bottom[bottom_id]->width()) << "Inputs must have same width."; CHECK_EQ(depth_, bottom[bottom_id]->depth()) << "Inputs must have same depth."; } num_output_ = this->layer_param_.convolution_param().num_output(); LOG(INFO)<< "num of output from param = " <<num_output_; CHECK_GT(num_output_, 0); CHECK_EQ(channels_ % group_, 0); // The im2col result buffer would only hold one image at a time to avoid // overly large memory usage. int height_out = (height_ + 2 * pad_h_ - kernel_h_) / stride_h_ + 1; int width_out = (width_ + 2 * pad_w_ - kernel_w_) / stride_w_ + 1; int depth_out = (depth_ + 2 * pad_d_ - kernel_d_) / stride_d_ + 1; col_buffer_.Reshape( 1, channels_ * kernel_h_ * kernel_w_* kernel_d_, height_out, width_out, depth_out); LOG(INFO)<<"Done col_buffer_.Reshape"; // Set the parameters CHECK_EQ(num_output_ % group_, 0) << "Number of output should be multiples of group."; bias_term_ = this->layer_param_.convolution_param().bias_term(); // Figure out the dimensions for individual gemms. M_ = num_output_ / group_; //K_ = channels_ * kernel_size_ * kernel_size_ / group_; //N_ = height_out * width_out; K_ = channels_ * kernel_h_ * kernel_w_ * kernel_d_ / group_; N_ = height_out * width_out * depth_out; for (int top_id = 0; top_id < top->size(); ++top_id) { (*top)[top_id]->Reshape(num_, num_output_, height_out, width_out, depth_out); } LOG(INFO)<<"Done (*top)[top_id]->Reshape"; // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } LOG(INFO)<<"start seting up weight"; // Intialize the weight this->blobs_[0].reset(new Blob<Dtype>( num_output_, channels_ / group_, kernel_h_, kernel_w_, kernel_d_)); // fill the weights LOG(INFO)<<"num_output = "<<num_output_<<" chanels /group = " << channels_ <<"/" <<group_<<" =" <<channels_ / group_; shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().weight_filler())); LOG(INFO)<<"weight filler start fill weight"; weight_filler->Fill(this->blobs_[0].get()); LOG(INFO)<<"done setup weight"; // If necessary, initialize and fill the bias term if (bias_term_) { LOG(INFO)<<"convolution layer bias setting: there is/are " << num_output_ << " of bias"; this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, 1, num_output_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Set up the bias filler if (bias_term_) { bias_multiplier_.reset(new SyncedMemory(N_ * sizeof(Dtype))); Dtype* bias_multiplier_data = reinterpret_cast<Dtype*>(bias_multiplier_->mutable_cpu_data()); for (int i = 0; i < N_; ++i) { bias_multiplier_data[i] = 1.; } } LOG(INFO)<<"Done setup conv layer"; }
void CmpInnerProductLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term(); transpose_ = this->layer_param_.inner_product_param().transpose(); N_ = num_output; const int axis = bottom[0]->CanonicalAxisIndex( this->layer_param_.inner_product_param().axis()); // Dimensions starting from "axis" are "flattened" into a single // length K_ vector. For example, if bottom[0]'s shape is (N, C, H, W), // and axis == 1, N inner products with dimension CHW are performed. K_ = bottom[0]->count(axis); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize the weights vector<int> weight_shape(2); if (transpose_) { weight_shape[0] = K_; weight_shape[1] = N_; } else { weight_shape[0] = N_; weight_shape[1] = K_; } this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization this->param_propagate_down_.resize(this->blobs_.size(), true); this->sparse_ratio_ = this->layer_param_.inner_product_param().sparse_ratio(); this->class_num_ = this->layer_param_.inner_product_param().class_num(); this->quantize_term_ = this->layer_param_.inner_product_param().quantize_term(); int count = this->blobs_[0]->count() ; vector<int> mask_shape(1,count); this->masks_.Reshape(mask_shape); int *mask_data = this->masks_.mutable_cpu_data(); caffe_set(count, 1, this->masks_.mutable_cpu_data()); if(quantize_term_) { this->indices_.Reshape(mask_shape); vector<int> cen_shape(1,class_num_); this->centroids_.Reshape(cen_shape); this->tmpDiff_.Reshape(cen_shape); this->freq_.Reshape(cen_shape); } }
void ConvolutionSKLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { LOG(INFO)<< "Setting up CONV_SK_LAYER"; CHECK_EQ(4, bottom[0]->num_axes()) << "Input must have 4 axes, " << "corresponding to (num, channels, height, width)"; // Configure the kernel size, padding, stride, and inputs. ConvolutionParameter conv_param = this->layer_param_.convolution_param(); CHECK(!conv_param.has_kernel_size() != !(conv_param.has_kernel_h() && conv_param.has_kernel_w())) << "Filter size is kernel_size OR kernel_h and kernel_w; not both"; CHECK(conv_param.has_kernel_size() || (conv_param.has_kernel_h() && conv_param.has_kernel_w())) << "For non-square filters both kernel_h and kernel_w are required."; CHECK((!conv_param.has_pad() && conv_param.has_pad_h() && conv_param.has_pad_w()) || (!conv_param.has_pad_h() && !conv_param.has_pad_w())) << "pad is pad OR pad_h and pad_w are required."; CHECK((!conv_param.has_stride() && conv_param.has_stride_h() && conv_param.has_stride_w()) || (!conv_param.has_stride_h() && !conv_param.has_stride_w())) << "Stride is stride OR stride_h and stride_w are required."; if (conv_param.has_kernel_size()) { kernel_h_ = kernel_w_ = conv_param.kernel_size(); } else { kernel_h_ = conv_param.kernel_h(); kernel_w_ = conv_param.kernel_w(); } CHECK_GT(kernel_h_, 0) << "Filter dimensions cannot be zero."; CHECK_GT(kernel_w_, 0) << "Filter dimensions cannot be zero."; if (!conv_param.has_pad_h()) { pad_h_ = pad_w_ = conv_param.pad(); } else { pad_h_ = conv_param.pad_h(); pad_w_ = conv_param.pad_w(); } CHECK_EQ(this->pad_h_, 0) << "pad_h_ must be 0"; CHECK_EQ(this->pad_w_, 0) << "pad_w_ must be 0"; if (!conv_param.has_stride_h()) { stride_h_ = stride_w_ = conv_param.stride(); } else { stride_h_ = conv_param.stride_h(); stride_w_ = conv_param.stride_w(); } if (!conv_param.has_kstride_h()) { kstride_h_ = kstride_w_ = conv_param.kstride(); } else { kstride_h_ = conv_param.kstride_h(); kstride_w_ = conv_param.kstride_w(); } // Special case: im2col is the identity for 1x1 convolution with stride 1 // and no padding, so flag for skipping the buffer and transformation. is_1x1_ = kernel_w_ == 1 && kernel_h_ == 1 && stride_h_ == 1 && stride_w_ == 1 && pad_h_ == 0 && pad_w_ == 0; // Configure output channels and groups. channels_ = bottom[0]->channels(); num_output_ = this->layer_param_.convolution_param().num_output(); CHECK_GT(num_output_, 0); group_ = this->layer_param_.convolution_param().group(); CHECK_EQ(channels_ % group_, 0); CHECK_EQ(num_output_ % group_, 0) << "Number of output should be multiples of group."; if (reverse_dimensions()) { conv_out_channels_ = channels_; conv_in_channels_ = num_output_; } else { conv_out_channels_ = num_output_; conv_in_channels_ = channels_; } // Handle the parameters: weights and biases. // - blobs_[0] holds the filter weights // - blobs_[1] holds the biases (optional) bias_term_ = this->layer_param_.convolution_param().bias_term(); if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize and fill the weights: // output channels x input channels per-group x kernel height x kernel width this->blobs_[0].reset(new Blob<Dtype>( conv_out_channels_, conv_in_channels_ / group_, kernel_h_, kernel_w_)); shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, initialize and fill the biases. if (bias_term_) { vector<int> bias_shape(1, num_output_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Propagate gradients to the parameters (as directed by backward pass). this->param_propagate_down_.resize(this->blobs_.size(), true); }
void MKLBatchNormLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { eps_ = this->layer_param_.batch_norm_param().eps(); use_weight_bias_ = this->layer_param_.batch_norm_param().use_weight_bias(); bias_term_ = this->layer_param_.batch_norm_param().bias_term(); // Workaround. Checking count of parameters in order to handle // topology for reference BatchNorm layer which don't have scaling if (this->layer_param_.param_size() == 3) { this->blobs_.resize(3); use_weight_bias_ = false; } size_t dim = 4, sizes[4], strides[4]; channels_ = bottom[0]->channels(); height_ = bottom[0]->height(); width_ = bottom[0]->width(); num_ = bottom[0]->num(); sizes[0] = width_; sizes[1] = height_; sizes[2] = channels_; sizes[3] = num_; strides[0] = 1; strides[1] = sizes[0]; strides[2] = sizes[0]*sizes[1]; strides[3] = sizes[0]*sizes[1]*sizes[2]; // Names are for debugging only fwd_bottom_data->name = "fwd_bottom_data @ " + this->layer_param_.name(); fwd_top_data->name = "fwd_top_data @ " + this->layer_param_.name(); bwd_bottom_diff->name = "bwd_bottom_diff @ " + this->layer_param_.name(); bwd_top_diff->name = "bwd_top_diff @ " + this->layer_param_.name(); dnnError_t e; e = dnnLayoutCreate<Dtype>(&layout_usr_, dim, sizes, strides); CHECK_EQ(e, E_SUCCESS); fwd_bottom_data->create_user_layout(dim, sizes, strides); fwd_top_data ->create_user_layout(dim, sizes, strides); bwd_bottom_diff->create_user_layout(dim, sizes, strides); bwd_top_diff ->create_user_layout(dim, sizes, strides); workspace_buffer_ = NULL; scaleShift_buffer_ = NULL; // "Lazy" allocation because here we don't know // what layout is used by neighbours. // Primitives will be allocated during the first fwd pass batchNormFwd = NULL; batchNormBwdData = NULL; batchNormBwdScaleShift = NULL; if (use_weight_bias_) { if ( bias_term_ ) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize scale and shift vector<int> scaleshift_shape(1); scaleshift_shape[0] = channels_; this->blobs_[0].reset(new Blob<Dtype>(scaleshift_shape)); FillerParameter filler_param( this->layer_param_.batch_norm_param().filler()); if (!this->layer_param_.batch_norm_param().has_filler()) { filler_param.set_type("constant"); filler_param.set_value(1); } shared_ptr<Filler<Dtype> > filler(GetFiller<Dtype>(filler_param)); filler->Fill(this->blobs_[0].get()); if ( bias_term_ ) { this->blobs_[1].reset(new Blob<Dtype>(scaleshift_shape)); FillerParameter bias_filler_param( this->layer_param_.batch_norm_param().bias_filler()); if (!this->layer_param_.batch_norm_param().has_bias_filler()) { bias_filler_param.set_type("constant"); bias_filler_param.set_value(0); } shared_ptr<Filler<Dtype> > bias_filler( GetFiller<Dtype>(bias_filler_param)); bias_filler->Fill(this->blobs_[1].get()); } } }
void BaseConvolutionNDLayer<Dtype>::LayerSetUp( const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { // Configure the kernel size, padding, stride, and inputs. ConvolutionParameter conv_param = this->layer_param_.convolution_param(); channel_axis_ = bottom[0]->CanonicalAxisIndex(conv_param.axis()); const int first_spatial_axis = channel_axis_ + 1; const int num_axes = bottom[0]->num_axes(); num_spatial_axes_ = num_axes - first_spatial_axis; CHECK_GE(num_spatial_axes_, 1); // Setup input dimensions (input_shape_). vector<int> bottom_dim_blob_shape(1, num_spatial_axes_ + 1); input_shape_.Reshape(bottom_dim_blob_shape); int* input_shape_data = input_shape_.mutable_cpu_data(); for (int i = 0; i < num_spatial_axes_ + 1; ++i) { input_shape_data[i] = bottom[0]->shape(channel_axis_ + i); } vector<int> spatial_dim_blob_shape(1, num_spatial_axes_); // Setup filter kernel dimensions (kernel_shape_). kernel_shape_.Reshape(spatial_dim_blob_shape); int* kernel_shape_data = kernel_shape_.mutable_cpu_data(); if (conv_param.has_kernel_h() || conv_param.has_kernel_w()) { CHECK_EQ(num_spatial_axes_, 2) << "kernel_h & kernel_w can only be used for 2D convolution."; CHECK_EQ(0, conv_param.kernel_size_size()) << "Either kernel_size or kernel_h/w should be specified; not both."; kernel_shape_data[0] = conv_param.kernel_h(); kernel_shape_data[1] = conv_param.kernel_w(); } else { const int num_kernel_dims = conv_param.kernel_size_size(); CHECK(num_kernel_dims == 1 || num_kernel_dims == num_spatial_axes_) << "kernel_size must be specified once, or once per spatial dimension " << "(kernel_size specified " << num_kernel_dims << " times; " << num_spatial_axes_ << " spatial dims);"; for (int i = 0; i < num_spatial_axes_; ++i) { kernel_shape_data[i] = conv_param.kernel_size((num_kernel_dims == 1) ? 0 : i); } } for (int i = 0; i < num_spatial_axes_; ++i) { CHECK_GT(kernel_shape_data[i], 0) << "Filter dimensions must be nonzero."; } // Setup stride dimensions (stride_). stride_.Reshape(spatial_dim_blob_shape); int* stride_data = stride_.mutable_cpu_data(); if (conv_param.has_stride_h() || conv_param.has_stride_w()) { CHECK_EQ(num_spatial_axes_, 2) << "stride_h & stride_w can only be used for 2D convolution."; CHECK_EQ(0, conv_param.stride_size()) << "Either stride or stride_h/w should be specified; not both."; stride_data[0] = conv_param.stride_h(); stride_data[1] = conv_param.stride_w(); } else { const int num_stride_dims = conv_param.stride_size(); CHECK(num_stride_dims == 0 || num_stride_dims == 1 || num_stride_dims == num_spatial_axes_) << "stride must be specified once, or once per spatial dimension " << "(stride specified " << num_stride_dims << " times; " << num_spatial_axes_ << " spatial dims);"; const int kDefaultStride = 1; for (int i = 0; i < num_spatial_axes_; ++i) { stride_data[i] = (num_stride_dims == 0) ? kDefaultStride : conv_param.stride((num_stride_dims == 1) ? 0 : i); CHECK_GT(stride_data[i], 0) << "Stride dimensions must be nonzero."; } } // Setup pad dimensions (pad_). pad_.Reshape(spatial_dim_blob_shape); int* pad_data = pad_.mutable_cpu_data(); if (conv_param.has_pad_h() || conv_param.has_pad_w()) { CHECK_EQ(num_spatial_axes_, 2) << "pad_h & pad_w can only be used for 2D convolution."; CHECK_EQ(0, conv_param.pad_size()) << "Either pad or pad_h/w should be specified; not both."; pad_data[0] = conv_param.pad_h(); pad_data[1] = conv_param.pad_w(); } else { const int num_pad_dims = conv_param.pad_size(); CHECK(num_pad_dims == 0 || num_pad_dims == 1 || num_pad_dims == num_spatial_axes_) << "pad must be specified once, or once per spatial dimension " << "(pad specified " << num_pad_dims << " times; " << num_spatial_axes_ << " spatial dims);"; const int kDefaultPad = 0; for (int i = 0; i < num_spatial_axes_; ++i) { pad_data[i] = (num_pad_dims == 0) ? kDefaultPad : conv_param.pad((num_pad_dims == 1) ? 0 : i); } } // Special case: im2col is the identity for 1x1 convolution with stride 1 // and no padding, so flag for skipping the buffer and transformation. is_1x1_ = true; for (int i = 0; i < num_spatial_axes_; ++i) { is_1x1_ &= kernel_shape_data[i] == 1 && stride_data[i] == 1 && pad_data[i] == 0; if (!is_1x1_) { break; } } // Configure output channels and groups. channels_ = bottom[0]->shape(channel_axis_); num_output_ = this->layer_param_.convolution_param().num_output(); CHECK_GT(num_output_, 0); group_ = this->layer_param_.convolution_param().group(); CHECK_EQ(channels_ % group_, 0); CHECK_EQ(num_output_ % group_, 0) << "Number of output should be multiples of group."; if (reverse_dimensions()) { conv_out_channels_ = channels_; conv_in_channels_ = num_output_; } else { conv_out_channels_ = num_output_; conv_in_channels_ = channels_; } // Handle the parameters: weights and biases. // - blobs_[0] holds the filter weights // - blobs_[1] holds the biases (optional) bias_term_ = this->layer_param_.convolution_param().bias_term(); if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize and fill the weights: // output channels x input channels per-group x kernel height x kernel width vector<int> weight_shape(2); weight_shape[0] = conv_out_channels_; weight_shape[1] = conv_in_channels_ / group_; for (int i = 0; i < num_spatial_axes_; ++i) { weight_shape.push_back(kernel_shape_data[i]); } this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, initialize and fill the biases. if (bias_term_) { vector<int> bias_shape(1, num_output_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Propagate gradients to the parameters (as directed by backward pass). this->param_propagate_down_.resize(this->blobs_.size(), true); }
void InnerProductLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int num_output = this->layer_param_.inner_product_param().num_output(); bias_term_ = this->layer_param_.inner_product_param().bias_term(); transpose_ = this->layer_param_.inner_product_param().transpose(); // 全连接层输出神经元的个数 N_ = num_output; const int axis = bottom[0]->CanonicalAxisIndex( this->layer_param_.inner_product_param().axis()); // K_ 单个样本特征向量长度 // Dimensions starting from "axis" are "flattened" into a single // length K_ vector. For example, if bottom[0]'s shape is (N, C, H, W), // and axis == 1, N inner products with dimension CHW are performed. K_ = bottom[0]->count(axis); // 在Caffe.proto里,LayerParameter中有一个repeated blobs field,但是在更多 // net的定义文件即prototxt文件里并没有blobs,那么在这里将进行处理__显然,如 // 果this->blobs_.size()>0那么参数blob就不需要初始化了,skip;反之,则进行初始化 // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize the weights vector<int> weight_shape(2); if (transpose_) { weight_shape[0] = K_; weight_shape[1] = N_; } else { weight_shape[0] = N_; weight_shape[1] = K_; } // 可以认为blobs_[0]的维度为N_*K_,即通常,我们将权值矩阵设为N*K维。可以 // 这么认为,但是在实际上,在C++中数据都是存放在内存中,并没有所谓的矩阵的概念 this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); // fill the weights 定义了一个智能指针 shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the bias term if (bias_term_) { vector<int> bias_shape(1, N_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.inner_product_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // parameter initialization // param_propagate_down_是从Layer<Dtype> 继承来的数据成员 this->param_propagate_down_.resize(this->blobs_.size(), true); }
void TiedConvolutionLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype> *> &bottom, vector<Blob<Dtype> *> *top) { ConvolutionParameter conv_param = this->layer_param_.convolution_param(); CHECK(!conv_param.has_kernel_size() != !(conv_param.has_kernel_h() && conv_param.has_kernel_w())) << "Filter size is kernel_size OR kernel_h and kernel_w; not both"; CHECK(conv_param.has_kernel_size() || (conv_param.has_kernel_h() && conv_param.has_kernel_w())) << "For non-square filters both kernel_h and kernel_w are required."; CHECK((!conv_param.has_pad() && conv_param.has_pad_h() && conv_param.has_pad_w()) || (!conv_param.has_pad_h() && !conv_param.has_pad_w())) << "pad is pad OR pad_h and pad_w are required."; CHECK((!conv_param.has_stride() && conv_param.has_stride_h() && conv_param.has_stride_w()) || (!conv_param.has_stride_h() && !conv_param.has_stride_w())) << "Stride is stride OR stride_h and stride_w are required."; if (conv_param.has_kernel_size()) { kernel_h_ = kernel_w_ = conv_param.kernel_size(); } else { kernel_h_ = conv_param.kernel_h(); kernel_w_ = conv_param.kernel_w(); } CHECK_GT(kernel_h_, 0) << "Filter dimensions cannot be zero."; CHECK_GT(kernel_w_, 0) << "Filter dimensions cannot be zero."; if (!conv_param.has_pad_h()) { pad_h_ = pad_w_ = conv_param.pad(); } else { pad_h_ = conv_param.pad_h(); pad_w_ = conv_param.pad_w(); } if (!conv_param.has_stride_h()) { stride_h_ = stride_w_ = conv_param.stride(); } else { stride_h_ = conv_param.stride_h(); stride_w_ = conv_param.stride_w(); } // Configure output channels and groups. channels_ = bottom[0]->channels(); num_output_ = conv_param.num_output(); CHECK_GT(num_output_, 0); group_ = conv_param.group(); CHECK_EQ(channels_ % group_, 0); CHECK_EQ(num_output_ % group_, 0) << "Number of output should be multiples of group."; // Handle the parameters: weights and biases. // - blobs_[0] holds the filter weights // - blobs_[1] holds the biases (optional) bias_term_ = conv_param.bias_term(); if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight // output channels x input channels per-group x kernel height x kernel width this->blobs_[0].reset( new Blob<Dtype>(num_output_, channels_ / group_, kernel_h_, kernel_w_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler( GetFiller<Dtype>(conv_param.weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, intiialize and fill the biases: // 1 x 1 x 1 x output channels. if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, num_output_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( conv_param.bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Propagate gradients to the parameters (as directed by backward pass). this->param_propagate_down_.resize(this->blobs_.size(), true); };
void Convolution3DLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) { CHECK_EQ(bottom.size(), 1) << "Conv Layer takes a single blob as input."; CHECK_EQ(top->size(), 1) << "Conv Layer takes a single blob as output."; kernel_size_ = this->layer_param_.convolution_param().kernel_size(); kernel_depth_ = this->layer_param_.convolution_param().kernel_depth(); stride_ = this->layer_param_.convolution_param().stride(); temporal_stride_ = this->layer_param_.convolution_param().temporal_stride(); pad_ = this->layer_param_.convolution_param().pad(); temporal_pad_ = this->layer_param_.convolution_param().temporal_pad(); num_ = bottom[0]->num(); channels_ = bottom[0]->channels(); length_ = bottom[0]->length(); height_ = bottom[0]->height(); width_ = bottom[0]->width(); num_output_ = this->layer_param_.convolution_param().num_output(); filter_group_ = this->layer_param_.convolution_param().filter_group(); CHECK_GT(num_output_, 0); // number of output filters must be divided by filter_group CHECK_EQ(num_output_ % filter_group_, 0); // The vol2col result buffer would only hold one image at a time to avoid // overly large memory usage. int height_out = (height_ + 2 * pad_ - kernel_size_) / stride_ + 1; int width_out = (width_ + 2 * pad_ - kernel_size_) / stride_ + 1; int length_out = (length_ + 2 * temporal_pad_ - kernel_depth_) / temporal_stride_ + 1; // buffer for one image col_buffer_.Reshape( 1, channels_ * kernel_depth_ * kernel_size_ * kernel_size_, length_out, height_out, width_out); bias_term_ = this->layer_param_.convolution_param().bias_term(); // Figure out the dimensions for individual gemms. M_ = num_output_ / filter_group_; // doing convolution filter_group_ times per volume K_ = channels_ * kernel_depth_ * kernel_size_ * kernel_size_; N_ = length_out * height_out * width_out; // output size (*top)[0]->Reshape(bottom[0]->num(), num_output_, length_out, height_out, width_out); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize the weights this->blobs_[0].reset(new Blob<Dtype>( num_output_, channels_, kernel_depth_, kernel_size_, kernel_size_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, initialize and fill the bias term if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, 1, num_output_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Set up the bias filler if (bias_term_) { bias_multiplier_.reset(new SyncedMemory(N_ * sizeof(Dtype))); Dtype* bias_multiplier_data = reinterpret_cast<Dtype*>(bias_multiplier_->mutable_cpu_data()); for (int i = 0; i < N_; ++i) { bias_multiplier_data[i] = 1.; } } }
void CudnnNdConvolutionLayer<Dtype>::LayerSetUp( const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { ConvolutionParameter conv_param = this->layer_param_.convolution_param(); // Configure the kernel size, padding, stride, and inputs. CHECK(conv_param.has_kernel_shape()) << "Kernel shape is required."; if (conv_param.has_pad_shape()) { CHECK_EQ(conv_param.kernel_shape().dim_size(), conv_param.pad_shape().dim_size()) << "Kernel and Pad shape don't match !"; } if (conv_param.has_stride_shape()) { CHECK_EQ(conv_param.kernel_shape().dim_size(), conv_param.stride_shape().dim_size()) << "Kernel and Stride shape don't match !"; } for (int i = 0; i < conv_param.kernel_shape().dim_size(); ++i) { kernel_shape_.push_back(conv_param.kernel_shape().dim(i)); CHECK_GT(kernel_shape_[i], 0) << "Filter dimensions cannot be zero."; } if (conv_param.has_pad_shape()) { for (int i = 0; i < conv_param.kernel_shape().dim_size(); ++i) { pad_shape_.push_back(conv_param.pad_shape().dim(i)); } } else { pad_shape_ = std::vector<int>(kernel_shape_.size(), 0); } if (conv_param.has_stride_shape()) { for (int i = 0; i < conv_param.kernel_shape().dim_size(); ++i) { stride_shape_.push_back(conv_param.stride_shape().dim(i)); } } else { stride_shape_ = std::vector<int>(kernel_shape_.size(), 1); } // Configure output channels and groups. channels_ = bottom[0]->shape(1); num_output_ = this->layer_param_.convolution_param().num_output(); CHECK_GT(num_output_, 0); group_ = this->layer_param_.convolution_param().group(); CHECK_EQ(channels_ % group_, 0); CHECK_EQ(num_output_ % group_, 0) << "Number of output should be multiples of group."; // Handle the parameters: weights and biases. // - blobs_[0] holds the filter weights // - blobs_[1] holds the biases (optional) bias_term_ = this->layer_param_.convolution_param().bias_term(); vector<int> weight_shape(kernel_shape_); weight_shape.insert(weight_shape.begin(), channels_ / group_); weight_shape.insert(weight_shape.begin(), num_output_); if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Initialize and fill the weights: // output channels x input channels per-group x kernel height x kernel width this->blobs_[0].reset(new Blob<Dtype>(weight_shape)); shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); // If necessary, initialize and fill the biases. if (bias_term_) { vector<int> bias_shape(1, num_output_); this->blobs_[1].reset(new Blob<Dtype>(bias_shape)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.convolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Propagate gradients to the parameters (as directed by backward pass). this->param_propagate_down_.resize(this->blobs_.size(), true); // Initialize CUDA streams and cuDNN. stream_ = new cudaStream_t[this->group_ * CUDNN_STREAMS_PER_GROUP]; handle_ = new cudnnHandle_t[this->group_ * CUDNN_STREAMS_PER_GROUP]; workspaceSizeInBytes = 0; workspace_data_ = NULL; for (int g = 0; g < this->group_ * CUDNN_STREAMS_PER_GROUP; g++) { CUDA_CHECK(cudaStreamCreate(&stream_[g])); CUDNN_CHECK(cudnnCreate(&handle_[g])); CUDNN_CHECK(cudnnSetStream(handle_[g], stream_[g])); } // Set the indexing parameters. weight_shape[0] /= group_; weight_offset_ = 1; for (int i = 0; i < weight_shape.size(); ++i) { weight_offset_ *= weight_shape[i]; } bias_offset_ = weight_shape[0]; // Create filter descriptor. cudnn::createNdFilterDesc<Dtype>(&filter_desc_, weight_shape); bwd_filter_algo_= new cudnnConvolutionBwdFilterAlgo_t[bottom.size()]; bwd_data_algo_ = new cudnnConvolutionBwdDataAlgo_t[bottom.size()]; workspace_bwd_filter_sizes_ = new size_t[bottom.size()]; workspace_bwd_data_sizes_ = new size_t[bottom.size()]; workspace_ = new void*[this->group_ * CUDNN_STREAMS_PER_GROUP]; // Create tensor descriptor(s) for data and corresponding convolution(s). for (int i = 0; i < bottom.size(); i++) { cudnnTensorDescriptor_t bottom_desc; cudnn::createTensorDesc<Dtype>(&bottom_desc); bottom_descs_.push_back(bottom_desc); cudnnTensorDescriptor_t top_desc; cudnn::createTensorDesc<Dtype>(&top_desc); top_descs_.push_back(top_desc); cudnnConvolutionDescriptor_t conv_desc; cudnn::createConvolutionDesc<Dtype>(&conv_desc); conv_descs_.push_back(conv_desc); workspace_bwd_data_sizes_[i] = 0; workspace_bwd_filter_sizes_[i] = 0; } // Tensor descriptor for bias. if (this->bias_term_) { cudnn::createTensorDesc<Dtype>(&bias_desc_); } handles_setup_ = true; }
void DeConvolutionLayer<Dtype>::SetUp(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) { Layer<Dtype>::SetUp(bottom, top); // we need the output of the corresponding deconvolution in order to determine the size kernel_size_ = this->layer_param_.deconvolution_param().kernel_size(); stride_ = this->layer_param_.deconvolution_param().stride(); group_ = this->layer_param_.deconvolution_param().group(); pad_ = this->layer_param_.deconvolution_param().pad(); height_out_ = this->layer_param_.deconvolution_param().output_height(); width_out_ = this->layer_param_.deconvolution_param().output_width(); // JTS TODO check num_ <-> num_output num_ = bottom[0]->num(); // TODO read channels_ and num_output_ from optional second input channels_ = this->layer_param_.deconvolution_param().output_channels(); //channels_ = bottom[0]->channels(); height_ = bottom[0]->height(); width_ = bottom[0]->width(); //num_output_ = this->layer_param_.deconvolution_param().num_output(); num_output_ = this->layer_param_.deconvolution_param().output_channels(); int inverse_num_out = bottom[0]->channels(); CHECK_GT(inverse_num_out, 0); CHECK_EQ(channels_ % group_, 0); // init im2col result buffer //std::cout << height_ << " " << width_ << std::endl; //std::cout << "nout "<< num_output_ << " " << height_out_ << " " << width_out_ << std::endl; col_buffer_.Reshape( 1, channels_ * kernel_size_ * kernel_size_, height_, width_); // Set the parameters CHECK_EQ(inverse_num_out % group_, 0) << "Number of output should be multiples of group."; bias_term_ = this->layer_param_.convolution_param().bias_term(); // Figure out the dimensions for individual gemms. // JTS check N_ + K_ M_ = inverse_num_out / group_; K_ = channels_ * kernel_size_ * kernel_size_ / group_; N_ = height_ * width_; (*top)[0]->Reshape(bottom[0]->num(), num_output_, height_out_, width_out_); // Check if we need to set up the weights if (this->blobs_.size() > 0) { LOG(INFO) << "Skipping parameter initialization"; } else { if (bias_term_) { this->blobs_.resize(2); } else { this->blobs_.resize(1); } // Intialize the weight this->blobs_[0].reset(new Blob<Dtype>( inverse_num_out, channels_ / group_, kernel_size_, kernel_size_)); // fill the weights shared_ptr<Filler<Dtype> > weight_filler(GetFiller<Dtype>( this->layer_param_.deconvolution_param().weight_filler())); weight_filler->Fill(this->blobs_[0].get()); //std::cout << "wcount " << this->blobs_[0]->count() << std::endl; // If necessary, intiialize and fill the bias term if (bias_term_) { this->blobs_[1].reset(new Blob<Dtype>(1, 1, 1, num_output_)); shared_ptr<Filler<Dtype> > bias_filler(GetFiller<Dtype>( this->layer_param_.deconvolution_param().bias_filler())); bias_filler->Fill(this->blobs_[1].get()); } } // Set up the bias filler if (bias_term_) { bias_multiplier_.reset(new SyncedMemory(N_ * sizeof(Dtype))); Dtype* bias_multiplier_data = reinterpret_cast<Dtype*>(bias_multiplier_->mutable_cpu_data()); for (int i = 0; i < N_; ++i) { bias_multiplier_data[i] = 1.; } } }