bn.py 1.83 KB
Newer Older
1
"""
2
 Copyright (C) 2018-2020 Intel Corporation
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
"""

import numpy as np

19
from mo.front.caffe.extractors.utils import input_as_const
20
from mo.front.common.replacement import FrontReplacementOp
21
from mo.graph.graph import Node, Graph
22 23 24 25 26 27 28 29 30 31 32
from mo.ops.scale_shift import ScaleShiftOp
from mo.utils.error import Error


class BNToScaleShift(FrontReplacementOp):
    """
    Replaces BN layer with ScaleShift.
    """
    op = "BN"
    enabled = True

33
    def replace_op(self, graph: Graph, node: Node):
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
        attrs = {'name': node.id + "/ScaleShift_"}

        param = graph.node[node.id]['pb'].bn_param
        pb_model = graph.node[node.id]['model_pb']
        blobs = pb_model.blobs

        if len(blobs) != 4:
            raise Error("Incorrect number of blobs in BN layer {}".format(node.id))

        mean = np.array(blobs[0].data)
        var = np.array(blobs[1].data)
        betta = np.array(blobs[2].data)
        gamma = np.array(blobs[3].data)

        gamma = gamma + np.repeat(param.eps, gamma.shape)

        scale = 1.0 / np.sqrt(gamma) * mean
        shift = var - betta * scale

        ss = ScaleShiftOp(graph, attrs)
        scale_shift = ss.create_node([node.in_node(0)])
55 56
        input_as_const(scale_shift, attrs, 1, 'weights', scale)
        input_as_const(scale_shift, attrs, 2, 'biases', shift)
57 58

        return [scale_shift.id]