|
|
|
@ -67,7 +67,7 @@ public: |
|
|
|
|
BaseConvolutionLayerImpl(const LayerParams ¶ms) |
|
|
|
|
{ |
|
|
|
|
setParamsFrom(params); |
|
|
|
|
getConvolutionKernelParams(params, kernel_size, pads_begin, pads_end, strides, dilations, padMode); |
|
|
|
|
getConvolutionKernelParams(params, kernel_size, pads_begin, pads_end, strides, dilations, padMode, adjust_pads); |
|
|
|
|
|
|
|
|
|
numOutput = params.get<int>("num_output"); |
|
|
|
|
int ngroups = params.get<int>("group", 1); |
|
|
|
@ -83,14 +83,14 @@ public: |
|
|
|
|
pad = Size(pads_begin[1], pads_begin[0]); |
|
|
|
|
dilation = Size(dilations[1], dilations[0]); |
|
|
|
|
|
|
|
|
|
adjust_pads.push_back(params.get<int>("adj_h", 0)); |
|
|
|
|
adjust_pads.push_back(params.get<int>("adj_w", 0)); |
|
|
|
|
|
|
|
|
|
adjustPad.height = adjust_pads[0]; |
|
|
|
|
adjustPad.width = adjust_pads[1]; |
|
|
|
|
CV_Assert(adjustPad.width < stride.width && |
|
|
|
|
adjustPad.height < stride.height); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < adjust_pads.size(); i++) { |
|
|
|
|
CV_Assert(adjust_pads[i] < strides[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fusedWeights = false; |
|
|
|
|
fusedBias = false; |
|
|
|
|
} |
|
|
|
@ -1241,29 +1241,39 @@ public: |
|
|
|
|
virtual bool supportBackend(int backendId) CV_OVERRIDE |
|
|
|
|
{ |
|
|
|
|
#ifdef HAVE_INF_ENGINE |
|
|
|
|
const int outGroupCn = blobs[0].size[1]; // Weights are in IOHW layout
|
|
|
|
|
const int outGroupCn = blobs[0].size[1]; // Weights are in IOHW or IODHW layout
|
|
|
|
|
const int group = numOutput / outGroupCn; |
|
|
|
|
|
|
|
|
|
if (backendId == DNN_BACKEND_INFERENCE_ENGINE) |
|
|
|
|
{ |
|
|
|
|
if (kernel_size.size() == 3) |
|
|
|
|
CV_Error(Error::StsNotImplemented, "Unsupported deconvolution3D layer"); |
|
|
|
|
if (kernel_size.size() == 3 && preferableTarget != DNN_TARGET_CPU) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (adjustPad.height || adjustPad.width) |
|
|
|
|
if (std::accumulate(adjust_pads.begin(), adjust_pads.end(), 0, std::plus<size_t>()) > 0) |
|
|
|
|
{ |
|
|
|
|
if (padMode.empty()) |
|
|
|
|
{ |
|
|
|
|
if (preferableTarget != DNN_TARGET_CPU && group != 1) |
|
|
|
|
{ |
|
|
|
|
if ((adjustPad.height && pad.height) || (adjustPad.width && pad.width)) |
|
|
|
|
for (int i = 0; i < adjust_pads.size(); i++) { |
|
|
|
|
if (adjust_pads[i] && pads_begin[i]) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
for (int i = 0; i < adjust_pads.size(); i++) { |
|
|
|
|
if (pads_end[i] < adjust_pads[i]) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return pad.width >= adjustPad.width && pad.height >= adjustPad.height; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
else if (padMode == "SAME") |
|
|
|
|
{ |
|
|
|
|
return kernel.width >= pad.width + 1 + adjustPad.width && |
|
|
|
|
kernel.height >= pad.height + 1 + adjustPad.height; |
|
|
|
|
for (int i = 0; i < adjust_pads.size(); i++) { |
|
|
|
|
if (kernel_size[i] < pads_begin[i] + 1 + adjust_pads[i]) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
else if (padMode == "VALID") |
|
|
|
|
return false; |
|
|
|
@ -1274,7 +1284,7 @@ public: |
|
|
|
|
return preferableTarget == DNN_TARGET_CPU; |
|
|
|
|
} |
|
|
|
|
if (preferableTarget == DNN_TARGET_OPENCL || preferableTarget == DNN_TARGET_OPENCL_FP16) |
|
|
|
|
return dilation.width == 1 && dilation.height == 1; |
|
|
|
|
return std::accumulate(dilations.begin(), dilations.end(), 1, std::multiplies<size_t>()) == 1; |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
@ -1861,11 +1871,14 @@ public: |
|
|
|
|
#ifdef HAVE_INF_ENGINE |
|
|
|
|
virtual Ptr<BackendNode> initInfEngine(const std::vector<Ptr<BackendWrapper> > &) CV_OVERRIDE |
|
|
|
|
{ |
|
|
|
|
auto ieWeights = wrapToInfEngineBlob(blobs[0], InferenceEngine::Layout::OIHW); |
|
|
|
|
InferenceEngine::Layout layout = blobs[0].dims == 5? InferenceEngine::Layout::NCDHW : |
|
|
|
|
InferenceEngine::Layout::OIHW; |
|
|
|
|
|
|
|
|
|
auto ieWeights = wrapToInfEngineBlob(blobs[0], layout); |
|
|
|
|
if (fusedWeights) |
|
|
|
|
{ |
|
|
|
|
ieWeights = InferenceEngine::make_shared_blob<float>( |
|
|
|
|
InferenceEngine::Precision::FP32, InferenceEngine::Layout::OIHW, |
|
|
|
|
InferenceEngine::Precision::FP32, layout, |
|
|
|
|
ieWeights->dims()); |
|
|
|
|
ieWeights->allocate(); |
|
|
|
|
|
|
|
|
@ -1874,7 +1887,7 @@ public: |
|
|
|
|
transpose(weightsMat, newWeights); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const int outGroupCn = blobs[0].size[1]; // Weights are in IOHW layout
|
|
|
|
|
const int outGroupCn = blobs[0].size[1]; // Weights are in IOHW or OIDHW layout
|
|
|
|
|
const int group = numOutput / outGroupCn; |
|
|
|
|
|
|
|
|
|
InferenceEngine::Builder::DeconvolutionLayer ieLayer(name); |
|
|
|
@ -1886,12 +1899,19 @@ public: |
|
|
|
|
|
|
|
|
|
if (padMode.empty()) |
|
|
|
|
{ |
|
|
|
|
ieLayer.setPaddingsEnd({pads_end[0] - adjust_pads[0], pads_end[1] - adjust_pads[1]}); |
|
|
|
|
std::vector<size_t> paddings_end; |
|
|
|
|
for (int i = 0; i < pads_end.size(); i++) { |
|
|
|
|
paddings_end.push_back(pads_end[i] - adjust_pads[i]); |
|
|
|
|
} |
|
|
|
|
ieLayer.setPaddingsEnd(paddings_end); |
|
|
|
|
} |
|
|
|
|
else if (padMode == "SAME") |
|
|
|
|
{ |
|
|
|
|
ieLayer.setPaddingsEnd({kernel_size[0] - pads_begin[0] - 1 - adjust_pads[0], |
|
|
|
|
kernel_size[1] - pads_begin[1] - 1 - adjust_pads[1]}); |
|
|
|
|
std::vector<size_t> paddings_end; |
|
|
|
|
for (int i = 0; i < pads_begin.size(); i++) { |
|
|
|
|
paddings_end.push_back(kernel_size[i] - pads_begin[i] - 1 - adjust_pads[i]); |
|
|
|
|
} |
|
|
|
|
ieLayer.setPaddingsEnd(paddings_end); |
|
|
|
|
} |
|
|
|
|
ieLayer.setGroup((size_t)group); |
|
|
|
|
ieLayer.setOutDepth((size_t)numOutput); |
|
|
|
@ -1911,10 +1931,12 @@ public: |
|
|
|
|
|
|
|
|
|
float flops = 0; |
|
|
|
|
int outChannels = blobs[0].size[0]; |
|
|
|
|
size_t karea = std::accumulate(kernel_size.begin(), kernel_size.end(), |
|
|
|
|
1, std::multiplies<size_t>()); |
|
|
|
|
|
|
|
|
|
for (int i = 0; i < inputs.size(); i++) |
|
|
|
|
{ |
|
|
|
|
flops += CV_BIG_INT(2)*outChannels*kernel.area()*total(inputs[i]); |
|
|
|
|
flops += CV_BIG_INT(2)*outChannels*karea*total(inputs[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return flops; |
|
|
|
|