trainer = $optimizer; $this->loader = $loader; $this->store = $store; $this->addOption( 'epochs', 'e', InputOption::VALUE_OPTIONAL, 'number of epochs to train' ); $this->addOption( 'layers', 'l', InputOption::VALUE_OPTIONAL, 'number of hidden layers' ); $this->addOption( 'shuffled', null, InputOption::VALUE_OPTIONAL, 'ratio of shuffled negative samples' ); $this->addOption( 'random', null, InputOption::VALUE_OPTIONAL, 'ratio of random negative samples' ); $this->addOption( 'learn-rate', null, InputOption::VALUE_OPTIONAL, 'learning rate' ); $this->addOption( 'validation-threshold', null, InputOption::VALUE_OPTIONAL, 'determines how much of the most recent data is used for validation. the default is one week' ); $this->addOption( 'max-age', null, InputOption::VALUE_OPTIONAL, 'determines the maximum age of test data' ); $this->addOption( 'now', null, InputOption::VALUE_OPTIONAL, 'overwrite the current time', time() ); $this->addOption( 'v6', null, InputOption::VALUE_NONE, 'train with IPv6 data' ); $this->addOption( 'dry-run', null, InputOption::VALUE_NONE, "train but don't persist the model" ); $this->addOption( 'now', null, InputOption::VALUE_OPTIONAL, 'the current time as timestamp', time() ); $this->registerStatsOption(); } protected function execute(InputInterface $input, OutputInterface $output): int { $strategy = $input->getOption('v6') ? new IpV6Strategy() : new Ipv4Strategy(); $config = $strategy->getDefaultMlpConfig(); if ($input->getOption('epochs') !== null) { $config = $config->setEpochs((int)$input->getOption('epochs')); } if ($input->getOption('layers') !== null) { $config = $config->setLayers((int)$input->getOption('layers')); } if ($input->getOption('shuffled') !== null) { $config = $config->setShuffledNegativeRate((float)$input->getOption('shuffled')); } if ($input->getOption('random') !== null) { $config = $config->setRandomNegativeRate((float)$input->getOption('random')); } if ($input->getOption('learn-rate') !== null) { $config = $config->setLearningRate((float)$input->getOption('learn-rate')); } $trainingDataConfig = TrainingDataConfig::default((int)$input->getOption('now')); if ($input->getOption('validation-threshold') !== null) { $trainingDataConfig = $trainingDataConfig->setThreshold((int)$input->getOption('validation-threshold')); } if ($input->getOption('max-age') !== null) { $trainingDataConfig = $trainingDataConfig->setMaxAge((int)$input->getOption('max-age')); } if ($input->getOption('now') !== null) { $trainingDataConfig = $trainingDataConfig->setNow((int)$input->getOption('now')); } try { if (extension_loaded('xdebug')) { $output->writeln('XDebug is active. This will slow down the training process.'); } $output->writeln('Using ' . $strategy::getTypeName() . ' strategy'); $collectedData = $this->loader->loadTrainingAndValidationData( $trainingDataConfig, $strategy ); $data = $this->loader->generateRandomShuffledData( $collectedData, $config, $strategy ); $result = $this->trainer->train( $config, $data, $strategy ); $this->printModelStatistics($result->getModel(), $input, $output); if (!$input->getOption('dry-run')) { $this->store->persist( $result->getClassifier(), $result->getModel() ); $output->writeln('Model and estimator persisted.'); } } catch (InsufficientDataException $ex) { $output->writeln('Not enough data, try again later (' . $ex->getMessage() . ')'); return 1; } catch (ServiceException $ex) { $output->writeln('Could not train a model: ' . $ex->getMessage() . ''); return 1; } return 0; } }