| 13 | class BatchNormal : public OpConverter { |
| 14 | public: |
| 15 | virtual void run(MNN::OpT* dstOp, const caffe::LayerParameter& parameters, const caffe::LayerParameter& weight) { |
| 16 | auto bn = new BatchNormT; |
| 17 | dstOp->main.value = bn; |
| 18 | auto& l = parameters; |
| 19 | auto w = &weight; |
| 20 | // blob0:mean blob1:slope blob2:scale_factor |
| 21 | const caffe::LayerParameter* w0 = (const caffe::LayerParameter*)w; |
| 22 | DCHECK(w0->blobs_size() >= 2) << "Batchnorm blob ERROR! ==> " << parameters.name(); |
| 23 | const caffe::BlobProto& mean_blob = w0->blobs(0); |
| 24 | const caffe::BlobProto& var_blob = w0->blobs(1); |
| 25 | const caffe::BatchNormParameter& batch_norm_param = l.batch_norm_param(); |
| 26 | float eps = batch_norm_param.eps(); |
| 27 | |
| 28 | bn->channels = mean_blob.data_size(); |
| 29 | std::vector<float> ones(mean_blob.data_size(), 1.f); |
| 30 | bn->slopeData = ones; |
| 31 | bn->varData.resize(var_blob.data_size()); |
| 32 | bn->meanData.resize(mean_blob.data_size()); |
| 33 | bn->epsilon = eps; |
| 34 | |
| 35 | int blob_cnt = w0->blobs_size(); |
| 36 | if (blob_cnt < 3) { |
| 37 | memcpy(bn->meanData.data(), mean_blob.data().data(), sizeof(float) * mean_blob.data_size()); |
| 38 | float tmp; |
| 39 | for (int j = 0; j < var_blob.data_size(); j++) { |
| 40 | tmp = var_blob.data().data()[j]; |
| 41 | bn->varData[j] = tmp; |
| 42 | } |
| 43 | } else { |
| 44 | auto scale_factor_div = w0->blobs(2).data().data()[0]; |
| 45 | float scale_factor = 0.0f; |
| 46 | if (scale_factor_div != 0.0f) { |
| 47 | scale_factor = 1.0f / scale_factor_div; |
| 48 | } |
| 49 | // pre-multiply scale_factor to mean and variance |
| 50 | float tmp; |
| 51 | for (int j = 0; j < mean_blob.data_size(); j++) { |
| 52 | tmp = mean_blob.data().data()[j] * scale_factor; |
| 53 | bn->meanData[j] = tmp; |
| 54 | } |
| 55 | for (int j = 0; j < var_blob.data_size(); j++) { |
| 56 | tmp = var_blob.data().data()[j] * scale_factor; |
| 57 | bn->varData[j] = tmp; |
| 58 | } |
| 59 | } |
| 60 | bn->biasData = std::vector<float>(mean_blob.data_size(), 0.0f); |
| 61 | } |
| 62 | BatchNormal() { |
| 63 | } |
| 64 | virtual ~BatchNormal() { |