Merge pull request #14445 from l-bat:batchnorm3d

pull/14586/head
Alexander Alekhin 6 years ago
commit d848594deb
  1. 27
      modules/dnn/src/layers/batch_norm_layer.cpp
  2. 7
      modules/dnn/test/test_onnx_importer.cpp
  3. 7
      modules/dnn/test/test_tf_importer.cpp

@ -29,6 +29,8 @@ class BatchNormLayerImpl CV_FINAL : public BatchNormLayer
public: public:
Mat weights_, bias_; Mat weights_, bias_;
UMat umat_weight, umat_bias; UMat umat_weight, umat_bias;
mutable int dims;
BatchNormLayerImpl(const LayerParams& params) BatchNormLayerImpl(const LayerParams& params)
{ {
@ -142,6 +144,7 @@ public:
std::vector<MatShape> &outputs, std::vector<MatShape> &outputs,
std::vector<MatShape> &internals) const CV_OVERRIDE std::vector<MatShape> &internals) const CV_OVERRIDE
{ {
dims = inputs[0].size();
if (!useGlobalStats && inputs[0][0] != 1) if (!useGlobalStats && inputs[0][0] != 1)
CV_Error(Error::StsNotImplemented, "Batch normalization in training mode with batch size > 1"); CV_Error(Error::StsNotImplemented, "Batch normalization in training mode with batch size > 1");
Layer::getMemoryShapes(inputs, requiredOutputs, outputs, internals); Layer::getMemoryShapes(inputs, requiredOutputs, outputs, internals);
@ -150,9 +153,9 @@ public:
virtual bool supportBackend(int backendId) CV_OVERRIDE virtual bool supportBackend(int backendId) CV_OVERRIDE
{ {
return backendId == DNN_BACKEND_OPENCV || return (backendId == DNN_BACKEND_OPENCV) ||
(backendId == DNN_BACKEND_HALIDE && haveHalide()) || (backendId == DNN_BACKEND_HALIDE && haveHalide()) ||
(backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine()); (backendId == DNN_BACKEND_INFERENCE_ENGINE && haveInfEngine() && (preferableTarget == DNN_TARGET_CPU || dims == 4));
} }
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
@ -178,11 +181,12 @@ public:
} }
UMat &inpBlob = inputs[0]; UMat &inpBlob = inputs[0];
CV_Assert(inpBlob.dims == 2 || inpBlob.dims == 4);
int groups = inpBlob.size[0]; int groups = inpBlob.size[0];
int channels = inpBlob.size[1]; int channels = inpBlob.size[1];
int rows = inpBlob.dims > 2 ? inpBlob.size[2] : 1; int planeSize = 1;
int cols = inpBlob.dims > 2 ? inpBlob.size[3] : 1; for (size_t i = 2; i < inpBlob.dims; i++) {
planeSize *= inpBlob.size[i];
}
String opts = (use_half) ? " -DDtype=half" : " -DDtype=float"; String opts = (use_half) ? " -DDtype=half" : " -DDtype=float";
for (size_t ii = 0; ii < outputs.size(); ii++) for (size_t ii = 0; ii < outputs.size(); ii++)
@ -196,7 +200,7 @@ public:
} }
else else
{ {
MatShape s = shape(groups * channels, rows * cols); MatShape s = shape(groups * channels, planeSize);
UMat src = inputs[ii].reshape(1, s.size(), &s[0]); UMat src = inputs[ii].reshape(1, s.size(), &s[0]);
UMat dst = outputs[ii].reshape(1, s.size(), &s[0]); UMat dst = outputs[ii].reshape(1, s.size(), &s[0]);
int number = (s[1] % 8 == 0) ? 8 : ((s[1] % 4 == 0) ? 4 : 1); int number = (s[1] % 8 == 0) ? 8 : ((s[1] % 4 == 0) ? 4 : 1);
@ -248,9 +252,10 @@ public:
CV_Assert(inputs.size() == 1); CV_Assert(inputs.size() == 1);
Mat &inpBlob = inputs[0]; Mat &inpBlob = inputs[0];
CV_Assert(inpBlob.dims == 2 || inpBlob.dims == 4); int planeSize = 1;
int rows = inpBlob.dims > 2 ? inpBlob.size[2] : 1; for (size_t i = 2; i < inpBlob.dims; i++) {
int cols = inpBlob.dims > 2 ? inpBlob.size[3] : 1; planeSize *= inpBlob.size[i];
}
for (size_t ii = 0; ii < outputs.size(); ii++) for (size_t ii = 0; ii < outputs.size(); ii++)
{ {
@ -262,8 +267,8 @@ public:
{ {
float w = weights_.at<float>(n); float w = weights_.at<float>(n);
float b = bias_.at<float>(n); float b = bias_.at<float>(n);
Mat inpBlobPlane(rows, cols, CV_32F, inpBlob.ptr<float>(num, n)); Mat inpBlobPlane(1, planeSize, CV_32F, inpBlob.ptr<float>(num, n));
Mat outBlobPlane(rows, cols, CV_32F, outBlob.ptr<float>(num, n)); Mat outBlobPlane(1, planeSize, CV_32F, outBlob.ptr<float>(num, n));
inpBlobPlane.convertTo(outBlobPlane, CV_32F, w, b); inpBlobPlane.convertTo(outBlobPlane, CV_32F, w, b);
} }
} }

@ -167,6 +167,13 @@ TEST_P(Test_ONNX_layers, BatchNormalization)
testONNXModels("batch_norm"); testONNXModels("batch_norm");
} }
TEST_P(Test_ONNX_layers, BatchNormalization3D)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU)
throw SkipTestException("");
testONNXModels("batch_norm_3d");
}
TEST_P(Test_ONNX_layers, Transpose) TEST_P(Test_ONNX_layers, Transpose)
{ {
if (backend == DNN_BACKEND_INFERENCE_ENGINE && if (backend == DNN_BACKEND_INFERENCE_ENGINE &&

@ -188,6 +188,13 @@ TEST_P(Test_TensorFlow_layers, batch_norm)
runTensorFlowNet("mvn_batch_norm_1x1"); runTensorFlowNet("mvn_batch_norm_1x1");
} }
TEST_P(Test_TensorFlow_layers, batch_norm3D)
{
if (backend == DNN_BACKEND_INFERENCE_ENGINE && target != DNN_TARGET_CPU)
throw SkipTestException("");
runTensorFlowNet("batch_norm3d");
}
TEST_P(Test_TensorFlow_layers, slim_batch_norm) TEST_P(Test_TensorFlow_layers, slim_batch_norm)
{ {
if (backend == DNN_BACKEND_INFERENCE_ENGINE) if (backend == DNN_BACKEND_INFERENCE_ENGINE)

Loading…
Cancel
Save