opencv: ConvolutionDepthwise is even slower than Normal Convolution.

System information (version)
  • OpenCV = 4.0.0
  • Operating System / Platform = Windows 64 Bit
  • Compiler = Visual Studio 2017
Detailed description

OpenCV dnn ConvolutionDepthwise is slow than normal Convolution.

settings:

  • net.setPreferableBackend(DNN_BACKEND_OPENCV);
  • net.setPreferableTarget(DNN_TARGET_CPU);
I made the following changes to my CNN model and found that it was slowing down!
```.prototxt
layer {
  name: "conv2"
  type:  "Convolution" # change to "ConvolutionDepthwise"
  bottom: "PReLU2"
  top: "Convolution3"
  convolution_param {
    num_output: 16
    pad: 0
    kernel_size: 3
    group: 1 # change to 16
    stride: 1
  }
}
Steps to reproduce
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace cv::dnn;

void benchmark(String network) {
  Net net = readNet(format("models/%s.prototxt", network),
                    format("models/%s.caffemodel", network));
  net.setPreferableBackend(DNN_BACKEND_OPENCV);
  net.setPreferableTarget(DNN_TARGET_CPU);
  net.enableFusion(true);
  vector<String> out_names = net.getUnconnectedOutLayersNames();
  cv::VideoCapture capture("data/single.mp4");
  cv::Mat frame;
  cv::TickMeter tm;
  int frames = 0;
  tm.reset();
  int cnt = 0;
  while (true) {
    capture >> frame;
    if (frame.empty())
      break;
    cnt++;
    resize(frame, frame, Size(800, 600));
    tm.start();
    vector<cv::Mat> out_blobs;
    net.setInput(blobFromImage(frame));
    net.forward(out_blobs, out_names);
    tm.stop();
    if (cv::waitKey(1) == 'q')
      break;
    if (cnt == 100)
      break;
  }
  std::cout << cv::format("%.2f ms", tm.getTimeMilli() / cnt) << std::endl;
}

int main() {
  benchmark("cnn");    //  31.65 ms
  benchmark("dw-cnn");  // 33.45 ms
  return 0;
}

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 16 (7 by maintainers)

Most upvoted comments

@dkurt I tested the effect of channels on the efficiency of dwconv v.s. conv. when channels increases, the advantages of dwconv become more obvious. Maybe dwconv is suitable when channels ≥ 64。

# input_size channels kernel  conv  dwconv 
[conv] (200,200) 8 (3,3) 1       1.137 2.193
[conv] (200,200) 16 (3,3) 1      2.625 3.745
[conv] (200,200) 24 (3,3) 1      4.873 5.092
[conv] (200,200) 32 (3,3) 1      7.362 6.797
[conv] (200,200) 40 (3,3) 1      10.641 7.921
[conv] (200,200) 48 (3,3) 1      12.965 10.240
[conv] (200,200) 56 (3,3) 1      17.792 11.705
[conv] (200,200) 64 (3,3) 1      21.720 13.004
[conv] (200,200) 72 (3,3) 1      26.834 14.821
[conv] (200,200) 80 (3,3) 1      32.796 15.445
[conv] (200,200) 88 (3,3) 1      38.270 17.314
[conv] (200,200) 96 (3,3) 1      44.186 19.254
[conv] (200,200) 104 (3,3) 1     51.257 20.643
[conv] (200,200) 112 (3,3) 1     57.805 22.509
[conv] (200,200) 120 (3,3) 1     66.571 23.821
[conv] (200,200) 128 (3,3) 1     72.659 25.288
[conv] (200,200) 136 (3,3) 1     82.218 26.600
[conv] (200,200) 144 (3,3) 1     89.219 28.354
[conv] (200,200) 152 (3,3) 1     102.585 29.390
[conv] (200,200) 160 (3,3) 1     111.799 31.308
[conv] (200,200) 168 (3,3) 1     119.989 35.291
[conv] (200,200) 176 (3,3) 1     132.741 35.816
[conv] (200,200) 184 (3,3) 1     139.151 34.804
[conv] (200,200) 192 (3,3) 1     150.889 36.444
[conv] (200,200) 200 (3,3) 1     170.022 38.876
[conv] (200,200) 208 (3,3) 1     182.679 41.147
[conv] (200,200) 216 (3,3) 1     191.036 42.001
[conv] (200,200) 224 (3,3) 1     198.157 44.676
[conv] (200,200) 232 (3,3) 1     223.772 44.297
[conv] (200,200) 240 (3,3) 1     234.968 46.444
[conv] (200,200) 248 (3,3) 1     247.612 48.174
[conv] (200,200) 256 (3,3) 1     271.131 49.109
[conv] (200,200) 264 (3,3) 1     291.241 51.955
[conv] (200,200) 272 (3,3) 1     307.448 52.358
[conv] (200,200) 280 (3,3) 1     335.322 53.022
[conv] (200,200) 288 (3,3) 1     346.874 55.096
[conv] (200,200) 296 (3,3) 1     360.024 56.518
[conv] (200,200) 304 (3,3) 1     391.232 57.815
[conv] (200,200) 312 (3,3) 1     404.028 60.479
[conv] (200,200) 320 (3,3) 1     437.910 60.934
[conv] (200,200) 328 (3,3) 1     450.590 61.679
[conv] (200,200) 336 (3,3) 1     466.046 67.430
[conv] (200,200) 344 (3,3) 1     492.733 68.805
[conv] (200,200) 352 (3,3) 1     530.170 66.588
[conv] (200,200) 360 (3,3) 1     546.002 68.855
[conv] (200,200) 368 (3,3) 1     557.379 70.640
[conv] (200,200) 376 (3,3) 1     615.192 70.587
[conv] (200,200) 384 (3,3) 1     612.089 74.243