API refactoring

renamed learnedParams blobs field
added new fields: name and type for Layer
pull/265/head
Vitaliy Lyudvichenko 10 years ago
parent f07c5647e3
commit fb66acb6c8
  1. 36
      modules/dnn/include/opencv2/dnn/dnn.hpp
  2. 4
      modules/dnn/src/caffe/caffe_importer.cpp
  3. 21
      modules/dnn/src/dnn.cpp
  4. 2
      modules/dnn/src/layers/concat_layer.cpp
  5. 23
      modules/dnn/src/layers/convolution_layer.cpp
  6. 2
      modules/dnn/src/layers/convolution_layer.hpp
  7. 24
      modules/dnn/src/layers/fully_connected_layer.cpp
  8. 6
      modules/dnn/src/layers/lrn_layer.cpp
  9. 2
      modules/dnn/src/layers/mvn_layer.cpp
  10. 2
      modules/dnn/src/layers/pooling_layer.cpp
  11. 2
      modules/dnn/src/layers/reshape_layer.cpp
  12. 2
      modules/dnn/src/layers/slice_layer.cpp
  13. 2
      modules/dnn/src/layers/softmax_layer.cpp
  14. 4
      modules/dnn/src/layers/split_layer.cpp
  15. 8
      modules/dnn/src/torch/torch_importer.cpp

@ -10,32 +10,44 @@ namespace cv
{
namespace dnn
{
/** @brief initialize dnn module and built-in layers
* This function automatically called on most of OpenCV builds,
* but you need to call it manually on some specific configurations.
*/
CV_EXPORTS void initModule();
class CV_EXPORTS LayerParams : public Dict
struct CV_EXPORTS LayerParams : public Dict
{
public:
///list of learned parameters stored as blobs
std::vector<Blob> blobs;
std::vector<Blob> learnedBlobs;
///optional, name of the layer instance (can be used internal purposes)
String name;
///optional, type name which was used for creating layer by layer factory
String type;
};
//Interface class allows to build new Layers
class CV_EXPORTS Layer
///Interface class allows to build new Layers
struct CV_EXPORTS Layer
{
public:
//learned params of layer must be stored here to allow externally read them
std::vector<Blob> learnedParams;
virtual ~Layer();
///list of learned parameters must be stored here to allow read them using Net::getParam()
std::vector<Blob> blobs;
//shape of output blobs must be adjusted with respect to shape of input blobs
virtual void allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs) = 0;
virtual void forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs) = 0;
//each input/output can be labeled to easily identify their using "layer_name.output_name"
//each input and output can be labeled to easily identify them using "<layer_name>[.output_name]" notation
virtual int inputNameToIndex(String inputName);
virtual int outputNameToIndex(String outputName);
String name; //!< name of the layer instance, can be used for logging or other internal purposes
String type; //!< type name which was used for creating layer by layer factory
Layer();
explicit Layer(const LayerParams &params); //!< intialize only #name, #type and #blobs fields
virtual ~Layer();
};
//containers for String and int
@ -63,7 +75,7 @@ namespace dnn
void forward(LayerId startLayer, LayerId toLayer);
void forward(const std::vector<LayerId> &startLayers, const std::vector<LayerId> &toLayers);
//[Wished feature] Optimized smart forward(). Makes forward only for layers which wasn't changed after previous forward().
//[Wished feature] Optimized forward: makes forward only for layers which wasn't changed after previous forward().
void forwardOpt(LayerId toLayer);
void forwardOpt(const std::vector<LayerId> &toLayers);

@ -193,10 +193,10 @@ namespace
return;
const caffe::LayerParameter &binLayer = netBinary.layer(li);
layerParams.learnedBlobs.resize(binLayer.blobs_size());
layerParams.blobs.resize(binLayer.blobs_size());
for (int bi = 0; bi < binLayer.blobs_size(); bi++)
{
blobFromProto(binLayer.blobs(bi), layerParams.learnedBlobs[bi]);
blobFromProto(binLayer.blobs(bi), layerParams.blobs[bi]);
}
}

@ -48,7 +48,12 @@ struct LayerData
{
LayerData() {}
LayerData(int _id, const String &_name, const String &_type, LayerParams &_params)
: id(_id), name(_name), type(_type), params(_params) {}
: id(_id), name(_name), type(_type), params(_params)
{
//add logging info
params.name = name;
params.type = type;
}
int id;
String name;
@ -470,7 +475,7 @@ Blob Net::getParam(LayerId layer, int numParam)
{
LayerData &ld = impl->getLayerData(layer);
std::vector<Blob> &layerBlobs = ld.layerInstance->learnedParams;
std::vector<Blob> &layerBlobs = ld.layerInstance->blobs;
CV_Assert(numParam < (int)layerBlobs.size());
return layerBlobs[numParam];
}
@ -487,7 +492,12 @@ void Net::deleteLayer(LayerId)
//////////////////////////////////////////////////////////////////////////
Importer::~Importer()
Importer::~Importer() {}
Layer::Layer() {}
Layer::Layer(const LayerParams &params)
: blobs(params.blobs), name(params.name), type(params.type)
{
}
@ -502,10 +512,7 @@ int Layer::outputNameToIndex(String)
return -1;
}
Layer::~Layer()
{
}
Layer::~Layer() {}
//////////////////////////////////////////////////////////////////////////

@ -6,7 +6,7 @@ namespace cv
{
namespace dnn
{
ConcatLayer::ConcatLayer(LayerParams &params)
ConcatLayer::ConcatLayer(LayerParams &params) : Layer(params)
{
axis = params.get<int>("axis", 1);
CV_Assert(axis >= 0);

@ -9,7 +9,7 @@ namespace cv
{
namespace dnn
{
ConvolutionLayer::ConvolutionLayer(LayerParams &params)
ConvolutionLayer::ConvolutionLayer(LayerParams &params) : Layer(params)
{
getKernelParams(params, kerH, kerW, padH, padW, strideH, strideW);
@ -18,15 +18,15 @@ namespace dnn
group = params.get<int>("group", 1);
CV_Assert(numOutput % group == 0);
CV_Assert(params.learnedBlobs.size() >= 1 && (!bias || params.learnedBlobs.size() >= 2));
learnedParams.assign(params.learnedBlobs.begin(), params.learnedBlobs.begin() + (bias ? 2 : 1));
CV_Assert(!bias || blobs.size() == 2);
CV_Assert( bias || blobs.size() == 1);
const Blob &wgtBlob = learnedParams[0];
const Blob &wgtBlob = blobs[0];
CV_Assert(wgtBlob.dims() == 4 && wgtBlob.cols() == kerW && wgtBlob.rows() == kerH);
if (bias)
{
Blob &biasBlob = learnedParams[1];
Blob &biasBlob = blobs[1];
CV_Assert(biasBlob.total() == (size_t)numOutput);
}
@ -43,7 +43,7 @@ namespace dnn
computeInpOutShape(inpBlob);
CV_Assert(inpCn % group == 0 && outCn % group == 0);
CV_Assert(learnedParams[0].num() == outCn && learnedParams[0].channels() == inpCn / group);
CV_Assert(blobs[0].num() == outCn && blobs[0].channels() == inpCn / group);
outGroupCn = outCn / group;
inpGroupCn = inpCn / group;
@ -73,7 +73,7 @@ namespace dnn
void ConvolutionLayer::forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs)
{
Blob &wgtBlob = learnedParams[0];
Blob &wgtBlob = blobs[0];
for (size_t ii = 0; ii < outputs.size(); ii++)
{
@ -93,7 +93,7 @@ namespace dnn
if (bias)
{
float *biasPtr = learnedParams[1].ptrf() + g*outGroupCn;
float *biasPtr = blobs[1].ptrf() + g*outGroupCn;
Mat biasMat(outGroupCn, 1, CV_32F, biasPtr);
cv::gemm(biasMat, biasOnesMat, 1, dstMat, 1, dstMat);
}
@ -144,6 +144,9 @@ namespace dnn
topH = outH; topW = outW; topCn = outCn;
}
DeConvolutionLayer::DeConvolutionLayer(LayerParams &params)
: ConvolutionLayer(params) {}
void DeConvolutionLayer::computeInpOutShape(const Blob &inpBlob)
{
outH = inpBlob.rows();
@ -159,7 +162,7 @@ namespace dnn
void DeConvolutionLayer::forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs)
{
Blob &wghtBlob = learnedParams[0];
Blob &wghtBlob = blobs[0];
for (size_t ii = 0; ii < outputs.size(); ii++)
{
@ -183,7 +186,7 @@ namespace dnn
if (bias)
{
float *biasPtr = learnedParams[1].ptrf() + g*inpGroupCn;
float *biasPtr = blobs[1].ptrf() + g*inpGroupCn;
Mat biasMat(inpGroupCn, 1, CV_32F, biasPtr);
cv::gemm(biasMat, biasOnesMat, 1, dstMat, 1, dstMat);
}

@ -43,7 +43,7 @@ namespace dnn
void col2im(Mat &dstMat);
public:
DeConvolutionLayer(LayerParams &params) : ConvolutionLayer(params) {}
DeConvolutionLayer(LayerParams &params);
void forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs);
};
}

@ -6,23 +6,15 @@ namespace cv
{
namespace dnn
{
FullyConnectedLayer::FullyConnectedLayer(LayerParams &params)
FullyConnectedLayer::FullyConnectedLayer(LayerParams &params) : Layer(params)
{
numOutputs = params.get<int>("num_output");
bias = params.get<bool>("bias_term", true);
axis_ = params.get<int>("axis", 1);
CV_Assert(params.learnedBlobs.size() >= 1);
CV_Assert(!bias || params.learnedBlobs.size() >= 2);
learnedParams.resize(bias ? 2 : 1);
learnedParams[0] = params.learnedBlobs[0];
CV_Assert(learnedParams[0].dims() >= 2 && learnedParams[0].total() >= (size_t)numOutputs);
if (bias)
{
learnedParams[1] = params.learnedBlobs[1];
CV_Assert(learnedParams[1].total() == (size_t)numOutputs);
}
CV_Assert(blobs.size() == (bias ? 2 : 1));
CV_Assert(blobs[0].dims() >= 2 && blobs[0].total() >= (size_t)numOutputs);
CV_Assert(!bias || blobs[1].total() == (size_t)numOutputs);
}
void FullyConnectedLayer::allocate(const std::vector<Blob*> &inputs, std::vector<Blob> &outputs)
@ -32,8 +24,8 @@ namespace dnn
axis = inputs[0]->canonicalAxis(axis_);
innerSize = (int)inputs[0]->total(axis);
CV_Assert((size_t)innerSize * (size_t)numOutputs == learnedParams[0].total());
CV_Assert(learnedParams[0].size(-2) == numOutputs && learnedParams[0].size(-1) == innerSize);
CV_Assert((size_t)innerSize * (size_t)numOutputs == blobs[0].total());
CV_Assert(blobs[0].size(-2) == numOutputs && blobs[0].size(-1) == innerSize);
outputs.resize(inputs.size());
for (size_t i = 0; i < inputs.size(); i++)
@ -63,7 +55,7 @@ namespace dnn
int K = innerSize;
Mat srcMat(M, K, inputs[i]->type(), inputs[i]->ptrf());
Mat weight(N, K, learnedParams[0].type(), learnedParams[0].ptrf());
Mat weight(N, K, blobs[0].type(), blobs[0].ptrf());
Mat dstMat(M, N, outputs[i].type(), outputs[i].ptrf());
//important: Caffe stores weights as transposed array
@ -72,7 +64,7 @@ namespace dnn
if (bias)
{
Mat biasOnesMat = Mat::ones(M, 1, CV_32F);
Mat biasMat(1, N, CV_32F, learnedParams[1].ptrf());
Mat biasMat(1, N, CV_32F, blobs[1].ptrf());
cv::gemm(biasOnesMat, biasMat, 1, dstMat, 1, dstMat);
}
}

@ -8,7 +8,7 @@ namespace cv
{
namespace dnn
{
LRNLayer::LRNLayer(LayerParams &params)
LRNLayer::LRNLayer(LayerParams &params) : Layer(params)
{
String nrmType = params.get<String>("norm_region", "ACROSS_CHANNELS");
if (nrmType == "ACROSS_CHANNELS")
@ -16,11 +16,11 @@ namespace dnn
else if (nrmType == "WITHIN_CHANNEL")
type = SPATIAL_NRM;
else
CV_Error(cv::Error::StsBadArg, "Unknown region type \"" + nrmType + "\"");
CV_Error(Error::StsBadArg, "Unknown region type \"" + nrmType + "\"");
size = params.get<int>("local_size", 5);
if (size % 2 != 1 || size <= 0)
CV_Error(cv::Error::StsBadArg, "LRN layer supports only positive odd values for local_size");
CV_Error(Error::StsBadArg, "LRN layer supports only positive odd values for local_size");
alpha = params.get<double>("alpha", 1);
beta = params.get<double>("beta", 0.75);

@ -7,7 +7,7 @@ namespace cv
namespace dnn
{
MVNLayer::MVNLayer(LayerParams &params)
MVNLayer::MVNLayer(LayerParams &params) : Layer(params)
{
eps = params.get<double>("eps", 1e-9);
acrossChannels = params.get<bool>("across_channels", false);

@ -12,7 +12,7 @@ namespace dnn
{
//TODO: add ceil_mode param
PoolingLayer::PoolingLayer(LayerParams &params)
PoolingLayer::PoolingLayer(LayerParams &params) : Layer(params)
{
if (params.has("pool"))
{

@ -7,7 +7,7 @@ namespace cv
namespace dnn
{
ReshapeLayer::ReshapeLayer(LayerParams &params)
ReshapeLayer::ReshapeLayer(LayerParams &params) : Layer(params)
{
inAxis = params.get<int>("axis", 0);
inNumAxes = params.get<int>("num_axes", -1);

@ -7,7 +7,7 @@ namespace cv
namespace dnn
{
SliceLayer::SliceLayer(LayerParams &params)
SliceLayer::SliceLayer(LayerParams &params) : Layer(params)
{
inAxis = params.get<int>("axis", 1);

@ -10,7 +10,7 @@ namespace cv
namespace dnn
{
//TODO: set default axis number to 1, and add custom shape length in FullyConnected
SoftMaxLayer::SoftMaxLayer(LayerParams &params)
SoftMaxLayer::SoftMaxLayer(LayerParams &params) : Layer(params)
{
//hotfix!!!
axis_ = params.get<int>("axis", 1);

@ -8,7 +8,7 @@ namespace dnn
{
//TODO: maybe "top_count" param is useless because it can be determined by output connections number?
SplitLayer::SplitLayer(LayerParams &params)
SplitLayer::SplitLayer(LayerParams &params) : Layer(params)
{
if (params.has("top_count"))
{
@ -39,4 +39,4 @@ void SplitLayer::forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs)
}
}
}
}

@ -437,12 +437,12 @@ struct TorchImporter : public ::cv::dnn::Importer
readTorchTable(scalarParams, tensorParams);
CV_Assert(tensorParams.count("weight"));
layerParams.learnedBlobs.push_back(tensorParams["weight"]);
layerParams.blobs.push_back(tensorParams["weight"]);
bool bias = tensorParams.count("bias") != 0;
layerParams.set("bias_term", bias);
if (bias)
layerParams.learnedBlobs.push_back(tensorParams["bias"]);
layerParams.blobs.push_back(tensorParams["bias"]);
layerParams.set("num_output", scalarParams.get<int>("nOutputPlane"));
convertTorchKernelsParams(scalarParams, layerParams);
@ -469,11 +469,11 @@ struct TorchImporter : public ::cv::dnn::Importer
CV_Assert(tensorParams.count("weight"));
Blob weightBlob = tensorParams["weight"];
layerParams.learnedBlobs.push_back(weightBlob);
layerParams.blobs.push_back(weightBlob);
bool bias = tensorParams.count("bias") != 0;
if (bias)
layerParams.learnedBlobs.push_back(tensorParams["bias"]);
layerParams.blobs.push_back(tensorParams["bias"]);
layerParams.set("bias_term", bias);
layerParams.set("num_output", weightBlob.size(0));

Loading…
Cancel
Save