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