trainer.cpp

/*

 * Compile using:

 * gcc -o trainer trainer.c `pkg-config --cflags --libs gtk+-2.0 gmodule-2.0`

*/

#include <pthread.h>

#include <gtk/gtk.h>

#include <gtkextra/gtkextra.h>

//#include <unistd.h>

//#include <glib.h>

#include <stdlib.h>

#include <string.h>

#include "FeedForwardNNTrainer.h"

/* Convenience macros for obtaining objects from UI file */

#define CH_GET_OBJECT( builder, name, type, data ) \

    data->name = type( gtk_builder_get_object( builder, #name ) )

#define CH_GET_WIDGET( builder, name, data ) \

    CH_GET_OBJECT( builder, name, GTK_WIDGET, data )

#define UI_FILE "trainer.glade"

#define ARRAYMAXSIZE 100000

static FeedForwardNN network;

static FeedForwardNN mseT;

static FeedForwardNN mseTT;

static FeedForwardNN cl;

pthread_t trainerThread=-1;

GtkPlotData *datasetTrain;

GtkPlotData *datasetTest;

double x[ARRAYMAXSIZE];

double yTrain[ARRAYMAXSIZE];

double yTest[ARRAYMAXSIZE];

int arraySizeTrain=0;

int arraySizeTest=0;

int maxEpochs=0;

int epochsBetweenReports=0;

#define MINERROR 0.00001

double desiredError=MINERROR;

/* Main data structure definition */

typedef struct _ChData ChData;

struct _ChData{

GtkWidget * windowTrainer;

GtkWidget * filechooserbuttonTrainingSet;

GtkWidget * filechooserbuttonTestSet;

GtkWidget * labelTrainingSetSize;

GtkWidget * labelTestSetSize;

GtkWidget * spinbuttonNLayers;


GtkWidget * checkbuttonClassifier;

GtkWidget * labelInputs;

GtkWidget * spinbuttonInputs;

GtkWidget * labelInputsAct;

GtkWidget * comboboxInputsAct;

GtkWidget * labelHid1;

GtkWidget * spinbuttonHid1;

GtkWidget * labelHid1Act;

GtkWidget * comboboxHid1Act;

GtkWidget * labelHid2;

GtkWidget * spinbuttonHid2;

GtkWidget * labelHid2Act;

GtkWidget * comboboxHid2Act;

GtkWidget * labelHid3;

GtkWidget * spinbuttonHid3;

GtkWidget * labelHid3Act;

GtkWidget * comboboxHid3Act;

GtkWidget * labelOutputs;

GtkWidget * spinbuttonOutputs;

GtkWidget * labelOutputsAct;

GtkWidget * comboboxOutputsAct;

GtkWidget * entryDesiredError;

GtkWidget * entryMaxEpochs;

GtkWidget * entryEpochsBetweenReports;

GtkWidget * comboboxLocation;

GtkWidget * comboboxAlgorithm;

GtkWidget * entryLearningRate;

GtkWidget * entryMomentum;

GtkWidget * checkbuttonShuffle;

GtkWidget * comboboxErrorFunction;

GtkWidget * checkbuttonNguyenWidrow;

GtkWidget * filechooserbuttonLoadNetwork;

GtkWidget * buttonCancelLoadNetwork;

GtkWidget * buttonStartTraining;

GtkWidget * buttonStopTraining;


GtkWidget * textviewTraining;

GtkTextBuffer * textbufferTraining;


GtkWidget * notebookEvolution;

GtkWidget * vboxPlot;

GtkWidget * canvasEvolution;

GtkWidget * plotEvolution;

GtkWidget * buttonSaveNetwork;

GtkWidget * radiobuttonLast;

GtkWidget * radiobuttonBestMSEtest;

GtkWidget * radiobuttonBestMSEtraintest;

GtkWidget * radiobuttonBestclassifier;

};

/* Function to open a dialog box displaying the message provided. */

//extern "C" 

void error_dialog (gchar *message,  GtkWindow * win ) {

GtkWidget *dialog;

/* Create the widgets */

dialog = gtk_message_dialog_new (win,

GTK_DIALOG_DESTROY_WITH_PARENT,

GTK_MESSAGE_ERROR,

GTK_BUTTONS_CLOSE,

"%s",message);

/* Destroy the dialog when the user responds to it (e.g. clicks a button) */

g_signal_connect_swapped (dialog, "response",

G_CALLBACK (gtk_widget_destroy),

dialog);

gtk_widget_show_all (dialog);

}

void build_start(GtkWidget *plot){

GdkColor colorTrain,colorTest;

datasetTrain = GTK_PLOT_DATA(gtk_plot_data_new());

datasetTest = GTK_PLOT_DATA(gtk_plot_data_new());


gtk_plot_data_set_points(datasetTrain, NULL, NULL, NULL, NULL, NULL);

gtk_plot_data_set_points(datasetTest, NULL, NULL, NULL, NULL, NULL);

gdk_color_parse("red", &colorTrain);

gdk_color_parse("green", &colorTest);

gtk_plot_data_set_symbol(datasetTrain,

GTK_PLOT_SYMBOL_NONE,

GTK_PLOT_SYMBOL_EMPTY,

10, 2, &colorTrain, &colorTrain);

gtk_plot_data_set_symbol(datasetTest,

GTK_PLOT_SYMBOL_NONE,

GTK_PLOT_SYMBOL_EMPTY,

10, 2, &colorTest, &colorTest);

gtk_plot_data_set_line_attributes(datasetTrain,

 GTK_PLOT_LINE_SOLID,

 (GdkCapStyle)0,

 (GdkJoinStyle)0,

 2, &colorTrain);

  gtk_plot_data_set_line_attributes(datasetTest,

 GTK_PLOT_LINE_SOLID,

 (GdkCapStyle)0,

 (GdkJoinStyle)0,

 2, &colorTest);

gtk_plot_data_set_legend(datasetTrain,"Training set");

gtk_plot_data_set_legend(datasetTest,"Test set");

gtk_plot_data_set_connector(datasetTrain, GTK_PLOT_CONNECT_STRAIGHT);

gtk_plot_data_set_connector(datasetTest, GTK_PLOT_CONNECT_STRAIGHT);

gtk_plot_add_data(GTK_PLOT(plot), datasetTrain);

gtk_plot_add_data(GTK_PLOT(plot), datasetTest);

gtk_widget_show(GTK_WIDGET(datasetTrain));

gtk_widget_show(GTK_WIDGET(datasetTest));

}

// This signal handler resizes the graph if its allocation was changed

int plot_expose_event(GtkWidget *canvas){

int width = canvas->allocation.width;

int height = canvas->allocation.height;

if (width != GTK_PLOT_CANVAS(canvas)->width

|| height != GTK_PLOT_CANVAS(canvas)->height){

gtk_plot_canvas_set_size(GTK_PLOT_CANVAS(canvas),width, height);

gtk_plot_canvas_paint(GTK_PLOT_CANVAS(canvas));

}

return 0;

}

// This is an example of how to update the data displayed in the

// widget. For more examples, see testrealtime.c.

void updateDataset(ChData * data){

// gtk_plot_axis_set_ticks(gtk_plot_get_axis(GTK_PLOT(data->plotEvolution), GTK_PLOT_AXIS_LEFT),0.5,1);

int freq=maxEpochs/10;

if (freq<=0)freq=1;

gtk_plot_axis_set_ticks(gtk_plot_get_axis(GTK_PLOT(data->plotEvolution), GTK_PLOT_AXIS_BOTTOM),freq,1);

gtk_plot_set_range(GTK_PLOT(data->plotEvolution), 0, maxEpochs, desiredError, 1);

gtk_plot_data_set_points(datasetTrain, x, yTrain, NULL, NULL, arraySizeTrain);

//if(arraySizeTest>0)

gtk_plot_data_set_points(datasetTest, x, yTest, NULL, NULL, arraySizeTest);

gtk_plot_canvas_paint(GTK_PLOT_CANVAS(data->canvasEvolution));

gtk_widget_queue_draw(data->canvasEvolution);

}

extern "C" G_MODULE_EXPORT void changeNLayers(GtkWidget *,  ChData * data ){

int NLayers=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonNLayers));

switch(NLayers){

case 5:

gtk_widget_show(data->labelHid3);

gtk_widget_show(data->spinbuttonHid3);

gtk_widget_show(data->labelHid3Act);

gtk_widget_show(data->comboboxHid3Act);


gtk_widget_show(data->labelHid2);

gtk_widget_show(data->spinbuttonHid2);

gtk_widget_show(data->labelHid2Act);

gtk_widget_show(data->comboboxHid2Act);

gtk_widget_show(data->labelHid1);

gtk_widget_show(data->spinbuttonHid1);

gtk_widget_show(data->labelHid1Act);

gtk_widget_show(data->comboboxHid1Act);

break;

case 4:

gtk_widget_hide(data->labelHid3);

gtk_widget_hide(data->spinbuttonHid3);

gtk_widget_hide(data->labelHid3Act);

gtk_widget_hide(data->comboboxHid3Act);


gtk_widget_show(data->labelHid2);

gtk_widget_show(data->spinbuttonHid2);

gtk_widget_show(data->labelHid2Act);

gtk_widget_show(data->comboboxHid2Act);

gtk_widget_show(data->labelHid1);

gtk_widget_show(data->spinbuttonHid1);

gtk_widget_show(data->labelHid1Act);

gtk_widget_show(data->comboboxHid1Act);

break;

case 3:

gtk_widget_hide(data->labelHid3);

gtk_widget_hide(data->spinbuttonHid3);

gtk_widget_hide(data->labelHid3Act);

gtk_widget_hide(data->comboboxHid3Act);


gtk_widget_hide(data->labelHid2);

gtk_widget_hide(data->spinbuttonHid2);

gtk_widget_hide(data->labelHid2Act);

gtk_widget_hide(data->comboboxHid2Act);

gtk_widget_show(data->labelHid1);

gtk_widget_show(data->spinbuttonHid1);

gtk_widget_show(data->labelHid1Act);

gtk_widget_show(data->comboboxHid1Act);

break;

default:

gtk_widget_hide(data->labelHid3);

gtk_widget_hide(data->spinbuttonHid3);

gtk_widget_hide(data->labelHid3Act);

gtk_widget_hide(data->comboboxHid3Act);


gtk_widget_hide(data->labelHid2);

gtk_widget_hide(data->spinbuttonHid2);

gtk_widget_hide(data->labelHid2Act);

gtk_widget_hide(data->comboboxHid2Act);

gtk_widget_hide(data->labelHid1);

gtk_widget_hide(data->spinbuttonHid1);

gtk_widget_hide(data->labelHid1Act);

gtk_widget_hide(data->comboboxHid1Act);

break;

}

}

extern "C" G_MODULE_EXPORT void changeLocation(GtkWidget *, ChData * data ){

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxAlgorithm),1);

}

extern "C" G_MODULE_EXPORT void changeAlgorithm(GtkWidget *, ChData * data ){

int act=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxLocation));

switch(act){

case 1:

if(gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxAlgorithm))==0)

error_dialog ((gchar *)"BP not implemented on GPU", GTK_WINDOW(data->windowTrainer));

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxAlgorithm),1);

break;

}

}

extern "C" G_MODULE_EXPORT void cancelTrainingSet(GtkWidget *,  ChData * data ){

gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(data->filechooserbuttonTrainingSet));

gtk_label_set_text(GTK_LABEL(data->labelTrainingSetSize),"0");

if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork))==NULL){

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),0);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),0);

}

}

extern "C" G_MODULE_EXPORT void cancelTestSet(GtkWidget *,  ChData * data ){

gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(data->filechooserbuttonTestSet));

gtk_label_set_text(GTK_LABEL(data->labelTestSetSize),"0");

if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork))==NULL){

if(gtk_label_get_text(GTK_LABEL(data->labelTrainingSetSize))[0]=='0'){

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),0);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),0);

}

}

}

extern "C" G_MODULE_EXPORT void changeTrainingSet(GtkWidget *,  ChData * data ){

FILE * pFile;

char str[80]="";

int in=0,out=0;

int success=0;

pFile = fopen (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTrainingSet)),"r+");

if(pFile!=NULL){

if(fscanf (pFile, "%s", str)<1)success=1;

if(fscanf (pFile, "%d", &in)<1)success=1;

if(fscanf (pFile, "%d", &out)<1)success=1;

fclose (pFile);

if(success==0){

gtk_label_set_text(GTK_LABEL(data->labelTrainingSetSize),str);


if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork))==NULL){

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),in);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),out);

}


return;

}

gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(data->filechooserbuttonTrainingSet));

error_dialog((char *)"Wrong format",GTK_WINDOW(data->windowTrainer));

cancelTrainingSet(NULL,data );

}


}

extern "C" G_MODULE_EXPORT void changeTestSet(GtkWidget *,  ChData * data ){

FILE * pFile;

char str[80]="";

int in=0,out=0;

int success=0;

pFile = fopen (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTestSet)),"r+");


if(pFile!=NULL){

if(fscanf (pFile, "%s", str)<1)success=1;

if(fscanf (pFile, "%d", &in)<1)success=1;

if(fscanf (pFile, "%d", &out)<1)success=1;

fclose (pFile);

if(success==0){

gtk_label_set_text(GTK_LABEL(data->labelTestSetSize),str);

if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork))==NULL){

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),in);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),out);

}

return;

}

gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(data->filechooserbuttonTestSet));

error_dialog((char *)"Wrong format",GTK_WINDOW(data->windowTrainer));

cancelTestSet(NULL,data );

}

}

extern "C" G_MODULE_EXPORT void cancelLoadNetwork(GtkWidget *,  ChData * data ){

gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork));

gtk_widget_set_sensitive(data->spinbuttonNLayers,TRUE);

gtk_widget_set_sensitive(data->spinbuttonInputs,FALSE);

gtk_widget_set_sensitive(data->spinbuttonHid1,TRUE);

gtk_widget_set_sensitive(data->spinbuttonHid2,TRUE);

gtk_widget_set_sensitive(data->spinbuttonHid3,TRUE);

gtk_widget_set_sensitive(data->spinbuttonOutputs,FALSE);

gtk_widget_set_sensitive(data->comboboxInputsAct,FALSE);

gtk_widget_set_sensitive(data->comboboxHid1Act,TRUE);

gtk_widget_set_sensitive(data->comboboxHid2Act,TRUE);

gtk_widget_set_sensitive(data->comboboxHid3Act,TRUE);

gtk_widget_set_sensitive(data->comboboxOutputsAct,TRUE);

changeTestSet(NULL,data);

changeTrainingSet(NULL,data);

}

extern "C" G_MODULE_EXPORT void loadNetwork(GtkWidget *,  ChData * data ){

FILE * pFile;

int nlayers=0,app=0;

int success=0;

pFile = fopen (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork)),"r+");

if(pFile!=NULL){

if(fscanf (pFile, "%d", &nlayers)<1){

success=1;

fclose (pFile);

}

else{

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonNLayers),nlayers);

switch(nlayers){

case 5:

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid1),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid2),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid3),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxInputsAct),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxHid1Act),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxHid2Act),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxHid3Act),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxOutputsAct),app);

break;

case 4:

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid1),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid2),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxInputsAct),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxHid1Act),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxHid2Act),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxOutputsAct),app);

break;

case 3:

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid1),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxInputsAct),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxHid1Act),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxOutputsAct),app);

break;

case 2:

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxInputsAct),app);

if(fscanf (pFile, "%d", &app)<1){success=1;break;}

gtk_combo_box_set_active(GTK_COMBO_BOX(data->comboboxOutputsAct),app);

break;

default:

success=1;break;

}

fclose (pFile);

if(success==0){

gtk_widget_set_sensitive(data->spinbuttonNLayers,FALSE);

gtk_widget_set_sensitive(data->spinbuttonInputs,FALSE);

gtk_widget_set_sensitive(data->spinbuttonHid1,FALSE);

gtk_widget_set_sensitive(data->spinbuttonHid2,FALSE);

gtk_widget_set_sensitive(data->spinbuttonHid3,FALSE);

gtk_widget_set_sensitive(data->spinbuttonOutputs,FALSE);

gtk_widget_set_sensitive(data->comboboxInputsAct,FALSE);

gtk_widget_set_sensitive(data->comboboxHid1Act,FALSE);

gtk_widget_set_sensitive(data->comboboxHid2Act,FALSE);

gtk_widget_set_sensitive(data->comboboxHid3Act,FALSE);

gtk_widget_set_sensitive(data->comboboxOutputsAct,FALSE);

return;

}

}

gtk_file_chooser_unselect_all(GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork));

error_dialog((char *)"Wrong format",GTK_WINDOW(data->windowTrainer));

cancelLoadNetwork(NULL,data );

}

}

void *training(void * d){

ChData * data =(ChData *)d;


if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTestSet))!=NULL){

LearningSet trainingSet(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTrainingSet)));

LearningSet testSet(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTestSet)));



if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork))==NULL){

int NLayers=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonNLayers));

int layers[NLayers];

int functs[NLayers];

switch(NLayers){

case 5:

layers[0]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonInputs));

functs[0]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxInputsAct));

layers[1]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid1));

functs[1]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid1Act));

layers[2]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid2));

functs[2]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid2Act));

layers[3]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid3));

functs[3]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid3Act));

layers[4]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs));

functs[4]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxOutputsAct));

break;

case 4:

layers[0]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonInputs));

functs[0]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxInputsAct));

layers[1]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid1));

functs[1]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid1Act));

layers[2]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid2));

functs[2]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid2Act));

layers[3]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs));

functs[3]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxOutputsAct));

break;

case 3:

layers[0]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonInputs));

functs[0]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxInputsAct));

layers[1]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid1));

functs[1]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid1Act));

layers[2]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs));

functs[2]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxOutputsAct));

break;

case 2:

layers[0]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonInputs));

functs[0]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxInputsAct));

layers[1]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs));

functs[1]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxOutputsAct));

break;

}


network=FeedForwardNN(NLayers,layers,functs);

}

else{

network=FeedForwardNN(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork)));

}

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->checkbuttonNguyenWidrow)))

network.initWidrowNguyen(trainingSet);

FeedForwardNNTrainer trainer;

trainer.selectNet(network);

trainer.selectTrainingSet(trainingSet);

trainer.selectTestSet(testSet);

trainer.selectBestMSETestNet(mseT);

trainer.selectBestMSETrainTestNet(mseTT);

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->checkbuttonClassifier)))

trainer.selectBestClassTestNet(cl);

int shuffle=0;

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->checkbuttonShuffle)))

shuffle=1;


float param[]={

gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxLocation)),

gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxAlgorithm)),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryDesiredError))),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryMaxEpochs))),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryEpochsBetweenReports))),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryLearningRate))),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryMomentum))),

shuffle,

gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxErrorFunction)),

};

gdk_threads_enter ();

gtk_widget_set_sensitive(data->buttonStartTraining,FALSE);

gtk_widget_set_sensitive(data->buttonStopTraining,TRUE);

gdk_threads_leave ();

trainer.train(9,param);


gdk_threads_enter ();

gtk_widget_set_sensitive(data->buttonSaveNetwork,TRUE);

gtk_widget_set_sensitive(data->radiobuttonLast,TRUE);

gtk_widget_set_sensitive(data->radiobuttonBestMSEtest,TRUE);

gtk_widget_set_sensitive(data->radiobuttonBestMSEtraintest,TRUE);

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->checkbuttonClassifier)))

gtk_widget_set_sensitive(data->radiobuttonBestclassifier,TRUE);

gdk_threads_leave ();

}

else{

LearningSet trainingSet(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTrainingSet)));


if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork))==NULL){

int NLayers=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonNLayers));

int layers[NLayers];

int functs[NLayers];

switch(NLayers){

case 5:

layers[0]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonInputs));

functs[0]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxInputsAct));

layers[1]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid1));

functs[1]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid1Act));

layers[2]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid2));

functs[2]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid2Act));

layers[3]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid3));

functs[3]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid3Act));

layers[4]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs));

functs[4]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxOutputsAct));

break;

case 4:

layers[0]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonInputs));

functs[0]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxInputsAct));

layers[1]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid1));

functs[1]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid1Act));

layers[2]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid2));

functs[2]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid2Act));

layers[3]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs));

functs[3]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxOutputsAct));

break;

case 3:

layers[0]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonInputs));

functs[0]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxInputsAct));

layers[1]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonHid1));

functs[1]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxHid1Act));

layers[2]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs));

functs[2]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxOutputsAct));

break;

case 2:

layers[0]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonInputs));

functs[0]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxInputsAct));

layers[1]=gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs));

functs[1]=gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxOutputsAct));

break;

}


network=FeedForwardNN (NLayers,layers,functs);

}

else{

network=FeedForwardNN(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork)));

}

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->checkbuttonNguyenWidrow)))

network.initWidrowNguyen(trainingSet);

FeedForwardNNTrainer trainer;

trainer.selectNet(network);

trainer.selectTrainingSet(trainingSet);

int shuffle=0;

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->checkbuttonShuffle)))

shuffle=1;


float param[]={

gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxLocation)),

gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxAlgorithm)),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryDesiredError))),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryMaxEpochs))),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryEpochsBetweenReports))),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryLearningRate))),

atof(gtk_entry_get_text(GTK_ENTRY(data->entryMomentum))),

shuffle,

gtk_combo_box_get_active(GTK_COMBO_BOX(data->comboboxErrorFunction)),

};


gdk_threads_enter ();

gtk_widget_set_sensitive(data->buttonStartTraining,FALSE);

gtk_widget_set_sensitive(data->buttonStopTraining,TRUE);

gdk_threads_leave ();

trainer.train(9,param);


gdk_threads_enter ();

gtk_widget_set_sensitive(data->buttonSaveNetwork,TRUE);

gtk_widget_set_sensitive(data->radiobuttonLast,TRUE);

gdk_threads_leave ();

}

pthread_exit(NULL);

}

void *listener(void * d){

ChData * data =(ChData *)d;

GtkTextIter iter;


int commpipe[2];


//setup communication pipeline first

if(pipe(commpipe)){

fprintf(stderr,"Pipe error!\n");

exit(1);

}

//saves stdin and stdout to restore after the pipe

int stdin_save, stdout_save;

stdin_save = dup(0);

stdout_save = dup(1);

//replace stdin with the in side of the pipe

dup2(commpipe[0],0);

//replace stdout with out side of the pipe

dup2(commpipe[1],1);

//set non-buffered output on stdout

setvbuf(stdout,(char*)NULL,_IONBF,0);

//from now on printf prints to stdin so i can grab the outputs of training

pthread_create(&trainerThread,(pthread_attr_t *)NULL,training, data);

char str[100];

char * pch;

char * dum;

arraySizeTrain=0;

arraySizeTest=0;


dum=fgets(str,100,stdin);

while(!strstr(str,"Training complete.")){

gdk_threads_enter ();

gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(data->textbufferTraining),&iter);

gtk_text_buffer_insert(GTK_TEXT_BUFFER(data->textbufferTraining),&iter,str,-1);

gtk_text_buffer_get_end_iter(data->textbufferTraining,&iter);

gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(data->textviewTraining),&iter,0.1,FALSE,0.5,0.5);

gdk_threads_leave ();

pch = strtok (str," \t");

while (pch != NULL){

if(strcmp(pch,"Epoch")==0){

pch = strtok (NULL, " \t");

x[arraySizeTrain]=atof(pch);

}

if(strcmp(pch,"Error")==0){

pch = strtok (NULL, " \t");

pch = strtok (NULL, " \t");

if(strcmp(pch,"train")==0){

pch = strtok (NULL, " \t");

pch = strtok (NULL, " \t");

yTrain[arraySizeTrain]=atof(pch);

arraySizeTrain++;

gdk_threads_enter ();

updateDataset(data);

gdk_threads_leave ();

}

if(strcmp(pch,"test")==0){

pch = strtok (NULL, " \t");

pch = strtok (NULL, " \t");

yTest[arraySizeTest]=atof(pch);

arraySizeTest++;

gdk_threads_enter ();

updateDataset(data);

gdk_threads_leave ();

}

}


pch = strtok (NULL, " \t");

}

dum=fgets(str,100,stdin);

}


gdk_threads_enter ();

gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(data->textbufferTraining),&iter);

gtk_text_buffer_insert(GTK_TEXT_BUFFER(data->textbufferTraining),&iter,str,-1);

gtk_text_buffer_get_end_iter(data->textbufferTraining,&iter);

gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(data->textviewTraining),&iter,0.1,FALSE,0.5,0.5);

gdk_threads_leave ();



//restore stdin and stdout

dup2(stdout_save, STDOUT_FILENO);

dup2(stdin_save, STDIN_FILENO);

gdk_threads_enter ();

gtk_widget_set_sensitive(data->buttonStartTraining,TRUE);

gtk_widget_set_sensitive(data->buttonStopTraining,FALSE);

gtk_widget_set_sensitive(data->checkbuttonClassifier,TRUE);


gdk_threads_leave ();


pthread_exit(NULL);

}

extern "C" G_MODULE_EXPORT void startTraining(GtkWidget *,  ChData * data ){

pthread_t threadid;


if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTrainingSet))!=NULL){


FILE * train,* test,* net;

int num=0,trainin=0,trainout=0,testin=0,testout=0,netin=0,netout=0;

int dum=0;

train = fopen (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTrainingSet)),"r+");

dum=fscanf (train, "%d", &num);

dum=fscanf (train, "%d", &trainin);

dum=fscanf (train, "%d", &trainout);

fclose (train);

if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTestSet))!=NULL){

test = fopen (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTestSet)),"r+");

dum=fscanf (test, "%d", &num);

dum=fscanf (test, "%d", &testin);

dum=fscanf (test, "%d", &testout);

fclose (test);

if(trainin!=testin||trainout!=testout){

error_dialog((char *)"Training set and test set of different formats",GTK_WINDOW(data->windowTrainer));

return;

}

}


if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork))!=NULL){

net = fopen (gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonLoadNetwork)),"r+");

dum=fscanf (net, "%d", &num);

dum=fscanf (net, "%d", &netin);

for(int i=1;i<num;i++)

dum=fscanf (net, "%d", &netout);

fclose (net);

if(trainin!=netin||trainout!=netout){

error_dialog((char *)"Training set and loaded network of different formats",GTK_WINDOW(data->windowTrainer));

return;

}

if(gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(data->filechooserbuttonTestSet))!=NULL){

if(testin!=netin||testout!=netout){

error_dialog((char *)"Test set and loaded network of different formats",GTK_WINDOW(data->windowTrainer));

return;

}

}

}


gtk_widget_set_sensitive(data->buttonStartTraining,FALSE);


maxEpochs=atoi(gtk_entry_get_text(GTK_ENTRY(data->entryMaxEpochs)));

epochsBetweenReports=atoi(gtk_entry_get_text(GTK_ENTRY(data->entryEpochsBetweenReports)));

desiredError=atof(gtk_entry_get_text(GTK_ENTRY(data->entryDesiredError)));

if(desiredError<=0)desiredError=MINERROR;


gtk_text_buffer_set_text(GTK_TEXT_BUFFER(data->textbufferTraining),"",-1);


gtk_widget_set_sensitive(data->checkbuttonClassifier,FALSE);

gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(data->radiobuttonLast),TRUE);


gtk_widget_set_sensitive(data->buttonSaveNetwork,FALSE);

gtk_widget_set_sensitive(data->radiobuttonLast,FALSE);

gtk_widget_set_sensitive(data->radiobuttonBestMSEtest,FALSE);

gtk_widget_set_sensitive(data->radiobuttonBestMSEtraintest,FALSE);

gtk_widget_set_sensitive(data->radiobuttonBestclassifier,FALSE);

pthread_create(&threadid,(pthread_attr_t *)NULL,listener, data);

}

else{

error_dialog ((gchar *)"No training set selected", GTK_WINDOW(data->windowTrainer));

}

}

extern "C" G_MODULE_EXPORT void stopTraining(GtkWidget *,  ChData * data){

if(trainerThread>0){

gtk_widget_set_sensitive(data->buttonStopTraining,FALSE);

pthread_kill(trainerThread,SIGINT);

trainerThread=-1;

}

}

extern "C" G_MODULE_EXPORT void saveNetwork(GtkWidget *,  ChData * data ){

GtkWidget *dialog;

dialog = gtk_file_chooser_dialog_new ("Save File",

 GTK_WINDOW(data->windowTrainer),

 GTK_FILE_CHOOSER_ACTION_SAVE,

 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,

 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,

 NULL);

gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);

gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), "network.net");

if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT){

char *filename;

filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->radiobuttonLast)))

network.saveToTxt(filename);

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->radiobuttonBestMSEtest)))

mseT.saveToTxt(filename);

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->radiobuttonBestMSEtraintest)))

mseTT.saveToTxt(filename);

if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(data->radiobuttonBestclassifier)))

cl.saveToTxt(filename);

g_free (filename);

}

gtk_widget_destroy (dialog);

}

extern "C" G_MODULE_EXPORT void on_window_destroy(GtkWidget *, GdkEventExpose *, ChData *){

gtk_main_quit();

}

int main(int argc, char **argv){

ChData     *data;

GtkBuilder *builder;

GError     *error = NULL;

g_thread_init (NULL);

gdk_threads_init ();

gdk_threads_enter ();

/* Init GTK+ */

gtk_init( &argc, &argv );

/* Create new GtkBuilder object */

builder = gtk_builder_new();

if( ! gtk_builder_add_from_file( builder, UI_FILE, &error ) )

{

g_warning( "%s", error->message );

g_free( error );

return( 1 );

}

/* Allocate data structure */

data = g_slice_new( ChData );

/* Get objects from UI */

#define GW( name ) CH_GET_WIDGET( builder, name, data )

GW(windowTrainer);

GW(filechooserbuttonTrainingSet);

GW(filechooserbuttonTestSet);

GW(spinbuttonNLayers);


GW(checkbuttonClassifier);

GW(labelInputs);

GW(spinbuttonInputs);

GW(labelInputsAct);

GW(comboboxInputsAct);

GW(labelHid1);

GW(spinbuttonHid1);

GW(labelHid1Act);

GW(comboboxHid1Act);

GW(labelHid2);

GW(spinbuttonHid2);

GW(labelHid2Act);

GW(comboboxHid2Act);

GW(labelHid3);

GW(spinbuttonHid3);

GW(labelHid3Act);

GW(comboboxHid3Act);

GW(labelOutputs);

GW(spinbuttonOutputs);

GW(labelOutputsAct);

GW(comboboxOutputsAct);

GW(entryDesiredError);

GW(entryMaxEpochs);

GW(entryEpochsBetweenReports);

GW(comboboxLocation);

GW(comboboxAlgorithm);

GW(entryLearningRate);

GW(entryMomentum);

GW(checkbuttonShuffle);

GW(comboboxErrorFunction);

GW(checkbuttonNguyenWidrow);

GW(labelTrainingSetSize);

GW(labelTestSetSize);

GW(filechooserbuttonLoadNetwork);

GW(buttonCancelLoadNetwork);

GW(buttonStartTraining);

GW(buttonStopTraining);


GW(textviewTraining);


CH_GET_OBJECT( builder, textbufferTraining, GTK_TEXT_BUFFER, data );


GW(notebookEvolution);

GW(vboxPlot);



GW(buttonSaveNetwork);

GW(radiobuttonLast);

GW(radiobuttonBestMSEtest);

GW(radiobuttonBestMSEtraintest);

GW(radiobuttonBestclassifier);


#undef GW


/* GtkPlot creation */

GtkWidget *w_plot_canvas, *w_plot;

GtkPlotCanvasChild *child;

GtkPlotAxis *x_axis, *y_axis;

w_plot_canvas = gtk_plot_canvas_new(500,300,1.0);

// Do this in order to have auto resize of plot with window.

GTK_PLOT_CANVAS_UNSET_FLAGS (GTK_PLOT_CANVAS (w_plot_canvas),GTK_PLOT_CANVAS_DND_FLAGS);

GTK_PLOT_CANVAS_SET_FLAGS (GTK_PLOT_CANVAS (w_plot_canvas),GTK_PLOT_CANVAS_CAN_RESIZE);

w_plot = gtk_plot_new(NULL);


gtk_plot_set_range(GTK_PLOT(w_plot), 0, 1000, MINERROR, 1);

gtk_plot_axis_set_ticks(gtk_plot_get_axis(GTK_PLOT(w_plot), GTK_PLOT_AXIS_LEFT),0.1,5);

gtk_plot_axis_set_ticks(gtk_plot_get_axis(GTK_PLOT(w_plot), GTK_PLOT_AXIS_BOTTOM),100,1);

child = gtk_plot_canvas_plot_new(GTK_PLOT(w_plot));

//gtk_plot_canvas_put_child(GTK_PLOT_CANVAS(w_plot_canvas), child,.10, .1, .9, .85);

gtk_plot_canvas_put_child(GTK_PLOT_CANVAS(w_plot_canvas), child,.10, .15, .9, .85);

// Setup the axis



// gtk_plot_set_legends_border(GTK_PLOT(w_plot), (GtkPlotBorderStyle)0, 0);

gtk_plot_legends_move(GTK_PLOT(w_plot),0.8,0.01);

gtk_plot_axis_set_visible(gtk_plot_get_axis(GTK_PLOT(w_plot),GTK_PLOT_AXIS_TOP), FALSE);

gtk_plot_axis_set_visible(gtk_plot_get_axis(GTK_PLOT(w_plot),GTK_PLOT_AXIS_RIGHT), FALSE);

x_axis = gtk_plot_get_axis(GTK_PLOT(w_plot), GTK_PLOT_AXIS_BOTTOM);

y_axis = gtk_plot_get_axis(GTK_PLOT(w_plot), GTK_PLOT_AXIS_LEFT);


gtk_plot_axis_set_labels_style(x_axis,GTK_PLOT_LABEL_FLOAT,0);

gtk_plot_axis_set_labels_style(y_axis,GTK_PLOT_LABEL_POW,0);


gtk_plot_axis_set_title(x_axis, "Epochs");

gtk_plot_axis_hide_title(y_axis);

gtk_plot_x0_set_visible(GTK_PLOT(w_plot), TRUE);

gtk_plot_y0_set_visible(GTK_PLOT(w_plot), TRUE);

gtk_plot_canvas_put_child(GTK_PLOT_CANVAS(w_plot_canvas),gtk_plot_canvas_text_new("Helvetica",12, 0,NULL, NULL,FALSE,GTK_JUSTIFY_CENTER,"MSE"),.10, .1, .20, .20);

gtk_plot_set_yscale(GTK_PLOT(w_plot),GTK_PLOT_SCALE_LOG10);

// Build data and put it in plot

build_start(w_plot);

gtk_widget_show(GTK_WIDGET(w_plot));


g_signal_connect(G_OBJECT(w_plot_canvas), "expose-event",G_CALLBACK(&plot_expose_event), NULL);


data->canvasEvolution=GTK_WIDGET(w_plot_canvas);

data->plotEvolution=w_plot;


gtk_widget_show(GTK_WIDGET(data->canvasEvolution));

gtk_box_pack_start(GTK_BOX(data->vboxPlot), data->canvasEvolution, TRUE, TRUE, 0);


gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonNLayers),2);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonInputs),1);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid1),1);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid2),1);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonHid3),1);

gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->spinbuttonOutputs),1);


/* Connect signals */

gtk_builder_connect_signals( builder, data );

/* Destroy builder, since we don't need it anymore */

g_object_unref( G_OBJECT( builder ) );


/* Show window. All other widgets are automatically shown by GtkBuilder */

gtk_widget_show( data->windowTrainer );

/* Start main loop */

gtk_main();


gdk_threads_leave ();

/* Free any allocated data */

g_slice_free( ChData, data );

return( 0 );

}