void PowerLayer<Dtype>::Backward_cpu( const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) { if (propagate_down[0]) { Dtype* bottom_diff = bottom[0]->mutable_cpu_diff(); const int count = bottom[0]->count(); const Dtype* top_diff = top[0]->cpu_diff(); if (diff_scale_ == Dtype(0) || power_ == Dtype(1)) { caffe_set(count, diff_scale_, bottom_diff); } else { const Dtype* bottom_data = bottom[0]->cpu_data(); // Compute dy/dx = scale * power * (shift + scale * x)^(power - 1) // = diff_scale * y / (shift + scale * x) if (power_ == Dtype(2)) { // Special case for y = (shift + scale * x)^2 // -> dy/dx = 2 * scale * (shift + scale * x) // = diff_scale * shift + diff_scale * scale * x caffe_cpu_axpby( count, diff_scale_ * scale_, bottom_data, Dtype(0), bottom_diff); if (shift_ != Dtype(0)) { caffe_add_scalar(count, diff_scale_ * shift_, bottom_diff); } } else if (shift_ == Dtype(0)) { // Special case for y = (scale * x)^power // -> dy/dx = scale * power * (scale * x)^(power - 1) // = scale * power * (scale * x)^power * (scale * x)^(-1) // = power * y / x const Dtype* top_data = top[0]->cpu_data(); caffe_div(count, top_data, bottom_data, bottom_diff); caffe_scal(count, power_, bottom_diff); } else { caffe_copy(count, bottom_data, bottom_diff); if (scale_ != Dtype(1)) { caffe_scal(count, scale_, bottom_diff); } if (shift_ != Dtype(0)) { caffe_add_scalar(count, shift_, bottom_diff); } const Dtype* top_data = top[0]->cpu_data(); caffe_div<Dtype>(count, top_data, bottom_diff, bottom_diff); if (diff_scale_ != Dtype(1)) { caffe_scal(count, diff_scale_, bottom_diff); } } } if (diff_scale_ != Dtype(0)) { caffe_mul(count, top_diff, bottom_diff, bottom_diff); } } }
void MVNLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) { const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = (*top)[0]->mutable_cpu_data(); int num; if (this->layer_param_.mvn_param().across_channels()) num = bottom[0]->num(); else num = bottom[0]->num() * bottom[0]->channels(); int dim = bottom[0]->count() / num; Dtype eps = 1e-10; if (this->layer_param_.mvn_param().normalize_variance()) { // put the squares of bottom into temp_ caffe_powx(bottom[0]->count(), bottom_data, Dtype(2), temp_.mutable_cpu_data()); // computes variance using var(X) = E(X^2) - (EX)^2 caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1. / dim, bottom_data, sum_multiplier_.cpu_data(), 0., mean_.mutable_cpu_data()); // EX caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1. / dim, temp_.cpu_data(), sum_multiplier_.cpu_data(), 0., variance_.mutable_cpu_data()); // E(X^2) caffe_powx(mean_.count(), mean_.cpu_data(), Dtype(2), temp_.mutable_cpu_data()); // (EX)^2 caffe_sub(mean_.count(), variance_.cpu_data(), temp_.cpu_data(), variance_.mutable_cpu_data()); // variance // do mean and variance normalization // subtract mean caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, -1., mean_.cpu_data(), sum_multiplier_.cpu_data(), 0., temp_.mutable_cpu_data()); caffe_add(temp_.count(), bottom_data, temp_.cpu_data(), top_data); // normalize variance caffe_powx(variance_.count(), variance_.cpu_data(), Dtype(0.5), variance_.mutable_cpu_data()); caffe_add_scalar(variance_.count(), eps, variance_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, 1., variance_.cpu_data(), sum_multiplier_.cpu_data(), 0., temp_.mutable_cpu_data()); caffe_div(temp_.count(), top_data, temp_.cpu_data(), top_data); } else { caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1. / dim, bottom_data, sum_multiplier_.cpu_data(), 0., mean_.mutable_cpu_data()); // EX // subtract mean caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, -1., mean_.cpu_data(), sum_multiplier_.cpu_data(), 0., temp_.mutable_cpu_data()); caffe_add(temp_.count(), bottom_data, temp_.cpu_data(), top_data); } }
void DeconvNormLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { Dtype* wa = weights_alphas->mutable_cpu_data(); exp_layer->Forward(exp_bottom_vec, exp_top_vec); for (int ch_in = 0; ch_in < weights_alphas->num(); ++ch_in) { caffe_mul(alphas->count(), this->blobs_[0]->cpu_data() + this->blobs_[0]->offset(ch_in), alphas->cpu_data(), wa + weights_alphas->offset(ch_in)); } deconv2_layer->Forward(bottom, deconv2_top_vec); deconv1_layer->Forward(deconv1_bottom_vec, deconv1_top_vec); Dtype* top_data = top[0]->mutable_cpu_data(); const Dtype* deconv1_top_vec_data = deconv1_top_vec[0]->cpu_data(); const Dtype* deconv2_top_vec_data = deconv2_top_vec[0]->cpu_data(); caffe_add_scalar(deconv1_top_vec[0]->count(), (Dtype) std::numeric_limits<Dtype>::epsilon(), deconv1_top_vec[0]->mutable_cpu_data()); for (int n = 0; n < bottom[0]->num(); ++n) { caffe_div(deconv1_top_vec[0]->count(), deconv2_top_vec_data + deconv2_top_vec[0]->offset(n), deconv1_top_vec_data, top_data + top[0]->offset(n)); if (this->bias_term_) { const Dtype* bias = this->blobs_[2]->cpu_data(); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, top[0]->channels(), top[0]->height() * top[0]->width(), 1, (Dtype)1., bias, bias_multiplier.cpu_data(), (Dtype)1., top_data + top[0]->offset(n)); } } }
void RMSPropSolver<Dtype>::ComputeUpdateValue(int param_id, Dtype rate) { const vector<Blob<Dtype>*>& net_params = this->net_->learnable_params(); const vector<float>& net_params_lr = this->net_->params_lr(); // get the learning rate Dtype delta = this->param_.delta(); Dtype rms_decay = this->param_.rms_decay(); Dtype local_rate = rate * net_params_lr[param_id]; switch (Caffe::mode()) { case Caffe::CPU: // compute square of gradient in update caffe_powx(net_params[param_id]->count(), net_params[param_id]->cpu_diff(), Dtype(2), this->update_[param_id]->mutable_cpu_data()); // update history caffe_cpu_axpby(net_params[param_id] -> count(), Dtype(1-rms_decay), this->update_[param_id]->cpu_data(), rms_decay, this->history_[param_id]-> mutable_cpu_data()); // prepare update caffe_powx(net_params[param_id]->count(), this->history_[param_id]->cpu_data(), Dtype(0.5), this->update_[param_id]->mutable_cpu_data()); caffe_add_scalar(net_params[param_id]->count(), delta, this->update_[param_id]->mutable_cpu_data()); caffe_div(net_params[param_id]->count(), net_params[param_id]->cpu_diff(), this->update_[param_id]->cpu_data(), this->update_[param_id]->mutable_cpu_data()); // scale and copy caffe_cpu_axpby(net_params[param_id]->count(), local_rate, this->update_[param_id]->cpu_data(), Dtype(0), net_params[param_id]->mutable_cpu_diff()); break; case Caffe::GPU: #ifndef CPU_ONLY rmsprop_update_gpu(net_params[param_id]->count(), net_params[param_id]->mutable_gpu_diff(), this->history_[param_id]->mutable_gpu_data(), rms_decay, delta, local_rate); #else NO_GPU; #endif break; default: LOG(FATAL) << "Unknown caffe mode: " << Caffe::mode(); } }
void BiasChannelLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const BiasChannelParameter_LabelType label_type = this->layer_param_.bias_channel_param().label_type(); caffe_copy(bottom[0]->count(), bottom[0]->cpu_data(), top[0]->mutable_cpu_data()); for (int n = 0; n < num_; ++n) { if (label_type == BiasChannelParameter_LabelType_IMAGE) { for (int j = 0; j < max_labels_; ++j) { const int label = static_cast<int>(*bottom[1]->cpu_data_at(n, j)); if (ignore_label_.count(label) != 0) { continue; } else if (label >= 0 && label < channels_) { // Bias the foreground or background scores const Dtype bias = (label == 0) ? bg_bias_ : fg_bias_; caffe_add_scalar(height_ * width_, bias, top[0]->mutable_cpu_data_at(n, label)); } else { LOG(FATAL) << "Unexpected label " << label; } } } else if (label_type == BiasChannelParameter_LabelType_PIXEL) { const Dtype *label_data = bottom[1]->cpu_data_at(n); Dtype *top_data = top[0]->mutable_cpu_data_at(n); const int spatial_dim = height_ * width_; for (int j = 0; j < spatial_dim; ++j) { const int label = static_cast<int>(label_data[j]); if (ignore_label_.count(label) != 0) { continue; } else if (has_background_label_) { if (label == background_label_) { top_data[background_label_ * spatial_dim + j] += bg_bias_; } else if (label >= 0 && label < channels_) { // Bias the foreground and background scores top_data[background_label_ * spatial_dim + j] += bg_bias_; top_data[label * spatial_dim + j] += fg_bias_; } else { LOG(FATAL) << "Unexpected label " << label; } } else { if (label >= 0 && label < channels_) { top_data[label * spatial_dim + j] += fg_bias_; } else { LOG(FATAL) << "Unexpected label " << label; } } } } } }
void RmseLossLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, vector<Blob<Dtype>*>* top) { num_rating_ = bottom[2]->cpu_data()[0]; int count = bottom[0]->count(); CHECK_LE(num_rating_, count) << "assigned rating length exceed boundary."; // const Dtype* data = bottom[0]->cpu_data(); // std::cout << "data" << std::endl; // for (int i = 0; i < 10; i++){ // std::cout << data[i] << "\t"; // } // std::cout << std::endl; // const Dtype* label = bottom[1]->cpu_data(); // std::cout << "label" << std::endl; // for (int i = 0; i < 10; i++){ // std::cout << label[i] << "\t"; // } // std::cout << std::endl; caffe_sub( num_rating_, bottom[0]->cpu_data(), bottom[1]->cpu_data(), diff_.mutable_cpu_data()); if (bias_!=0) { caffe_add_scalar(num_rating_, bias_, diff_.mutable_cpu_data()); } // const Dtype* diff_cpu = diff_.cpu_data(); // std::cout << "diff_cpu" << std::endl; // for (int i = 0; i < 10; i++){ // std::cout << diff_cpu[i] << "\t"; // } // std::cout << std::endl; Dtype dot = caffe_cpu_dot(num_rating_, diff_.cpu_data(), diff_.cpu_data()); // std::cout << "dot:" << dot << std::endl; // Dtype loss = dot / bottom[0]->num() / Dtype(2); Dtype loss = sqrt(dot / num_rating_); // rmse, temp for movielens. (*top)[0]->mutable_cpu_data()[0] = loss; // LOG(INFO) << "loss:" << loss << " num_rating_:" << num_rating_; }
void LogLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) { if (!propagate_down[0]) { return; } const int count = bottom[0]->count(); const Dtype* bottom_data = bottom[0]->cpu_data(); const Dtype* top_diff = top[0]->cpu_diff(); Dtype* bottom_diff = bottom[0]->mutable_cpu_diff(); caffe_cpu_copy(count, bottom_data, bottom_diff); if (input_scale_ != Dtype(1)) { caffe_scal(count, input_scale_, bottom_diff); } if (input_shift_ != Dtype(0)) { caffe_add_scalar(count, input_shift_, bottom_diff); } caffe_powx(count, bottom_diff, Dtype(-1), bottom_diff); if (backward_num_scale_ != Dtype(1)) { caffe_scal(count, backward_num_scale_, bottom_diff); } caffe_mul(count, top_diff, bottom_diff, bottom_diff); }
void MVNLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); int num; if (this->layer_param_.mvn_param().across_channels()) num = bottom[0]->num(); else num = bottom[0]->num() * bottom[0]->channels(); int dim = bottom[0]->count() / num; // subtract mean caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1. / dim, bottom_data, sum_multiplier_.cpu_data(), 0., mean_.mutable_cpu_data()); // EX caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, -1., mean_.cpu_data(), sum_multiplier_.cpu_data(), 0., temp_.mutable_cpu_data()); caffe_add(temp_.count(), bottom_data, temp_.cpu_data(), top_data); // X-EX if (this->layer_param_.mvn_param().normalize_variance()) { // compute variance using var(X) = E((X-EX)^2) caffe_powx(bottom[0]->count(), top_data, Dtype(2), temp_.mutable_cpu_data()); // (X-EX)^2 caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1. / dim, temp_.cpu_data(), sum_multiplier_.cpu_data(), 0., variance_.mutable_cpu_data()); // E((X-EX)^2) // normalize variance caffe_powx(variance_.count(), variance_.cpu_data(), Dtype(0.5), variance_.mutable_cpu_data()); caffe_add_scalar(variance_.count(), eps_, variance_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, 1., variance_.cpu_data(), sum_multiplier_.cpu_data(), 0., temp_.mutable_cpu_data()); caffe_div(temp_.count(), top_data, temp_.cpu_data(), top_data); } }
void LogLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const int count = bottom[0]->count(); const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); if (input_scale_ == Dtype(1) && input_shift_ == Dtype(0)) { caffe_log(count, bottom_data, top_data); } else { caffe_cpu_copy(count, bottom_data, top_data); if (input_scale_ != Dtype(1)) { caffe_scal(count, input_scale_, top_data); } if (input_shift_ != Dtype(0)) { caffe_add_scalar(count, input_shift_, top_data); } caffe_log(count, top_data, top_data); } if (base_scale_ != Dtype(1)) { caffe_scal(count, base_scale_, top_data); } }
void PowerLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { Dtype* top_data = top[0]->mutable_cpu_data(); const int count = bottom[0]->count(); // Special case where we can ignore the input: scale or power is 0. if (diff_scale_ == Dtype(0)) { Dtype value = (power_ == 0) ? Dtype(1) : pow(shift_, power_); caffe_set(count, value, top_data); return; } const Dtype* bottom_data = bottom[0]->cpu_data(); caffe_copy(count, bottom_data, top_data); if (scale_ != Dtype(1)) { caffe_scal(count, scale_, top_data); } if (shift_ != Dtype(0)) { caffe_add_scalar(count, shift_, top_data); } if (power_ != Dtype(1)) { caffe_powx(count, top_data, power_, top_data); } }
void AdaGradSolver<Dtype>::ComputeUpdateValue(uint_tp param_id, Dtype rate) { CHECK(Caffe::root_solver()); const vector<Blob<Dtype>*>& net_params = this->net_->learnable_params(); const vector<float>& net_params_lr = this->net_->params_lr(); Dtype delta = this->param_.delta(); Dtype local_rate = rate * net_params_lr[param_id]; switch (Caffe::mode()) { case Caffe::CPU: { // compute square of gradient in update caffe_powx(net_params[param_id]->count(), net_params[param_id]->cpu_diff(), Dtype(2), this->update_[param_id]->mutable_cpu_data()); // update history caffe_add(net_params[param_id]->count(), this->update_[param_id]->cpu_data(), this->history_[param_id]->cpu_data(), this->history_[param_id]->mutable_cpu_data()); // prepare update caffe_powx(net_params[param_id]->count(), this->history_[param_id]->cpu_data(), Dtype(0.5), this->update_[param_id]->mutable_cpu_data()); caffe_add_scalar(net_params[param_id]->count(), delta, this->update_[param_id]->mutable_cpu_data()); caffe_div(net_params[param_id]->count(), net_params[param_id]->cpu_diff(), this->update_[param_id]->cpu_data(), this->update_[param_id]->mutable_cpu_data()); // scale and copy caffe_cpu_axpby(net_params[param_id]->count(), local_rate, this->update_[param_id]->cpu_data(), Dtype(0), net_params[param_id]->mutable_cpu_diff()); break; } case Caffe::GPU: { #ifndef CPU_ONLY if (this->device_->backend() == BACKEND_CUDA) { #ifdef USE_CUDA // compute square of gradient in update caffe_gpu_powx(net_params[param_id]->count(), net_params[param_id]->gpu_diff(), Dtype(2), this->update_[param_id]->mutable_gpu_data()); // update history caffe_gpu_add(net_params[param_id]->count(), this->update_[param_id]->gpu_data(), this->history_[param_id]->gpu_data(), this->history_[param_id]->mutable_gpu_data()); // prepare update caffe_gpu_powx(net_params[param_id]->count(), this->history_[param_id]->gpu_data(), Dtype(0.5), this->update_[param_id]->mutable_gpu_data()); caffe_gpu_add_scalar(net_params[param_id]->count(), delta, this->update_[param_id]->mutable_gpu_data()); caffe_gpu_div(net_params[param_id]->count(), net_params[param_id]->gpu_diff(), this->update_[param_id]->gpu_data(), this->update_[param_id]->mutable_gpu_data()); // scale and copy caffe_gpu_axpby(net_params[param_id]->count(), local_rate, this->update_[param_id]->gpu_data(), Dtype(0), net_params[param_id]->mutable_gpu_diff()); #endif // USE_CUDA } else { #ifdef USE_GREENTEA // compute square of gradient in update greentea_gpu_powx<Dtype>( this->device_->id(), net_params[param_id]->count(), (cl_mem) (net_params[param_id]->gpu_diff()), 0, Dtype(2), (cl_mem) (this->update_[param_id]->mutable_gpu_data()), 0); // update history greentea_gpu_add<Dtype>( this->device_->id(), net_params[param_id]->count(), (cl_mem) (this->update_[param_id]->gpu_data()), 0, (cl_mem) (this->history_[param_id]->gpu_data()), 0, (cl_mem) (this->history_[param_id]->mutable_gpu_data()), 0); // prepare update greentea_gpu_powx<Dtype>( this->device_->id(), net_params[param_id]->count(), (cl_mem) (this->history_[param_id]->gpu_data()), 0, Dtype(0.5), (cl_mem) (this->update_[param_id]->mutable_gpu_data()), 0); greentea_gpu_add_scalar<Dtype>( this->device_->id(), net_params[param_id]->count(), delta, (cl_mem) (this->update_[param_id]->mutable_gpu_data()), 0); greentea_gpu_div<Dtype>( this->device_->id(), net_params[param_id]->count(), (cl_mem) (net_params[param_id]->gpu_diff()), 0, (cl_mem) (this->update_[param_id]->gpu_data()), 0, (cl_mem) (this->update_[param_id]->mutable_gpu_data()), 0); // scale and copy greentea_gpu_axpby<Dtype>( this->device_->id(), net_params[param_id]->count(), local_rate, (cl_mem) (this->update_[param_id]->gpu_data()), 0, Dtype(0), (cl_mem) (net_params[param_id]->mutable_gpu_diff()), 0); #endif // USE_GREENTEA } #else NO_GPU; #endif break; } default: LOG(FATAL)<< "Unknown caffe mode: " << Caffe::mode(); } }
void AdaGradSolver<Dtype>::ComputeUpdateValue() { vector<shared_ptr<Blob<Dtype> > >& net_params = this->net_->params(); vector<float>& net_params_lr = this->net_->params_lr(); vector<float>& net_params_weight_decay = this->net_->params_weight_decay(); // get the learning rate Dtype rate = this->GetLearningRate(); Dtype delta = this->param_.delta(); if (this->param_.display() && this->iter_ % this->param_.display() == 0) { LOG(INFO) << "Iteration " << this->iter_ << ", lr = " << rate; } Dtype weight_decay = this->param_.weight_decay(); string regularization_type = this->param_.regularization_type(); switch (Caffe::mode()) { case Caffe::CPU: for (int param_id = 0; param_id < net_params.size(); ++param_id) { Dtype local_rate = rate * net_params_lr[param_id]; Dtype local_decay = weight_decay * net_params_weight_decay[param_id]; if (local_decay) { if (regularization_type == "L2") { // add weight decay caffe_axpy(net_params[param_id]->count(), local_decay, net_params[param_id]->cpu_data(), net_params[param_id]->mutable_cpu_diff()); } else if (regularization_type == "L1") { caffe_cpu_sign(net_params[param_id]->count(), net_params[param_id]->cpu_data(), this->temp_[param_id]->mutable_cpu_data()); caffe_axpy(net_params[param_id]->count(), local_decay, this->temp_[param_id]->cpu_data(), net_params[param_id]->mutable_cpu_diff()); } else { LOG(FATAL) << "Unknown regularization type: " << regularization_type; } } // compute square of gradient in update caffe_powx(net_params[param_id]->count(), net_params[param_id]->cpu_diff(), Dtype(2), this->update_[param_id]->mutable_cpu_data()); // update history caffe_add(net_params[param_id]->count(), this->update_[param_id]->cpu_data(), this->history_[param_id]->cpu_data(), this->history_[param_id]->mutable_cpu_data()); // prepare update caffe_powx(net_params[param_id]->count(), this->history_[param_id]->cpu_data(), Dtype(0.5), this->update_[param_id]->mutable_cpu_data()); caffe_add_scalar(net_params[param_id]->count(), delta, this->update_[param_id]->mutable_cpu_data()); caffe_div(net_params[param_id]->count(), net_params[param_id]->cpu_diff(), this->update_[param_id]->cpu_data(), this->update_[param_id]->mutable_cpu_data()); // scale and copy caffe_cpu_axpby(net_params[param_id]->count(), local_rate, this->update_[param_id]->cpu_data(), Dtype(0), net_params[param_id]->mutable_cpu_diff()); } break; case Caffe::GPU: #ifndef CPU_ONLY for (int param_id = 0; param_id < net_params.size(); ++param_id) { Dtype local_rate = rate * net_params_lr[param_id]; Dtype local_decay = weight_decay * net_params_weight_decay[param_id]; if (local_decay) { if (regularization_type == "L2") { // add weight decay caffe_gpu_axpy(net_params[param_id]->count(), local_decay, net_params[param_id]->gpu_data(), net_params[param_id]->mutable_gpu_diff()); } else if (regularization_type == "L1") { caffe_gpu_sign(net_params[param_id]->count(), net_params[param_id]->gpu_data(), this->temp_[param_id]->mutable_gpu_data()); caffe_gpu_axpy(net_params[param_id]->count(), local_decay, this->temp_[param_id]->gpu_data(), net_params[param_id]->mutable_gpu_diff()); } else { LOG(FATAL) << "Unknown regularization type: " << regularization_type; } } // compute square of gradient in update caffe_gpu_powx(net_params[param_id]->count(), net_params[param_id]->gpu_diff(), Dtype(2), this->update_[param_id]->mutable_gpu_data()); // update history caffe_gpu_add(net_params[param_id]->count(), this->update_[param_id]->gpu_data(), this->history_[param_id]->gpu_data(), this->history_[param_id]->mutable_gpu_data()); // prepare update caffe_gpu_powx(net_params[param_id]->count(), this->history_[param_id]->gpu_data(), Dtype(0.5), this->update_[param_id]->mutable_gpu_data()); caffe_gpu_add_scalar(net_params[param_id]->count(), delta, this->update_[param_id]->mutable_gpu_data()); caffe_gpu_div(net_params[param_id]->count(), net_params[param_id]->gpu_diff(), this->update_[param_id]->gpu_data(), this->update_[param_id]->mutable_gpu_data()); // scale and copy caffe_gpu_axpby(net_params[param_id]->count(), local_rate, this->update_[param_id]->gpu_data(), Dtype(0), net_params[param_id]->mutable_gpu_diff()); } #else NO_GPU; #endif break; default: LOG(FATAL) << "Unknown caffe mode: " << Caffe::mode(); } }
void BNLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, const vector<Blob<Dtype>*>& bottom) { if (frozen_) { if (propagate_down[0]) { const Dtype* const_top_diff = top[0]->cpu_diff(); Dtype* bottom_diff = bottom[0]->mutable_cpu_diff(); // Use the moving average variance caffe_copy(batch_statistic_.count(), this->blobs_[3]->cpu_data(), batch_statistic_.mutable_cpu_data()); // Add eps caffe_add_scalar(batch_statistic_.count(), bn_eps_, batch_statistic_.mutable_cpu_data()); // Standard deviation caffe_powx(batch_statistic_.count(), batch_statistic_.cpu_data(), Dtype(0.5), batch_statistic_.mutable_cpu_data()); // Divide slope by std caffe_div(batch_statistic_.count(), this->blobs_[0]->cpu_data(), batch_statistic_.cpu_data(), batch_statistic_.mutable_cpu_data()); // Broadcast caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_statistic_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), broadcast_buffer_.mutable_cpu_data()); // Elementwise multiply top grad with (slope / std) caffe_mul(broadcast_buffer_.count(), const_top_diff, broadcast_buffer_.cpu_data(), bottom_diff); } return; } // gradient w.r.t. slope if (this->param_propagate_down_[0]) { const Dtype* const_top_diff = top[0]->cpu_diff(); Dtype* scale_diff = this->blobs_[0]->mutable_cpu_diff(); caffe_mul(broadcast_buffer_.count(), x_norm_.cpu_data(), const_top_diff, broadcast_buffer_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasNoTrans, num_ * channels_, height_ * width_, Dtype(1), broadcast_buffer_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasTrans, num_, channels_, Dtype(1), spatial_statistic_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(1), scale_diff); } // gradient w.r.t. bias if (this->param_propagate_down_[1]) { const Dtype* const_top_diff = top[0]->cpu_diff(); Dtype* shift_diff = this->blobs_[1]->mutable_cpu_diff(); caffe_cpu_gemv<Dtype>(CblasNoTrans, num_ * channels_, height_ * width_, Dtype(1), const_top_diff, spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasTrans, num_, channels_, Dtype(1), spatial_statistic_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(1), shift_diff); } // gradient w.r.t. normalized inputs if (propagate_down[0]) { const Dtype* const_top_diff = top[0]->cpu_diff(); const Dtype* const_bottom_diff = bottom[0]->cpu_diff(); Dtype* bottom_diff = bottom[0]->mutable_cpu_diff(); const Dtype* scale_data = this->blobs_[0]->cpu_data(); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), scale_data, Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), broadcast_buffer_.mutable_cpu_data()); caffe_mul(broadcast_buffer_.count(), const_top_diff, broadcast_buffer_.cpu_data(), broadcast_buffer_.mutable_cpu_data()); // sum of x_hat * (dl / dx_hat) caffe_mul(broadcast_buffer_.count(), x_norm_.cpu_data(), broadcast_buffer_.cpu_data(), bottom_diff); caffe_cpu_gemv<Dtype>(CblasNoTrans, num_ * channels_, height_ * width_, Dtype(1), const_bottom_diff, spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasTrans, num_, channels_, Dtype(1), spatial_statistic_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(0), batch_statistic_.mutable_cpu_data()); // x_hat times the sum caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_statistic_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), bottom_diff); caffe_mul(broadcast_buffer_.count(), x_norm_.cpu_data(), const_bottom_diff, bottom_diff); // Subtract the average of x_hat times the sum caffe_cpu_gemv<Dtype>(CblasNoTrans, num_ * channels_, height_ * width_, Dtype(1), broadcast_buffer_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasTrans, num_, channels_, Dtype(1), spatial_statistic_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(0), batch_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_statistic_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(1), bottom_diff); caffe_cpu_axpby(broadcast_buffer_.count(), Dtype(1), broadcast_buffer_.cpu_data(), Dtype(-1) / (num_ * height_ * width_), bottom_diff); // Divide by the std caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), x_std_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), broadcast_buffer_.mutable_cpu_data()); caffe_div(broadcast_buffer_.count(), const_bottom_diff, broadcast_buffer_.cpu_data(), bottom_diff); } }
void MVNLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top, const vector<bool>& propagate_down, vector<Blob<Dtype>*>* bottom) { const Dtype* top_diff = top[0]->cpu_diff(); const Dtype* top_data = top[0]->cpu_data(); const Dtype* bottom_data = (*bottom)[0]->cpu_data(); Dtype* bottom_diff = (*bottom)[0]->mutable_cpu_diff(); int num; if (this->layer_param_.mvn_param().across_channels()) num = (*bottom)[0]->num(); else num = (*bottom)[0]->num() * (*bottom)[0]->channels(); int dim = (*bottom)[0]->count() / num; Dtype eps = 1e-10; if (this->layer_param_.mvn_param().normalize_variance()) { caffe_mul(temp_.count(), top_data, top_diff, bottom_diff); caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1., bottom_diff, sum_multiplier_.cpu_data(), 0., mean_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, 1., mean_.cpu_data(), sum_multiplier_.cpu_data(), 0., bottom_diff); caffe_mul(temp_.count(), top_data, bottom_diff, bottom_diff); caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1., top_diff, sum_multiplier_.cpu_data(), 0., mean_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, 1., mean_.cpu_data(), sum_multiplier_.cpu_data(), 1., bottom_diff); caffe_cpu_axpby(temp_.count(), Dtype(1), top_diff, Dtype(-1. / dim), bottom_diff); // put the squares of bottom into temp_ caffe_powx(temp_.count(), bottom_data, Dtype(2), temp_.mutable_cpu_data()); // computes variance using var(X) = E(X^2) - (EX)^2 caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1. / dim, bottom_data, sum_multiplier_.cpu_data(), 0., mean_.mutable_cpu_data()); // EX caffe_cpu_gemv<Dtype>(CblasNoTrans, num, dim, 1. / dim, temp_.cpu_data(), sum_multiplier_.cpu_data(), 0., variance_.mutable_cpu_data()); // E(X^2) caffe_powx(mean_.count(), mean_.cpu_data(), Dtype(2), temp_.mutable_cpu_data()); // (EX)^2 caffe_sub(mean_.count(), variance_.cpu_data(), temp_.cpu_data(), variance_.mutable_cpu_data()); // variance // normalize variance caffe_powx(variance_.count(), variance_.cpu_data(), Dtype(0.5), variance_.mutable_cpu_data()); caffe_add_scalar(variance_.count(), eps, variance_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, dim, 1, 1., variance_.cpu_data(), sum_multiplier_.cpu_data(), 0., temp_.mutable_cpu_data()); caffe_div(temp_.count(), bottom_diff, temp_.cpu_data(), bottom_diff); } else { caffe_copy(temp_.count(), top_diff, bottom_diff); } }
void BNLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); const Dtype* const_top_data = top[0]->cpu_data(); const Dtype* scale_data = this->blobs_[0]->cpu_data(); const Dtype* shift_data = this->blobs_[1]->cpu_data(); switch (this->layer_param_.bn_param().bn_mode()) { case BNParameter_BNMode_LEARN: // put the squares of bottom into buffer_blob_ caffe_powx(bottom[0]->count(), bottom_data, Dtype(2), buffer_blob_.mutable_cpu_data()); // computes variance using var(X) = E(X^2) - (EX)^2 // EX across spatial caffe_cpu_gemv<Dtype>(CblasNoTrans, N_ * C_, H_ * W_, Dtype(1. / (H_ * W_)), bottom_data, spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_mean_.mutable_cpu_data()); // EX across batch caffe_cpu_gemv<Dtype>(CblasTrans, N_, C_, Dtype(1. / N_), spatial_mean_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(0), batch_mean_.mutable_cpu_data()); // E(X^2) across spatial caffe_cpu_gemv<Dtype>(CblasNoTrans, N_ * C_, H_ * W_, Dtype(1. / (H_ * W_)), buffer_blob_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_variance_.mutable_cpu_data()); // E(X^2) across batch caffe_cpu_gemv<Dtype>(CblasTrans, N_, C_, Dtype(1. / N_), spatial_variance_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(0), batch_variance_.mutable_cpu_data()); caffe_powx(batch_mean_.count(), batch_mean_.cpu_data(), Dtype(2), buffer_blob_.mutable_cpu_data()); // (EX)^2 caffe_sub(batch_mean_.count(), batch_variance_.cpu_data(), buffer_blob_.cpu_data(), batch_variance_.mutable_cpu_data()); // variance // save top[1] (batch_mean) and top[2] (batch_variance) if (top.size() > 1) { caffe_copy(batch_mean_.count(), batch_mean_.cpu_data(), top[1]->mutable_cpu_data()); } if (top.size() > 2) { caffe_copy(batch_variance_.count(), batch_variance_.cpu_data(), top[2]->mutable_cpu_data()); } // do mean and variance normalization // subtract mean caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_, C_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_mean_.cpu_data(), Dtype(0), spatial_mean_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_ * C_, H_ * W_, 1, Dtype(-1), spatial_mean_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); caffe_add(buffer_blob_.count(), bottom_data, buffer_blob_.cpu_data(), top_data); // normalize variance caffe_add_scalar(batch_variance_.count(), var_eps_, batch_variance_.mutable_cpu_data()); caffe_powx(batch_variance_.count(), batch_variance_.cpu_data(), Dtype(0.5), batch_variance_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_, C_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_variance_.cpu_data(), Dtype(0), spatial_variance_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_ * C_, H_ * W_, 1, Dtype(1), spatial_variance_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); caffe_div(buffer_blob_.count(), const_top_data, buffer_blob_.cpu_data(), top_data); // Saving x_norm caffe_copy(buffer_blob_.count(), const_top_data, x_norm_.mutable_cpu_data()); // scale caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_, C_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), scale_data, Dtype(0), spatial_variance_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_ * C_, H_ * W_, 1, Dtype(1), spatial_variance_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); caffe_mul(buffer_blob_.count(), top_data, buffer_blob_.cpu_data(), top_data); // shift caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_, C_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), shift_data, Dtype(0), spatial_mean_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_ * C_, H_ * W_, 1, Dtype(1), spatial_mean_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); caffe_add(buffer_blob_.count(), const_top_data, buffer_blob_.cpu_data(), top_data); break; case BNParameter_BNMode_INFERENCE: // scale caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_, C_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), scale_data, Dtype(0), spatial_variance_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_ * C_, H_ * W_, 1, Dtype(1), spatial_variance_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); caffe_mul(buffer_blob_.count(), bottom_data, buffer_blob_.cpu_data(), top_data); // shift caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_, C_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), shift_data, Dtype(0), spatial_mean_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, N_ * C_, H_ * W_, 1, Dtype(1), spatial_mean_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); caffe_add(buffer_blob_.count(), const_top_data, buffer_blob_.cpu_data(), top_data); break; default: LOG(FATAL) << "Unknown BN mode."; } }
void BNLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const Dtype* const_bottom_data = bottom[0]->cpu_data(); const Dtype* const_top_data = top[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); const Dtype* scale_data = this->blobs_[0]->cpu_data(); const Dtype* shift_data = this->blobs_[1]->cpu_data(); // ---------- mean subtraction ---------- // // statistic across spatial caffe_cpu_gemv<Dtype>(CblasNoTrans, num_ * channels_, height_ * width_, Dtype(1. / (height_ * width_)), const_bottom_data, spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); // statistic across batch caffe_cpu_gemv<Dtype>(CblasTrans, num_, channels_, Dtype(1. / num_), spatial_statistic_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(0), batch_statistic_.mutable_cpu_data()); // save history mean if (this->phase_ == TRAIN) { caffe_cpu_axpby(batch_statistic_.count(), decay_, batch_statistic_.cpu_data(), Dtype(1) - decay_, this->blobs_[2]->mutable_cpu_data()); } if (this->phase_ == TEST && moving_average_) { // use moving average mean caffe_copy(batch_statistic_.count(), this->blobs_[2]->cpu_data(), batch_statistic_.mutable_cpu_data()); } // put mean blob into buffer_blob_ caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_statistic_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(-1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); // substract mean caffe_add(buffer_blob_.count(), const_bottom_data, buffer_blob_.cpu_data(), top_data); // ---------- variance normalization ---------- // // put the squares of X - mean into buffer_blob_ caffe_powx(buffer_blob_.count(), const_top_data, Dtype(2), buffer_blob_.mutable_cpu_data()); // statistic across spatial caffe_cpu_gemv<Dtype>(CblasNoTrans, num_ * channels_, height_ * width_, Dtype(1. / (height_ * width_)), buffer_blob_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); // statistic across batch caffe_cpu_gemv<Dtype>(CblasTrans, num_, channels_, Dtype(1. / num_), spatial_statistic_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(0), batch_statistic_.mutable_cpu_data()); // save history variance if (this->phase_ == TRAIN) { caffe_cpu_axpby(batch_statistic_.count(), decay_, batch_statistic_.cpu_data(), Dtype(1) - decay_, this->blobs_[3]->mutable_cpu_data()); } if (this->phase_ == TEST && moving_average_) { // use moving average variance caffe_copy(batch_statistic_.count(), this->blobs_[3]->cpu_data(), batch_statistic_.mutable_cpu_data()); } // add eps caffe_add_scalar(batch_statistic_.count(), var_eps_, batch_statistic_.mutable_cpu_data()); // std caffe_powx(batch_statistic_.count(), batch_statistic_.cpu_data(), Dtype(0.5), batch_statistic_.mutable_cpu_data()); // put std blob into buffer_blob_ caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_statistic_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); // variance normalization caffe_div(buffer_blob_.count(), const_top_data, buffer_blob_.cpu_data(), top_data); // ---------- save x_norm and x_std ---------- // caffe_copy(buffer_blob_.count(), const_top_data, x_norm_.mutable_cpu_data()); caffe_copy(batch_statistic_.count(), batch_statistic_.cpu_data(), x_std_.mutable_cpu_data()); // ---------- scale ---------- // caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), scale_data, Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); caffe_mul(buffer_blob_.count(), const_top_data, buffer_blob_.cpu_data(), top_data); // ---------- shift ---------- // caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), shift_data, Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), buffer_blob_.mutable_cpu_data()); caffe_add(buffer_blob_.count(), const_top_data, buffer_blob_.cpu_data(), top_data); }
void caffe_cpu_zero_mean(const int N, Dtype* Y) { Dtype mn; mn = caffe_cpu_asum(N, Y); mn = -(mn / N); caffe_add_scalar(N, mn, Y); }
void BNLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const Dtype* const_bottom_data = bottom[0]->cpu_data(); const Dtype* const_top_data = top[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); const Dtype* scale_data = this->blobs_[0]->cpu_data(); const Dtype* shift_data = this->blobs_[1]->cpu_data(); // Mean normalization if (frozen_ || this->phase_ == TEST) { // Use the moving average mean caffe_copy(batch_statistic_.count(), this->blobs_[2]->cpu_data(), batch_statistic_.mutable_cpu_data()); } else { // Compute the mean by averaging over spatial and batch dimensions. caffe_cpu_gemv<Dtype>(CblasNoTrans, num_ * channels_, height_ * width_, Dtype(1) / (height_ * width_), const_bottom_data, spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasTrans, num_, channels_, Dtype(1) / num_, spatial_statistic_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(0), batch_statistic_.mutable_cpu_data()); // Add to the moving average if (!frozen_) { caffe_cpu_axpby(batch_statistic_.count(), Dtype(1) - bn_momentum_, batch_statistic_.cpu_data(), bn_momentum_, this->blobs_[2]->mutable_cpu_data()); } } // Broadcast the mean vector caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_statistic_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(-1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), broadcast_buffer_.mutable_cpu_data()); // Subtract caffe_add(broadcast_buffer_.count(), const_bottom_data, broadcast_buffer_.cpu_data(), top_data); // Variance normalization if (frozen_ || this->phase_ == TEST) { // Use the moving average variance caffe_copy(batch_statistic_.count(), this->blobs_[3]->cpu_data(), batch_statistic_.mutable_cpu_data()); } else { caffe_powx(broadcast_buffer_.count(), const_top_data, Dtype(2), broadcast_buffer_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasNoTrans, num_ * channels_, height_ * width_, Dtype(1) / (height_ * width_), broadcast_buffer_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasTrans, num_, channels_, Dtype(1) / num_, spatial_statistic_.cpu_data(), batch_sum_multiplier_.cpu_data(), Dtype(0), batch_statistic_.mutable_cpu_data()); // Add eps caffe_add_scalar(batch_statistic_.count(), bn_eps_, batch_statistic_.mutable_cpu_data()); // Inverse standard deviation caffe_powx(batch_statistic_.count(), batch_statistic_.cpu_data(), Dtype(-0.5), batch_statistic_.mutable_cpu_data()); // Add to the moving average if (!frozen_) { caffe_cpu_axpby(batch_statistic_.count(), Dtype(1) - bn_momentum_, batch_statistic_.cpu_data(), bn_momentum_, this->blobs_[3]->mutable_cpu_data()); } } // Broadcast the inverse std caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), batch_statistic_.cpu_data(), Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), broadcast_buffer_.mutable_cpu_data()); // Multiply with the inverse std caffe_mul(broadcast_buffer_.count(), const_top_data, broadcast_buffer_.cpu_data(), top_data); // Save the normalized inputs and std for backprop if (!frozen_) { caffe_copy(broadcast_buffer_.count(), const_top_data, x_norm_.mutable_cpu_data()); caffe_copy(batch_statistic_.count(), batch_statistic_.cpu_data(), x_inv_std_.mutable_cpu_data()); } // Scale caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), scale_data, Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), broadcast_buffer_.mutable_cpu_data()); caffe_mul(broadcast_buffer_.count(), const_top_data, broadcast_buffer_.cpu_data(), top_data); // Shift caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_, channels_, 1, Dtype(1), batch_sum_multiplier_.cpu_data(), shift_data, Dtype(0), spatial_statistic_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num_ * channels_, height_ * width_, 1, Dtype(1), spatial_statistic_.cpu_data(), spatial_sum_multiplier_.cpu_data(), Dtype(0), broadcast_buffer_.mutable_cpu_data()); caffe_add(broadcast_buffer_.count(), const_top_data, broadcast_buffer_.cpu_data(), top_data); }
void BatchNormLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) { const Dtype* bottom_data = bottom[0]->cpu_data(); Dtype* top_data = top[0]->mutable_cpu_data(); int num = bottom[0]->shape(0); int spatial_dim = bottom[0]->count()/(bottom[0]->shape(0)*channels_); if (bottom[0] != top[0]) { caffe_copy(bottom[0]->count(), bottom_data, top_data); } if (use_global_stats_) { // use the stored mean/variance estimates. const Dtype scale_factor = this->blobs_[2]->cpu_data()[0] == 0 ? 0 : 1 / this->blobs_[2]->cpu_data()[0]; caffe_cpu_scale(variance_.count(), scale_factor, this->blobs_[0]->cpu_data(), mean_.mutable_cpu_data()); caffe_cpu_scale(variance_.count(), scale_factor, this->blobs_[1]->cpu_data(), variance_.mutable_cpu_data()); } else { // compute mean caffe_cpu_gemv<Dtype>(CblasNoTrans, channels_ * num, spatial_dim, 1. / (num * spatial_dim), bottom_data, spatial_sum_multiplier_.cpu_data(), 0., num_by_chans_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasTrans, num, channels_, 1., num_by_chans_.cpu_data(), batch_sum_multiplier_.cpu_data(), 0., mean_.mutable_cpu_data()); } // subtract mean caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, channels_, 1, 1, batch_sum_multiplier_.cpu_data(), mean_.cpu_data(), 0., num_by_chans_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels_ * num, spatial_dim, 1, -1, num_by_chans_.cpu_data(), spatial_sum_multiplier_.cpu_data(), 1., top_data); if (!use_global_stats_) { // compute variance using var(X) = E((X-EX)^2) caffe_powx(top[0]->count(), top_data, Dtype(2), temp_.mutable_cpu_data()); // (X-EX)^2 caffe_cpu_gemv<Dtype>(CblasNoTrans, channels_ * num, spatial_dim, 1. / (num * spatial_dim), temp_.cpu_data(), spatial_sum_multiplier_.cpu_data(), 0., num_by_chans_.mutable_cpu_data()); caffe_cpu_gemv<Dtype>(CblasTrans, num, channels_, 1., num_by_chans_.cpu_data(), batch_sum_multiplier_.cpu_data(), 0., variance_.mutable_cpu_data()); // E((X_EX)^2) // compute and save moving average this->blobs_[2]->mutable_cpu_data()[0] *= moving_average_fraction_; this->blobs_[2]->mutable_cpu_data()[0] += 1; caffe_cpu_axpby(mean_.count(), Dtype(1), mean_.cpu_data(), moving_average_fraction_, this->blobs_[0]->mutable_cpu_data()); int m = bottom[0]->count()/channels_; Dtype bias_correction_factor = m > 1 ? Dtype(m)/(m-1) : 1; caffe_cpu_axpby(variance_.count(), bias_correction_factor, variance_.cpu_data(), moving_average_fraction_, this->blobs_[1]->mutable_cpu_data()); } // normalize variance caffe_add_scalar(variance_.count(), eps_, variance_.mutable_cpu_data()); caffe_powx(variance_.count(), variance_.cpu_data(), Dtype(0.5), variance_.mutable_cpu_data()); // replicate variance to input size caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, num, channels_, 1, 1, batch_sum_multiplier_.cpu_data(), variance_.cpu_data(), 0., num_by_chans_.mutable_cpu_data()); caffe_cpu_gemm<Dtype>(CblasNoTrans, CblasNoTrans, channels_ * num, spatial_dim, 1, 1., num_by_chans_.cpu_data(), spatial_sum_multiplier_.cpu_data(), 0., temp_.mutable_cpu_data()); caffe_div(temp_.count(), top_data, temp_.cpu_data(), top_data); // TODO(cdoersch): The caching is only needed because later in-place layers // might clobber the data. Can we skip this if they won't? caffe_copy(x_norm_.count(), top_data, x_norm_.mutable_cpu_data()); }
void DataTransformer<Dtype>::Transform(Blob<Dtype>* input_blob, Blob<Dtype>* transformed_blob) { const int crop_size = param_.crop_size(); const int input_num = input_blob->num(); const int input_channels = input_blob->channels(); const int input_height = input_blob->height(); const int input_width = input_blob->width(); if (transformed_blob->count() == 0) { // Initialize transformed_blob with the right shape. if (crop_size) { transformed_blob->Reshape(input_num, input_channels, crop_size, crop_size); } else { transformed_blob->Reshape(input_num, input_channels, input_height, input_width); } } const int num = transformed_blob->num(); const int channels = transformed_blob->channels(); const int height = transformed_blob->height(); const int width = transformed_blob->width(); const int size = transformed_blob->count(); CHECK_LE(input_num, num); CHECK_EQ(input_channels, channels); CHECK_GE(input_height, height); CHECK_GE(input_width, width); const Dtype scale = param_.scale(); const bool do_mirror = param_.mirror() && Rand(2); const bool has_mean_file = param_.has_mean_file(); const bool has_mean_values = mean_values_.size() > 0; // mask_size is defaulted to 0 in caffe/proto/caffe.proto const int mask_size = param_.mask_size(); // mask_freq is defaulted to 1 in 3 in caffe/proto/caffe.proto const int mask_freq = param_.mask_freq(); int h_off = 0; int w_off = 0; if (crop_size) { CHECK_EQ(crop_size, height); CHECK_EQ(crop_size, width); // We only do random crop when we do training. if (phase_ == TRAIN) { h_off = Rand(input_height - crop_size + 1); w_off = Rand(input_width - crop_size + 1); } else { h_off = (input_height - crop_size) / 2; w_off = (input_width - crop_size) / 2; } } else { CHECK_EQ(input_height, height); CHECK_EQ(input_width, width); } // initialize masking offsets to be same as cropping offsets // so that there is no conflict bool masking = (phase_ == TRAIN) && (mask_size > 0) && (Rand(mask_freq) == 0); int h_mask_start = h_off; int w_mask_start = w_off; if (masking) { int h_effective = input_height; int w_effective = input_width; if (crop_size) { h_effective = w_effective = crop_size; } CHECK_GE(h_effective, mask_size); CHECK_GE(w_effective, mask_size); h_mask_start += Rand(h_effective-mask_size+1); w_mask_start += Rand(w_effective-mask_size+1); } int h_mask_end = h_mask_start + mask_size; int w_mask_end = w_mask_start + mask_size; Dtype* input_data = input_blob->mutable_cpu_data(); if (has_mean_file) { CHECK_EQ(input_channels, data_mean_.channels()); CHECK_EQ(input_height, data_mean_.height()); CHECK_EQ(input_width, data_mean_.width()); for (int n = 0; n < input_num; ++n) { int offset = input_blob->offset(n); caffe_sub(data_mean_.count(), input_data + offset, data_mean_.cpu_data(), input_data + offset); } } if (has_mean_values) { CHECK(mean_values_.size() == 1 || mean_values_.size() == input_channels) << "Specify either 1 mean_value or as many as channels: " << input_channels; if (mean_values_.size() == 1) { caffe_add_scalar(input_blob->count(), -(mean_values_[0]), input_data); } else { for (int n = 0; n < input_num; ++n) { for (int c = 0; c < input_channels; ++c) { int offset = input_blob->offset(n, c); caffe_add_scalar(input_height * input_width, -(mean_values_[c]), input_data + offset); } } } } Dtype* transformed_data = transformed_blob->mutable_cpu_data(); for (int n = 0; n < input_num; ++n) { int top_index_n = n * channels; int data_index_n = n * channels; for (int c = 0; c < channels; ++c) { int top_index_c = (top_index_n + c) * height; int data_index_c = (data_index_n + c) * input_height + h_off; for (int h = 0; h < height; ++h) { int top_index_h = (top_index_c + h) * width; int data_index_h = (data_index_c + h) * input_width + w_off; if (do_mirror) { int top_index_w = top_index_h + width - 1; for (int w = 0; w < width; ++w) { if (masking && (h > h_mask_start) && (w > w_mask_start) && (h < h_mask_end) && (w < w_mask_end)) { transformed_data[top_index_w-w] = 0; } else { transformed_data[top_index_w-w] = input_data[data_index_h + w]; } } } else { for (int w = 0; w < width; ++w) { if (masking && (h > h_mask_start) && (w > w_mask_start) && (h < h_mask_end) && (w < w_mask_end)) { transformed_data[top_index_h + w] = 0; } else { transformed_data[top_index_h + w] = input_data[data_index_h + w]; } } } } } } if (scale != Dtype(1)) { DLOG(INFO) << "Scale: " << scale; caffe_scal(size, scale, transformed_data); } }
void DataTransformer<Dtype>::Transform(Blob<Dtype>* input_blob, Blob<Dtype>* transformed_blob) { const int crop_size = param_.crop_size(); const int input_num = input_blob->num(); const int input_channels = input_blob->channels(); const int input_height = input_blob->height(); const int input_width = input_blob->width(); if (transformed_blob->count() == 0) { // Initialize transformed_blob with the right shape. if (crop_size) { transformed_blob->Reshape(input_num, input_channels, crop_size, crop_size); } else { transformed_blob->Reshape(input_num, input_channels, input_height, input_width); } } const int num = transformed_blob->num(); const int channels = transformed_blob->channels(); const int height = transformed_blob->height(); const int width = transformed_blob->width(); const int size = transformed_blob->count(); CHECK_LE(input_num, num); CHECK_EQ(input_channels, channels); CHECK_GE(input_height, height); CHECK_GE(input_width, width); const Dtype scale = param_.scale(); const bool do_mirror = param_.mirror() && Rand(2); const bool has_mean_file = param_.has_mean_file(); const bool has_mean_values = mean_values_.size() > 0; int h_off = 0; int w_off = 0; if (crop_size) { CHECK_EQ(crop_size, height); CHECK_EQ(crop_size, width); // We only do random crop when we do training. if (phase_ == TRAIN) { h_off = Rand(input_height - crop_size + 1); w_off = Rand(input_width - crop_size + 1); } else { h_off = (input_height - crop_size) / 2; w_off = (input_width - crop_size) / 2; } } else { CHECK_EQ(input_height, height); CHECK_EQ(input_width, width); } Dtype* input_data = input_blob->mutable_cpu_data(); if (has_mean_file) { CHECK_EQ(input_channels, data_mean_.channels()); CHECK_EQ(input_height, data_mean_.height()); CHECK_EQ(input_width, data_mean_.width()); for (int n = 0; n < input_num; ++n) { int offset = input_blob->offset(n); caffe_sub(data_mean_.count(), input_data + offset, data_mean_.cpu_data(), input_data + offset); } } if (has_mean_values) { CHECK(mean_values_.size() == 1 || mean_values_.size() == input_channels) << "Specify either 1 mean_value or as many as channels: " << input_channels; if (mean_values_.size() == 1) { caffe_add_scalar(input_blob->count(), -(mean_values_[0]), input_data); } else { for (int n = 0; n < input_num; ++n) { for (int c = 0; c < input_channels; ++c) { int offset = input_blob->offset(n, c); caffe_add_scalar(input_height * input_width, -(mean_values_[c]), input_data + offset); } } } } Dtype* transformed_data = transformed_blob->mutable_cpu_data(); for (int n = 0; n < input_num; ++n) { int top_index_n = n * channels; int data_index_n = n * channels; for (int c = 0; c < channels; ++c) { int top_index_c = (top_index_n + c) * height; int data_index_c = (data_index_n + c) * input_height + h_off; for (int h = 0; h < height; ++h) { int top_index_h = (top_index_c + h) * width; int data_index_h = (data_index_c + h) * input_width + w_off; if (do_mirror) { int top_index_w = top_index_h + width - 1; for (int w = 0; w < width; ++w) { transformed_data[top_index_w-w] = input_data[data_index_h + w]; } } else { for (int w = 0; w < width; ++w) { transformed_data[top_index_h + w] = input_data[data_index_h + w]; } } } } } if (scale != Dtype(1)) { DLOG(INFO) << "Scale: " << scale; caffe_scal(size, scale, transformed_data); } }
void FlowDataLayer<Dtype>::Decompress(const cv::Mat& cv_img, Blob<Dtype>* transformed_blob) { const int img_channels = cv_img.channels(); const int img_height = cv_img.rows; const int img_width = cv_img.cols; const int channels = transformed_blob->channels(); const int height = transformed_blob->height(); const int width = transformed_blob->width(); const int count = height * width; const bool subtract_mean = this->layer_param_. flow_data_param().subtract_mean(); CHECK_EQ(channels, 2) << "Flow fileds must have 2 channels"; CHECK_EQ(img_channels, 3) << "Flow Image must have 3 channels"; CHECK_EQ(height, img_height); CHECK_EQ(width, img_width); CHECK(cv_img.depth() == CV_8U) << "Image data type must be unsigned byte"; Dtype* transformed_data = transformed_blob->mutable_cpu_data(); int u_index, v_index; Dtype total_u = 0.0; Dtype total_v = 0.0; for (int h = 0; h < height; ++h) { const uchar* ptr = cv_img.ptr<uchar>(h); int img_index = 0; for (int w = 0; w < width; ++w) { // Computes the fractions. Dtype pixel = static_cast<Dtype>(ptr[img_index++]); Dtype u_frac = static_cast<Dtype>(floor(static_cast<double>(pixel) / 10.0)); Dtype v_frac = (pixel - 10 * u_frac) / 10.0; u_frac = u_frac / 10.0; // Horizontal flow. v_index = (height + h) * width + w; pixel = static_cast<Dtype>(ptr[img_index++]); transformed_data[v_index] = pixel - 127.0; // Vertical flow. u_index = h * width + w; pixel = static_cast<Dtype>(ptr[img_index++]); transformed_data[u_index] = pixel - 127.0; // Adds in the fraction part. transformed_data[u_index] += u_frac; transformed_data[v_index] += v_frac; if (subtract_mean) { // Computes the total. total_u += transformed_data[u_index]; total_v += transformed_data[v_index]; } } } // Subtracts the mean flow vector if required. if (subtract_mean) { Dtype mean_u = total_u / count, mean_v = total_v / count; caffe_add_scalar(height * width, (Dtype)(-1.0 * mean_u), transformed_data); caffe_add_scalar(height * width, (Dtype)(-1.0 * mean_v), transformed_data + height * width); // // for (int h = 0; h < height; ++h) { // for (int w = 0; w < width; ++w) { // transformed_data[h*width + w] -= mean_u; // transformed_data[(height + h)*width + w] -= mean_v; // } // } } }