parent
211f83fa22
commit
eeb17c26fd
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,91 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. 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 "ConvOp.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
/*
|
||||
* imData = [input_channels, input_height, input_width]
|
||||
* colData = [input_channels, filter_height, filter_width,
|
||||
* output_height, output_width]
|
||||
*/
|
||||
template <DeviceType Device, class T>
|
||||
class DepthwiseConvFunctor {
|
||||
public:
|
||||
void operator()(int outputSize,
|
||||
const T* inputData,
|
||||
const T* filterData,
|
||||
int batchSize,
|
||||
int outputChannels,
|
||||
int outputHeight,
|
||||
int outputWidth,
|
||||
int filterHeight,
|
||||
int filterWidth,
|
||||
int strideH,
|
||||
int strideW,
|
||||
int paddingH,
|
||||
int paddingW,
|
||||
T* outputData);
|
||||
};
|
||||
|
||||
template <DeviceType Device, class T>
|
||||
class DepthwiseConvGradInputFunctor {
|
||||
public:
|
||||
void operator()(int inputSize,
|
||||
const T* outputGrad,
|
||||
const T* filterData,
|
||||
int batchSize,
|
||||
int outputChannels,
|
||||
int outputHeight,
|
||||
int outputWidth,
|
||||
int inputHeight,
|
||||
int inputWidth,
|
||||
int filterHeight,
|
||||
int filterWidth,
|
||||
int strideH,
|
||||
int strideW,
|
||||
int paddingH,
|
||||
int paddingW,
|
||||
T* inputGrad);
|
||||
};
|
||||
|
||||
template <DeviceType Device, class T>
|
||||
class DepthwiseConvGradFilterFunctor {
|
||||
public:
|
||||
void operator()(int num_i,
|
||||
int colDataSize,
|
||||
const T* outputGrad,
|
||||
const T* inputData,
|
||||
int batchSize,
|
||||
int outputChannels,
|
||||
int outputHeight,
|
||||
int outputWidth,
|
||||
int inputHeight,
|
||||
int inputWidth,
|
||||
int filterHeight,
|
||||
int filterWidth,
|
||||
int strideH,
|
||||
int strideW,
|
||||
int paddingH,
|
||||
int paddingW,
|
||||
T* colData,
|
||||
T* multiplierData,
|
||||
T* filterGrad);
|
||||
|
||||
}; // namespace paddle
|
||||
|
||||
} // namespace paddle
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,165 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. 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 "DepthwiseConvLayer.h"
|
||||
#include "paddle/utils/Logging.h"
|
||||
#include "paddle/utils/Stat.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
/*
|
||||
* The calculation of the exconvt(convolution transpose (deconv) operation)
|
||||
* is a swap of forward and backward of the calculation of exconv.
|
||||
* */
|
||||
REGISTER_LAYER(depthwise_conv, DepthwiseConvLayer);
|
||||
|
||||
bool DepthwiseConvLayer::init(const LayerMap &layerMap,
|
||||
const ParameterMap ¶meterMap) {
|
||||
/* Initialize the basic convolutional parent class */
|
||||
ExpandConvBaseLayer::init(layerMap, parameterMap);
|
||||
|
||||
size_t numInputs = config_.inputs_size();
|
||||
inputShape_.resize(numInputs);
|
||||
filterShape_.resize(numInputs);
|
||||
outputShape_.resize(numInputs);
|
||||
multiplierShape_.resize(numInputs);
|
||||
weightMultiplier_.resize(numInputs);
|
||||
|
||||
for (int i = 0; i < config_.inputs_size(); i++) {
|
||||
std::vector<size_t> paddings = {(size_t)paddingY_[i], (size_t)padding_[i]};
|
||||
std::vector<size_t> strides = {(size_t)strideY_[i], (size_t)stride_[i]};
|
||||
Matrix::resizeOrCreate(weightMultiplier_[i],
|
||||
(size_t)outputH_[i] * (size_t)outputW_[i],
|
||||
(size_t)1,
|
||||
false,
|
||||
useGpu_);
|
||||
weightMultiplier_[i]->one();
|
||||
createFunction(forward_,
|
||||
"DepthwiseConv",
|
||||
FuncConfig()
|
||||
.set("paddings", paddings)
|
||||
.set("strides", strides)
|
||||
.set("groups", (size_t)groups_[i]));
|
||||
|
||||
createFunction(backward_,
|
||||
"DepthwiseConvGradInput",
|
||||
FuncConfig()
|
||||
.set("paddings", paddings)
|
||||
.set("strides", strides)
|
||||
.set("groups", (size_t)groups_[i]));
|
||||
|
||||
createFunction(backward_,
|
||||
"DepthwiseConvGradFilter",
|
||||
FuncConfig()
|
||||
.set("paddings", paddings)
|
||||
.set("strides", strides)
|
||||
.set("groups", (size_t)groups_[i]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// i is the index of input layers
|
||||
#define BACKWARD_INPUT(i, inputs, outputs) \
|
||||
backward_[2 * i]->calc(inputs, outputs)
|
||||
#define BACKWARD_FILTER(i, inputs, outputs) \
|
||||
backward_[2 * i + 1]->calc(inputs, outputs)
|
||||
|
||||
void DepthwiseConvLayer::forward(PassType passType) {
|
||||
Layer::forward(passType);
|
||||
|
||||
size_t batchSize = inputLayers_[0]->getOutputValue()->getHeight();
|
||||
resetOutput(batchSize, getOutputSize());
|
||||
|
||||
// Calculate the shape of the input, output, and filter.
|
||||
for (size_t i = 0; i < inputLayers_.size(); ++i) {
|
||||
inputShape_[i] = TensorShape({(size_t)batchSize,
|
||||
(size_t)channels_[i],
|
||||
(size_t)imgSizeH_[i],
|
||||
(size_t)imgSizeW_[i]});
|
||||
multiplierShape_[i] =
|
||||
TensorShape({(size_t)outputH_[i] * (size_t)outputW_[i], (size_t)1});
|
||||
filterShape_[i] = TensorShape({(size_t)groups_[i],
|
||||
(size_t)numFilters_ / groups_[i],
|
||||
(size_t)channels_[i] / groups_[i],
|
||||
(size_t)filterSizeY_[i],
|
||||
(size_t)filterSize_[i]});
|
||||
outputShape_[i] = TensorShape({(size_t)batchSize,
|
||||
(size_t)numFilters_,
|
||||
(size_t)outputH_[i],
|
||||
(size_t)outputW_[i]});
|
||||
}
|
||||
|
||||
// Calculate the output value.
|
||||
for (size_t i = 0; i < inputLayers_.size(); ++i) {
|
||||
BufferArgs inputs;
|
||||
BufferArgs outputs;
|
||||
inputs.addArg(*getInputValue(i), inputShape_[i]);
|
||||
inputs.addArg(*weights_[i]->getW(), filterShape_[i]);
|
||||
outputs.addArg(
|
||||
*getOutputValue(), outputShape_[i], i == 0 ? ASSIGN_TO : ADD_TO);
|
||||
|
||||
forward_[i]->calc(inputs, outputs);
|
||||
}
|
||||
|
||||
/* add the bias-vector */
|
||||
if (biases_.get()) {
|
||||
if (sharedBiases_) {
|
||||
addSharedBias();
|
||||
} else {
|
||||
addUnsharedBias();
|
||||
}
|
||||
}
|
||||
|
||||
/* activation */
|
||||
forwardActivation();
|
||||
}
|
||||
|
||||
void DepthwiseConvLayer::backward(const UpdateCallback &callback) {
|
||||
backwardActivation();
|
||||
|
||||
MatrixPtr outGrad = getOutputGrad();
|
||||
if (biases_ && biases_->getWGrad()) {
|
||||
bpropBiases(outGrad);
|
||||
/* Increasing the number of gradient */
|
||||
biases_->getParameterPtr()->incUpdate(callback);
|
||||
}
|
||||
|
||||
// Calculate the input grad and filter grad.
|
||||
for (size_t i = 0; i < inputLayers_.size(); ++i) {
|
||||
if (getInputGrad(i)) {
|
||||
BufferArgs inputs;
|
||||
BufferArgs outputs;
|
||||
inputs.addArg(*getOutputGrad(), outputShape_[i]);
|
||||
inputs.addArg(*weights_[i]->getW(), filterShape_[i]);
|
||||
outputs.addArg(*getInputGrad(i), inputShape_[i], ADD_TO);
|
||||
BACKWARD_INPUT(i, inputs, outputs);
|
||||
}
|
||||
|
||||
if (weights_[i]->getWGrad()) {
|
||||
BufferArgs inputs;
|
||||
BufferArgs outputs;
|
||||
inputs.addArg(*getOutputGrad(), outputShape_[i]);
|
||||
inputs.addArg(*getInputValue(i), inputShape_[i]);
|
||||
inputs.addArg(*weightMultiplier_[i], multiplierShape_[i]);
|
||||
// weight_multiplier
|
||||
outputs.addArg(*weights_[i]->getWGrad(), filterShape_[i], ADD_TO);
|
||||
BACKWARD_FILTER(i, inputs, outputs);
|
||||
|
||||
/* Increasing the number of gradient */
|
||||
weights_[i]->getParameterPtr()->incUpdate(callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace paddle
|
@ -0,0 +1,52 @@
|
||||
/* Copyright (c) 2016 PaddlePaddle Authors. 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 <vector>
|
||||
#include "ExpandConvBaseLayer.h"
|
||||
#include "paddle/math/Matrix.h"
|
||||
|
||||
namespace paddle {
|
||||
|
||||
/**
|
||||
* @brief A subclass of convolution layer.
|
||||
* This layer expands input and use matrix multiplication to
|
||||
* calculate convolution operation.
|
||||
*
|
||||
* The config file api is img_conv_layer.
|
||||
*/
|
||||
|
||||
class DepthwiseConvLayer : public ExpandConvBaseLayer {
|
||||
public:
|
||||
explicit DepthwiseConvLayer(const LayerConfig& config)
|
||||
: ExpandConvBaseLayer(config) {}
|
||||
|
||||
~DepthwiseConvLayer() {}
|
||||
|
||||
bool init(const LayerMap& layerMap,
|
||||
const ParameterMap& parameterMap) override;
|
||||
|
||||
void forward(PassType passType) override;
|
||||
void backward(const UpdateCallback& callback) override;
|
||||
|
||||
protected:
|
||||
std::vector<TensorShape> inputShape_;
|
||||
std::vector<TensorShape> filterShape_;
|
||||
std::vector<TensorShape> outputShape_;
|
||||
std::vector<TensorShape> multiplierShape_;
|
||||
std::vector<MatrixPtr> weightMultiplier_;
|
||||
};
|
||||
|
||||
} // namespace paddle
|
Loading…
Reference in new issue