from torch.nn import init


def init_weights(net, init_type='normal', init_gain=0.02):
    """
    Init network weights
    :param net: net to which init weights
    :param init_type: type of weight initialisation
    :param init_gain: gain value for weight initialisation func
    :return:
    """

    def init_func(m):
        """
        :param m: is like self so is the class Generator for example
        :return:
        """
        class_name = m.__class__.__name__
        if hasattr(m, 'weight') and (class_name.find('Conv') != -1 or class_name.find('Linear') != -1):
            if init_type == 'normal':
                init.normal_(m.weight.data, 0.0, init_gain)
            elif init_type == 'xavier':
                init.xavier_normal_(m.weight.data, gain=init_gain)
            elif init_type == 'kaiming':
                init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')
            elif init_type == 'orthogonal':
                init.orthogonal_(m.weight.data, gain=init_gain)
            else:
                raise NotImplementedError('initialization method [%s] is not implemented' % init_type)
            if hasattr(m, 'bias') and m.bias is not None:
                init.constant_(m.bias.data, 0.0)
        # BatchNorm Layer's weight is not a matrix; only normal distribution applies.
        elif class_name.find('BatchNorm2d') != -1:
            init.normal_(m.weight.data, 1.0, init_gain)
            init.constant_(m.bias.data, 0.0)

    # print('initialize network with %s' % init_type)
    # apply the initialization function <init_func>
    net.apply(init_func)

from torch.nn import init


def init_weights(net, init_type='normal', init_gain=0.02):
    """
    Init network weights
    :param net: net to which init weights
    :param init_type: type of weight initialisation
    :param init_gain: gain value for weight initialisation func
    :return:
    """

    def init_func(m):
        """
        :param m: is like self so is the class Generator for example
        :return:
        """
        class_name = m.__class__.__name__
        if hasattr(m, 'weight') and (class_name.find('Conv') != -1 or class_name.find('Linear') != -1):
            if init_type == 'normal':
                init.normal_(m.weight.data, 0.0, init_gain)
            elif init_type == 'xavier':
                init.xavier_normal_(m.weight.data, gain=init_gain)
            elif init_type == 'kaiming':
                init.kaiming_normal_(m.weight.data, a=0, mode='fan_in')
            elif init_type == 'orthogonal':
                init.orthogonal_(m.weight.data, gain=init_gain)
            else:
                raise NotImplementedError('initialization method [%s] is not implemented' % init_type)
            if hasattr(m, 'bias') and m.bias is not None:
                init.constant_(m.bias.data, 0.0)
        # BatchNorm Layer's weight is not a matrix; only normal distribution applies.
        elif class_name.find('BatchNorm2d') != -1:
            init.normal_(m.weight.data, 1.0, init_gain)
            init.constant_(m.bias.data, 0.0)

    # print('initialize network with %s' % init_type)
    # apply the initialization function <init_func>
    net.apply(init_func)

Init network weights     :param net: net to which init weights     :param init_type: type of weight initialisation     :param init_gain: gain value for weight initialisation func     :return: :param m: is like self so is the class Generator for example         :return: # BatchNorm Layer's weight is not a matrix; only normal distribution applies. # print('initialize network with %s' % init_type) # apply the initialization function <init_func>