mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 23:33:05 +04:00
Merge pull request #16088 from alalek:dnn_eltwise_layer_different_src_channels
dnn(eltwise): fix handling of different number of channels * dnn(test): reproducer for Eltwise layer issue from PR16063 * dnn(eltwise): rework support for inputs with different channels * dnn(eltwise): get rid of finalize(), variableChannels * dnn(eltwise): update input sorting by number of channels - do not swap inputs if number of channels are same after truncation * dnn(test): skip "shortcut" with batch size 2 on MYRIAD targets
This commit is contained in:
committed by
GitHub
parent
f2cce5fd8c
commit
5ee7abbe3c
@@ -1582,30 +1582,28 @@ TEST(Layer_Test_Convolution, relu_fusion)
|
||||
}
|
||||
|
||||
typedef testing::TestWithParam<tuple<bool, tuple<Backend, Target> > > Layer_Test_Eltwise_unequal;
|
||||
TEST_P(Layer_Test_Eltwise_unequal, Accuracy)
|
||||
TEST_P(Layer_Test_Eltwise_unequal, accuracy_input_0_truncate)
|
||||
{
|
||||
bool weighted = get<0>(GetParam());
|
||||
int backendId = get<0>(get<1>(GetParam()));
|
||||
int targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
if (backendId == DNN_BACKEND_OPENCV && targetId == DNN_TARGET_OPENCL_FP16)
|
||||
applyTestTag(CV_TEST_TAG_DNN_SKIP_OPENCL_FP16);
|
||||
|
||||
Net net;
|
||||
LayerParams lp;
|
||||
lp.type = "Eltwise";
|
||||
lp.name = "testLayer";
|
||||
lp.set<std::string>("output_channels_mode", "input_0_truncate");
|
||||
|
||||
const int inpShapes[][4] = {{1, 4, 2, 2}, {1, 5, 2, 2}, {1, 3, 2, 2}};
|
||||
const int out_channels = inpShapes[0][1];
|
||||
std::vector<String> inpNames(3);
|
||||
std::vector<Mat> inputs(3);
|
||||
size_t numOutValues = 1*4*2*2; // By the first input
|
||||
|
||||
std::vector<float> weights(3, 1);
|
||||
if (weighted)
|
||||
{
|
||||
for (int i = 0; i < inputs.size(); ++i)
|
||||
randu(Mat(1, 1, CV_32F, &weights[i]), -1, 1);
|
||||
weights[i] = -0.125f + i * 0.25f;
|
||||
lp.set("coeff", DictValue::arrayReal<float*>(&weights[0], weights.size()));
|
||||
}
|
||||
|
||||
@@ -1613,27 +1611,103 @@ TEST_P(Layer_Test_Eltwise_unequal, Accuracy)
|
||||
for (int i = 0; i < inputs.size(); ++i)
|
||||
{
|
||||
inputs[i].create(4, inpShapes[i], CV_32F);
|
||||
randu(inputs[i], 0, 255);
|
||||
size_t total = inputs[i].total();
|
||||
for (size_t j = 0; j < total; j++)
|
||||
inputs[i].ptr<float>()[j] = j + i * 100;
|
||||
inpNames[i] = format("input_%d", i);
|
||||
net.connect(0, i, eltwiseId, i);
|
||||
}
|
||||
Mat ref(1, numOutValues, CV_32F, Scalar(0));
|
||||
Mat ref(4, inpShapes[0], CV_32F, Scalar(0));
|
||||
|
||||
net.setInputsNames(inpNames);
|
||||
for (int i = 0; i < inputs.size(); ++i)
|
||||
{
|
||||
//std::cout << ref.reshape(1,1) << endl;
|
||||
net.setInput(inputs[i], inpNames[i]);
|
||||
if (numOutValues >= inputs[i].total())
|
||||
ref.colRange(0, inputs[i].total()) += weights[i] * inputs[i].reshape(1, 1);
|
||||
else
|
||||
ref += weights[i] * inputs[i].reshape(1, 1).colRange(0, numOutValues);
|
||||
for (size_t batchId = 0; batchId < ref.size[0]; batchId++)
|
||||
{
|
||||
int input_channels = inputs[i].size[1];
|
||||
Range ranges[4] = { Range(batchId, batchId + 1), Range(0, std::min(out_channels, input_channels)), Range::all(), Range::all() };
|
||||
Mat ref_slice = ref(ranges);
|
||||
Mat input_slice = inputs[i](ranges);
|
||||
ref_slice += weights[i] * input_slice;
|
||||
}
|
||||
}
|
||||
|
||||
net.setPreferableBackend(backendId);
|
||||
net.setPreferableTarget(targetId);
|
||||
Mat out = net.forward();
|
||||
normAssert(out.reshape(1, 1), ref);
|
||||
normAssert(out, ref);
|
||||
if (testing::Test::HasFailure())
|
||||
{
|
||||
std::cout << out.reshape(1,1) << endl;
|
||||
std::cout << ref.reshape(1,1) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_P(Layer_Test_Eltwise_unequal, accuracy_input_0)
|
||||
{
|
||||
bool weighted = get<0>(GetParam());
|
||||
int backendId = get<0>(get<1>(GetParam()));
|
||||
int targetId = get<1>(get<1>(GetParam()));
|
||||
|
||||
Net net;
|
||||
LayerParams lp;
|
||||
lp.type = "Eltwise";
|
||||
lp.name = "testLayer";
|
||||
lp.set<std::string>("output_channels_mode", "input_0");
|
||||
|
||||
const int inpShapes[][4] = {{1, 4, 2, 2}, {1, 2, 2, 2}, {1, 3, 2, 2}};
|
||||
const int out_channels = inpShapes[0][1];
|
||||
std::vector<String> inpNames(3);
|
||||
std::vector<Mat> inputs(3);
|
||||
|
||||
std::vector<float> weights(3, 1);
|
||||
if (weighted)
|
||||
{
|
||||
for (int i = 0; i < inputs.size(); ++i)
|
||||
weights[i] = -0.125f + i * 0.25f;
|
||||
lp.set("coeff", DictValue::arrayReal<float*>(&weights[0], weights.size()));
|
||||
}
|
||||
|
||||
int eltwiseId = net.addLayer(lp.name, lp.type, lp);
|
||||
for (int i = 0; i < inputs.size(); ++i)
|
||||
{
|
||||
inputs[i].create(4, inpShapes[i], CV_32F);
|
||||
size_t total = inputs[i].total();
|
||||
for (size_t j = 0; j < total; j++)
|
||||
inputs[i].ptr<float>()[j] = j + i * 100;
|
||||
inpNames[i] = format("input_%d", i);
|
||||
net.connect(0, i, eltwiseId, i);
|
||||
}
|
||||
Mat ref(4, inpShapes[0], CV_32F, Scalar(0));
|
||||
|
||||
net.setInputsNames(inpNames);
|
||||
for (int i = 0; i < inputs.size(); ++i)
|
||||
{
|
||||
//std::cout << ref.reshape(1,1) << endl;
|
||||
net.setInput(inputs[i], inpNames[i]);
|
||||
for (size_t batchId = 0; batchId < ref.size[0]; batchId++)
|
||||
{
|
||||
int input_channels = inputs[i].size[1];
|
||||
Range ranges[4] = { Range(batchId, batchId + 1), Range(0, std::min(out_channels, input_channels)), Range::all(), Range::all() };
|
||||
Mat ref_slice = ref(ranges);
|
||||
Mat input_slice = inputs[i](ranges);
|
||||
ref_slice += weights[i] * input_slice;
|
||||
}
|
||||
}
|
||||
|
||||
net.setPreferableBackend(backendId);
|
||||
net.setPreferableTarget(targetId);
|
||||
Mat out = net.forward();
|
||||
normAssert(out, ref);
|
||||
if (testing::Test::HasFailure())
|
||||
{
|
||||
std::cout << out.reshape(1,1) << endl;
|
||||
std::cout << ref.reshape(1,1) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(/**/, Layer_Test_Eltwise_unequal, Combine(
|
||||
testing::Bool(),
|
||||
dnnBackendsAndTargets()
|
||||
|
||||
Reference in New Issue
Block a user