| 466 | } |
| 467 | |
| 468 | void batch_normalize_gradient( |
| 469 | const double eps, |
| 470 | const tensor& gradient_input, |
| 471 | const tensor& means, |
| 472 | const tensor& invstds, |
| 473 | const tensor& src, |
| 474 | const tensor& gamma, |
| 475 | tensor& src_grad, |
| 476 | tensor& gamma_grad, |
| 477 | tensor& beta_grad |
| 478 | ) |
| 479 | { |
| 480 | const long num = src.k()*src.nr()*src.nc(); |
| 481 | DLIB_CASSERT(src.num_samples() > 1); |
| 482 | DLIB_CASSERT(num == (long)means.size()); |
| 483 | DLIB_CASSERT(num == (long)invstds.size()); |
| 484 | DLIB_CASSERT(num == (long)gamma.size()); |
| 485 | DLIB_CASSERT(num == (long)gamma_grad.size()); |
| 486 | DLIB_CASSERT(num == (long)beta_grad.size()); |
| 487 | DLIB_CASSERT(have_same_dimensions(gradient_input, src)); |
| 488 | DLIB_CASSERT(have_same_dimensions(gradient_input, src_grad)); |
| 489 | DLIB_CASSERT(eps > 0); |
| 490 | |
| 491 | const float in_scale = 1; |
| 492 | const float out_scale = 1; |
| 493 | const float in_scale_params = 1; |
| 494 | const float out_scale_params = 0; |
| 495 | |
| 496 | CHECK_CUDNN(cudnnBatchNormalizationBackward( |
| 497 | context(), |
| 498 | CUDNN_BATCHNORM_PER_ACTIVATION, |
| 499 | &in_scale, |
| 500 | &out_scale, |
| 501 | &in_scale_params, |
| 502 | &out_scale_params, |
| 503 | descriptor(src), |
| 504 | src.device(), |
| 505 | descriptor(gradient_input), |
| 506 | gradient_input.device(), |
| 507 | descriptor(src_grad), |
| 508 | src_grad.device(), |
| 509 | descriptor(gamma), |
| 510 | gamma.device(), |
| 511 | gamma_grad.device(), |
| 512 | beta_grad.device(), |
| 513 | eps, |
| 514 | means.device(), |
| 515 | invstds.device())); |
| 516 | } |
| 517 | |
| 518 | // ------------------------------------------------------------------------------------ |
| 519 |
nothing calls this directly
no test coverage detected