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> 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); CV_Assert(m.type() == cv::DataType<TFloat>::type);
return (TFloat*) rawPtr(num, cn, row, col); 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 inline int Blob::type() const

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

Loading…
Cancel
Save