You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
3.8 KiB
136 lines
3.8 KiB
/*****************************************************************************
|
|
*
|
|
* demo program - part of CLIPP (command line interfaces for modern C++)
|
|
*
|
|
* released under MIT license
|
|
*
|
|
* (c) 2017-2018 André Müller; foss@andremueller-online.de
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include <iostream>
|
|
#include <stdexcept>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <clipp.h>
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
enum class mode {
|
|
none, train, validate, classify
|
|
};
|
|
|
|
struct settings {
|
|
mode selected = mode::none;
|
|
std::string imageFile;
|
|
std::string labelFile;
|
|
std::string modelFile = "out.mdl";
|
|
std::size_t batchSize = 128;
|
|
std::size_t threads = 0;
|
|
std::size_t inputLimit = 0;
|
|
std::vector<std::string> inputFiles;
|
|
};
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
settings configuration(int argc, char* argv[])
|
|
{
|
|
using namespace clipp;
|
|
|
|
settings s;
|
|
|
|
std::vector<std::string> unrecognized;
|
|
|
|
auto isfilename = clipp::match::prefix_not("-");
|
|
|
|
auto inputOptions = (
|
|
required("-i", "-I", "--img") & !value(isfilename, "image file", s.imageFile),
|
|
required("-l", "-L", "--lbl") & !value(isfilename, "label file", s.labelFile)
|
|
);
|
|
|
|
auto trainMode = (
|
|
command("train", "t", "T").set(s.selected,mode::train)
|
|
.if_conflicted([]{std::cerr << "conflicting modes\n"; }),
|
|
|
|
inputOptions,
|
|
|
|
(option("-n") & integer("limit", s.inputLimit))
|
|
% "limit number of input images",
|
|
|
|
(option("-o", "-O", "--out") & !value("model file", s.modelFile))
|
|
% "write model to specific file; default: 'out.mdl'",
|
|
|
|
(option("-b", "--batch-size") & integer("batch size", s.batchSize)),
|
|
|
|
(option("-p") & integer("threads", s.threads))
|
|
% "number of threads to use; default: optimum for machine"
|
|
);
|
|
|
|
auto validationMode = (
|
|
command("validate", "v", "V").set(s.selected,mode::validate),
|
|
!value(isfilename, "model", s.modelFile),
|
|
inputOptions
|
|
);
|
|
|
|
auto classificationMode = (
|
|
command("classify", "c", "C").set(s.selected,mode::classify),
|
|
!value(isfilename, "model", s.modelFile),
|
|
!values(isfilename, "images", s.inputFiles)
|
|
);
|
|
|
|
auto cli = (
|
|
trainMode | validationMode | classificationMode,
|
|
any_other(unrecognized)
|
|
);
|
|
|
|
auto res = parse(argc, argv, cli);
|
|
|
|
debug::print(std::cout, res);
|
|
|
|
if(!res || !unrecognized.empty()) {
|
|
std::string msg = "Wrong command line arguments!\n";
|
|
|
|
if(s.selected == mode::none) {
|
|
msg += "Please select a mode!\n";
|
|
}
|
|
else {
|
|
for(const auto& m : res.missing()) {
|
|
if(!m.param()->flags().empty()) {
|
|
msg += "Missing option: " + m.param()->flags().front() + '\n';
|
|
}
|
|
else if(!m.param()->label().empty()) {
|
|
msg += "Missing value: " + m.param()->label() + '\n';
|
|
}
|
|
}
|
|
|
|
for(const auto& arg : unrecognized) {
|
|
msg += "Argument not recognized: " + arg + '\n';
|
|
}
|
|
}
|
|
|
|
auto fmt = doc_formatting{}.first_column(8).doc_column(16);
|
|
//.max_flags_per_param_in_usage(3).surround_alternative_flags("(", ")");
|
|
|
|
msg += "\nUsage:\n" + usage_lines(cli, argv[0], fmt).str() + '\n';
|
|
msg += "\nOptions:\n" + documentation(cli, fmt).str() + '\n';
|
|
|
|
throw std::invalid_argument{msg};
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
|
|
|
|
//-------------------------------------------------------------------
|
|
int main(int argc, char* argv[])
|
|
{
|
|
try {
|
|
auto conf = configuration(argc, argv);
|
|
std::cout << "SUCCESS\n";
|
|
}
|
|
catch(std::exception& e) {
|
|
std::cerr << "ERROR: " << e.what() << '\n';
|
|
}
|
|
}
|