Fixed mean image support for IR v10 (#1926)
* Fixed mean image support for IR v10 * Fixed comments
This commit is contained in:
parent
7859aab4b0
commit
a072c3b7b6
@ -196,7 +196,135 @@ std::shared_ptr<ICNNNetwork> V10Parser::parse(const pugi::xml_node& root, std::i
|
||||
result_nodes[0]->add_control_dependency(assign);
|
||||
}
|
||||
}
|
||||
return CNNNetwork(function);
|
||||
CNNNetwork net(function);
|
||||
parsePreProcess(net, root, binStream);
|
||||
return net;
|
||||
}
|
||||
|
||||
void V10Parser::parsePreProcess(CNNNetwork& network, const pugi::xml_node& root, std::istream& binStream) {
|
||||
/*
|
||||
<pre-process mean-precision="FP32">
|
||||
<channel id = ”0”>
|
||||
<mean offset = "121930449" size = "51529" / > // in case of array – ref to the .bin file
|
||||
</channel>
|
||||
</pre-process>
|
||||
*/
|
||||
|
||||
auto ppNode = root.child("pre-process");
|
||||
if (ppNode.empty()) {
|
||||
return;
|
||||
}
|
||||
// find out to what input this belongs to
|
||||
std::string inputName;
|
||||
InputInfo::Ptr preProcessInput;
|
||||
|
||||
inputName = GetStrAttr(ppNode, "reference-layer-name", "");
|
||||
inputName = ngraph::trim(inputName);
|
||||
if (inputName.empty()) {
|
||||
// fallback (old format), look for the picture in the inputs
|
||||
InputsDataMap inputs = network.getInputsInfo();
|
||||
|
||||
if (inputs.empty()) THROW_IE_EXCEPTION << "network has no input";
|
||||
|
||||
for (auto i : inputs) {
|
||||
if (i.second->getTensorDesc().getDims().size() == 4) {
|
||||
preProcessInput = i.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!preProcessInput) {
|
||||
preProcessInput = inputs.begin()->second;
|
||||
}
|
||||
|
||||
inputName = preProcessInput->name();
|
||||
} else {
|
||||
preProcessInput = network.getInputsInfo()[inputName];
|
||||
if (!preProcessInput)
|
||||
THROW_IE_EXCEPTION << "pre-process name ref '" << inputName << "' refers to un-existing input";
|
||||
}
|
||||
|
||||
// dims vector without batch size
|
||||
SizeVector inputDims = preProcessInput->getTensorDesc().getDims();
|
||||
size_t noOfChannels = 0, width = 0, height = 0;
|
||||
|
||||
if (inputDims.size() < 2) {
|
||||
THROW_IE_EXCEPTION << "network did not define input dimensions properly";
|
||||
} else if (inputDims.size() == 2) { // NC
|
||||
noOfChannels = inputDims[1];
|
||||
width = inputDims[1];
|
||||
height = inputDims[0];
|
||||
} else if (inputDims.size() == 3) {
|
||||
width = inputDims[2];
|
||||
height = inputDims[1];
|
||||
noOfChannels = inputDims[0];
|
||||
} else if (inputDims.size() == 4) {
|
||||
width = inputDims[3];
|
||||
height = inputDims[2];
|
||||
noOfChannels = inputDims[1];
|
||||
} else if (inputDims.size() == 5) {
|
||||
width = inputDims[4];
|
||||
height = inputDims[3];
|
||||
noOfChannels = inputDims[2];
|
||||
}
|
||||
|
||||
PreProcessInfo& pp = preProcessInput->getPreProcess();
|
||||
pp.init(noOfChannels);
|
||||
|
||||
auto meanSegmentPrecision = GetPrecisionAttr(ppNode, "mean-precision", Precision::UNSPECIFIED);
|
||||
if (!meanSegmentPrecision || meanSegmentPrecision == Precision::MIXED)
|
||||
THROW_IE_EXCEPTION << "mean blob defined without specifying precision.";
|
||||
|
||||
ResponseDesc resp;
|
||||
InferenceEngine::PreProcessChannel::Ptr preProcessChannel;
|
||||
|
||||
int lastChanNo = -1;
|
||||
std::unordered_set<int> idsForMeanImage;
|
||||
|
||||
FOREACH_CHILD(chan, ppNode, "channel") {
|
||||
int chanNo = GetIntAttr(chan, "id", lastChanNo + 1);
|
||||
if (chanNo >= static_cast<int>(noOfChannels) || chanNo < 0) {
|
||||
THROW_IE_EXCEPTION << "Pre-process channel id invalid: " << chanNo;
|
||||
}
|
||||
lastChanNo = chanNo;
|
||||
preProcessChannel = pp[chanNo];
|
||||
|
||||
auto meanNode = chan.child("mean");
|
||||
if (!meanNode.empty()) {
|
||||
if (!meanNode.attribute("size")) {
|
||||
THROW_IE_EXCEPTION << "mean should have the attribute: size";
|
||||
}
|
||||
if (meanNode.attribute("size")) {
|
||||
idsForMeanImage.insert(chanNo);
|
||||
size_t size = static_cast<size_t>(GetIntAttr(meanNode, "size"));
|
||||
size_t offset = static_cast<size_t>(GetIntAttr(meanNode, "offset"));
|
||||
if (width * height * meanSegmentPrecision.size() != size) {
|
||||
THROW_IE_EXCEPTION << "mean blob size mismatch expected input, got: " << size
|
||||
<< " extpecting " << width << " x " << height << " x "
|
||||
<< meanSegmentPrecision.size();
|
||||
}
|
||||
preProcessChannel->meanData = make_blob_with_precision(TensorDesc(meanSegmentPrecision, {height, width}, Layout::HW));
|
||||
preProcessChannel->meanData->allocate();
|
||||
auto lockedMem = preProcessChannel->meanData->buffer();
|
||||
char* data = lockedMem.as<char *>();
|
||||
binStream.seekg(offset, std::ios::beg);
|
||||
binStream.read(data, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (idsForMeanImage.size() == noOfChannels) {
|
||||
pp.setVariant(MEAN_IMAGE);
|
||||
} else if (idsForMeanImage.size() == 0) {
|
||||
pp.setVariant(NONE);
|
||||
} else {
|
||||
std::string validMeanImageIds = "";
|
||||
for (auto id : idsForMeanImage) {
|
||||
validMeanImageIds += std::to_string(id) + " ";
|
||||
}
|
||||
THROW_IE_EXCEPTION << "mean is not provided for all channels\n"
|
||||
"Provided mean image for: "
|
||||
<< validMeanImageIds;
|
||||
}
|
||||
}
|
||||
|
||||
V10Parser::GenericLayerParams V10Parser::parseGenericParams(const pugi::xml_node& node) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifdef IR_READER_V10
|
||||
# include <ngraph/node.hpp>
|
||||
# include <legacy/ie_ngraph_utils.hpp>
|
||||
# include <cpp/ie_cnn_network.h>
|
||||
#endif // IR_READER_V10
|
||||
|
||||
#include <ie_blob.h>
|
||||
@ -169,6 +170,7 @@ private:
|
||||
std::istream& binStream, const GenericLayerParams& params);
|
||||
|
||||
GenericLayerParams parseGenericParams(const pugi::xml_node& node);
|
||||
void parsePreProcess(CNNNetwork& network, const pugi::xml_node& root, std::istream& binStream);
|
||||
|
||||
std::map<std::string, DataPtr> portsToData;
|
||||
std::map<std::string, GenericLayerParams> layersParseInfo;
|
||||
|
@ -461,6 +461,100 @@ TEST(CNNNGraphImplTests, ReadFromCNNNetReader) {
|
||||
ASSERT_EQ(3, network.layerCount());
|
||||
}
|
||||
|
||||
TEST(CNNNGraphImplTests, ReadMeanImageFromCNNNetReader) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="Activation" version="10">
|
||||
<pre-process mean-precision="FP32" reference-layer-name="data">
|
||||
<channel id="0">
|
||||
<mean offset="0" size="1936"/>
|
||||
</channel>
|
||||
<channel id="1">
|
||||
<mean offset="1936" size="1936"/>
|
||||
</channel>
|
||||
<channel id="2">
|
||||
<mean offset="3872" size="1936"/>
|
||||
</channel>
|
||||
</pre-process>
|
||||
<layers>
|
||||
<layer name="data" type="Parameter" id="0" version="opset1">
|
||||
<data shape="1,3,22,22" element_type="f32"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="activation" id="1" type="ReLU" version="opset1">
|
||||
<input>
|
||||
<port id="1" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="output" type="Result" id="2" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
<dim>22</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="1"/>
|
||||
<edge from-layer="1" from-port="2" to-layer="2" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
InferenceEngine::Core core;
|
||||
size_t hwSize = 22*22;
|
||||
size_t dataSize = hwSize*3;
|
||||
Blob::Ptr data = make_shared_blob<float>(TensorDesc(Precision::FP32, {dataSize}, Layout::C));
|
||||
data->allocate();
|
||||
{
|
||||
auto lockData = data->buffer();
|
||||
float *dataPtr = lockData.as<float*>();
|
||||
|
||||
for (size_t i = 0; i < dataSize; ++i) {
|
||||
dataPtr[i] = i;
|
||||
}
|
||||
}
|
||||
CNNNetwork network = core.ReadNetwork(model, data);
|
||||
ASSERT_EQ(3, network.layerCount());
|
||||
auto inputInfo = network.getInputsInfo().begin()->second;
|
||||
ASSERT_NE(inputInfo, nullptr);
|
||||
auto preProc = inputInfo->getPreProcess();
|
||||
ASSERT_EQ(3, preProc.getNumberOfChannels());
|
||||
ASSERT_EQ(preProc.getMeanVariant(), MeanVariant::MEAN_IMAGE);
|
||||
|
||||
for (size_t i = 0; i < preProc.getNumberOfChannels(); i++) {
|
||||
auto chMeanImg = preProc[i];
|
||||
ASSERT_NE(chMeanImg, nullptr);
|
||||
ASSERT_NE(chMeanImg->meanData, nullptr);
|
||||
auto lockData = chMeanImg->meanData->cbuffer();
|
||||
auto *dataPtr = lockData.as<const float*>();
|
||||
for (size_t j = 0; j < hwSize; j++) {
|
||||
ASSERT_EQ(dataPtr[j], hwSize*i + j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CNNNGraphImplTests, CanChangeInputPrecision) {
|
||||
std::shared_ptr<ngraph::Function> ngraph;
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user