@@ -135,7 +135,7 @@ class ANN_MLPImpl : public ANN_MLP
135
135
136
136
void setActivationFunction (int _activ_func, double _f_param1, double _f_param2 )
137
137
{
138
- if ( _activ_func < 0 || _activ_func > GAUSSIAN )
138
+ if ( _activ_func < 0 || _activ_func > LEAKYRELU )
139
139
CV_Error ( CV_StsOutOfRange, " Unknown activation function" );
140
140
141
141
activ_func = _activ_func;
@@ -153,11 +153,23 @@ class ANN_MLPImpl : public ANN_MLP
153
153
case GAUSSIAN:
154
154
max_val = 1 .; min_val = 0.05 ;
155
155
max_val1 = 1 .; min_val1 = 0.02 ;
156
- if ( fabs (_f_param1) < FLT_EPSILON )
156
+ if ( fabs (_f_param1) < FLT_EPSILON)
157
157
_f_param1 = 1 .;
158
- if ( fabs (_f_param2) < FLT_EPSILON )
158
+ if ( fabs (_f_param2) < FLT_EPSILON)
159
159
_f_param2 = 1 .;
160
160
break ;
161
+ case RELU:
162
+ if (fabs (_f_param1) < FLT_EPSILON)
163
+ _f_param1 = 1 ;
164
+ min_val = max_val = min_val1 = max_val1 = 0 .;
165
+ _f_param2 = 0 .;
166
+ break ;
167
+ case LEAKYRELU:
168
+ if (fabs (_f_param1) < FLT_EPSILON)
169
+ _f_param1 = 0.01 ;
170
+ min_val = max_val = min_val1 = max_val1 = 0 .;
171
+ _f_param2 = 0 .;
172
+ break ;
161
173
default :
162
174
min_val = max_val = min_val1 = max_val1 = 0 .;
163
175
_f_param1 = 1 .;
@@ -368,140 +380,194 @@ class ANN_MLPImpl : public ANN_MLP
368
380
}
369
381
}
370
382
371
- void calc_activ_func ( Mat& sums, const Mat& w ) const
383
+ void calc_activ_func (Mat& sums, const Mat& w) const
372
384
{
373
- const double * bias = w.ptr <double >(w.rows - 1 );
385
+ const double * bias = w.ptr <double >(w.rows - 1 );
374
386
int i, j, n = sums.rows , cols = sums.cols ;
375
387
double scale = 0 , scale2 = f_param2;
376
388
377
- switch ( activ_func )
389
+ switch ( activ_func)
378
390
{
379
- case IDENTITY:
380
- scale = 1 .;
381
- break ;
382
- case SIGMOID_SYM:
383
- scale = -f_param1;
384
- break ;
385
- case GAUSSIAN:
386
- scale = -f_param1*f_param1;
387
- break ;
388
- default :
389
- ;
391
+ case IDENTITY:
392
+ scale = 1 .;
393
+ break ;
394
+ case SIGMOID_SYM:
395
+ scale = -f_param1;
396
+ break ;
397
+ case GAUSSIAN:
398
+ scale = -f_param1*f_param1;
399
+ break ;
400
+ case RELU:
401
+ scale = 1 ;
402
+ break ;
403
+ case LEAKYRELU:
404
+ scale = 1 ;
405
+ break ;
406
+ default :
407
+ ;
390
408
}
391
409
392
- CV_Assert ( sums.isContinuous () );
410
+ CV_Assert (sums.isContinuous ());
393
411
394
- if ( activ_func != GAUSSIAN )
412
+ if ( activ_func != GAUSSIAN)
395
413
{
396
- for ( i = 0 ; i < n; i++ )
414
+ for ( i = 0 ; i < n; i++)
397
415
{
398
416
double * data = sums.ptr <double >(i);
399
- for ( j = 0 ; j < cols; j++ )
417
+ for (j = 0 ; j < cols; j++)
418
+ {
400
419
data[j] = (data[j] + bias[j])*scale;
420
+ if (activ_func == RELU)
421
+ if (data[j] < 0 )
422
+ data[j] = 0 ;
423
+ if (activ_func == LEAKYRELU)
424
+ if (data[j] < 0 )
425
+ data[j] *= f_param1;
426
+ }
401
427
}
402
428
403
- if ( activ_func == IDENTITY )
429
+ if ( activ_func == IDENTITY || activ_func == RELU || activ_func == LEAKYRELU )
404
430
return ;
405
431
}
406
432
else
407
433
{
408
- for ( i = 0 ; i < n; i++ )
434
+ for ( i = 0 ; i < n; i++)
409
435
{
410
436
double * data = sums.ptr <double >(i);
411
- for ( j = 0 ; j < cols; j++ )
437
+ for ( j = 0 ; j < cols; j++)
412
438
{
413
439
double t = data[j] + bias[j];
414
440
data[j] = t*t*scale;
415
441
}
416
442
}
417
443
}
418
444
419
- exp ( sums, sums );
445
+ exp (sums, sums);
420
446
421
- if ( sums.isContinuous () )
447
+ if ( sums.isContinuous ())
422
448
{
423
449
cols *= n;
424
450
n = 1 ;
425
451
}
426
452
427
- switch ( activ_func )
453
+ switch ( activ_func)
428
454
{
429
- case SIGMOID_SYM:
430
- for ( i = 0 ; i < n; i++ )
455
+ case SIGMOID_SYM:
456
+ for (i = 0 ; i < n; i++)
457
+ {
458
+ double * data = sums.ptr <double >(i);
459
+ for (j = 0 ; j < cols; j++)
431
460
{
432
- double * data = sums.ptr <double >(i);
433
- for ( j = 0 ; j < cols; j++ )
461
+ if (!cvIsInf (data[j]))
434
462
{
435
- if (!cvIsInf (data[j]))
436
- {
437
- double t = scale2*(1 . - data[j])/(1 . + data[j]);
438
- data[j] = t;
439
- }
440
- else
441
- {
442
- data[j] = -scale2;
443
- }
463
+ double t = scale2*(1 . - data[j]) / (1 . + data[j]);
464
+ data[j] = t;
465
+ }
466
+ else
467
+ {
468
+ data[j] = -scale2;
444
469
}
445
470
}
446
- break ;
471
+ }
472
+ break ;
447
473
448
- case GAUSSIAN:
449
- for ( i = 0 ; i < n; i++ )
450
- {
451
- double * data = sums.ptr <double >(i);
452
- for ( j = 0 ; j < cols; j++ )
453
- data[j] = scale2*data[j];
454
- }
455
- break ;
474
+ case GAUSSIAN:
475
+ for ( i = 0 ; i < n; i++)
476
+ {
477
+ double * data = sums.ptr <double >(i);
478
+ for ( j = 0 ; j < cols; j++)
479
+ data[j] = scale2*data[j];
480
+ }
481
+ break ;
456
482
457
- default :
458
- ;
483
+ default :
484
+ ;
459
485
}
460
486
}
461
487
462
- void calc_activ_func_deriv ( Mat& _xf, Mat& _df, const Mat& w ) const
488
+ void calc_activ_func_deriv (Mat& _xf, Mat& _df, const Mat& w) const
463
489
{
464
- const double * bias = w.ptr <double >(w.rows - 1 );
490
+ const double * bias = w.ptr <double >(w.rows - 1 );
465
491
int i, j, n = _xf.rows , cols = _xf.cols ;
466
492
467
- if ( activ_func == IDENTITY )
493
+ if ( activ_func == IDENTITY)
468
494
{
469
- for ( i = 0 ; i < n; i++ )
495
+ for ( i = 0 ; i < n; i++)
470
496
{
471
497
double * xf = _xf.ptr <double >(i);
472
498
double * df = _df.ptr <double >(i);
473
499
474
- for ( j = 0 ; j < cols; j++ )
500
+ for ( j = 0 ; j < cols; j++)
475
501
{
476
502
xf[j] += bias[j];
477
503
df[j] = 1 ;
478
504
}
479
505
}
480
506
}
481
- else if ( activ_func == GAUSSIAN )
507
+ else if (activ_func == RELU)
508
+ {
509
+ for (i = 0 ; i < n; i++)
510
+ {
511
+ double * xf = _xf.ptr <double >(i);
512
+ double * df = _df.ptr <double >(i);
513
+
514
+ for (j = 0 ; j < cols; j++)
515
+ {
516
+ xf[j] += bias[j];
517
+ if (xf[j] < 0 )
518
+ {
519
+ xf[j] = 0 ;
520
+ df[j] = 0 ;
521
+ }
522
+ else
523
+ df[j] = 1 ;
524
+ }
525
+ }
526
+ }
527
+ else if (activ_func == LEAKYRELU)
528
+ {
529
+ for (i = 0 ; i < n; i++)
530
+ {
531
+ double * xf = _xf.ptr <double >(i);
532
+ double * df = _df.ptr <double >(i);
533
+
534
+ for (j = 0 ; j < cols; j++)
535
+ {
536
+ xf[j] += bias[j];
537
+ if (xf[j] < 0 )
538
+ {
539
+ xf[j] = f_param1*xf[j];
540
+ df[j] = f_param1;
541
+ }
542
+ else
543
+ df[j] = 1 ;
544
+ }
545
+ }
546
+ }
547
+ else if (activ_func == GAUSSIAN)
482
548
{
483
549
double scale = -f_param1*f_param1;
484
550
double scale2 = scale*f_param2;
485
- for ( i = 0 ; i < n; i++ )
551
+ for ( i = 0 ; i < n; i++)
486
552
{
487
553
double * xf = _xf.ptr <double >(i);
488
554
double * df = _df.ptr <double >(i);
489
555
490
- for ( j = 0 ; j < cols; j++ )
556
+ for ( j = 0 ; j < cols; j++)
491
557
{
492
558
double t = xf[j] + bias[j];
493
- df[j] = t* 2 * scale2;
559
+ df[j] = t * 2 * scale2;
494
560
xf[j] = t*t*scale;
495
561
}
496
562
}
497
- exp ( _xf, _xf );
563
+ exp (_xf, _xf);
498
564
499
- for ( i = 0 ; i < n; i++ )
565
+ for ( i = 0 ; i < n; i++)
500
566
{
501
567
double * xf = _xf.ptr <double >(i);
502
568
double * df = _df.ptr <double >(i);
503
569
504
- for ( j = 0 ; j < cols; j++ )
570
+ for ( j = 0 ; j < cols; j++)
505
571
df[j] *= xf[j];
506
572
}
507
573
}
@@ -510,34 +576,34 @@ class ANN_MLPImpl : public ANN_MLP
510
576
double scale = f_param1;
511
577
double scale2 = f_param2;
512
578
513
- for ( i = 0 ; i < n; i++ )
579
+ for ( i = 0 ; i < n; i++)
514
580
{
515
581
double * xf = _xf.ptr <double >(i);
516
582
double * df = _df.ptr <double >(i);
517
583
518
- for ( j = 0 ; j < cols; j++ )
584
+ for ( j = 0 ; j < cols; j++)
519
585
{
520
586
xf[j] = (xf[j] + bias[j])*scale;
521
587
df[j] = -fabs (xf[j]);
522
588
}
523
589
}
524
590
525
- exp ( _df, _df );
591
+ exp (_df, _df);
526
592
527
593
// ((1+exp(-ax))^-1)'=a*((1+exp(-ax))^-2)*exp(-ax);
528
594
// ((1-exp(-ax))/(1+exp(-ax)))'=(a*exp(-ax)*(1+exp(-ax)) + a*exp(-ax)*(1-exp(-ax)))/(1+exp(-ax))^2=
529
595
// 2*a*exp(-ax)/(1+exp(-ax))^2
530
- scale *= 2 * f_param2;
531
- for ( i = 0 ; i < n; i++ )
596
+ scale *= 2 * f_param2;
597
+ for ( i = 0 ; i < n; i++)
532
598
{
533
599
double * xf = _xf.ptr <double >(i);
534
600
double * df = _df.ptr <double >(i);
535
601
536
- for ( j = 0 ; j < cols; j++ )
602
+ for ( j = 0 ; j < cols; j++)
537
603
{
538
604
int s0 = xf[j] > 0 ? 1 : -1 ;
539
- double t0 = 1 ./ (1 . + df[j]);
540
- double t1 = scale*df[j]* t0*t0;
605
+ double t0 = 1 . / (1 . + df[j]);
606
+ double t1 = scale*df[j] * t0*t0;
541
607
t0 *= scale2*(1 . - df[j])*s0;
542
608
df[j] = t1;
543
609
xf[j] = t0;
@@ -1110,7 +1176,9 @@ class ANN_MLPImpl : public ANN_MLP
1110
1176
{
1111
1177
const char * activ_func_name = activ_func == IDENTITY ? " IDENTITY" :
1112
1178
activ_func == SIGMOID_SYM ? " SIGMOID_SYM" :
1113
- activ_func == GAUSSIAN ? " GAUSSIAN" : 0 ;
1179
+ activ_func == GAUSSIAN ? " GAUSSIAN" :
1180
+ activ_func == RELU ? " RELU" :
1181
+ activ_func == LEAKYRELU ? " LEAKYRELU" : 0 ;
1114
1182
1115
1183
if ( activ_func_name )
1116
1184
fs << " activation_function" << activ_func_name;
@@ -1191,6 +1259,8 @@ class ANN_MLPImpl : public ANN_MLP
1191
1259
{
1192
1260
activ_func = activ_func_name == " SIGMOID_SYM" ? SIGMOID_SYM :
1193
1261
activ_func_name == " IDENTITY" ? IDENTITY :
1262
+ activ_func_name == " RELU" ? RELU :
1263
+ activ_func_name == " LEAKYRELU" ? LEAKYRELU :
1194
1264
activ_func_name == " GAUSSIAN" ? GAUSSIAN : -1 ;
1195
1265
CV_Assert ( activ_func >= 0 );
1196
1266
}
0 commit comments