mirror of
https://github.com/opencv/opencv.git
synced 2024-11-29 13:47:32 +08:00
Merge pull request #15203 from l-bat:determine_inp_shape
* Determine input shapes * Add test * Remove getInputShapes * Fix model * Fix constructors * Add Caffe test * Fix predict
This commit is contained in:
parent
358d69956a
commit
f1ea9d86b9
@ -424,6 +424,36 @@ public:
|
|||||||
}
|
}
|
||||||
dstNet.setInputsNames(netInputs);
|
dstNet.setInputsNames(netInputs);
|
||||||
|
|
||||||
|
std::vector<MatShape> inp_shapes;
|
||||||
|
if (net.input_shape_size() > 0 || (layersSize > 0 && net.layer(0).has_input_param() &&
|
||||||
|
net.layer(0).input_param().shape_size() > 0)) {
|
||||||
|
|
||||||
|
int size = (net.input_shape_size() > 0) ? net.input_shape_size() :
|
||||||
|
net.layer(0).input_param().shape_size();
|
||||||
|
for (int inp_id = 0; inp_id < size; inp_id++)
|
||||||
|
{
|
||||||
|
const caffe::BlobShape &_input_shape = (net.input_shape_size() > 0) ?
|
||||||
|
net.input_shape(inp_id) :
|
||||||
|
net.layer(0).input_param().shape(inp_id);
|
||||||
|
MatShape shape;
|
||||||
|
for (int i = 0; i < _input_shape.dim_size(); i++) {
|
||||||
|
shape.push_back((int)_input_shape.dim(i));
|
||||||
|
}
|
||||||
|
inp_shapes.push_back(shape);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (net.input_dim_size() > 0) {
|
||||||
|
MatShape shape;
|
||||||
|
for (int dim = 0; dim < net.input_dim_size(); dim++) {
|
||||||
|
shape.push_back(net.input_dim(dim));
|
||||||
|
}
|
||||||
|
inp_shapes.push_back(shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int inp_id = 0; inp_id < inp_shapes.size(); inp_id++) {
|
||||||
|
dstNet.setInput(Mat(inp_shapes[inp_id], CV_32F), netInputs[inp_id]);
|
||||||
|
}
|
||||||
|
|
||||||
addedBlobs.clear();
|
addedBlobs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2455,6 +2455,18 @@ struct Net::Impl
|
|||||||
{
|
{
|
||||||
std::vector<LayerPin>& inputLayerIds = layers[id].inputBlobsId;
|
std::vector<LayerPin>& inputLayerIds = layers[id].inputBlobsId;
|
||||||
|
|
||||||
|
if (inOutShapes[0].in[0].empty() && !layers[0].outputBlobs.empty())
|
||||||
|
{
|
||||||
|
ShapesVec shapes;
|
||||||
|
for (int i = 0; i < layers[0].outputBlobs.size(); i++)
|
||||||
|
{
|
||||||
|
Mat& inp = layers[0].outputBlobs[i];
|
||||||
|
CV_Assert(inp.total());
|
||||||
|
shapes.push_back(shape(inp));
|
||||||
|
}
|
||||||
|
inOutShapes[0].in = shapes;
|
||||||
|
}
|
||||||
|
|
||||||
if (inOutShapes[id].in.empty())
|
if (inOutShapes[id].in.empty())
|
||||||
{
|
{
|
||||||
for(int i = 0; i < inputLayerIds.size(); i++)
|
for(int i = 0; i < inputLayerIds.size(); i++)
|
||||||
@ -2595,14 +2607,23 @@ Net Net::readFromModelOptimizer(const String& xml, const String& bin)
|
|||||||
InferenceEngine::CNNNetwork ieNet = reader.getNetwork();
|
InferenceEngine::CNNNetwork ieNet = reader.getNetwork();
|
||||||
|
|
||||||
std::vector<String> inputsNames;
|
std::vector<String> inputsNames;
|
||||||
|
std::vector<MatShape> inp_shapes;
|
||||||
for (auto& it : ieNet.getInputsInfo())
|
for (auto& it : ieNet.getInputsInfo())
|
||||||
{
|
{
|
||||||
inputsNames.push_back(it.first);
|
inputsNames.push_back(it.first);
|
||||||
|
std::vector<size_t> dims = it.second->getTensorDesc().getDims();
|
||||||
|
inp_shapes.push_back(std::vector<int>(dims.begin(), dims.end()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Net cvNet;
|
Net cvNet;
|
||||||
cvNet.setInputsNames(inputsNames);
|
cvNet.setInputsNames(inputsNames);
|
||||||
|
|
||||||
|
// set empty input to determine input shapes
|
||||||
|
for (int inp_id = 0; inp_id < inputsNames.size(); ++inp_id)
|
||||||
|
{
|
||||||
|
cvNet.setInput(Mat(inp_shapes[inp_id], CV_32F), inputsNames[inp_id]);
|
||||||
|
}
|
||||||
|
|
||||||
Ptr<InfEngineBackendNode> backendNode(new InfEngineBackendNode(InferenceEngine::Builder::Layer("")));
|
Ptr<InfEngineBackendNode> backendNode(new InfEngineBackendNode(InferenceEngine::Builder::Layer("")));
|
||||||
backendNode->net = Ptr<InfEngineBackendNet>(new InfEngineBackendNet(ieNet));
|
backendNode->net = Ptr<InfEngineBackendNet>(new InfEngineBackendNet(ieNet));
|
||||||
for (auto& it : ieNet.getOutputsInfo())
|
for (auto& it : ieNet.getOutputsInfo())
|
||||||
|
@ -47,12 +47,22 @@ Model::Model(const String& model, const String& config)
|
|||||||
: Net(readNet(model, config)), impl(new Impl)
|
: Net(readNet(model, config)), impl(new Impl)
|
||||||
{
|
{
|
||||||
impl->outNames = getUnconnectedOutLayersNames();
|
impl->outNames = getUnconnectedOutLayersNames();
|
||||||
}
|
std::vector<MatShape> inLayerShapes;
|
||||||
|
std::vector<MatShape> outLayerShapes;
|
||||||
|
getLayerShapes(MatShape(), 0, inLayerShapes, outLayerShapes);
|
||||||
|
if (!inLayerShapes.empty() && inLayerShapes[0].size() == 4)
|
||||||
|
impl->size = Size(inLayerShapes[0][3], inLayerShapes[0][2]);
|
||||||
|
};
|
||||||
|
|
||||||
Model::Model(const Net& network) : Net(network), impl(new Impl)
|
Model::Model(const Net& network) : Net(network), impl(new Impl)
|
||||||
{
|
{
|
||||||
impl->outNames = getUnconnectedOutLayersNames();
|
impl->outNames = getUnconnectedOutLayersNames();
|
||||||
}
|
std::vector<MatShape> inLayerShapes;
|
||||||
|
std::vector<MatShape> outLayerShapes;
|
||||||
|
getLayerShapes(MatShape(), 0, inLayerShapes, outLayerShapes);
|
||||||
|
if (!inLayerShapes.empty() && inLayerShapes[0].size() == 4)
|
||||||
|
impl->size = Size(inLayerShapes[0][3], inLayerShapes[0][2]);
|
||||||
|
};
|
||||||
|
|
||||||
Model& Model::setInputSize(const Size& size)
|
Model& Model::setInputSize(const Size& size)
|
||||||
{
|
{
|
||||||
|
@ -479,18 +479,17 @@ TEST_P(Test_Caffe_nets, DenseNet_121)
|
|||||||
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
applyTestTag(CV_TEST_TAG_MEMORY_512MB);
|
||||||
checkBackend();
|
checkBackend();
|
||||||
const string proto = findDataFile("dnn/DenseNet_121.prototxt", false);
|
const string proto = findDataFile("dnn/DenseNet_121.prototxt", false);
|
||||||
const string model = findDataFile("dnn/DenseNet_121.caffemodel", false);
|
const string weights = findDataFile("dnn/DenseNet_121.caffemodel", false);
|
||||||
|
|
||||||
Mat inp = imread(_tf("dog416.png"));
|
Mat inp = imread(_tf("dog416.png"));
|
||||||
inp = blobFromImage(inp, 1.0 / 255, Size(224, 224), Scalar(), true, true);
|
Model model(proto, weights);
|
||||||
|
model.setInputScale(1.0 / 255).setInputSwapRB(true).setInputCrop(true);
|
||||||
|
std::vector<Mat> outs;
|
||||||
Mat ref = blobFromNPY(_tf("densenet_121_output.npy"));
|
Mat ref = blobFromNPY(_tf("densenet_121_output.npy"));
|
||||||
|
|
||||||
Net net = readNetFromCaffe(proto, model);
|
model.setPreferableBackend(backend);
|
||||||
net.setPreferableBackend(backend);
|
model.setPreferableTarget(target);
|
||||||
net.setPreferableTarget(target);
|
model.predict(inp, outs);
|
||||||
|
|
||||||
net.setInput(inp);
|
|
||||||
Mat out = net.forward();
|
|
||||||
|
|
||||||
// Reference is an array of 1000 values from a range [-6.16, 7.9]
|
// Reference is an array of 1000 values from a range [-6.16, 7.9]
|
||||||
float l1 = default_l1, lInf = default_lInf;
|
float l1 = default_l1, lInf = default_lInf;
|
||||||
@ -506,9 +505,9 @@ TEST_P(Test_Caffe_nets, DenseNet_121)
|
|||||||
{
|
{
|
||||||
l1 = 0.11; lInf = 0.5;
|
l1 = 0.11; lInf = 0.5;
|
||||||
}
|
}
|
||||||
normAssert(out, ref, "", l1, lInf);
|
normAssert(outs[0], ref, "", l1, lInf);
|
||||||
if (target != DNN_TARGET_MYRIAD || getInferenceEngineVPUType() != CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
if (target != DNN_TARGET_MYRIAD || getInferenceEngineVPUType() != CV_DNN_INFERENCE_ENGINE_VPU_TYPE_MYRIAD_X)
|
||||||
expectNoFallbacksFromIE(net);
|
expectNoFallbacksFromIE(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(Test_Caffe, multiple_inputs)
|
TEST(Test_Caffe, multiple_inputs)
|
||||||
|
@ -240,20 +240,6 @@ void runIE(Target target, const std::string& xmlPath, const std::string& binPath
|
|||||||
infRequest.Infer();
|
infRequest.Infer();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<String> getOutputsNames(const Net& net)
|
|
||||||
{
|
|
||||||
std::vector<String> names;
|
|
||||||
if (names.empty())
|
|
||||||
{
|
|
||||||
std::vector<int> outLayers = net.getUnconnectedOutLayers();
|
|
||||||
std::vector<String> layersNames = net.getLayerNames();
|
|
||||||
names.resize(outLayers.size());
|
|
||||||
for (size_t i = 0; i < outLayers.size(); ++i)
|
|
||||||
names[i] = layersNames[outLayers[i] - 1];
|
|
||||||
}
|
|
||||||
return names;
|
|
||||||
}
|
|
||||||
|
|
||||||
void runCV(Target target, const std::string& xmlPath, const std::string& binPath,
|
void runCV(Target target, const std::string& xmlPath, const std::string& binPath,
|
||||||
const std::map<std::string, cv::Mat>& inputsMap,
|
const std::map<std::string, cv::Mat>& inputsMap,
|
||||||
std::map<std::string, cv::Mat>& outputsMap)
|
std::map<std::string, cv::Mat>& outputsMap)
|
||||||
@ -263,7 +249,7 @@ void runCV(Target target, const std::string& xmlPath, const std::string& binPath
|
|||||||
net.setInput(it.second, it.first);
|
net.setInput(it.second, it.first);
|
||||||
net.setPreferableTarget(target);
|
net.setPreferableTarget(target);
|
||||||
|
|
||||||
std::vector<String> outNames = getOutputsNames(net);
|
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
|
||||||
std::vector<Mat> outs;
|
std::vector<Mat> outs;
|
||||||
net.forward(outs, outNames);
|
net.forward(outs, outNames);
|
||||||
|
|
||||||
@ -319,5 +305,46 @@ INSTANTIATE_TEST_CASE_P(/**/,
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
typedef TestWithParam<Target> DNNTestHighLevelAPI;
|
||||||
|
TEST_P(DNNTestHighLevelAPI, predict)
|
||||||
|
{
|
||||||
|
initDLDTDataPath();
|
||||||
|
|
||||||
|
Target target = (dnn::Target)(int)GetParam();
|
||||||
|
bool isFP16 = (target == DNN_TARGET_OPENCL_FP16 || target == DNN_TARGET_MYRIAD);
|
||||||
|
|
||||||
|
OpenVINOModelTestCaseInfo modelInfo = getOpenVINOTestModels().find("age-gender-recognition-retail-0013")->second;
|
||||||
|
|
||||||
|
std::string modelPath = isFP16 ? modelInfo.modelPathFP16 : modelInfo.modelPathFP32;
|
||||||
|
|
||||||
|
std::string xmlPath = findDataFile(modelPath + ".xml");
|
||||||
|
std::string binPath = findDataFile(modelPath + ".bin");
|
||||||
|
|
||||||
|
Model model(xmlPath, binPath);
|
||||||
|
Mat frame = imread(findDataFile("dnn/googlenet_1.png"));
|
||||||
|
std::vector<Mat> outs;
|
||||||
|
model.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
|
||||||
|
model.setPreferableTarget(target);
|
||||||
|
model.predict(frame, outs);
|
||||||
|
|
||||||
|
Net net = readNet(xmlPath, binPath);
|
||||||
|
Mat input = blobFromImage(frame, 1.0, Size(62, 62));
|
||||||
|
net.setInput(input);
|
||||||
|
net.setPreferableBackend(DNN_BACKEND_INFERENCE_ENGINE);
|
||||||
|
net.setPreferableTarget(target);
|
||||||
|
|
||||||
|
std::vector<String> outNames = net.getUnconnectedOutLayersNames();
|
||||||
|
std::vector<Mat> refs;
|
||||||
|
net.forward(refs, outNames);
|
||||||
|
|
||||||
|
CV_Assert(refs.size() == outs.size());
|
||||||
|
for (int i = 0; i < refs.size(); ++i)
|
||||||
|
normAssert(outs[i], refs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(/**/,
|
||||||
|
DNNTestHighLevelAPI, testing::ValuesIn(getAvailableTargets(DNN_BACKEND_INFERENCE_ENGINE))
|
||||||
|
);
|
||||||
|
|
||||||
}}
|
}}
|
||||||
#endif // HAVE_INF_ENGINE
|
#endif // HAVE_INF_ENGINE
|
||||||
|
Loading…
Reference in New Issue
Block a user