13.6.6. Macro “modelerClassificationNeuralNetworks.C

13.6.6.1. Objective

The objective of this macro is to build a surrogate model (an Artificial Neural Network) from a database for a “Classification” Problem. From a first database loaded from the ASCII file problem2Classes_001000.dat, which defines three variables \((x,y) \in [-1., 1]^{2}\) and \(rc01 \in \{0, 1\}\) on 1000 patterns,

../../_images/modelerClassificationNeuralNetworks_App.png

two ASCII files are created, one with the 800st patterns (_problem2Classes_app_.dat), the other with the 200 last patterns (_problem2Classes_val_.dat). The surrogate model is built with the database extracted from the first of the two files, the second allowing to perform calculations with a function.

13.6.6.2. Macro Uranie

    // Load a database in an ASCII file
    TDataServer * tdsu = new TDataServer("tdsu","tds u");
    TDataServer * tds = new TDataServer("tdsApp", "tds App for problem2Classes");
    TDataServer * tdsv = new TDataServer();

    Int_t nH1 = 15;
    Int_t nH2 = 10;
    Int_t nH3 = 5;

    TString sX = "x:y";
    TString sY = "rc01";
    TString sYhat = Form("%shat_%d_%d_%d", sY.Data(), nH1, nH2, nH3);

    tdsu->fileDataRead("problem2Classes_001000.dat");

    // Split into 2 datasets for learning and testing
    tdsu->exportData("_problem2Classes_app_.dat", "", Form("%s<=800", tdsu->getIteratorName()));
    tdsu->exportData("_problem2Classes_val_.dat", "", Form("%s>800", tdsu->getIteratorName()));

    tds->fileDataRead("_problem2Classes_app_.dat");

    TANNModeler* tann = new TANNModeler(tds, Form("%s,%d,%d,%d,@%s", sX.Data(), nH1, nH2, nH3, sY.Data()));
    //tann->setLog();
    tann->setNormalization(TANNModeler::kMinusOneOne);
    tann->setFcnTol(1e-6);
    tann->train(2, 2, "test", kFALSE);

    tann->exportFunction("c++","uranie_ann_problem2Classes","ANNproblem2Classes");

    gROOT->LoadMacro("uranie_ann_problem2Classes.C");

    tdsv->fileDataRead("_problem2Classes_val_.dat");

    // evaluate the surrogate model on the database
    TLauncherFunction * tlf = new TLauncherFunction(tdsv, "ANNproblem2Classes", sX, sYhat);
    tlf->run();

    TCanvas *c = new TCanvas("c1", "Graph for the Macro modeler",5,64,1270,667);
    // Buils a surrogate model (Artificial Neural Networks) from the DataBase
    tds->getTuple()->SetMarkerStyle(8);
    tds->getTuple()->SetMarkerSize(1.0);
    tds->getTuple()->SetMarkerColor(kGreen);
    tds->draw(Form("%s:%s", sY.Data(), sX.Data()));

    tdsv->getTuple()->SetMarkerStyle(8);
    tdsv->getTuple()->SetMarkerSize(0.75);
    tdsv->getTuple()->SetMarkerColor(kRed);
    tdsv->Draw(Form("%s:%s", sYhat.Data(), sX.Data()),"","same");

The main TDataServer loads the main ASCII data file problem2Classes_001000.dat

    TDataServer * tdsu = new TDataServer("tdsu","tds u");
    tdsu->fileDataRead("problem2Classes_001000.dat");

The database is split with the internal iterator attribute in two parts by exporting the 800st patterns in a file and the remaining 200 in another one

    tdsu->exportData("_problem2Classes_app_.dat", "", Form("%s<=800", tdsu->getIteratorName()));
    tdsu->exportData("_problem2Classes_val_.dat", "", Form("%s>800", tdsu->getIteratorName()));

A second TDataServer loads _problem2Classes_app_.dat and builds the surrogate model over all the variables with 3 hidden layers, a Hyperbolic Tangent (TanH) activation function (normalization) in the 3 hidden layers and set the function tolerance to 1e-.6. The “@” character behind the output name defines a classification problem.

    TDataServer * tds = new TDataServer("tdsApp", "tds App for problem2Classes");
    tds->fileDataRead("_problem2Classes_app_.dat");
    TANNModeler* tann = new TANNModeler(tds, Form("%s,%d,%d,%d,@%s", sX.Data(), nH1, nH2, nH3, sY.Data()));
    tann->setNormalization(TANNModeler::kMinusOneOne);
    tann->setFcnTol(1e-6);
    tann->train(2, 2, "test", kFALSE);

The model is exported in an external file in C++ language "uranie_ann_problem2Classes.C" where the function name is ANNproblem2Classes

    tann->exportFunction("c++","uranie_ann_problem2Classes","ANNproblem2Classes");

The model is loaded from the macro uranie_ann_problem2Classes.C and applied on the second database with the function ANNproblem2Classes.

    TDataServer * tdsv = new TDataServer();
    gROOT->LoadMacro("uranie_ann_problem2Classes.C");
    tdsv->fileDataRead("_problem2Classes_val_.dat");
    TLauncherFunction * tlf = new TLauncherFunction(tdsv, "ANNproblem2Classes", sX, sYhat);
    tlf->run();

We draw on a 3D graph, the learning database (in green) and the estimations by the Artificial Neural Network with red points.

    TCanvas *c = new TCanvas("c1", "Graph for the Macro modeler",5,64,1270,667);
    tds->getTuple()->SetMarkerStyle(8);
    tds->getTuple()->SetMarkerSize(1.0);
    tds->getTuple()->SetMarkerColor(kGreen);
    tds->draw(Form("%s:%s", sY.Data(), sX.Data()));

    tdsv->getTuple()->SetMarkerStyle(8);
    tdsv->getTuple()->SetMarkerSize(0.75);
    tdsv->getTuple()->SetMarkerColor(kRed);
    tdsv->Draw(Form("%s:%s", sYhat.Data(), sX.Data()),"","same");

13.6.6.3. Graph

../../_images/modelerClassificationNeuralNetworks.png

Figure 13.42 Graph of the macro “modelerClassificationNeuralNetworks.C”

13.6.6.4. Console

--- Uranie v4.11/0 --- Developed with ROOT (6.36.06)
                      Copyright (C) 2013-2026 CEA/DES 
                      Contact: support-uranie@cea.fr 
                      Date: Thu Feb 12, 2026

 <URANIE::WARNING> 
 <URANIE::WARNING> *** URANIE WARNING ***
 <URANIE::WARNING> *** File[${SOURCEDIR}/dataSERVER/souRCE/TDataServer.cxx] Line[760]
 <URANIE::WARNING> TDataServer::fileDataRead: Expected iterator tdsu__n__iter__ not found but _tds___n__iter__ looks like an URANIE iterator => Will be used as so.
 <URANIE::WARNING> *** END of URANIE WARNING ***
 <URANIE::WARNING> 
 <URANIE::WARNING> 
 <URANIE::WARNING> *** URANIE WARNING ***
 <URANIE::WARNING> *** File[${SOURCEDIR}/dataSERVER/souRCE/TDataServer.cxx] Line[760]
 <URANIE::WARNING> TDataServer::fileDataRead: Expected iterator tdsApp__n__iter__ not found but _tds___n__iter__ looks like an URANIE iterator => Will be used as so.
 <URANIE::WARNING> *** END of URANIE WARNING ***
 <URANIE::WARNING> 
 ** TANNModeler::train niter[2] ninit[2]
 ** init the ANN
 ** Input  (1) Name[x] Min[-0.999842] Max[0.998315]
 ** Input  (2) Name[y] Min[-0.999434] Max[0.998071]
 ** Output  (1) Name[rc01] Min[0] Max[1]
 ** Tolerance  (1e-06)
 ** sHidden    (15,10,5) (30)
 ** Nb Weights (266)
 ** ActivationFunction[TanH]
 **

 ** iter[1/2] : ** : mse_min[0.00813999]
 ** iter[2/2] : ** : mse_min[0.00636923]

 ** solutions : 2
 ** isol[1] iter[0] learn[0.00405863] test[0.00813999] *
 ** isol[2] iter[1] learn[0.00560685] test[0.00636923] *
 ** CPU training finished. Total elapsed time: 19.2 sec

*******************************
*** TModeler::exportFunction lang[c++] file[uranie_ann_problem2Classes] name[ANNproblem2Classes] soption[]

*******************************

*******************************
*** exportFunction lang[c++] file[uranie_ann_problem2Classes] name[ANNproblem2Classes]
*** End Of exportFunction
*******************************