parent
aa2cd2ce8f
commit
2575b74fee
@ -0,0 +1,241 @@
|
|||||||
|
/* 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 "paddle/utils/Logging.h"
|
||||||
|
#include "ConvBaseLayerCpu.h"
|
||||||
|
namespace paddle {
|
||||||
|
|
||||||
|
bool ConvBaseLayerCpu::init(const LayerMap &layerMap,
|
||||||
|
const ParameterMap ¶meterMap) {
|
||||||
|
/* Initialize the basic convolutional parent class */
|
||||||
|
ConvBaseLayer::init(layerMap, parameterMap);
|
||||||
|
|
||||||
|
int channel;
|
||||||
|
/* Initialize the projection */
|
||||||
|
for (auto &inputConfig : config_.inputs()) {
|
||||||
|
const ConvConfig &conf = inputConfig.conv_conf();
|
||||||
|
subM_.push_back(numFilters_ / conf.groups());
|
||||||
|
subN_.push_back(conf.output_x() * conf.output_x());
|
||||||
|
channel = isConv_ ? conf.channels() : numFilters_;
|
||||||
|
subK_.push_back(channel * conf.filter_size() * conf.filter_size() /
|
||||||
|
conf.groups());
|
||||||
|
/* Consistent caffe mode for multiple input */
|
||||||
|
caffeMode_ = conf.caffe_mode();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::resetExpandInput(size_t height, size_t width) {
|
||||||
|
Matrix::resizeOrCreate(expandInput_, height, width, false, useGpu_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::addSharedBias() {
|
||||||
|
size_t mapW = getSize() / numFilters_;
|
||||||
|
size_t mapH = getOutputValue()->getElementCnt() / mapW;
|
||||||
|
MatrixPtr out =
|
||||||
|
Matrix::create(getOutputValue()->getData(), mapH, mapW, false, useGpu_);
|
||||||
|
|
||||||
|
Matrix::resizeOrCreate(transOutValue_, mapW, mapH, false, useGpu_);
|
||||||
|
|
||||||
|
out->transpose(transOutValue_, false); // false means no memory allocation
|
||||||
|
transOutValue_->reshape(transOutValue_->getElementCnt() / numFilters_,
|
||||||
|
numFilters_);
|
||||||
|
|
||||||
|
MatrixPtr bias =
|
||||||
|
Matrix::create(biases_->getW()->getData(), 1,
|
||||||
|
biases_->getW()->getElementCnt(), false, useGpu_);
|
||||||
|
transOutValue_->addBias(*bias, 1.0f);
|
||||||
|
|
||||||
|
transOutValue_->reshape(mapW, mapH);
|
||||||
|
transOutValue_->transpose(out, false); // false means no memory allocation
|
||||||
|
|
||||||
|
out->clear();
|
||||||
|
bias->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::addUnsharedBias() {
|
||||||
|
MatrixPtr outValue = getOutputValue();
|
||||||
|
MatrixPtr bias =
|
||||||
|
Matrix::create(biases_->getW()->getData(), 1,
|
||||||
|
biases_->getW()->getElementCnt(), false, useGpu_);
|
||||||
|
outValue->addBias(*bias, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::expandOneFrame(MatrixPtr image, size_t startIdx,
|
||||||
|
int inIdx) {
|
||||||
|
int channel = isConv_ ? channels_[inIdx] : numFilters_;
|
||||||
|
|
||||||
|
resetExpandInput(subK_[inIdx] * groups_[inIdx], subN_[inIdx]);
|
||||||
|
real *imgData = image->getData() + startIdx * image->getWidth();
|
||||||
|
MatrixPtr imageTmp = Matrix::create(
|
||||||
|
imgData, 1, imgSizeH_[inIdx] * imgSizeW_[inIdx] * channel, false,
|
||||||
|
useGpu_);
|
||||||
|
expandInput_->convExpand(*imageTmp, imgSizeH_[inIdx], imgSizeW_[inIdx],
|
||||||
|
channel, filterSize_[inIdx],
|
||||||
|
filterSize_[inIdx], stride_[inIdx], stride_[inIdx],
|
||||||
|
padding_[inIdx], padding_[inIdx],
|
||||||
|
outputH_[inIdx], outputW_[inIdx]);
|
||||||
|
imageTmp->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::expandFwdOnce(MatrixPtr image, MatrixPtr out,
|
||||||
|
int inIdx, int startIdx) {
|
||||||
|
int subM = subM_[inIdx];
|
||||||
|
int subN = subN_[inIdx];
|
||||||
|
int subK = subK_[inIdx];
|
||||||
|
|
||||||
|
expandOneFrame(image, startIdx, inIdx);
|
||||||
|
|
||||||
|
int nf = isConv_ ? numFilters_ : channels_[inIdx];
|
||||||
|
|
||||||
|
real *outData =
|
||||||
|
out->getData() + startIdx * subN * nf;
|
||||||
|
|
||||||
|
real *wgtData = weights_[inIdx]->getW()->getData();
|
||||||
|
real *expInData = expandInput_->getData();
|
||||||
|
for (int g = 0; g < groups_[inIdx]; ++g) {
|
||||||
|
MatrixPtr A =
|
||||||
|
Matrix::create(wgtData, subK, subM, true, useGpu_); // mark transpose
|
||||||
|
MatrixPtr B = Matrix::create(expInData, subK, subN, false, useGpu_);
|
||||||
|
MatrixPtr C = Matrix::create(outData, subM, subN, false, useGpu_);
|
||||||
|
C->mul(A, B, 1, 1);
|
||||||
|
|
||||||
|
A->clear();
|
||||||
|
B->clear();
|
||||||
|
C->clear();
|
||||||
|
wgtData += subK * subM;
|
||||||
|
expInData += subK * subN;
|
||||||
|
outData += subM * subN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::bpropActs(MatrixPtr image, MatrixPtr out, int inpIdx) {
|
||||||
|
int channel = isConv_ ? channels_[inpIdx] : numFilters_;
|
||||||
|
|
||||||
|
int subM = subM_[inpIdx];
|
||||||
|
int subN = subN_[inpIdx];
|
||||||
|
int subK = subK_[inpIdx];
|
||||||
|
size_t batchSize = image->getHeight();
|
||||||
|
MatrixPtr tgtGrad = out;
|
||||||
|
|
||||||
|
/* reset the expand-grad memory */
|
||||||
|
resetExpandInput(subK * groups_[inpIdx], subN);
|
||||||
|
|
||||||
|
real *localGradData = image->getData();
|
||||||
|
real *tgtGradData = tgtGrad->getData();
|
||||||
|
for (size_t n = 0; n < batchSize; n++) {
|
||||||
|
real *wgtData = weights_[inpIdx]->getW()->getData();
|
||||||
|
real *expandInData = expandInput_->getData();
|
||||||
|
|
||||||
|
for (int g = 0; g < groups_[inpIdx]; g++) {
|
||||||
|
// create temporary matrix
|
||||||
|
MatrixPtr C = Matrix::create(expandInData, subK, subN, false, useGpu_);
|
||||||
|
MatrixPtr B = Matrix::create(localGradData, subM, subN, false, useGpu_);
|
||||||
|
MatrixPtr A = Matrix::create(wgtData, subK, subM, false, useGpu_);
|
||||||
|
C->mul(A, B); // mul
|
||||||
|
|
||||||
|
// clear the temporary matrix
|
||||||
|
A->clear();
|
||||||
|
B->clear();
|
||||||
|
C->clear();
|
||||||
|
|
||||||
|
expandInData += subK * subN;
|
||||||
|
localGradData += subM * subN;
|
||||||
|
wgtData += subK * subM;
|
||||||
|
}
|
||||||
|
|
||||||
|
// shrink one frame outGrad
|
||||||
|
MatrixPtr oneGradTmp = Matrix::create(
|
||||||
|
expandInput_->getData(), subK * groups_[inpIdx], subN, false, useGpu_);
|
||||||
|
MatrixPtr vTmp = Matrix::create(
|
||||||
|
tgtGradData, 1,
|
||||||
|
imgSizeH_[inpIdx] * imgSizeW_[inpIdx] * channel, false,
|
||||||
|
useGpu_);
|
||||||
|
vTmp->convShrink(*oneGradTmp, imgSizeH_[inpIdx], imgSizeW_[inpIdx],
|
||||||
|
channel, filterSize_[inpIdx],
|
||||||
|
filterSize_[inpIdx], stride_[inpIdx], stride_[inpIdx],
|
||||||
|
padding_[inpIdx], padding_[inpIdx],
|
||||||
|
outputH_[inpIdx], outputW_[inpIdx], 1.0f, 1.0f);
|
||||||
|
vTmp->clear();
|
||||||
|
oneGradTmp->clear();
|
||||||
|
|
||||||
|
// move the data-pointer
|
||||||
|
tgtGradData += imgSizeH_[inpIdx] * imgSizeW_[inpIdx] * channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::bpropWeights(MatrixPtr image, MatrixPtr out,
|
||||||
|
int inpIdx) {
|
||||||
|
MatrixPtr weightGrad = weights_[inpIdx]->getWGrad();
|
||||||
|
|
||||||
|
int subM = subM_[inpIdx];
|
||||||
|
int subN = subN_[inpIdx];
|
||||||
|
int subK = subK_[inpIdx];
|
||||||
|
size_t batchSize = image->getHeight();
|
||||||
|
resetExpandInput(subK * groups_[inpIdx], subN);
|
||||||
|
|
||||||
|
real *gradData = out->getData();
|
||||||
|
|
||||||
|
for (size_t n = 0; n < batchSize; n++) { // frame by frame
|
||||||
|
// expand
|
||||||
|
expandOneFrame(image, n, inpIdx);
|
||||||
|
real *wGradData = weightGrad->getData();
|
||||||
|
real *expandInData = expandInput_->getData();
|
||||||
|
|
||||||
|
// expand-mul one-group by one
|
||||||
|
for (int g = 0; g < groups_[inpIdx]; g++) {
|
||||||
|
MatrixPtr A = Matrix::create(expandInData, subK, subN, false, useGpu_);
|
||||||
|
MatrixPtr B = Matrix::create(gradData, subM, subN, true, useGpu_);
|
||||||
|
MatrixPtr C = Matrix::create(wGradData, subK, subM, false, useGpu_);
|
||||||
|
C->mul(A, B, 1, 1);
|
||||||
|
|
||||||
|
A->clear();
|
||||||
|
B->clear();
|
||||||
|
C->clear();
|
||||||
|
gradData += subM * subN;
|
||||||
|
wGradData += subK * subM;
|
||||||
|
expandInData += subK * subN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::bpropSharedBias(MatrixPtr biases, MatrixPtr v) {
|
||||||
|
size_t mapW = getSize() / numFilters_;
|
||||||
|
size_t mapH = v->getElementCnt() / mapW;
|
||||||
|
MatrixPtr vTmp = Matrix::create(v->getData(), mapH, mapW, false, useGpu_);
|
||||||
|
|
||||||
|
Matrix::resizeOrCreate(transOutValue_, mapW, mapH, false, useGpu_);
|
||||||
|
|
||||||
|
vTmp->transpose(transOutValue_, false); // false means no memory allocation
|
||||||
|
transOutValue_->reshape(transOutValue_->getElementCnt() / numFilters_,
|
||||||
|
numFilters_);
|
||||||
|
biases->collectBias(*transOutValue_, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConvBaseLayerCpu::bpropBiases(MatrixPtr v) {
|
||||||
|
MatrixPtr biases =
|
||||||
|
Matrix::create(biases_->getWGrad()->getData(), 1,
|
||||||
|
biases_->getWGrad()->getElementCnt(), false, useGpu_);
|
||||||
|
if (sharedBiases_) {
|
||||||
|
bpropSharedBias(biases, v);
|
||||||
|
} else {
|
||||||
|
biases->collectBias(*v, 1.0f);
|
||||||
|
}
|
||||||
|
biases->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace paddle
|
@ -0,0 +1,91 @@
|
|||||||
|
/* 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 "ConvBaseLayer.h"
|
||||||
|
#include "paddle/math/Matrix.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace paddle {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A subclass of ConvBaseLayer that is a superclass of both
|
||||||
|
* ExpandConvLayer and ExpandConvTransLayer
|
||||||
|
*/
|
||||||
|
class ConvBaseLayerCpu : public ConvBaseLayer {
|
||||||
|
protected:
|
||||||
|
/// For expand convolution.
|
||||||
|
/// subM_ = numFilters_ / groups_.
|
||||||
|
IntV subM_;
|
||||||
|
/// subN_ = outputH_ * outputW_.
|
||||||
|
IntV subN_;
|
||||||
|
/// subK_ = channels_ * filterPixels_ * groups_.
|
||||||
|
IntV subK_;
|
||||||
|
/// The spatial dimensions of height of input feature map.
|
||||||
|
IntV imgSizeH_;
|
||||||
|
/// The spatial dimensions of width of input feature map.
|
||||||
|
IntV imgSizeW_;
|
||||||
|
/// The spatial dimensions of height of output feature map.
|
||||||
|
IntV outputH_;
|
||||||
|
/// The spatial dimensions of width of output feature map.
|
||||||
|
IntV outputW_;
|
||||||
|
|
||||||
|
/*The expandInput_ and transOutValue_ are used for CPU expand conv calc*/
|
||||||
|
/// Expand one sample at a time. shape:
|
||||||
|
/// (numChannels * filterPixels_, outputSizeH * outputSizeW)
|
||||||
|
MatrixPtr expandInput_;
|
||||||
|
/// The transpose of output, which is an auxiliary matrix.
|
||||||
|
MatrixPtr transOutValue_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ConvBaseLayerCpu(const LayerConfig& config)
|
||||||
|
: ConvBaseLayer(config) {}
|
||||||
|
|
||||||
|
~ConvBaseLayerCpu() {}
|
||||||
|
|
||||||
|
bool init(const LayerMap& layerMap, const ParameterMap& parameterMap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or resize expandInput_.
|
||||||
|
*/
|
||||||
|
void resetExpandInput(size_t height, size_t width);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add shared bias.
|
||||||
|
*/
|
||||||
|
void addSharedBias();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add unshared bias.
|
||||||
|
*/
|
||||||
|
void addUnsharedBias();
|
||||||
|
/**
|
||||||
|
* Expand one input sample.
|
||||||
|
*/
|
||||||
|
void expandOneFrame(MatrixPtr image, size_t startIdx, int inIdx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expand one input sample and perform matrix multiplication.
|
||||||
|
*/
|
||||||
|
void expandFwdOnce(MatrixPtr image, MatrixPtr out, int inIdx, int startIdx);
|
||||||
|
|
||||||
|
void bpropSharedBias(MatrixPtr biases, MatrixPtr v);
|
||||||
|
void bpropBiases(MatrixPtr v);
|
||||||
|
void bpropWeights(MatrixPtr image, MatrixPtr out, int inpIdx);
|
||||||
|
void bpropActs(MatrixPtr image, MatrixPtr out, int inpIdx);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace paddle
|
@ -1,88 +0,0 @@
|
|||||||
/* 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 "paddle/utils/Logging.h"
|
|
||||||
#include "ConvTransBaseLayer.h"
|
|
||||||
namespace paddle {
|
|
||||||
|
|
||||||
bool ConvTransBaseLayer::init(const LayerMap& layerMap,
|
|
||||||
const ParameterMap& parameterMap) {
|
|
||||||
/* Initialize the basic parent class */
|
|
||||||
Layer::init(layerMap, parameterMap);
|
|
||||||
|
|
||||||
/* Initialize the convolutional layer parameter */
|
|
||||||
/* Everything is the same as ConvBaseLayer.cpp except that the meaning of
|
|
||||||
* num_filters and channel is switched.
|
|
||||||
*
|
|
||||||
* In the config, num_filters refer to the number of feature maps in the
|
|
||||||
* output of convTransLayer, and channel refer to the number of feature maps
|
|
||||||
* in the input of convTransLayer.
|
|
||||||
*
|
|
||||||
* However, within the convTrans class, the channel is related to the output
|
|
||||||
* and num_filters is related to the input, so that it is consistent with the
|
|
||||||
* settings in convLayer.
|
|
||||||
* */
|
|
||||||
channel_ = config_.num_filters();
|
|
||||||
sharedBiases_ = config_.shared_biases();
|
|
||||||
for (auto& inputConfig : config_.inputs()) {
|
|
||||||
const ConvConfig& conf = inputConfig.conv_conf();
|
|
||||||
padding_.push_back(conf.padding());
|
|
||||||
stride_.push_back(conf.stride());
|
|
||||||
filterSize_.push_back(conf.filter_size());
|
|
||||||
paddingY_.push_back(conf.padding_y());
|
|
||||||
strideY_.push_back(conf.stride_y());
|
|
||||||
filterSizeY_.push_back(conf.filter_size_y());
|
|
||||||
filterPixels_.push_back(filterSize_.back() * filterSizeY_.back());
|
|
||||||
numFilters_.push_back(conf.channels());
|
|
||||||
imgSize_.push_back(conf.img_size());
|
|
||||||
imgPixels_.push_back(imgSize_.back() * imgSize_.back());
|
|
||||||
groups_.push_back(conf.groups());
|
|
||||||
filterChannels_.push_back(conf.filter_channels());
|
|
||||||
outputX_.push_back(conf.output_x());
|
|
||||||
outputs_.push_back(outputX_.back() * outputX_.back());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the weightList */
|
|
||||||
CHECK(inputLayers_.size() == parameters_.size());
|
|
||||||
for (size_t i = 0; i < inputLayers_.size(); i++) {
|
|
||||||
size_t height, width;
|
|
||||||
height = filterPixels_[i] * filterChannels_[i];
|
|
||||||
width = numFilters_[i];
|
|
||||||
|
|
||||||
// create a new weight
|
|
||||||
CHECK_EQ(parameters_[i]->getSize(), width * height);
|
|
||||||
Weight* w = new Weight(height, width, parameters_[i]);
|
|
||||||
weights_.emplace_back(w);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize the biases_ */
|
|
||||||
if (biasParameter_.get() != NULL) {
|
|
||||||
if (sharedBiases_) {
|
|
||||||
CHECK_EQ((size_t)channel_, biasParameter_->getSize());
|
|
||||||
biases_ =
|
|
||||||
std::unique_ptr<Weight>(new Weight(channel_, 1, biasParameter_));
|
|
||||||
} else {
|
|
||||||
biases_ =
|
|
||||||
std::unique_ptr<Weight>(new Weight(getSize(), 1, biasParameter_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// default caffe model
|
|
||||||
caffeMode_ = true;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace paddle
|
|
@ -1,117 +0,0 @@
|
|||||||
/* 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"
|
|
||||||
namespace paddle {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A Base Convolution Layer, which convolves the input image
|
|
||||||
* with learned filters and (optionally) adds biases.
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ConvTransBaseLayer : public Layer {
|
|
||||||
protected:
|
|
||||||
typedef std::vector<int> IntV;
|
|
||||||
|
|
||||||
/// The number of channel in image (the output of the deconv layer).
|
|
||||||
int channel_;
|
|
||||||
/// The x dimension of the padding.
|
|
||||||
IntV padding_;
|
|
||||||
/// The y dimension of the padding.
|
|
||||||
IntV paddingY_;
|
|
||||||
/// The x dimension of the stride.
|
|
||||||
IntV stride_;
|
|
||||||
/// The y dimension of the stride.
|
|
||||||
IntV strideY_;
|
|
||||||
/// The x dimension of a filter kernel.
|
|
||||||
IntV filterSize_;
|
|
||||||
/// The y dimension of a filter kernel.
|
|
||||||
IntV filterSizeY_;
|
|
||||||
/// The number of filters(i.e. the number channels of the deconv layer input)
|
|
||||||
IntV numFilters_;
|
|
||||||
/// The spatial dimensions of input feature map.
|
|
||||||
IntV imgSize_;
|
|
||||||
/// The total pixel size of input feature map.
|
|
||||||
/// imgPixels_ = imgSizeX_ * imgSizeY_.
|
|
||||||
IntV imgPixels_;
|
|
||||||
/// filterPixels_ = filterSizeX_ * filterSizeY_.
|
|
||||||
IntV filterPixels_;
|
|
||||||
/// filterChannels_ = channels_/groups_.
|
|
||||||
IntV filterChannels_;
|
|
||||||
/// The spatial dimensions of output feature map.
|
|
||||||
IntV outputX_;
|
|
||||||
/// The spatial dimensions of output feature map.
|
|
||||||
IntV outputs_;
|
|
||||||
/// Group size, refer to grouped convolution in
|
|
||||||
/// Alex Krizhevsky's paper: when group=2, the first half of the
|
|
||||||
/// filters are only connected to the first half of the input channels,
|
|
||||||
/// and the second half only connected to the second half.
|
|
||||||
IntV groups_;
|
|
||||||
/// Whether the bias is shared for feature in each channel.
|
|
||||||
bool sharedBiases_;
|
|
||||||
|
|
||||||
/// shape of weight: (numChannels * filterPixels_, numFilters)
|
|
||||||
WeightList weights_;
|
|
||||||
/// If shared_biases is false shape of bias: (numFilters_, 1)
|
|
||||||
/// If shared_biases is ture shape of bias:
|
|
||||||
/// (numFilters_ * outputX * outputY, 1)
|
|
||||||
std::unique_ptr<Weight> biases_;
|
|
||||||
|
|
||||||
/// True by default. The only difference is the calculation
|
|
||||||
/// of output size.
|
|
||||||
bool caffeMode_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ConvTransBaseLayer(const LayerConfig& config) : Layer(config) {}
|
|
||||||
|
|
||||||
virtual bool init(const LayerMap& layerMap, const ParameterMap& parameterMap);
|
|
||||||
|
|
||||||
Weight& getWeight(int idx) { return *weights_[idx]; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculate image size based on caffeMode_ from outputSize.
|
|
||||||
* - input(+padding): 0123456789
|
|
||||||
* - imageSize(+padding) = 10;
|
|
||||||
* - filterSize = 3;
|
|
||||||
* - stride = 2;
|
|
||||||
* - caffeMode_ is true:
|
|
||||||
- output: (012), (234), (456), (678)
|
|
||||||
- outputSize = 4;
|
|
||||||
* - caffeMode_ is false:
|
|
||||||
* - output: (012), (234), (456), (678), (9)
|
|
||||||
* - outputSize = 5;
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In order to be consistent with the convLayer, here the outputSize is
|
|
||||||
* actually the size of the input image of convTransLayer, and the image size
|
|
||||||
* is actually the size of the output image of convTransLayer
|
|
||||||
*/
|
|
||||||
int imageSize(int outputSize, int filterSize, int padding, int stride) {
|
|
||||||
int imageSize;
|
|
||||||
if (!caffeMode_) {
|
|
||||||
imageSize =
|
|
||||||
(outputSize - 1) * stride + filterSize - 2 * padding - stride + 1;
|
|
||||||
} else {
|
|
||||||
imageSize = (outputSize - 1) * stride + filterSize - 2 * padding;
|
|
||||||
}
|
|
||||||
CHECK_GE(imageSize, 1);
|
|
||||||
return imageSize;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace paddle
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in new issue