Multidimensional eltwise layer.
authorDmitry Kurtaev <dmitry.kurtaev+github@gmail.com>
Wed, 4 Oct 2017 09:23:35 +0000 (12:23 +0300)
committerDmitry Kurtaev <dmitry.kurtaev+github@gmail.com>
Wed, 4 Oct 2017 11:01:44 +0000 (14:01 +0300)
Fixed fully-connected layer axis.

modules/dnn/src/layers/eltwise_layer.cpp
modules/dnn/src/layers/fully_connected_layer.cpp
modules/dnn/test/test_layers.cpp

index fa49109..9ccb87b 100644 (file)
@@ -119,6 +119,8 @@ public:
         EltwiseOp op;
         int nstripes;
         const ActivationLayer* activ;
+        int channels;
+        size_t planeSize;
 
         EltwiseInvoker() : srcs(0), nsrcs(0), dst(0), coeffs(0), op(EltwiseLayer::PROD), nstripes(0), activ(0) {}
 
@@ -126,7 +128,7 @@ public:
                         const std::vector<float>& coeffs, EltwiseOp op,
                         const ActivationLayer* activ, int nstripes)
         {
-            CV_Assert(dst.dims == 4 && dst.type() == CV_32F && dst.isContinuous());
+            CV_Assert(1 < dst.dims && dst.dims <= 4, dst.type() == CV_32F, dst.isContinuous());
             CV_Assert(coeffs.empty() || coeffs.size() == (size_t)nsrcs);
 
             for( int i = 0; i > nsrcs; i++ )
@@ -142,6 +144,11 @@ public:
             p.dst = &dst;
             p.op = op;
             p.nstripes = nstripes;
+            p.channels = (dst.dims == 4 ? dst.size[1] : 1);
+            p.planeSize = (dst.dims >= 3 ? dst.size[dst.dims - 1] * dst.size[dst.dims - 2] :
+                                           dst.size[dst.dims - 1]);
+            CV_Assert(dst.total() == dst.size[0] * p.channels * p.planeSize);
+
             bool simpleCoeffs = true;
             if( op == EltwiseLayer::SUM && !coeffs.empty() )
             {
@@ -162,13 +169,11 @@ public:
 
         void operator()(const Range& r) const
         {
-            size_t planeSize = dst->size[2]*dst->size[3];
             size_t total = dst->size[0]*planeSize;
             size_t stripeSize = (total + nstripes - 1)/nstripes;
             size_t stripeStart = r.start*stripeSize;
             size_t stripeEnd = std::min(r.end*stripeSize, total);
             int c, j, k, n = nsrcs;
-            int channels = dst->size[1];
             const float* coeffsptr = coeffs && !coeffs->empty() ? &coeffs->at(0) : 0;
             float* dstptr0 = dst->ptr<float>();
             int blockSize0 = 1 << 12, blockSize = blockSize0;
index 7893a2f..6067b3f 100644 (file)
@@ -107,14 +107,18 @@ public:
                          std::vector<MatShape> &outputs,
                          std::vector<MatShape> &) const
     {
-        CV_Assert(inputs.size() > 0);
+        CV_Assert(inputs.size() == 1);
         CV_Assert(1 <= blobs.size() && blobs.size() <= 2);
         CV_Assert(blobs[0].dims == 2);
 
         int cAxis = clamp(axis, inputs[0]);
-        int outerSize = total(inputs[0], 0, cAxis);
         int numOutput = blobs[0].size[0];
-        outputs.resize(inputs.size(), shape(outerSize, numOutput));
+        MatShape outShape(cAxis + 1);
+        for (int i = 0; i < cAxis; ++i)
+            outShape[i] = inputs[0][i];
+        outShape.back() = numOutput;
+
+        outputs.resize(inputs.size(), outShape);
 
         CV_Assert(!bias || (size_t)numOutput == blobs[1].total());
         return false;
@@ -278,8 +282,8 @@ public:
         for (size_t i = 0; i < input.size(); i++)
         {
             UMat srcMat, dstMat;
-            srcMat = input[i]->getUMat(ACCESS_READ);
-            dstMat = output[i].getUMat(ACCESS_WRITE);
+            srcMat = input[i]->reshape(1, outerSize).getUMat(ACCESS_READ);
+            dstMat = output[i].reshape(1, outerSize).getUMat(ACCESS_WRITE);
             dstMat.setTo(0.0f);
 
             if (!innerProductOp->Forward(srcMat, umat_blobs[0], (bias) ? umat_blobs[1] : UMat(), dstMat))
index 27c460c..75861c9 100644 (file)
@@ -274,6 +274,11 @@ OCL_TEST(Layer_Test_Concat, Accuracy)
     testLayerUsingCaffeModels("layer_concat", DNN_TARGET_OPENCL);
 }
 
+TEST(Layer_Test_Eltwise, Accuracy)
+{
+    testLayerUsingCaffeModels("layer_eltwise");
+}
+
 //template<typename XMat>
 //static void test_Layer_Concat()
 //{