ImageDeserializerBase::ImageDeserializerBase(CorpusDescriptorPtr corpus, const ConfigParameters& config, bool primary) : DataDeserializerBase(primary), m_corpus(corpus) { assert(m_corpus); ConfigParameters inputs = config("input"); std::vector<std::string> featureNames = GetSectionsWithParameter("ImageDeserializerBase", inputs, "transforms"); std::vector<std::string> labelNames = GetSectionsWithParameter("ImageDeserializerBase", inputs, "labelDim"); if (featureNames.size() != 1 || labelNames.size() != 1) RuntimeError( "Please specify a single feature and label stream. '%d' features , '%d' labels found.", static_cast<int>(featureNames.size()), static_cast<int>(labelNames.size())); string precision = config("precision", "float"); m_precision = AreEqualIgnoreCase(precision, "float") ? ElementType::tfloat : ElementType::tdouble; m_verbosity = config(L"verbosity", 0); // Feature stream. ConfigParameters featureSection = inputs(featureNames[0]); auto features = std::make_shared<StreamDescription>(); features->m_id = 0; features->m_name = msra::strfun::utf16(featureSection.ConfigName()); features->m_storageType = StorageType::dense; // Due to performance, now we support images of different types. features->m_elementType = ElementType::tvariant; m_streams.push_back(features); // Label stream. ConfigParameters label = inputs(labelNames[0]); size_t labelDimension = label("labelDim"); auto labels = std::make_shared<StreamDescription>(); labels->m_id = 1; labels->m_name = msra::strfun::utf16(label.ConfigName()); labels->m_sampleLayout = std::make_shared<TensorShape>(labelDimension); labels->m_storageType = StorageType::sparse_csc; labels->m_elementType = m_precision; m_streams.push_back(labels); m_labelGenerator = labels->m_elementType == ElementType::tfloat ? (LabelGeneratorPtr)std::make_shared<TypedLabelGenerator<float>>(labelDimension) : std::make_shared<TypedLabelGenerator<double>>(labelDimension); m_grayscale = config(L"grayscale", false); // TODO: multiview should be done on the level of randomizer/transformers - it is responsiblity of the // TODO: randomizer to collect how many copies each transform needs and request same sequence several times. m_multiViewCrop = config(L"multiViewCrop", false); }
void CompositeDataReader::CreateTransforms(const ConfigParameters& deserializerConfig) { std::string defaultModule = deserializerConfig("module"); argvector<ConfigParameters> inputs = deserializerConfig("input"); for (size_t i = 0; i < inputs.size(); ++i) { // Trying to find transfomers in a stream section of the config. auto inputSections = TryGetSectionsWithParameter(inputs[i], "transforms"); if (inputSections.size() > 1) { LogicError("Only a single 'transforms' config is allowed per stream."); } // No need to create anything for this stream, skipping. if (inputSections.empty()) { continue; } ConfigParameters input = inputs[i](inputSections.front()); std::wstring inputName = msra::strfun::utf16(input.ConfigName()); // Read tranformers in order and appending them to the transformer pipeline. argvector<ConfigParameters> transforms = input("transforms"); for (size_t j = 0; j < transforms.size(); ++j) { TransformerPtr transformer = CreateTransformer(transforms[j], defaultModule); m_transforms.push_back(Transformation{transformer, inputName}); } } }
ImageConfigHelper::ImageConfigHelper(const ConfigParameters& config) : m_dataFormat(CHW) { std::vector<std::string> featureNames = GetSectionsWithParameter(config, "width"); std::vector<std::string> labelNames = GetSectionsWithParameter(config, "labelDim"); // REVIEW alexeyk: currently support only one feature and label section. if (featureNames.size() != 1 || labelNames.size() != 1) { RuntimeError( "ImageReader currently supports a single feature and label stream. '%d' features , '%d' labels found.", static_cast<int>(featureNames.size()), static_cast<int>(labelNames.size())); } ConfigParameters featureSection = config(featureNames[0]); size_t w = featureSection("width"); size_t h = featureSection("height"); size_t c = featureSection("channels"); std::string mbFmt = featureSection("mbFormat", "nchw"); if (AreEqualIgnoreCase(mbFmt, "nhwc") || AreEqualIgnoreCase(mbFmt, "legacy")) { m_dataFormat = HWC; } else if (!AreEqualIgnoreCase(mbFmt, "nchw") || AreEqualIgnoreCase(mbFmt, "cudnn")) { RuntimeError("ImageReader does not support the sample format '%s', only 'nchw' and 'nhwc' are supported.", mbFmt.c_str()); } auto features = std::make_shared<StreamDescription>(); features->m_id = 0; features->m_name = msra::strfun::utf16(featureSection.ConfigName()); features->m_sampleLayout = std::make_shared<TensorShape>(ImageDimensions(w, h, c).AsTensorShape(m_dataFormat)); m_streams.push_back(features); ConfigParameters label = config(labelNames[0]); size_t labelDimension = label("labelDim"); auto labelSection = std::make_shared<StreamDescription>(); labelSection->m_id = 1; labelSection->m_name = msra::strfun::utf16(label.ConfigName()); labelSection->m_sampleLayout = std::make_shared<TensorShape>(labelDimension); m_streams.push_back(labelSection); m_mapPath = config(L"file"); std::string rand = config(L"randomize", "auto"); if (AreEqualIgnoreCase(rand, "auto")) { m_randomize = true; } else if (AreEqualIgnoreCase(rand, "none")) { m_randomize = false; } else { RuntimeError("'randomize' parameter must be set to 'auto' or 'none'"); } // Identify precision string precision = config.Find("precision", "float"); if (AreEqualIgnoreCase(precision, "float")) { features->m_elementType = ElementType::tfloat; labelSection->m_elementType = ElementType::tfloat; } else if (AreEqualIgnoreCase(precision, "double")) { features->m_elementType = ElementType::tdouble; labelSection->m_elementType = ElementType::tdouble; } else { RuntimeError("Not supported precision '%s'. Expected 'double' or 'float'.", precision.c_str()); } m_cpuThreadCount = config(L"numCPUThreads", 0); }