00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00047 #include "image.h"
00048 #include "proto2D.h"
00049 #include "lcsom.h"
00050 #include <math.h>
00051 #include <time.h>
00052 #include <stdlib.h>
00053 #include <stdarg.h>
00054
00055
00056
00057
00075 param *csom_lect( csom_t *csom, param *ptp, char *debq)
00076 {
00077 char question[500];
00078
00079
00080 sprintf(question, "%s input_neurons (unsigned int)", debq);
00081 lec_param(question, ptp);
00082 csom->input_neurons = (int)atoi(ptp->rep);
00083 ptp = ptp->next;
00084
00085 sprintf(question, "%s output_neurons (unsigned int)", debq);
00086 lec_param(question, ptp);
00087 csom->output_neurons = (int)atoi(ptp->rep);
00088 ptp = ptp->next;
00089
00090
00091
00092
00093
00094
00095 sprintf(question, "%s max_neigh (unsigned int)", debq);
00096 lec_param(question, ptp);
00097 csom->max_neigh = (int)atoi(ptp->rep);
00098 while ((float)csom->max_neigh>(float)(csom->output_neurons/2.00))
00099 {printf("WARNING: max_neigh must be < %f (output_neurons/2)",(float)(csom->output_neurons/2.00));
00100 sprintf(question, "%s max_neigh (unsigned int)", debq);
00101 lec_param(question, ptp);
00102 csom->max_neigh = (int)atoi(ptp->rep);
00103 }
00104 ptp = ptp->next;
00105
00106 sprintf(question, "%s max_learn_rate (float)", debq);
00107 lec_param(question, ptp);
00108 csom->max_learn_rate = (float)atof(ptp->rep);
00109 ptp = ptp->next;
00110
00111 sprintf(question, "%s max_epoch (unsigned int)", debq);
00112 lec_param(question, ptp);
00113 csom->max_epoch = (int)atoi(ptp->rep);
00114 ptp = ptp->next;
00115
00116 sprintf(question, "%s random init or not? (1/0)", debq);
00117 lec_param(question, ptp);
00118 csom->random_init = (int)atoi(ptp->rep);
00119 ptp = ptp->next;
00120
00121 sprintf(question, "%s rescale the input space or not? (1/0)", debq);
00122 lec_param(question, ptp);
00123 csom->rescale_sw = (int)atoi(ptp->rep);
00124 ptp = ptp->next;
00125
00126 return(ptp);
00127 }
00128
00129
00130
00131
00132
00139 int csom_init(csom_t *csom)
00140 {
00141
00142 unsigned int i,j;
00143
00144
00145 if( (csom->x=(float **)malloc((csom->input_neurons)*sizeof(float*))) == NULL )
00146 {printf ("\n fatal error: a.13 allocation impossible\n"); exit(1);}
00147 if( (csom->x[0]=(float *)malloc((csom->input_neurons)*(csom->element)*sizeof(float))) == NULL )
00148 {printf ("\n fatal error: a.14 allocation impossible\n"); exit(1);}
00149 for (i=1;i<csom->input_neurons;i++)
00150 {csom->x[i]=csom->x[0]+((csom->element)*i);}
00151
00152
00153 if( (csom->w=(float **)malloc((csom->input_neurons)*sizeof(float*))) == NULL )
00154 {printf ("\n fatal error: a.01 allocation impossible\n"); exit(1);}
00155 if( (csom->w[0]=(float *)malloc((csom->input_neurons)*(csom->output_neurons)*sizeof(float))) == NULL )
00156 {printf ("\n fatal error: a.02 allocation impossible\n"); exit(1);}
00157 for (i=1;i<csom->input_neurons;i++)
00158 {csom->w[i]=csom->w[0]+((csom->output_neurons)*i);}
00159
00160
00161 if( (csom->w_new=(float **)malloc((csom->input_neurons)*sizeof(float*))) == NULL )
00162 {printf ("\n fatal error: a.03 allocation impossible\n"); exit(1);}
00163 if( (csom->w_new[0]=(float *)malloc((csom->input_neurons)*(csom->output_neurons)*sizeof(float))) == NULL )
00164 {printf ("\n fatal error: a.04 allocation impossible\n"); exit(1);}
00165 for (i=1;i<csom->input_neurons;i++)
00166 {csom->w_new[i]=csom->w_new[0]+((csom->output_neurons)*i);}
00167
00168
00169 if( (csom->d=(float *)malloc((csom->output_neurons)*sizeof(float))) == NULL)
00170 {printf ("\n fatal error: a.05 allocation impossible\n"); exit(1);}
00171
00172
00173
00174 #ifdef DEBUG
00175 if( (csom->activations=(int *)malloc((csom->output_neurons)*sizeof(int))) == NULL)
00176 {printf ("\n fatal error: a.06 allocation impossible\n"); exit(1);}
00177 #endif
00178
00179 if( (csom->neigh_rate=(float *)malloc((csom->max_epoch)*sizeof(float))) == NULL)
00180 {printf ("\n fatal error: a.07 allocation impossible\n"); exit(1);}
00181 if( (csom->learn_rate=(float *)malloc((csom->max_epoch)*sizeof(float))) == NULL)
00182 {printf ("\n fatal error: a.08 allocation impossible\n"); exit(1);}
00183 if( (csom->csom_out=(int *)malloc((csom->element)*sizeof(int))) == NULL)
00184 {printf ("\n fatal error: a.09 allocation impossible\n"); exit(1);}
00185
00186
00187 for (i=0;i<csom->max_epoch;i++)
00188 {csom->neigh_rate[i]=ceil((float)-(csom->max_neigh*1.00/csom->max_epoch*1.00)*i*1.00 + csom->max_neigh);}
00189
00190 csom->neigh_rate[csom->max_epoch-1]=1;
00191
00192
00193 for (i=0;i<csom->max_epoch;i++) { csom->learn_rate[i]=csom->max_learn_rate*(pow((0.01/csom->max_learn_rate),((float)i/csom->max_epoch)));}
00194
00195
00196
00197 srand((unsigned int) time(NULL));
00198
00199 for (i=0;i<csom->output_neurons;i++)
00200 {
00201 if (csom->random_init)
00202 {for (j=0;j<csom->input_neurons;j++)
00203 {csom->w[j][i]=(int)(255 *(double)rand() / RAND_MAX);}
00204 }
00205 else
00206 {for (j=0;j<csom->input_neurons;j++)
00207 {csom->w[j][i]=(float)i*254.00/csom->output_neurons;}
00208 }
00209 }
00210
00211 return 0;
00212 }
00213
00214
00221 int csom_calc(csom_t *csom)
00222 {
00224 int i,j;
00226 float d_min;
00228 int winner=0;
00230 int winner_df;
00232 char keep_training;
00234 int vector_no;
00236 int st,dr;
00238 float min_input,max_input,rescale_factor;
00239
00240
00241 csom->epoch=0;
00242 keep_training=1;
00243
00244
00245 if (csom->rescale_sw)
00246 {
00247 for (j=0;j<csom->input_neurons;j++)
00248 {max_input=csom->x[j][0];
00249 min_input=csom->x[j][0];
00250 for (i=1;i<csom->element;i++)
00251 {if (csom->x[j][i]>max_input) {max_input=csom->x[j][i];}
00252 if (csom->x[j][i]<min_input) {min_input=csom->x[j][i];}
00253 }
00254 rescale_factor=255.00/(max_input-min_input);
00255 for (i=0;i<csom->element;i++)
00256 {csom->x[j][i]=csom->x[j][i]*rescale_factor;}
00257 }
00258 }
00259
00260 while (keep_training)
00261 {
00262
00263
00264
00265
00266
00267
00268
00269
00270 csom->evolution=0;
00271 #ifdef DEBUG
00272 for (j=0;j<csom->output_neurons;j++) {csom->activations[j]=0;}
00273 #endif
00274 for (vector_no=0; vector_no<csom->element; vector_no++)
00275 {d_min=99999999.99;
00276 csom->element_current=vector_no;
00277
00278 for (j=0;j<csom->output_neurons;j++)
00279 {
00280 csom->d[j]=0;
00281 {for (i=0;i<csom->input_neurons;i++)
00282 {csom->d[j]+=(csom->x[i][vector_no] - csom->w[i][j])*(csom->x[i][vector_no] - csom->w[i][j]);}
00283 }
00284
00285 if (csom->d[j]<d_min) {d_min=csom->d[j]; winner=j;}
00286 }
00287
00288 csom->csom_out[csom->element_current]=winner;
00289 #ifdef DEBUG
00290 csom->activations[winner]++;
00291 #endif
00292
00293
00294 winner_df=0;
00295 st=winner;
00296 dr=winner;
00297
00298
00299 while (winner_df<csom->neigh_rate[csom->epoch])
00300 {
00301 for (i=0;i<csom->input_neurons;i++)
00302 {
00303
00304 csom->w_new[i][dr]=csom->w[i][dr]+csom->learn_rate[csom->epoch]*(1-(winner_df*1.000000001/csom->neigh_rate[csom->epoch]))*(csom->x[i][vector_no]-csom->w[i][dr]);
00305 #ifdef DEBUG
00306 csom->evolution+=pow(csom->w_new[i][dr]-csom->w[i][dr],2);
00307 #endif
00308 csom->w[i][dr]=csom->w_new[i][dr];
00309
00310
00311 csom->w_new[i][st]=csom->w[i][st]+csom->learn_rate[csom->epoch]*(1-(winner_df*1.000000001/csom->neigh_rate[csom->epoch]))*(csom->x[i][vector_no]-csom->w[i][st]);
00312 #ifdef DEBUG
00313 csom->evolution+=pow(csom->w_new[i][st]-csom->w[i][st],2);
00314 #endif
00315 csom->w[i][st]=csom->w_new[i][st];
00316 }
00317
00318 if (st==0) {st=csom->output_neurons;}
00319 if (dr==csom->output_neurons-1) {dr=-1;}
00320
00321 st--; dr++; winner_df++;
00322 }
00323 }
00324
00325 csom->epoch++;
00326 #ifdef DEBUG
00327 printf("epoch %d\n",csom->epoch);
00328 #endif
00329
00330 if (csom->epoch>=csom->max_epoch) {keep_training=0;}
00331 }
00332
00333
00334 return 0;
00335 }
00336
00337
00338
00344 int csom_destruct(csom_t *csom)
00345 {
00346
00347
00348
00349 free (csom->x[0]);
00350 free (csom->x);
00351
00352
00353
00354 free (csom->w[0]);
00355 free (csom->w);
00356 csom->w=NULL;
00357
00358
00359
00360 free (csom->w_new[0]);
00361 free (csom->w_new); csom->w_new=NULL;
00362
00363
00364 free(csom->d); csom->d=NULL;
00365
00366 #ifdef DEBUG
00367
00368 free(csom->activations); csom->activations=NULL;
00369 #endif
00370
00371
00372 free(csom->neigh_rate); csom->neigh_rate=NULL;
00373
00374
00375 free(csom->learn_rate); csom->learn_rate=NULL;
00376
00377
00378 free(csom->csom_out); csom->csom_out=NULL;
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 return 0;
00393 }
00394
00395
00396
00404 int imau1tocsomvect(float **data, int nb_attr, ...)
00405 {
00406
00407 int i,j,k;
00408 va_list ap;
00409 imau1 imag;
00410
00411 va_start(ap, nb_attr);
00412
00413 for (i=0; i<nb_attr; i++)
00414 {
00415 imag=va_arg(ap, imau1);
00416 for(j=0; j<imag.nr; j++)
00417 for(k=0; k<imag.nc; k++)
00418 {data[i][k+j*imag.nc]=(float)imag.p[j][k]*1.00;}
00419 }
00420
00421 va_end(ap);
00422 return 0;
00423 }
00424
00425
00426
00435 int csomvecttoimau1(csom_t *csom, int dimX, int dimY, imau1 *imres)
00436 {
00437 unsigned char *colormap;
00438 int eticheta;
00439 int i,j;
00440
00441 if( (colormap=(unsigned char *)malloc((csom->output_neurons)*sizeof(unsigned char))) == NULL)
00442 {printf ("\n fatal error: a.05 allocation impossible\n"); exit(1);}
00443
00444
00445
00446 for (i=0;i<csom->output_neurons;i++) {colormap[i]=floor(i*254/(csom->output_neurons-1));}
00447
00448 imres->nc = dimX;
00449 imres->nr = dimY;
00450 sprintf(imres->nom, "csom_out");
00451
00452 alloc_imau1(imres);
00453
00454 for(j=0; j<imres->nr; j++)
00455 for(i=0; i<imres->nc; i++)
00456 {eticheta=csom->csom_out[i+j*imres->nc];
00457 imres->p[j][i] = colormap[eticheta];
00458 }
00459
00460 free(colormap);
00461 colormap=NULL;
00462 return 0;
00463 }
00464
00465