| 238 | } |
| 239 | |
| 240 | void Train( |
| 241 | const NCatboostOptions::TCatBoostOptions& catboostOption, |
| 242 | const TString& trainDir, |
| 243 | const TMaybe<TCustomObjectiveDescriptor>& objectiveDescriptor, |
| 244 | const TMaybe<TCustomMetricDescriptor>& evalMetricDescriptor, |
| 245 | const TLabelConverter& labelConverter, |
| 246 | const TVector<THolder<IMetric>>& metrics, |
| 247 | bool isErrorTrackerActive, |
| 248 | ITrainingCallbacks* trainingCallbacks, |
| 249 | TFoldContext* foldContext, |
| 250 | IModelTrainer* modelTrainer, |
| 251 | NPar::ILocalExecutor* localExecutor |
| 252 | ) { |
| 253 | TTrainModelInternalOptions internalOptions; |
| 254 | internalOptions.CalcMetricsOnly = !foldContext->FullModel.Defined(); |
| 255 | internalOptions.ForceCalcEvalMetricOnEveryIteration = isErrorTrackerActive; |
| 256 | |
| 257 | auto foldOutputOptions = foldContext->OutputOptions; |
| 258 | foldOutputOptions.SetTrainDir(trainDir); |
| 259 | if (foldContext->FullModel.Defined()) { |
| 260 | // TrainModel saves model either to memory pointed by dstModel, or to ResultModelPath |
| 261 | foldOutputOptions.ResultModelPath = NCatboostOptions::TOption<TString>("result_model_file", "model"); |
| 262 | } |
| 263 | TMetricsAndTimeLeftHistory metricsAndTimeHistory; |
| 264 | const auto defaultCustomCallbacks = MakeHolder<TCustomCallbacks>(Nothing()); |
| 265 | modelTrainer->TrainModel( |
| 266 | internalOptions, |
| 267 | catboostOption, |
| 268 | foldOutputOptions, |
| 269 | objectiveDescriptor, |
| 270 | evalMetricDescriptor, |
| 271 | foldContext->TrainingData, |
| 272 | /*precomputedSingleOnlineCtrDataForSingleFold*/ Nothing(), |
| 273 | labelConverter, |
| 274 | trainingCallbacks, |
| 275 | defaultCustomCallbacks.Get(), |
| 276 | /*initModel*/ Nothing(), |
| 277 | THolder<TLearnProgress>(), |
| 278 | /*initModelApplyCompatiblePools*/ TDataProviders(), |
| 279 | localExecutor, |
| 280 | /*rand*/ Nothing(), |
| 281 | foldContext->FullModel.Defined() ? foldContext->FullModel.Get() : nullptr, |
| 282 | TVector<TEvalResult*>{&foldContext->LastUpdateEvalResult}, |
| 283 | &metricsAndTimeHistory, |
| 284 | (foldContext->TaskType == ETaskType::CPU) ? &foldContext->LearnProgress : nullptr |
| 285 | ); |
| 286 | if (foldContext->FullModel.Defined()) { |
| 287 | TFileOutput modelFile(JoinFsPaths(trainDir, foldContext->OutputOptions.ResultModelPath.Get())); |
| 288 | foldContext->FullModel->Save(&modelFile); |
| 289 | } |
| 290 | const auto skipMetricOnTrain = GetSkipMetricOnTrain(metrics); |
| 291 | for (const auto& trainMetrics : metricsAndTimeHistory.LearnMetricsHistory) { |
| 292 | foldContext->MetricValuesOnTrain.emplace_back(GetMetricValues(metrics, skipMetricOnTrain, trainMetrics)); |
| 293 | } |
| 294 | for (const auto& testMetrics : metricsAndTimeHistory.TestMetricsHistory) { |
| 295 | CB_ENSURE(testMetrics.size() <= 1, "Expect only one test dataset"); |
| 296 | if (!testMetrics.empty()) { |
| 297 | foldContext->MetricValuesOnTest.emplace_back(GetMetricValues(metrics, /*skipMetric*/{}, testMetrics[0])); |
no test coverage detected