InstanceNormalization.py 2.4 KB
Newer Older
C
channingss 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
#   Copyright (c) 2019  PaddlePaddle Authors. All Rights Reserved.
#
# 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.

C
channingss 已提交
15 16 17 18 19 20 21 22 23 24
from .register import register


def InstanceNormalization_shape(input_shape):
    return input_shape


def InstanceNormalization_layer(inputs, name=None):
    # TODO(lvmengsi@baidu.com): Check the accuracy when using fluid.layers.layer_norm.
    epsilon = 1e-5
C
channingss 已提交
25 26
    input_ = inputs[0]
    mean = fluid.layers.reduce_mean(input_, dim=[2, 3], keep_dim=True)
C
channingss 已提交
27
    var = fluid.layers.reduce_mean(fluid.layers.square(input_ - mean),
C
channingss 已提交
28 29 30 31 32 33 34 35 36 37 38 39
                                   dim=[2, 3],
                                   keep_dim=True)
    if name is not None:
        scale_name = name + "_scale"
        offset_name = name + "_offset"
    scale_param = fluid.ParamAttr(name=scale_name,
                                  initializer=fluid.initializer.Constant(1.0),
                                  trainable=True)
    offset_param = fluid.ParamAttr(name=offset_name,
                                   initializer=fluid.initializer.Constant(0.0),
                                   trainable=True)
    scale = fluid.layers.create_parameter(attr=scale_param,
C
channingss 已提交
40
                                          shape=input_.shape[1:2],
C
channingss 已提交
41 42
                                          dtype="float32")
    offset = fluid.layers.create_parameter(attr=offset_param,
C
channingss 已提交
43
                                           shape=input_.shape[1:2],
C
channingss 已提交
44 45
                                           dtype="float32")

C
channingss 已提交
46
    tmp = fluid.layers.elementwise_mul(x=(input_ - mean), y=scale, axis=1)
C
channingss 已提交
47 48 49 50 51 52 53 54 55 56 57 58 59
    tmp = tmp / fluid.layers.sqrt(var + epsilon)
    tmp = fluid.layers.elementwise_add(tmp, offset, axis=1)
    return tmp


def InstanceNormalization_weights(name, data=None):
    weights_name = [name + '_scale']
    return weights_name


register(kind='InstanceNormalization',
         shape=InstanceNormalization_shape,
         layer=InstanceNormalization_layer,
C
channingss 已提交
60
         child_func=None,
C
channingss 已提交
61
         weights=InstanceNormalization_weights)