parent
46bd5f53e3
commit
cdac60f616
@ -0,0 +1,81 @@
|
||||
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
#include "PoolProjection.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
REGISTER_PROJECTION_CREATE_FUNC(pool2, &PoolProjection::create);
|
||||
|
||||
PoolProjection* PoolProjection::create(const ProjectionConfig& config,
|
||||
ParameterPtr parameter, bool useGpu) {
|
||||
const std::string& pool = config.pool_conf().pool_type();
|
||||
if (pool == "max") {
|
||||
return new MaxPoolProjection(config, parameter, useGpu);
|
||||
} else if (pool == "avg") {
|
||||
return new AvgPoolProjection(config, parameter, useGpu);
|
||||
} else {
|
||||
LOG(FATAL) << "Unknown pool type: " << pool;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void MaxPoolProjection::forward() {
|
||||
MatrixPtr inputV = in_->value;
|
||||
MatrixPtr outV = out_->value;
|
||||
outV->maxPoolForward(*inputV, imgSizeY_, imgSize_, channels_,
|
||||
sizeX_, sizeY_, strideY_, stride_,
|
||||
outputY_, outputX_, confPaddingY_, confPadding_);
|
||||
}
|
||||
|
||||
void MaxPoolProjection::backward(const UpdateCallback& callback) {
|
||||
(void)callback;
|
||||
MatrixPtr outGrad = out_->grad;
|
||||
MatrixPtr inputV = in_->value;
|
||||
MatrixPtr outV = out_->value;
|
||||
MatrixPtr inputGrad = in_->grad;
|
||||
|
||||
if (NULL == inputGrad) {
|
||||
return;
|
||||
}
|
||||
inputGrad->maxPoolBackward(*inputV, imgSizeY_, imgSize_, *outGrad, *outV,
|
||||
sizeX_, sizeY_,
|
||||
strideY_, stride_, outputY_, outputX_, 1, 1,
|
||||
confPaddingY_, confPadding_);
|
||||
}
|
||||
|
||||
void AvgPoolProjection::forward() {
|
||||
MatrixPtr inputV = in_->value;
|
||||
MatrixPtr outV = out_->value;
|
||||
outV->avgPoolForward(*inputV, imgSizeY_, imgSize_, channels_,
|
||||
sizeX_, sizeY_, strideY_, stride_,
|
||||
outputY_, outputX_, confPaddingY_, confPadding_);
|
||||
}
|
||||
|
||||
void AvgPoolProjection::backward(const UpdateCallback& callback) {
|
||||
(void)callback;
|
||||
|
||||
MatrixPtr outputGrad = out_->grad;
|
||||
MatrixPtr inputGrad = in_->grad;
|
||||
|
||||
if (NULL == inputGrad) {
|
||||
return;
|
||||
}
|
||||
|
||||
inputGrad->avgPoolBackward(*outputGrad, imgSizeY_, imgSize_,
|
||||
sizeX_, sizeY_, strideY_, stride_,
|
||||
outputY_, outputX_, 1, 1,
|
||||
confPaddingY_, confPadding_);
|
||||
}
|
||||
} // namespace paddle
|
@ -0,0 +1,72 @@
|
||||
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Projection.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
class PoolProjection : public Projection {
|
||||
protected:
|
||||
size_t imgSizeY_, imgSize_;
|
||||
size_t outputY_, outputX_;
|
||||
size_t strideY_, stride_;
|
||||
size_t sizeY_, sizeX_;
|
||||
int confPaddingY_, confPadding_;
|
||||
size_t channels_;
|
||||
std::string poolType_;
|
||||
|
||||
public:
|
||||
PoolProjection(const ProjectionConfig& config, ParameterPtr parameter,
|
||||
bool useGpu)
|
||||
: Projection(config, parameter, useGpu) {
|
||||
const PoolConfig& conf = config_.pool_conf();
|
||||
poolType_ = conf.pool_type();
|
||||
channels_ = conf.channels();
|
||||
sizeX_ = conf.size_x();
|
||||
stride_ = conf.stride();
|
||||
outputX_ = conf.output_x();
|
||||
imgSize_ = conf.img_size();
|
||||
confPadding_ = conf.padding();
|
||||
|
||||
sizeY_ = conf.has_size_y() ? conf.size_y() : conf.size_x();
|
||||
imgSizeY_ = conf.has_img_size_y() ? conf.img_size_y() : conf.img_size();
|
||||
strideY_ = conf.has_stride_y() ? conf.stride_y() : conf.stride();
|
||||
confPaddingY_ = conf.has_padding_y() ? conf.padding_y() : conf.padding();
|
||||
outputY_ = conf.has_output_y() ? conf.output_y() : conf.output_x();
|
||||
}
|
||||
static PoolProjection* create(const ProjectionConfig& config,
|
||||
ParameterPtr parameter, bool useGpu);
|
||||
const std::string& getPoolType() const { return poolType_; }
|
||||
};
|
||||
|
||||
class MaxPoolProjection : public PoolProjection {
|
||||
public:
|
||||
MaxPoolProjection(const ProjectionConfig& config, ParameterPtr parameter,
|
||||
bool useGpu)
|
||||
: PoolProjection(config, parameter, useGpu) {}
|
||||
virtual void forward();
|
||||
virtual void backward(const UpdateCallback& callback = nullptr);
|
||||
};
|
||||
|
||||
class AvgPoolProjection : public PoolProjection {
|
||||
public:
|
||||
AvgPoolProjection(const ProjectionConfig& config, ParameterPtr parameter,
|
||||
bool useGpu)
|
||||
: PoolProjection(config, parameter, useGpu) {}
|
||||
virtual void forward();
|
||||
virtual void backward(const UpdateCallback& callback = nullptr);
|
||||
};
|
||||
} // namespace paddle
|
@ -0,0 +1,128 @@
|
||||
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
#include "SpatialPyramidPoolLayer.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
REGISTER_LAYER(spp, SpatialPyramidPoolLayer);
|
||||
|
||||
ProjectionConfig SpatialPyramidPoolLayer::getConfig(size_t imgSizeW,
|
||||
size_t imgSizeH,
|
||||
size_t channels,
|
||||
size_t pyramidLevel,
|
||||
std::string& poolType) {
|
||||
ProjectionConfig config;
|
||||
config.set_type("pool2");
|
||||
PoolConfig* conf = config.mutable_pool_conf();
|
||||
conf->set_channels(channels);
|
||||
conf->set_img_size(imgSizeW);
|
||||
conf->set_img_size_y(imgSizeH);
|
||||
conf->set_pool_type(poolType);
|
||||
|
||||
int numBins = std::pow(2, pyramidLevel);
|
||||
|
||||
int sizeH = std::ceil(imgSizeH / static_cast<double>(numBins));
|
||||
int remainderH = sizeH * numBins - imgSizeH;
|
||||
int paddingH = (remainderH + 1) / 2;
|
||||
int outSizeH = outputSize(imgSizeH, sizeH, paddingH, sizeH);
|
||||
|
||||
int sizeW = std::ceil(imgSizeW / static_cast<double>(numBins));
|
||||
int remainderW = sizeW * numBins - imgSizeW;
|
||||
int paddingW = (remainderW + 1) / 2;
|
||||
int outSizeW = outputSize(imgSizeW, sizeW, paddingW, sizeW);
|
||||
|
||||
conf->set_stride(sizeW);
|
||||
conf->set_stride_y(sizeH);
|
||||
conf->set_size_x(sizeW);
|
||||
conf->set_size_y(sizeH);
|
||||
conf->set_padding(paddingW);
|
||||
conf->set_padding_y(paddingH);
|
||||
conf->set_output_x(outSizeW);
|
||||
conf->set_output_y(outSizeH);
|
||||
config.set_output_size(outSizeH * outSizeW * channels);
|
||||
return config;
|
||||
}
|
||||
|
||||
void SpatialPyramidPoolLayer::splitInput(Argument& input, size_t height,
|
||||
size_t width, bool useGpu) {
|
||||
input.value = getInput(0).value;
|
||||
if (passType_ != PASS_TEST && needGradient()) {
|
||||
Matrix::resizeOrCreate(input.grad, height, width, /* trans */ false,
|
||||
useGpu);
|
||||
input.grad->zeroMem();
|
||||
}
|
||||
}
|
||||
|
||||
bool SpatialPyramidPoolLayer::init(const LayerMap& layerMap,
|
||||
const ParameterMap& parameterMap) {
|
||||
Layer::init(layerMap, parameterMap);
|
||||
CHECK_EQ(config_.inputs_size(), 1);
|
||||
|
||||
const SppConfig& sppConf = config_.inputs(0).spp_conf();
|
||||
pyramidHeight_ = sppConf.pyramid_height();
|
||||
poolType_ = sppConf.pool_type();
|
||||
|
||||
channels_ = sppConf.channels();
|
||||
imgSizeW_ = sppConf.img_size();
|
||||
imgSizeH_ = sppConf.has_img_size_y() ? sppConf.img_size_y() : imgSizeW_;
|
||||
poolProjections_.reserve(pyramidHeight_);
|
||||
projCol_.reserve(pyramidHeight_);
|
||||
projInput_.reserve(pyramidHeight_);
|
||||
projOutput_.resize(pyramidHeight_);
|
||||
|
||||
size_t startCol = 0;
|
||||
size_t endCol = 0;
|
||||
for (size_t i = 0; i < pyramidHeight_; i++) {
|
||||
poolProjections_.emplace_back(PoolProjection::create(
|
||||
getConfig(imgSizeW_, imgSizeH_, channels_, i, poolType_),
|
||||
nullptr, useGpu_));
|
||||
endCol += poolProjections_[i]->getOutputSize();
|
||||
projCol_.push_back(std::make_pair(startCol, endCol));
|
||||
startCol = endCol;
|
||||
projInput_.emplace_back(Argument());
|
||||
}
|
||||
outputSize_ = endCol;
|
||||
return true;
|
||||
}
|
||||
|
||||
void SpatialPyramidPoolLayer::forward(PassType passType) {
|
||||
Layer::forward(passType);
|
||||
|
||||
int batchSize = getInput(0).getBatchSize();
|
||||
resetOutput(batchSize, outputSize_);
|
||||
for (size_t i = 0; i < pyramidHeight_; i++) {
|
||||
size_t startCol = projCol_[i].first;
|
||||
size_t endCol = projCol_[i].second;
|
||||
projOutput_[i].value = output_.value->subColMatrix(startCol, endCol);
|
||||
projOutput_[i].grad = output_.grad->subColMatrix(startCol, endCol);
|
||||
splitInput(projInput_[i], getInput(0).value->getHeight(),
|
||||
getInput(0).value->getWidth(), useGpu_);
|
||||
}
|
||||
for (size_t i = 0; i < pyramidHeight_; i++) {
|
||||
poolProjections_[i]->forward(&projInput_[i], &projOutput_[i], passType);
|
||||
}
|
||||
}
|
||||
|
||||
void SpatialPyramidPoolLayer::backward(const UpdateCallback& callback) {
|
||||
for (size_t i = 0; i < pyramidHeight_; i++) {
|
||||
if (poolProjections_[i]) {
|
||||
poolProjections_[i]->backward(callback);
|
||||
getInput(0).grad->add(*projInput_[i].grad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace paddle
|
||||
|
@ -0,0 +1,54 @@
|
||||
/* Copyright (c) 2016 Baidu, Inc. All Rights Reserve.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License. */
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Layer.h"
|
||||
#include "PoolProjection.h"
|
||||
#include "paddle/utils/Logging.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
class SpatialPyramidPoolLayer : public Layer {
|
||||
protected:
|
||||
size_t channels_;
|
||||
size_t imgSizeW_;
|
||||
size_t imgSizeH_;
|
||||
size_t pyramidHeight_;
|
||||
size_t outputSize_;
|
||||
std::string poolType_;
|
||||
|
||||
std::vector<std::unique_ptr<PoolProjection>> poolProjections_;
|
||||
std::vector<Argument> projInput_;
|
||||
std::vector<Argument> projOutput_;
|
||||
std::vector<std::pair<size_t, size_t>> projCol_;
|
||||
|
||||
public:
|
||||
explicit SpatialPyramidPoolLayer(const LayerConfig& config) : Layer(config) {}
|
||||
~SpatialPyramidPoolLayer() {}
|
||||
|
||||
virtual bool init(const LayerMap& layerMap, const ParameterMap& parameterMap);
|
||||
ProjectionConfig getConfig(size_t sizeX_, size_t sizeY_, size_t channels,
|
||||
size_t pyamidLevel_, std::string& poolType_);
|
||||
|
||||
int outputSize(int imageSize, int windowSize, int padding, int stride) {
|
||||
return (imageSize - windowSize + 2 * padding) / stride + 1;
|
||||
}
|
||||
|
||||
virtual void forward(PassType passType);
|
||||
virtual void backward(const UpdateCallback& callback = nullptr);
|
||||
void splitInput(Argument& input, size_t height, size_t width, bool useGpu);
|
||||
};
|
||||
} // namespace paddle
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue