# Path: mozi/utils/theano_utils.py
# def sharedX(value, dtype=floatX, name=None, borrow=False, **kwargs):
#     return theano.shared(np.asarray(value, dtype=dtype), name=name, borrow=borrow, **kwargs)


import numpy as np
import theano
from mozi.utils.theano_utils import sharedX



def get_fans(shape):
    '''From keras'''
    fan_in = shape[0] if len(shape) == 2 else np.prod(shape[1:])
    fan_out = shape[1] if len(shape) == 2 else shape[0]
    return fan_in, fan_out


class WeightInitialization(object):

    def __call__(self, dim, name='W'):
        raise NotImplementedError(str(type(self))+" does not implement __call__.")


class GaussianWeight(WeightInitialization):
    def __init__(self, mean=0, std=0.1):
        self.mean = mean
        self.std = std

    def __call__(self, dim, name='W', **kwargs):
        W_values = np.random.normal(loc=self.mean, scale=self.std, size=dim)

# Path: mozi/utils/theano_utils.py
# def sharedX(value, dtype=floatX, name=None, borrow=False, **kwargs):
#     return theano.shared(np.asarray(value, dtype=dtype), name=name, borrow=borrow, **kwargs)


# Path: mozi/weight_init.py
import numpy as np
import theano
from mozi.utils.theano_utils import sharedX




def get_fans(shape):
    '''From keras'''
    fan_in = shape[0] if len(shape) == 2 else np.prod(shape[1:])
    fan_out = shape[1] if len(shape) == 2 else shape[0]
    return fan_in, fan_out


class WeightInitialization(object):

    def __call__(self, dim, name='W'):
        raise NotImplementedError(str(type(self))+" does not implement __call__.")


class GaussianWeight(WeightInitialization):
    def __init__(self, mean=0, std=0.1):
        self.mean = mean
        self.std = std

    def __call__(self, dim, name='W', **kwargs):
        W_values = np.random.normal(loc=self.mean, scale=self.std, size=dim)

        return sharedX(name=name, value=W_values, borrow=True, **kwargs)