Skip to content

Commit

Permalink
API refactoring
Browse files Browse the repository at this point in the history
renamed learnedParams blobs field
added new fields: name and type for Layer
  • Loading branch information
Vitaliy Lyudvichenko committed Aug 21, 2015
1 parent f07c564 commit fb66acb
Show file tree
Hide file tree
Showing 15 changed files with 77 additions and 63 deletions.
36 changes: 24 additions & 12 deletions modules/dnn/include/opencv2/dnn/dnn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);

Expand Down
4 changes: 2 additions & 2 deletions modules/dnn/src/caffe/caffe_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
}
}

Expand Down
21 changes: 14 additions & 7 deletions modules/dnn/src/dnn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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];
}
Expand All @@ -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)
{

}
Expand All @@ -502,10 +512,7 @@ int Layer::outputNameToIndex(String)
return -1;
}

Layer::~Layer()
{

}
Layer::~Layer() {}

//////////////////////////////////////////////////////////////////////////

Expand Down
2 changes: 1 addition & 1 deletion modules/dnn/src/layers/concat_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
23 changes: 13 additions & 10 deletions modules/dnn/src/layers/convolution_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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);
}

Expand All @@ -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;
Expand Down Expand Up @@ -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++)
{
Expand All @@ -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);
}
Expand Down Expand Up @@ -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();
Expand All @@ -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++)
{
Expand All @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion modules/dnn/src/layers/convolution_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
};
}
Expand Down
24 changes: 8 additions & 16 deletions modules/dnn/src/layers/fully_connected_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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++)
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}
Expand Down
6 changes: 3 additions & 3 deletions modules/dnn/src/layers/lrn_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ 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")
type = CHANNEL_NRM;
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);
Expand Down
2 changes: 1 addition & 1 deletion modules/dnn/src/layers/mvn_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion modules/dnn/src/layers/pooling_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
{
Expand Down
2 changes: 1 addition & 1 deletion modules/dnn/src/layers/reshape_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion modules/dnn/src/layers/slice_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace cv
namespace dnn
{

SliceLayer::SliceLayer(LayerParams &params)
SliceLayer::SliceLayer(LayerParams &params) : Layer(params)
{
inAxis = params.get<int>("axis", 1);

Expand Down
2 changes: 1 addition & 1 deletion modules/dnn/src/layers/softmax_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions modules/dnn/src/layers/split_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"))
{
Expand Down Expand Up @@ -39,4 +39,4 @@ void SplitLayer::forward(std::vector<Blob*> &inputs, std::vector<Blob> &outputs)
}

}
}
}
8 changes: 4 additions & 4 deletions modules/dnn/src/torch/torch_importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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));
Expand Down

0 comments on commit fb66acb

Please sign in to comment.