| 588 | } |
| 589 | |
| 590 | void test_batch_normalize_conv() |
| 591 | { |
| 592 | using namespace dlib::tt; |
| 593 | print_spinner(); |
| 594 | resizable_tensor src(5,5,4,4), gamma, beta, dest, dest2, dest3, means, vars, gradient_input(5,5,4,4); |
| 595 | tt::tensor_rand rnd; |
| 596 | rnd.fill_gaussian(src,10); |
| 597 | rnd.fill_gaussian(gradient_input); |
| 598 | gamma = matrix_cast<float>(gaussian_randm(1,5, 1)); |
| 599 | beta = matrix_cast<float>(gaussian_randm(1,5, 2)); |
| 600 | |
| 601 | gamma = 1; |
| 602 | beta = 0; |
| 603 | |
| 604 | resizable_tensor running_means; |
| 605 | resizable_tensor running_variances; |
| 606 | batch_normalize_conv(DEFAULT_BATCH_NORM_EPS,dest, means, vars, 1, running_means, running_variances, src, gamma, beta); |
| 607 | const double scale = (src.num_samples()*src.nr()*src.nc())/(src.num_samples()*src.nr()*src.nc()-1.0); |
| 608 | // Turn back into biased variance estimate because that's how |
| 609 | // batch_normalize_conv() works, so if we want to match it this is necessary. |
| 610 | running_variances = mat(running_variances)/scale; |
| 611 | batch_normalize_conv_inference(DEFAULT_BATCH_NORM_EPS,dest2, src, gamma, beta, running_means, running_variances); |
| 612 | DLIB_TEST(max(abs(mat(dest2)-mat(dest))) < 1e-5); |
| 613 | cpu::batch_normalize_conv_inference(DEFAULT_BATCH_NORM_EPS,dest3, src, gamma, beta, running_means, running_variances); |
| 614 | DLIB_TEST(max(abs(mat(dest3)-mat(dest))) < 1e-5); |
| 615 | |
| 616 | |
| 617 | auto grad_src = [&](long idx) { |
| 618 | auto f = [&](float eps) { |
| 619 | const float old = src.host()[idx]; |
| 620 | src.host()[idx] += eps; |
| 621 | batch_normalize_conv(DEFAULT_BATCH_NORM_EPS,dest, means, vars, 1, running_means, running_variances, src, gamma, beta); |
| 622 | float result = dot(gradient_input, dest); |
| 623 | src.host()[idx] = old; |
| 624 | return result; |
| 625 | }; |
| 626 | const float eps = 0.01; |
| 627 | return (f(+eps)-f(-eps))/(2*eps); |
| 628 | }; |
| 629 | auto grad_gamma = [&](long idx) { |
| 630 | auto f = [&](float eps) { |
| 631 | const float old = gamma.host()[idx]; |
| 632 | gamma.host()[idx] += eps; |
| 633 | batch_normalize_conv(DEFAULT_BATCH_NORM_EPS,dest, means, vars, 1, running_means, running_variances, src, gamma, beta); |
| 634 | float result = dot(gradient_input, dest); |
| 635 | gamma.host()[idx] = old; |
| 636 | return result; |
| 637 | }; |
| 638 | const float eps = 0.01; |
| 639 | return (f(+eps)-f(-eps))/(2*eps); |
| 640 | }; |
| 641 | auto grad_beta = [&](long idx) { |
| 642 | auto f = [&](float eps) { |
| 643 | const float old = beta.host()[idx]; |
| 644 | beta.host()[idx] += eps; |
| 645 | batch_normalize_conv(DEFAULT_BATCH_NORM_EPS,dest, means, vars, 1, running_means, running_variances, src, gamma, beta); |
| 646 | float result = dot(gradient_input, dest); |
| 647 | beta.host()[idx] = old; |
no test coverage detected