92 lines
3.1 KiB
C++
92 lines
3.1 KiB
C++
#include <cmath>
|
|
#include <algorithm>
|
|
#include <vector>
|
|
|
|
#include "caffe/layer.hpp"
|
|
#include "caffe/layers/dspp_layer.hpp"
|
|
|
|
#include <boost/spirit/include/phoenix_core.hpp>
|
|
#include <boost/spirit/include/phoenix_operator.hpp>
|
|
|
|
|
|
namespace caffe {
|
|
template <typename Dtype>
|
|
void DSPPLayer<Dtype>::LayerSetUp(const vector<Blob<Dtype>*>& bottom,
|
|
const vector<Blob<Dtype>*>& top) {
|
|
}
|
|
|
|
template <typename Dtype>
|
|
void DSPPLayer<Dtype>::Reshape(const vector<Blob<Dtype>*>& bottom, const vector<Blob<Dtype>*>& top) {
|
|
|
|
num_ = bottom[1]->shape()[0];
|
|
channel_ = bottom[1]->shape()[1]; // the input data size
|
|
height_ = bottom[1]->shape()[2];
|
|
width_ = bottom[1]->shape()[3];
|
|
|
|
// init output size
|
|
vector<int> output_shape;
|
|
output_shape.push_back(num_);
|
|
output_shape.push_back(channel_);
|
|
output_shape.push_back(height_);
|
|
output_shape.push_back(width_);
|
|
top[0]->Reshape(output_shape);
|
|
}
|
|
|
|
template <typename Dtype>
|
|
void DSPPLayer<Dtype>::Forward_cpu(const vector<Blob<Dtype>*>& bottom,
|
|
const vector<Blob<Dtype>*>& top) {
|
|
Dtype* top_data = top[0]->mutable_cpu_data();
|
|
|
|
caffe_set<Dtype>(top[0]->count(), 0, top_data); // initilize to be 0
|
|
|
|
for (int n=0; n<num_; ++n) {
|
|
for (int h = 0; h < height_; ++h) { // for the input data size
|
|
for (int w = 0; w < width_; ++w) {
|
|
for (int c = 0; c < channel_; ++c) {
|
|
top_data[top[0]->offset(n, c, h, w)] = bottom[1]->data_at(n, c, h, w) * bottom[0]->data_at(n, 0, h, w);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
top_data = NULL;
|
|
}
|
|
|
|
template <typename Dtype>
|
|
void DSPPLayer<Dtype>::Backward_cpu(const vector<Blob<Dtype>*>& top,
|
|
const vector<bool>& propagate_down,
|
|
const vector<Blob<Dtype>*>& bottom) {
|
|
if (propagate_down[0]) {
|
|
const Dtype* top_diff = top[0]->cpu_diff();
|
|
Dtype* data_diff = bottom[1]->mutable_cpu_diff();
|
|
Dtype* heat_map_diff = bottom[0]->mutable_cpu_diff();
|
|
|
|
caffe_set<Dtype>(bottom[1]->count(), 0, data_diff);
|
|
caffe_set<Dtype>(bottom[0]->count(), 0, heat_map_diff);
|
|
// Dtype activation_h, activation_w;
|
|
|
|
for (int n = 0; n < num_; ++n) {
|
|
for (int h = 0; h < height_; ++h) {
|
|
for (int w = 0; w < width_; ++w) {
|
|
for (int c = 0; c < channel_; ++c) {
|
|
|
|
Dtype buffer = top_diff[top[0]->offset(n, c, h, w)];
|
|
data_diff[bottom[1]->offset(n, c, h, w)] = buffer * (bottom[0]->data_at(n, 0, h, w));
|
|
|
|
buffer *= bottom[1]->data_at(n,c,h,w) / channel_;
|
|
|
|
heat_map_diff[bottom[0]->offset(n,0,h,w)] += buffer;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
top_diff = NULL;
|
|
data_diff = NULL;
|
|
heat_map_diff = NULL;
|
|
|
|
}
|
|
}
|
|
|
|
INSTANTIATE_CLASS(DSPPLayer);
|
|
REGISTER_LAYER_CLASS(DSPP);
|
|
|
|
} // namespace caffe
|