/* file: saga_logistic_loss_dense_batch.cpp */
/*******************************************************************************
* Copyright 2014-2019 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
/*
! Content:
! C++ example of the SAGA algorithm
!******************************************************************************/
/**
*
* \example saga_logistic_loss_dense_batch.cpp
*/
#include "daal.h"
#include "service.h"
#include
// time measurement
#include
#include
using namespace std;
using namespace daal;
using namespace daal::algorithms;
using namespace daal::data_management;
using namespace daal::algorithms::optimization_solver;
// const string datasetFileName = "../data/batch/XM_100.csv";
const string datasetFileName = "/path/data_banknote_authentication.csv";
// const string groundTruthFileName = "../data/batch/saga_solution_100_features.csv";
// const size_t nFeatures = 100; /* Number of features in training and testing data sets */
const size_t nFeatures = 4; /* Number of features in training and testing data sets */
const size_t nIterations = 100000000;
/*
stepLength bellow will be set automaticly as sklearn does for batchSize=1 case,
and line-search will be used for n=number of terms(deterministic case)
also it can be set by user at any value.
*/
const DAAL_ALGORITHM_FP_TYPE tol = 1e-12;
int main(int argc, char *argv[])
{
std::chrono::system_clock::time_point start = std::chrono::high_resolution_clock::now();
ios_base::sync_with_stdio(false);
checkArguments(argc, argv, 1, &datasetFileName);
/* Initialize FileDataSource to retrieve the input data from a .csv file */
FileDataSource dataSource(datasetFileName,
DataSource::notAllocateNumericTable,
DataSource::doDictionaryFromContext);
/* Create Numeric Tables for input data and dependent variables */
NumericTablePtr data(new HomogenNumericTable(nFeatures, 0, NumericTable::doNotAllocate));
NumericTablePtr dependentVariables(new HomogenNumericTable(1, 0, NumericTable::doNotAllocate));
NumericTablePtr mergedData(new MergedNumericTable(data, dependentVariables));
/* Retrieve the data from input file */
dataSource.loadDataBlock(mergedData.get());
services::SharedPtr > func(new optimization_solver::logistic_loss::Batch(data->getNumberOfRows()));
func->input.set(optimization_solver::logistic_loss::data, data);
func->input.set(optimization_solver::logistic_loss::dependentVariables, dependentVariables);
const size_t nParameters = (nFeatures + 1);
DAAL_ALGORITHM_FP_TYPE argument[nParameters];
// DAAL_ALGORITHM_FP_TYPE argument[nParameters] = { 6.76, -7.21, -3.86, -4.85, -0.53 };
for(int i = 0; i < nParameters; i++)
argument[i] = 0;
argument[0] = 0;
argument[1] = 0;
func->parameter().penaltyL1 = 0.0;
func->parameter().penaltyL2 = 0; /* penalty L2 is set to zero value as sklearn doesn`t support l1 and l2 similtaniously in curent moment */
func->parameter().interceptFlag = true;
func->parameter().resultsToCompute = optimization_solver::objective_function::gradient |
optimization_solver::objective_function::value;
/* Create objects to compute the SAGA result using the default method */
daal::algorithms::optimization_solver::saga::Batch sagaAlgorithm(func);
/* Set input objects for the the SAGA algorithm */
sagaAlgorithm.input.set(optimization_solver::iterative_solver::inputArgument,
HomogenNumericTable::create(argument, 1, nParameters));
sagaAlgorithm.parameter().nIterations = nIterations;
sagaAlgorithm.parameter().accuracyThreshold = tol;
sagaAlgorithm.parameter().batchSize = 1;//data->getNumberOfRows();
sagaAlgorithm.compute();
int nIter = sagaAlgorithm.getResult()->get(daal::algorithms::optimization_solver::iterative_solver::nIterations)->getValue(0,0);
std::cout << "Number of Iterations (nIter): " << std::setprecision(8) << nIter << "\n";
int nRows = sagaAlgorithm.getResult()->get(daal::algorithms::optimization_solver::iterative_solver::minimum)->getNumberOfRows();
for ( int i = 0 ; i < nRows; i ++)
{
DAAL_ALGORITHM_FP_TYPE optParam = sagaAlgorithm.getResult()->get(iterative_solver::minimum)->getValue(0,i);
// opt.vars.push_back(optParam);
std::cout << std::setprecision(8) << "optParam[" << i << "] = " << optParam << std::endl;
}
daal::services::Status s;
func->input.set(logistic_loss::argument, sagaAlgorithm.getResult()->get(iterative_solver::minimum));
func->parameter().resultsToCompute = objective_function::value;
s = func->compute();
DAAL_ALGORITHM_FP_TYPE optValue = func->getResult()->get(objective_function::valueIdx)->getValue(0,0);
std::cout << std::endl << "Objective function: " << std::setprecision(8) << optValue << std::endl << std::endl;
// End time
std::chrono::system_clock::time_point end = std::chrono::high_resolution_clock::now();
double time_taken = chrono::duration_cast(end - start).count();
time_taken *= 1e-9;
std::cout << "Time taken: " << fixed << time_taken << std::setprecision(9) << " sec" << endl;
return 0;
}