You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

layernorm.cpp 4.3 kB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // Tencent is pleased to support the open source community by making ncnn available.
  2. //
  3. // Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
  4. //
  5. // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
  6. // in compliance with the License. You may obtain a copy of the License at
  7. //
  8. // https://opensource.org/licenses/BSD-3-Clause
  9. //
  10. // Unless required by applicable law or agreed to in writing, software distributed
  11. // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  12. // CONDITIONS OF ANY KIND, either express or implied. See the License for the
  13. // specific language governing permissions and limitations under the License.
  14. #include "layernorm.h"
  15. #include <math.h>
  16. namespace ncnn {
  17. LayerNorm::LayerNorm()
  18. {
  19. one_blob_only = true;
  20. support_inplace = true;
  21. }
  22. int LayerNorm::load_param(const ParamDict& pd)
  23. {
  24. affine_size = pd.get(0, 0);
  25. eps = pd.get(1, 0.001f);
  26. affine = pd.get(2, 1);
  27. return 0;
  28. }
  29. int LayerNorm::load_model(const ModelBin& mb)
  30. {
  31. if (affine == 0)
  32. return 0;
  33. gamma_data = mb.load(affine_size, 1);
  34. if (gamma_data.empty())
  35. return -100;
  36. beta_data = mb.load(affine_size, 1);
  37. if (beta_data.empty())
  38. return -100;
  39. return 0;
  40. }
  41. int LayerNorm::forward_inplace(Mat& bottom_top_blob, const Option& opt) const
  42. {
  43. // x = (x - mean) / sqrt(var + eps) * gamma + beta
  44. int dims = bottom_top_blob.dims;
  45. if (dims == 2)
  46. {
  47. int w = bottom_top_blob.w;
  48. int h = bottom_top_blob.h;
  49. // assert affine_size == w
  50. #pragma omp parallel for num_threads(opt.num_threads)
  51. for (int i = 0; i < h; i++)
  52. {
  53. float* ptr = bottom_top_blob.row(i);
  54. // mean and var
  55. float sum = 0.f;
  56. float sqsum = 0.f;
  57. for (int j = 0; j < w; j++)
  58. {
  59. sum += ptr[j];
  60. //sqsum += ptr[j] * ptr[j];
  61. }
  62. float mean = sum / w;
  63. float tmp = 0.f;
  64. for (int j = 0; j < w; j++)
  65. {
  66. tmp = ptr[j] - mean;
  67. sqsum += tmp * tmp;
  68. }
  69. float var = sqsum / w;
  70. // the var maybe minus due to accuracy
  71. //float var = sqsum / w - mean * mean;
  72. float a = static_cast<float>(1.f / (sqrt(var + eps)));
  73. float b = -mean * a;
  74. if (affine)
  75. {
  76. for (int j = 0; j < w; j++)
  77. {
  78. ptr[j] = (ptr[j] * a + b) * gamma_data[j] + beta_data[j];
  79. }
  80. }
  81. else
  82. {
  83. for (int j = 0; j < w; j++)
  84. {
  85. ptr[j] = ptr[j] * a + b;
  86. }
  87. }
  88. }
  89. }
  90. if (dims == 3)
  91. {
  92. int w = bottom_top_blob.w;
  93. int h = bottom_top_blob.h;
  94. int channels = bottom_top_blob.c;
  95. int size = w * h;
  96. // assert affine_size == size
  97. #pragma omp parallel for num_threads(opt.num_threads)
  98. for (int q = 0; q < channels; q++)
  99. {
  100. float* ptr = bottom_top_blob.channel(q);
  101. // mean and var
  102. float sum = 0.f;
  103. float sqsum = 0.f;
  104. for (int i = 0; i < size; i++)
  105. {
  106. sum += ptr[i];
  107. //sqsum += ptr[i] * ptr[i];
  108. }
  109. float mean = sum / size;
  110. float tmp = 0.f;
  111. for (int i = 0; i < size; i++)
  112. {
  113. tmp = ptr[i] - mean;
  114. sqsum += tmp * tmp;
  115. }
  116. float var = sqsum / size;
  117. // the var maybe minus due to accuracy
  118. //float var = sqsum / size - mean * mean;
  119. float a = static_cast<float>(1.f / (sqrt(var + eps)));
  120. float b = -mean * a;
  121. if (affine)
  122. {
  123. for (int i = 0; i < size; i++)
  124. {
  125. ptr[i] = (ptr[i] * a + b) * gamma_data[i] + beta_data[i];
  126. }
  127. }
  128. else
  129. {
  130. for (int i = 0; i < size; i++)
  131. {
  132. ptr[i] = ptr[i] * a + b;
  133. }
  134. }
  135. }
  136. }
  137. return 0;
  138. }
  139. } // namespace ncnn