| 503 | } |
| 504 | |
| 505 | void test_batch_normalize() |
| 506 | { |
| 507 | using namespace dlib::tt; |
| 508 | print_spinner(); |
| 509 | resizable_tensor src, gamma, beta, dest, dest2, dest3, means, vars, gradient_input; |
| 510 | src = matrix_cast<float>(gaussian_randm(5,5, 0) + 10); |
| 511 | gamma = matrix_cast<float>(gaussian_randm(1,5, 1)); |
| 512 | beta = matrix_cast<float>(gaussian_randm(1,5, 2)); |
| 513 | gradient_input = matrix_cast<float>(gaussian_randm(5,5, 3)); |
| 514 | |
| 515 | gamma = 1; |
| 516 | beta = 0; |
| 517 | |
| 518 | resizable_tensor running_means; |
| 519 | resizable_tensor running_variances; |
| 520 | batch_normalize(DEFAULT_BATCH_NORM_EPS,dest, means, vars, 1, running_means, running_variances, src, gamma, beta); |
| 521 | const double scale = (src.num_samples())/(src.num_samples()-1.0); |
| 522 | // Turn back into biased variance estimate because that's how batch_normalize() works, so if we want to match it this is necessary. |
| 523 | running_variances = mat(running_variances)/scale; |
| 524 | batch_normalize_inference(DEFAULT_BATCH_NORM_EPS,dest2, src, gamma, beta, running_means, running_variances); |
| 525 | DLIB_TEST_MSG(max(abs(mat(dest2)-mat(dest))) < 1e-5, max(abs(mat(dest2)-mat(dest)))); |
| 526 | cpu::batch_normalize_inference(DEFAULT_BATCH_NORM_EPS,dest3, src, gamma, beta, running_means, running_variances); |
| 527 | DLIB_TEST_MSG(max(abs(mat(dest3)-mat(dest))) < 1e-5, max(abs(mat(dest3)-mat(dest)))); |
| 528 | |
| 529 | |
| 530 | auto grad_src = [&](long idx) { |
| 531 | auto f = [&](float eps) { |
| 532 | const float old = src.host()[idx]; |
| 533 | src.host()[idx] += eps; |
| 534 | batch_normalize(DEFAULT_BATCH_NORM_EPS,dest, means, vars, 1, running_means, running_variances, src, gamma, beta); |
| 535 | float result = dot(gradient_input, dest); |
| 536 | src.host()[idx] = old; |
| 537 | return result; |
| 538 | }; |
| 539 | const float eps = 0.01; |
| 540 | return (f(+eps)-f(-eps))/(2*eps); |
| 541 | }; |
| 542 | auto grad_gamma = [&](long idx) { |
| 543 | auto f = [&](float eps) { |
| 544 | const float old = gamma.host()[idx]; |
| 545 | gamma.host()[idx] += eps; |
| 546 | batch_normalize(DEFAULT_BATCH_NORM_EPS,dest, means, vars, 1, running_means, running_variances, src, gamma, beta); |
| 547 | float result = dot(gradient_input, dest); |
| 548 | gamma.host()[idx] = old; |
| 549 | return result; |
| 550 | }; |
| 551 | const float eps = 0.01; |
| 552 | return (f(+eps)-f(-eps))/(2*eps); |
| 553 | }; |
| 554 | auto grad_beta = [&](long idx) { |
| 555 | auto f = [&](float eps) { |
| 556 | const float old = beta.host()[idx]; |
| 557 | beta.host()[idx] += eps; |
| 558 | batch_normalize(DEFAULT_BATCH_NORM_EPS,dest, means, vars, 1, running_means, running_variances, src, gamma, beta); |
| 559 | float result = dot(gradient_input, dest); |
| 560 | beta.host()[idx] = old; |
| 561 | return result; |
| 562 | }; |
no test coverage detected