| 175 | } |
| 176 | |
| 177 | virtual std::vector<Express::VARP> onForward(const std::vector<Express::VARP>& inputs) override { |
| 178 | Express::VARP x = inputs[0]; |
| 179 | auto dimFormat = x->getInfo()->order; |
| 180 | VARP outputData = nullptr; |
| 181 | if (getIsTraining()) { |
| 182 | if (dimFormat == NC4HW4 || dimFormat == NHWC) { |
| 183 | x = _Convert(x, NCHW); |
| 184 | } |
| 185 | MNN_ASSERT(x->getInfo()->dim[1] == mChannels); |
| 186 | auto sampleMean = _ReduceMean(x, mReductionDims, true); // mean for each channel in the batch |
| 187 | auto xSub = x - sampleMean; |
| 188 | auto sampleVar = _ReduceMean(_Square(xSub), mReductionDims, |
| 189 | true); // variance for each channel in the batch |
| 190 | auto rSampleStd = _Reciprocal(_Sqrt(sampleVar + _Const(mEps))); |
| 191 | auto normalizedData = xSub * rSampleStd; |
| 192 | outputData = normalizedData * mScale + mBias; |
| 193 | |
| 194 | mRunningMean = _Const(mMomentum) * mRunningMean + _Const(1 - mMomentum) * sampleMean; |
| 195 | mRunningVariance = _Const(mMomentum) * mRunningVariance + _Const(1 - mMomentum) * sampleVar; |
| 196 | outputData->setName(name()); |
| 197 | outputData = _Convert(outputData, dimFormat); |
| 198 | setParameter(mRunningMean, mRunningMeanPos); |
| 199 | setParameter(mRunningVariance, mRunningVariancePos); |
| 200 | return {outputData}; |
| 201 | } |
| 202 | auto rStd = _Const(1.0f) / _Sqrt(mRunningVariance + _Const(mEps)); |
| 203 | auto alpha = rStd * mScale; |
| 204 | auto beta = mBias - mRunningMean * rStd * mScale; |
| 205 | //outputData = (_Convert(x, NCHW) * alpha) + beta; |
| 206 | alpha.fix(VARP::CONSTANT); |
| 207 | beta.fix(VARP::CONSTANT); |
| 208 | //FUNC_PRINT_ALL(alpha->readMap<float>()[0], f); |
| 209 | x = _Convert(x, NC4HW4); |
| 210 | std::vector<float> scale(alpha->getInfo()->size); |
| 211 | std::vector<float> bias(beta->getInfo()->size); |
| 212 | ::memcpy(scale.data(), alpha->readMap<float>(), scale.size() * sizeof(float)); |
| 213 | ::memcpy(bias.data(), beta->readMap<float>(), bias.size() * sizeof(float)); |
| 214 | outputData = _Scale(x, mChannels, std::move(scale), std::move(bias)); |
| 215 | outputData->setName(name()); |
| 216 | outputData = _Convert(outputData, dimFormat); |
| 217 | return {outputData}; |
| 218 | } |
| 219 | |
| 220 | private: |
| 221 | BatchNormModule() = default; |
nothing calls this directly
no test coverage detected