#include "daal.h"
#include "service.h"
#include "neural_net_dense_distr.h"
using namespace std;
using namespace daal;
using namespace daal::algorithms;
using namespace daal::algorithms::neural_networks;
using namespace daal::services;
const string trainDatasetFileNames[4] =
{
"../data/distributed/neural_network_train_dense_1.csv", "../data/distributed/neural_network_train_dense_2.csv",
"../data/distributed/neural_network_train_dense_3.csv", "../data/distributed/neural_network_train_dense_4.csv"
};
const string trainGroundTruthFileNames[4] =
{
"../data/distributed/neural_network_train_ground_truth_1.csv", "../data/distributed/neural_network_train_ground_truth_2.csv",
"../data/distributed/neural_network_train_ground_truth_3.csv", "../data/distributed/neural_network_train_ground_truth_4.csv"
};
string testDatasetFile = "../data/batch/neural_network_test.csv";
string testGroundTruthFile = "../data/batch/neural_network_test_ground_truth.csv";
const size_t nNodes = 4;
const size_t batchSize = 100;
const size_t batchSizeLocal = batchSize / nNodes;
TensorPtr trainingData[nNodes];
TensorPtr trainingGroundTruth[nNodes];
prediction::ModelPtr predictionModel;
prediction::ResultPtr predictionResult;
training::ModelPtr trainingModel;
training::TopologyPtr topology[nNodes];
training::TopologyPtr topologyMaster;
SharedPtr<training::Distributed<step2Master> > net;
SharedPtr<training::Distributed<step1Local> > netLocal[nNodes];
void initializeNetwork();
void trainModel();
void testModel();
void printResults();
int main(int argc, char *argv[])
{
checkArguments(argc, argv, 10, &trainDatasetFileNames[0], &trainDatasetFileNames[1], &trainDatasetFileNames[2], &trainDatasetFileNames[3],
&trainGroundTruthFileNames[0], &trainGroundTruthFileNames[1], &trainGroundTruthFileNames[2], &trainGroundTruthFileNames[3],
&testDatasetFile, &testGroundTruthFile);
initializeNetwork();
trainModel();
testModel();
printResults();
return 0;
}
void initializeNetwork()
{
SharedPtr<optimization_solver::sgd::Batch<> > sgdAlgorithm(new optimization_solver::sgd::Batch<>());
sgdAlgorithm->parameter.batchSize = batchSizeLocal;
for (size_t node = 0; node < nNodes; node++)
{
trainingData[node] = readTensorFromCSV(trainDatasetFileNames[node]);
trainingGroundTruth[node] = readTensorFromCSV(trainGroundTruthFileNames[node], true);
}
Collection<size_t> dataDims = trainingData[0]->getDimensions();
topologyMaster = configureNet();
net = SharedPtr<training::Distributed<step2Master> >(new training::Distributed<step2Master>(sgdAlgorithm));
services::Collection<size_t> oneBatchDimensions = dataDims;
oneBatchDimensions[0] = batchSizeLocal;
net->initialize(oneBatchDimensions, *topologyMaster);
for(size_t node = 0; node < nNodes; node++)
{
topology[node] = configureNet();
training::ModelPtr trainingModel(new training::Model());
trainingModel->initialize<float>(oneBatchDimensions, *(topology[node]));
netLocal[node] = SharedPtr<training::Distributed<step1Local> >(new training::Distributed<step1Local>());
netLocal[node]->input.set(training::inputModel, trainingModel);
}
}
void trainModel()
{
SharedPtr<optimization_solver::sgd::Batch<> > sgdAlgorithm(new optimization_solver::sgd::Batch<>());
float learningRate = 0.001f;
sgdAlgorithm->parameter.learningRateSequence = NumericTablePtr(new HomogenNumericTable<>(1, 1, NumericTable::doAllocate, learningRate));
sgdAlgorithm->parameter.batchSize = batchSizeLocal;
net->parameter.optimizationSolver = sgdAlgorithm;
size_t nSamples = trainingData[0]->getDimensions().get(0);
for (size_t i = 0; i < nSamples - batchSizeLocal + 1; i += batchSizeLocal)
{
for (size_t node = 0; node < nNodes; node++)
{
netLocal[node]->input.set(training::data, getNextSubtensor(trainingData[node], i, batchSizeLocal) );
netLocal[node]->input.set(training::groundTruth, getNextSubtensor(trainingGroundTruth[node], i, batchSizeLocal));
netLocal[node]->compute();
net->input.add(training::partialResults, node, netLocal[node]->getPartialResult());
}
net->compute();
training::ModelPtr wbModel = net->getPartialResult()->get(training::resultFromMaster)->get(training::model);
checkPtr((void *)wbModel.get());
NumericTablePtr wb = wbModel->getWeightsAndBiases();
for (size_t node = 0; node < nNodes; node++)
{
netLocal[node]->input.get(training::inputModel)->setWeightsAndBiases(wb);
}
}
net->finalizeCompute();
training::ModelPtr trModel = net->getResult()->get(training::model);
checkPtr((void *)trModel.get());
predictionModel = trModel->getPredictionModel<float>();
}
void testModel()
{
TensorPtr predictionData = readTensorFromCSV(testDatasetFile);
prediction::Batch<> net;
net.parameter.batchSize = predictionData->getDimensionSize(0);
net.input.set(prediction::model, predictionModel);
net.input.set(prediction::data, predictionData);
net.compute();
predictionResult = net.getResult();
}
void printResults()
{
TensorPtr predictionGroundTruth = readTensorFromCSV(testGroundTruthFile);
printTensors<int, float>(predictionGroundTruth, predictionResult->get(prediction::prediction),
"Ground truth", "Neural network predictions: each class probability",
"Neural network classification results (first 20 observations):", 20);
}