commit
d1945e8d56
@ -1 +1 @@
|
|||||||
go_library(paddle_master SHARED)
|
go_library(paddle_master SHARED DEPS paddle_go_optimizer)
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
/* 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. */
|
||||||
|
|
||||||
|
syntax="proto2";
|
||||||
|
package paddle.framework;
|
||||||
|
|
||||||
|
import "attr_type.proto";
|
||||||
|
|
||||||
|
// AttrDesc is used to describe Attributes of an Operator. It contain's
|
||||||
|
// name, type, and value of Attribute.
|
||||||
|
//
|
||||||
|
// e.g, for scale=3.0: name=scala, type=AttrType.FLOAT, value=3.0
|
||||||
|
message AttrDesc {
|
||||||
|
required string name = 1;
|
||||||
|
required AttrType type = 2;
|
||||||
|
optional int32 i = 3;
|
||||||
|
optional float f = 4;
|
||||||
|
optional string s = 5;
|
||||||
|
repeated int32 ints = 6;
|
||||||
|
repeated float floats = 7;
|
||||||
|
repeated string strings = 8;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Protocol Message to describe an Operator.
|
||||||
|
//
|
||||||
|
// In PaddlePaddle, Operator is used to do a certain computation such
|
||||||
|
// as "add", "sub", "cosine", etc.
|
||||||
|
// (1) Operator needs to know the input and output variable names.
|
||||||
|
// (2) Some ops may have special attributes such as "scale" in "CosineOp".
|
||||||
|
//
|
||||||
|
// 3rd-party language can build this proto message and call
|
||||||
|
// AddOp(const OpDesc& op_desc) of Paddle core to create an Operator.
|
||||||
|
message OpDesc {
|
||||||
|
// input names of this Operator.
|
||||||
|
repeated string inputs = 1;
|
||||||
|
|
||||||
|
// output names of this Operator.
|
||||||
|
repeated string outputs = 2;
|
||||||
|
|
||||||
|
// type of this Operator, such as "add", "sub", "fc".
|
||||||
|
required string type = 3;
|
||||||
|
|
||||||
|
// Attributes of this Operator. e.g., scale=3.0 in cosine op.
|
||||||
|
repeated AttrDesc attrs = 4;
|
||||||
|
};
|
@ -0,0 +1,35 @@
|
|||||||
|
/* 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 <gtest/gtest.h>
|
||||||
|
#include <paddle/framework/op_desc.pb.h>
|
||||||
|
|
||||||
|
TEST(OpDesc, Create) {
|
||||||
|
paddle::framework::OpDesc op_desc;
|
||||||
|
op_desc.set_type("add");
|
||||||
|
op_desc.add_inputs("X");
|
||||||
|
op_desc.add_inputs("Y");
|
||||||
|
op_desc.add_outputs("Z");
|
||||||
|
|
||||||
|
auto attr = op_desc.mutable_attrs()->Add();
|
||||||
|
attr->set_type(paddle::framework::AttrType::FLOAT);
|
||||||
|
attr->set_f(3.14);
|
||||||
|
|
||||||
|
// required field name is not set, so IsInitialized should be false.
|
||||||
|
ASSERT_FALSE(op_desc.IsInitialized());
|
||||||
|
|
||||||
|
attr->set_name("add");
|
||||||
|
// after all required fields are set, IsInitialized should be true now.
|
||||||
|
ASSERT_TRUE(op_desc.IsInitialized());
|
||||||
|
}
|
@ -0,0 +1,154 @@
|
|||||||
|
/* 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 "DetectionOutputLayer.h"
|
||||||
|
|
||||||
|
namespace paddle {
|
||||||
|
|
||||||
|
REGISTER_LAYER(detection_output, DetectionOutputLayer);
|
||||||
|
|
||||||
|
bool DetectionOutputLayer::init(const LayerMap& layerMap,
|
||||||
|
const ParameterMap& parameterMap) {
|
||||||
|
Layer::init(layerMap, parameterMap);
|
||||||
|
auto& layerConf = config_.inputs(0).detection_output_conf();
|
||||||
|
numClasses_ = layerConf.num_classes();
|
||||||
|
inputNum_ = layerConf.input_num();
|
||||||
|
nmsThreshold_ = layerConf.nms_threshold();
|
||||||
|
confidenceThreshold_ = layerConf.confidence_threshold();
|
||||||
|
nmsTopK_ = layerConf.nms_top_k();
|
||||||
|
keepTopK_ = layerConf.keep_top_k();
|
||||||
|
backgroundId_ = layerConf.background_id();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DetectionOutputLayer::forward(PassType passType) {
|
||||||
|
Layer::forward(passType);
|
||||||
|
size_t batchSize = getInputValue(*getLocInputLayer(0))->getHeight();
|
||||||
|
|
||||||
|
locSizeSum_ = 0;
|
||||||
|
confSizeSum_ = 0;
|
||||||
|
for (size_t n = 0; n < inputNum_; ++n) {
|
||||||
|
const MatrixPtr inLoc = getInputValue(*getLocInputLayer(n));
|
||||||
|
const MatrixPtr inConf = getInputValue(*getConfInputLayer(n));
|
||||||
|
locSizeSum_ += inLoc->getElementCnt();
|
||||||
|
confSizeSum_ += inConf->getElementCnt();
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix::resizeOrCreate(locTmpBuffer_, 1, locSizeSum_, false, useGpu_);
|
||||||
|
Matrix::resizeOrCreate(
|
||||||
|
confTmpBuffer_, confSizeSum_ / numClasses_, numClasses_, false, useGpu_);
|
||||||
|
|
||||||
|
size_t locOffset = 0;
|
||||||
|
size_t confOffset = 0;
|
||||||
|
auto& layerConf = config_.inputs(0).detection_output_conf();
|
||||||
|
for (size_t n = 0; n < inputNum_; ++n) {
|
||||||
|
const MatrixPtr inLoc = getInputValue(*getLocInputLayer(n));
|
||||||
|
const MatrixPtr inConf = getInputValue(*getConfInputLayer(n));
|
||||||
|
|
||||||
|
size_t height = getInput(*getLocInputLayer(n)).getFrameHeight();
|
||||||
|
if (!height) height = layerConf.height();
|
||||||
|
size_t width = getInput(*getLocInputLayer(n)).getFrameWidth();
|
||||||
|
if (!width) width = layerConf.width();
|
||||||
|
locOffset += appendWithPermute(*inLoc,
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
locSizeSum_,
|
||||||
|
locOffset,
|
||||||
|
batchSize,
|
||||||
|
*locTmpBuffer_,
|
||||||
|
kNCHWToNHWC);
|
||||||
|
confOffset += appendWithPermute(*inConf,
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
confSizeSum_,
|
||||||
|
confOffset,
|
||||||
|
batchSize,
|
||||||
|
*confTmpBuffer_,
|
||||||
|
kNCHWToNHWC);
|
||||||
|
}
|
||||||
|
CHECK_EQ(locOffset, locSizeSum_ / batchSize);
|
||||||
|
CHECK_EQ(confOffset, confSizeSum_ / batchSize);
|
||||||
|
|
||||||
|
MatrixPtr priorValue;
|
||||||
|
if (useGpu_) {
|
||||||
|
Matrix::resizeOrCreate(locCpuBuffer_, 1, locSizeSum_, false, false);
|
||||||
|
Matrix::resizeOrCreate(
|
||||||
|
confCpuBuffer_, confSizeSum_ / numClasses_, numClasses_, false, false);
|
||||||
|
MatrixPtr priorTmpValue = getInputValue(*getPriorBoxLayer());
|
||||||
|
Matrix::resizeOrCreate(
|
||||||
|
priorCpuValue_, 1, priorTmpValue->getElementCnt(), false, false);
|
||||||
|
|
||||||
|
locCpuBuffer_->copyFrom(*locTmpBuffer_);
|
||||||
|
confCpuBuffer_->copyFrom(*confTmpBuffer_);
|
||||||
|
priorCpuValue_->copyFrom(*priorTmpValue);
|
||||||
|
|
||||||
|
locBuffer_ = locCpuBuffer_;
|
||||||
|
confBuffer_ = confCpuBuffer_;
|
||||||
|
priorValue = priorCpuValue_;
|
||||||
|
} else {
|
||||||
|
priorValue = getInputValue(*getPriorBoxLayer());
|
||||||
|
locBuffer_ = locTmpBuffer_;
|
||||||
|
confBuffer_ = confTmpBuffer_;
|
||||||
|
}
|
||||||
|
confBuffer_->softmax(*confBuffer_);
|
||||||
|
|
||||||
|
size_t numPriors = priorValue->getElementCnt() / 8;
|
||||||
|
std::vector<std::vector<NormalizedBBox>> allDecodedBBoxes;
|
||||||
|
for (size_t n = 0; n < batchSize; ++n) {
|
||||||
|
std::vector<NormalizedBBox> decodedBBoxes;
|
||||||
|
for (size_t i = 0; i < numPriors; ++i) {
|
||||||
|
size_t priorOffset = i * 8;
|
||||||
|
size_t locPredOffset = n * numPriors * 4 + i * 4;
|
||||||
|
std::vector<NormalizedBBox> priorBBoxVec;
|
||||||
|
getBBoxFromPriorData(
|
||||||
|
priorValue->getData() + priorOffset, 1, priorBBoxVec);
|
||||||
|
std::vector<std::vector<real>> priorBBoxVar;
|
||||||
|
getBBoxVarFromPriorData(
|
||||||
|
priorValue->getData() + priorOffset, 1, priorBBoxVar);
|
||||||
|
std::vector<real> locPredData;
|
||||||
|
for (size_t j = 0; j < 4; ++j)
|
||||||
|
locPredData.push_back(*(locBuffer_->getData() + locPredOffset + j));
|
||||||
|
NormalizedBBox bbox =
|
||||||
|
decodeBBoxWithVar(priorBBoxVec[0], priorBBoxVar[0], locPredData);
|
||||||
|
decodedBBoxes.push_back(bbox);
|
||||||
|
}
|
||||||
|
allDecodedBBoxes.push_back(decodedBBoxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::map<size_t, std::vector<size_t>>> allIndices;
|
||||||
|
size_t numKept = getDetectionIndices(confBuffer_->getData(),
|
||||||
|
numPriors,
|
||||||
|
numClasses_,
|
||||||
|
backgroundId_,
|
||||||
|
batchSize,
|
||||||
|
confidenceThreshold_,
|
||||||
|
nmsTopK_,
|
||||||
|
nmsThreshold_,
|
||||||
|
keepTopK_,
|
||||||
|
allDecodedBBoxes,
|
||||||
|
&allIndices);
|
||||||
|
|
||||||
|
resetOutput(numKept, 7);
|
||||||
|
MatrixPtr outV = getOutputValue();
|
||||||
|
getDetectionOutput(confBuffer_->getData(),
|
||||||
|
numKept,
|
||||||
|
numPriors,
|
||||||
|
numClasses_,
|
||||||
|
batchSize,
|
||||||
|
allIndices,
|
||||||
|
allDecodedBBoxes,
|
||||||
|
*outV);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace paddle
|
@ -0,0 +1,77 @@
|
|||||||
|
/* 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 <map>
|
||||||
|
#include <vector>
|
||||||
|
#include "DetectionUtil.h"
|
||||||
|
#include "Layer.h"
|
||||||
|
|
||||||
|
namespace paddle {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The detection output layer for a SSD detection task. This layer applies the
|
||||||
|
* Non-maximum suppression to the all predicted bounding box and keeps the
|
||||||
|
* Top-K bounding boxes.
|
||||||
|
* - Input: This layer needs three input layers: The first input layer
|
||||||
|
* is the priorbox layer. The rest two input layers are convolution
|
||||||
|
* layers for generating bbox location offset and the classification
|
||||||
|
* confidence.
|
||||||
|
* - Output: The predict bounding box locations.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DetectionOutputLayer : public Layer {
|
||||||
|
public:
|
||||||
|
explicit DetectionOutputLayer(const LayerConfig& config) : Layer(config) {}
|
||||||
|
|
||||||
|
bool init(const LayerMap& layerMap, const ParameterMap& parameterMap);
|
||||||
|
|
||||||
|
void forward(PassType passType);
|
||||||
|
|
||||||
|
void backward(const UpdateCallback& callback = nullptr) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline LayerPtr getPriorBoxLayer() { return inputLayers_[0]; }
|
||||||
|
|
||||||
|
inline LayerPtr getLocInputLayer(size_t index) {
|
||||||
|
return inputLayers_[1 + index];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline LayerPtr getConfInputLayer(size_t index) {
|
||||||
|
return inputLayers_[1 + inputNum_ + index];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
size_t numClasses_; // number of classes
|
||||||
|
size_t inputNum_; // number of input layers
|
||||||
|
real nmsThreshold_;
|
||||||
|
real confidenceThreshold_;
|
||||||
|
size_t nmsTopK_;
|
||||||
|
size_t keepTopK_;
|
||||||
|
size_t backgroundId_;
|
||||||
|
|
||||||
|
size_t locSizeSum_;
|
||||||
|
size_t confSizeSum_;
|
||||||
|
|
||||||
|
MatrixPtr locBuffer_;
|
||||||
|
MatrixPtr confBuffer_;
|
||||||
|
MatrixPtr locTmpBuffer_;
|
||||||
|
MatrixPtr confTmpBuffer_;
|
||||||
|
MatrixPtr priorCpuValue_;
|
||||||
|
MatrixPtr locCpuBuffer_;
|
||||||
|
MatrixPtr confCpuBuffer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace paddle
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,103 @@
|
|||||||
|
/* 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 "CostLayer.h"
|
||||||
|
#include "DataLayer.h"
|
||||||
|
#include "DetectionUtil.h"
|
||||||
|
#include "Layer.h"
|
||||||
|
|
||||||
|
using std::vector;
|
||||||
|
using std::pair;
|
||||||
|
|
||||||
|
namespace paddle {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The multibox loss layer for a SSD detection task.
|
||||||
|
* The loss is composed by the location loss and the confidence loss.
|
||||||
|
* The location loss is a smooth L1 loss and the confidence loss is
|
||||||
|
* a softmax loss.
|
||||||
|
* - Input: This layer needs four input layers: The first input layer
|
||||||
|
* is the priorbox layer and the second layer is a label layer.
|
||||||
|
* The rest two input layers are convolution layers for generating
|
||||||
|
* bbox location offset and the classification confidence.
|
||||||
|
* - Output: The Single Shot Multibox Detection loss value.
|
||||||
|
* Reference:
|
||||||
|
* Wei Liu, Dragomir Anguelov, Dumitru Erhan, Christian Szegedy, Scott Reed,
|
||||||
|
* Cheng-Yang Fu, Alexander C. Berg. SSD: Single Shot MultiBox Detector
|
||||||
|
*/
|
||||||
|
|
||||||
|
class MultiBoxLossLayer : public CostLayer {
|
||||||
|
public:
|
||||||
|
explicit MultiBoxLossLayer(const LayerConfig& config) : CostLayer(config) {}
|
||||||
|
|
||||||
|
bool init(const LayerMap& layerMap, const ParameterMap& parameterMap);
|
||||||
|
|
||||||
|
void forward(PassType passType);
|
||||||
|
|
||||||
|
void backward(const UpdateCallback& callback = nullptr);
|
||||||
|
|
||||||
|
void forwardImp(Matrix& output, Argument& label, Matrix& cost) {}
|
||||||
|
|
||||||
|
void backwardImp(Matrix& outputValue, Argument& label, Matrix& outputGrad) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline LayerPtr getPriorBoxLayer() { return inputLayers_[0]; }
|
||||||
|
inline LayerPtr getLabelLayer() { return inputLayers_[1]; }
|
||||||
|
inline LayerPtr getLocInputLayer(size_t index) {
|
||||||
|
return inputLayers_[2 + index];
|
||||||
|
}
|
||||||
|
inline LayerPtr getConfInputLayer(size_t index) {
|
||||||
|
return inputLayers_[2 + inputNum_ + index];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t numClasses_;
|
||||||
|
real overlapThreshold_;
|
||||||
|
real negPosRatio_;
|
||||||
|
real negOverlap_;
|
||||||
|
size_t inputNum_;
|
||||||
|
size_t backgroundId_;
|
||||||
|
|
||||||
|
real locLoss_;
|
||||||
|
real confLoss_;
|
||||||
|
|
||||||
|
size_t numPriors_;
|
||||||
|
size_t numMatches_;
|
||||||
|
size_t numNegs_;
|
||||||
|
size_t numConf_;
|
||||||
|
size_t locSizeSum_;
|
||||||
|
size_t confSizeSum_;
|
||||||
|
|
||||||
|
vector<vector<int>> allMatchIndices_;
|
||||||
|
vector<vector<int>> allNegIndices_;
|
||||||
|
MatrixPtr locGTData_;
|
||||||
|
IVectorPtr confGTData_;
|
||||||
|
|
||||||
|
MatrixPtr locBuffer_;
|
||||||
|
MatrixPtr confBuffer_;
|
||||||
|
MatrixPtr locDiff_;
|
||||||
|
MatrixPtr confProb_;
|
||||||
|
|
||||||
|
MatrixPtr labelCpuValue_;
|
||||||
|
MatrixPtr priorCpuValue_;
|
||||||
|
MatrixPtr locCpuBuffer_;
|
||||||
|
MatrixPtr confCpuBuffer_;
|
||||||
|
MatrixPtr locTmpBuffer_;
|
||||||
|
MatrixPtr confTmpBuffer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace paddle
|
@ -0,0 +1,194 @@
|
|||||||
|
/* 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 <gtest/gtest.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "LayerGradUtil.h"
|
||||||
|
#include "paddle/testing/TestUtil.h"
|
||||||
|
|
||||||
|
using namespace paddle; // NOLINT
|
||||||
|
using namespace std; // NOLINT
|
||||||
|
|
||||||
|
// Do one forward pass of priorBox layer and check to see if its output
|
||||||
|
// matches the given result
|
||||||
|
void doOneDetectionOutputTest(MatrixPtr& inputLoc,
|
||||||
|
MatrixPtr& inputConf,
|
||||||
|
MatrixPtr& inputPriorBox,
|
||||||
|
size_t feature_map_width,
|
||||||
|
size_t feature_map_height,
|
||||||
|
real nms_threshold,
|
||||||
|
bool use_gpu,
|
||||||
|
MatrixPtr& result) {
|
||||||
|
// Setting up the detection output layer
|
||||||
|
TestConfig configt;
|
||||||
|
configt.layerConfig.set_type("detection_output");
|
||||||
|
LayerInputConfig* input = configt.layerConfig.add_inputs();
|
||||||
|
configt.layerConfig.add_inputs();
|
||||||
|
configt.layerConfig.add_inputs();
|
||||||
|
|
||||||
|
DetectionOutputConfig* detOutput = input->mutable_detection_output_conf();
|
||||||
|
detOutput->set_width(feature_map_width);
|
||||||
|
detOutput->set_height(feature_map_height);
|
||||||
|
detOutput->set_nms_threshold(nms_threshold);
|
||||||
|
detOutput->set_num_classes(2);
|
||||||
|
detOutput->set_nms_top_k(20);
|
||||||
|
detOutput->set_keep_top_k(10);
|
||||||
|
detOutput->set_background_id(0);
|
||||||
|
detOutput->set_confidence_threshold(0.01);
|
||||||
|
detOutput->set_input_num(1);
|
||||||
|
configt.inputDefs.push_back({INPUT_DATA_TARGET, "priorbox", 32, 0});
|
||||||
|
configt.inputDefs.push_back({INPUT_DATA, "input_loc", 16, 0});
|
||||||
|
configt.inputDefs.push_back({INPUT_DATA, "input_conf", 8, 0});
|
||||||
|
|
||||||
|
// data layer initialize
|
||||||
|
std::vector<DataLayerPtr> dataLayers;
|
||||||
|
LayerMap layerMap;
|
||||||
|
vector<Argument> datas;
|
||||||
|
initDataLayer(
|
||||||
|
configt, &dataLayers, &datas, &layerMap, "priorbox", 1, false, use_gpu);
|
||||||
|
|
||||||
|
dataLayers[0]->getOutputValue()->copyFrom(*inputPriorBox);
|
||||||
|
dataLayers[1]->getOutputValue()->copyFrom(*inputLoc);
|
||||||
|
dataLayers[2]->getOutputValue()->copyFrom(*inputConf);
|
||||||
|
|
||||||
|
// test layer initialize
|
||||||
|
bool store_FLAGS_use_gpu = FLAGS_use_gpu;
|
||||||
|
FLAGS_use_gpu = use_gpu;
|
||||||
|
std::vector<ParameterPtr> parameters;
|
||||||
|
LayerPtr detectionOutputLayer;
|
||||||
|
initTestLayer(configt, &layerMap, ¶meters, &detectionOutputLayer);
|
||||||
|
FLAGS_use_gpu = store_FLAGS_use_gpu;
|
||||||
|
detectionOutputLayer->forward(PASS_GC);
|
||||||
|
checkMatrixEqual(detectionOutputLayer->getOutputValue(), result);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Layer, detectionOutputLayerFwd) {
|
||||||
|
bool useGpu = false;
|
||||||
|
// CPU case 1.
|
||||||
|
MatrixPtr inputLoc;
|
||||||
|
MatrixPtr inputConf;
|
||||||
|
MatrixPtr inputPriorBox;
|
||||||
|
MatrixPtr result, result2, result3, result4;
|
||||||
|
real nmsTreshold = 0.01;
|
||||||
|
real inputLocData[] = {0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1,
|
||||||
|
0.1};
|
||||||
|
real inputConfData[] = {0.1, 0.9, 0.2, 0.8, 0.3, 0.7, 0.4, 0.6};
|
||||||
|
real inputPriorBoxData[] = {0.1, 0.1, 0.5, 0.5, 0.1, 0.1, 0.2, 0.2,
|
||||||
|
0.2, 0.2, 0.6, 0.6, 0.1, 0.1, 0.2, 0.2,
|
||||||
|
0.3, 0.3, 0.7, 0.7, 0.1, 0.1, 0.2, 0.2,
|
||||||
|
0.4, 0.4, 0.8, 0.8, 0.1, 0.1, 0.2, 0.2};
|
||||||
|
real resultData[] = {
|
||||||
|
0, 1, 0.68997443, 0.099959746, 0.099959746, 0.50804031, 0.50804031};
|
||||||
|
inputLoc = Matrix::create(1, 16, false, useGpu);
|
||||||
|
inputConf = Matrix::create(1, 8, false, useGpu);
|
||||||
|
inputPriorBox = Matrix::create(1, 32, false, useGpu);
|
||||||
|
result = Matrix::create(1, 7, false, useGpu);
|
||||||
|
inputLoc->setData(inputLocData);
|
||||||
|
inputConf->setData(inputConfData);
|
||||||
|
inputPriorBox->setData(inputPriorBoxData);
|
||||||
|
result->setData(resultData);
|
||||||
|
doOneDetectionOutputTest(inputLoc,
|
||||||
|
inputConf,
|
||||||
|
inputPriorBox,
|
||||||
|
/* feature_map_width */ 1,
|
||||||
|
/* feature_map_height */ 1,
|
||||||
|
nmsTreshold,
|
||||||
|
useGpu,
|
||||||
|
result);
|
||||||
|
|
||||||
|
// CPU case 2.
|
||||||
|
nmsTreshold = 0.2;
|
||||||
|
result2 = Matrix::create(2, 7, false, useGpu);
|
||||||
|
real resultData2[] = {0,
|
||||||
|
1,
|
||||||
|
0.68997443,
|
||||||
|
0.099959746,
|
||||||
|
0.099959746,
|
||||||
|
0.50804031,
|
||||||
|
0.50804031,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
0.59868765,
|
||||||
|
0.29995975,
|
||||||
|
0.29995975,
|
||||||
|
0.70804024,
|
||||||
|
0.70804024};
|
||||||
|
result2->setData(resultData2);
|
||||||
|
doOneDetectionOutputTest(inputLoc,
|
||||||
|
inputConf,
|
||||||
|
inputPriorBox,
|
||||||
|
/* feature_map_width */ 1,
|
||||||
|
/* feature_map_height */ 1,
|
||||||
|
nmsTreshold,
|
||||||
|
useGpu,
|
||||||
|
result2);
|
||||||
|
|
||||||
|
#ifndef PADDLE_ONLY_CPU
|
||||||
|
// GPU case 1.
|
||||||
|
useGpu = true;
|
||||||
|
inputLoc = Matrix::create(1, 16, false, useGpu);
|
||||||
|
inputConf = Matrix::create(1, 8, false, useGpu);
|
||||||
|
inputPriorBox = Matrix::create(1, 32, false, useGpu);
|
||||||
|
inputLoc->copyFrom(inputLocData, 16);
|
||||||
|
inputConf->copyFrom(inputConfData, 8);
|
||||||
|
inputPriorBox->copyFrom(inputPriorBoxData, 32);
|
||||||
|
|
||||||
|
nmsTreshold = 0.01;
|
||||||
|
result3 = Matrix::create(1, 7, false, useGpu);
|
||||||
|
result3->copyFrom(resultData, 7);
|
||||||
|
doOneDetectionOutputTest(inputLoc,
|
||||||
|
inputConf,
|
||||||
|
inputPriorBox,
|
||||||
|
/* feature_map_width */ 1,
|
||||||
|
/* feature_map_height */ 1,
|
||||||
|
nmsTreshold,
|
||||||
|
useGpu,
|
||||||
|
result3);
|
||||||
|
|
||||||
|
// GPU case 2.
|
||||||
|
nmsTreshold = 0.2;
|
||||||
|
result4 = Matrix::create(2, 7, false, useGpu);
|
||||||
|
result4->copyFrom(resultData2, 14);
|
||||||
|
doOneDetectionOutputTest(inputLoc,
|
||||||
|
inputConf,
|
||||||
|
inputPriorBox,
|
||||||
|
/* feature_map_width */ 1,
|
||||||
|
/* feature_map_height */ 1,
|
||||||
|
nmsTreshold,
|
||||||
|
useGpu,
|
||||||
|
result4);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
testing::InitGoogleTest(&argc, argv);
|
||||||
|
initMain(argc, argv);
|
||||||
|
return RUN_ALL_TESTS();
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue