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 );
}