Added group param to convolution_layer.cpp

pull/265/head
Vitaliy Lyudvichenko 10 years ago
parent 66fa1e10f6
commit 13edaaacc3
  1. 7
      modules/dnn/include/opencv2/dnn/dnn.inl.hpp
  2. 49
      modules/dnn/src/layers/convolution_layer.cpp

@ -90,10 +90,11 @@ namespace dnn
}
template<typename TFloat>
TFloat *Blob::ptr(int num, int cn, int row, int col)
TFloat *Blob::ptr(int n, int cn, int row, int col)
{
CV_Assert(m.type() == cv::DataType<TFloat>::type && m.dims == 4);
return (TFloat*) rawPtr(num, cn, row, col);
CV_Assert(m.type() == cv::DataType<TFloat>::type);
CV_Assert(0 <= n && n < num() && 0 <= cn && cn < channels() && 0 <= row && row < rows() && 0 <= col && col < cols());
return (TFloat*) rawPtr(n, cn, row, col);
}
inline int Blob::type() const

@ -5,7 +5,6 @@ namespace cv
{
namespace dnn
{
//TODO: implement group parameter
//TODO: simultaneously convolution and bias addition for cache optimization
class ConvolutionLayer : public Layer
{
@ -15,10 +14,11 @@ namespace dnn
int strideH, strideW;
int kernelH, kernelW;
int inH, inW, inCn, colCn;
int inH, inW, inCn, kerSize;
int outH, outW;
int groupCn, groupCnOut;
Mat imColsMat, biasOnesMat;
Mat srcColsMat, biasOnesMat;
void computeOutputShape(int inH, int inW);
@ -61,7 +61,9 @@ namespace dnn
Blob &weightBlob = learnedParams[0];
inCn = inputs[0]->channels();
CV_Assert(inCn % group == 0 && weightBlob.channels() == inCn/group);
CV_Assert(inCn % group == 0 && numOutput % group == 0 && weightBlob.channels() == inCn/group);
groupCnOut = numOutput / group;
groupCn = inCn / group;
inH = inputs[0]->rows();
inW = inputs[0]->cols();
@ -76,8 +78,8 @@ namespace dnn
outputs[i].create(num, numOutput, outH, outW);
}
colCn = kernelH * kernelW * inCn;
imColsMat.create(colCn, outH * outW, CV_32F);
kerSize = kernelH * kernelW * groupCn;
srcColsMat.create(kerSize, outH * outW, CV_32F);
if (bias)
{
@ -117,32 +119,35 @@ namespace dnn
{
CV_Assert(inputs.size() == outputs.size());
float *colPtr = imColsMat.ptr<float>();
float *weigtsPtr = learnedParams[0].ptr<float>();
float *biasPtr = (bias) ? learnedParams[1].ptr<float>() : NULL;
CV_Assert(group == 1);
float *srcColPtr = srcColsMat.ptr<float>();
for (size_t ii = 0; ii < outputs.size(); ii++)
{
int num = inputs[ii]->num();
Blob &input = *inputs[ii];
Blob &output = outputs[ii];
int num = input.num();
for (int n = 0; n < num; n++)
{
float *srcImPtr = inputs[ii]->ptr<float>(n);
float *dstImPtr = outputs[ii].ptr<float>(n);
for (int g = 0; g < group; g++)
{
float *srcPtr = input.ptr<float>(n, g*groupCn);
im2col_cpu(srcPtr, groupCn, inH, inW, kernelH, kernelW, padH, padW, strideH, strideW, srcColPtr);
im2col_cpu(srcImPtr, inCn, inH, inW, kernelH, kernelW, padH, padW, strideH, strideW, colPtr);
float *kerPtr = learnedParams[0].ptr<float>(g*groupCnOut);
float *dstPtr = output.ptr<float>(n, g*groupCnOut);
Mat weightsMat(numOutput, colCn, CV_32F, weigtsPtr);
Mat dstIm(numOutput, outH*outW, CV_32F, dstImPtr);
Mat kerMat(groupCnOut, kerSize, CV_32F, kerPtr);
Mat dstMat(groupCnOut, outH*outW, CV_32F, dstPtr);
cv::gemm(weightsMat, imColsMat, 1, noArray(), 0, dstIm);
cv::gemm(kerMat, srcColsMat, 1, noArray(), 0, dstMat);
if (bias)
{
Mat biasMat(numOutput, 1, CV_32F, biasPtr);
cv::gemm(biasMat, biasOnesMat, 1, dstIm, 1, dstIm);
if (bias)
{
float *biasPtr = learnedParams[1].ptr<float>() + g*groupCnOut;
Mat biasMat(groupCnOut, 1, CV_32F, biasPtr);
cv::gemm(biasMat, biasOnesMat, 1, dstMat, 1, dstMat);
}
}
}
}

Loading…
Cancel
Save