# Path: lxmls/deep_learning/mlp.py
# class MLP(Model):
#     def __init__(self, **config):
# 
#         # CHECK THE PARAMETERS ARE VALID
#         self.sanity_checks(config)
# 
#         # OPTIONAL MODEL LOADING
#         model_folder = config.get('model_folder', None)
#         if model_folder is not None:
#             saved_config, loaded_parameters = self.load(model_folder)
#             # Note that if a config is given this is used instead of the saved
#             # one (must be consistent)
#             if config is None:
#                 config = saved_config
#         else:
#             loaded_parameters = None
# 
#         # MEMBER VARIABLES
#         self.num_layers = len(config['geometry']) - 1
#         self.config = config
#         self.parameters = initialize_mlp_parameters(
#             config['geometry'],
#             loaded_parameters
#         )
# 
#     def sanity_checks(self, config):
# 
#         model_folder = config.get('model_folder', None)
# 
#         assert bool(config is None) or bool(model_folder is None), \
#             "Need to specify config, model_folder or both"
# 
#         if model_folder is not None:
#             model_file = "%s/config.yml" % model_folder
#             assert os.path.isfile(model_file), "Need to provide %s" % model_file
# 
#     def load(self, model_folder):
#         """
#         Load model
#         """
# 
#         # Configuration un yaml format
#         config_file = "%s/config.yml" % model_folder
#         config = load_config(config_file)
# 
#         # Computation graph parameters as pickle file
#         parameter_file = "%s/parameters.pkl" % model_folder
#         loaded_parameters = load_parameters(parameter_file)
# 
#         return config, loaded_parameters
# 
#     def save(self, model_folder):
#         """
#         Save model
#         """
# 
#         # Create folder if it does not exist
#         if not os.path.isdir(model_folder):
#             os.mkdir(model_folder)
# 
#         # Configuration un yaml format
#         config_file = "%s/config.yml" % model_folder
#         save_config(config_file, self.config)
# 
#         # Computation graph parameters as pickle file
#         parameter_file = "%s/parameters.pkl" % model_folder
#         with open(parameter_file, 'wb') as fid:
#             cPickle.dump(self.parameters, fid, cPickle.HIGHEST_PROTOCOL)
# 
#     def plot_weights(self, show=True, aspect='auto'):
#         """
#         Plots the weights of the newtwork
# 
#         Use show = False to plot various models one after the other
#         """
#         import matplotlib.pyplot as plt
#         plt.figure()
#         for n in range(self.n_layers):
# 
#             # Get weights and bias
#             weight, bias = self.parameters[n]
# 
#             # Plot them
#             plt.subplot(2, self.n_layers, n+1)
#             plt.imshow(weight, aspect=aspect, interpolation='nearest')
#             plt.title('Layer %d Weight' % n)
#             plt.colorbar()
#             plt.subplot(2, self.n_layers, self.n_layers+(n+1))
#             plt.plot(bias)
#             plt.title('Layer %d Bias' % n)
#             plt.colorbar()
# 
#         if show:
#             plt.show()
# 
# Path: lxmls/deep_learning/utils.py
# def index2onehot(index, N):
#     """
#     Transforms index to one-hot representation, for example
# 
#     Input: e.g. index = [1, 2, 0], N = 4
#     Output:     [[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0]]
#     """
#     L = index.shape[0]
#     onehot = np.zeros((L, N))
#     for l in np.arange(L):
#         onehot[l, index[l]] = 1
#     return onehot
# 
# def logsumexp(a, axis=None, keepdims=False):
#     """
#     This is an improvement over the original logsumexp of
#     scipy/maxentropy/maxentutils.py that allows specifying an axis to sum
#     It also allows keepdims=True.
#     """
#     if axis is None:
#         a = np.asarray(a)
#         a_max = a.max()
#         return a_max + np.log(np.exp(a-a_max).sum())
#     else:
#         a_max = np.amax(a, axis=axis, keepdims=keepdims)
#         return a_max + np.log((np.exp(a-a_max)).sum(axis, keepdims=keepdims))


import numpy as np
from lxmls.deep_learning.mlp import MLP
from lxmls.deep_learning.utils import index2onehot, logsumexp


class NumpyMLP(MLP):
    """
    Basic MLP with forward-pass and gradient computation in Numpy
    """

    def __init__(self, **config):

        # This will initialize
        # self.config
        # self.parameters

# Path: lxmls/deep_learning/mlp.py
# class MLP(Model):
#     def __init__(self, **config):
# 
#         # CHECK THE PARAMETERS ARE VALID
#         self.sanity_checks(config)
# 
#         # OPTIONAL MODEL LOADING
#         model_folder = config.get('model_folder', None)
#         if model_folder is not None:
#             saved_config, loaded_parameters = self.load(model_folder)
#             # Note that if a config is given this is used instead of the saved
#             # one (must be consistent)
#             if config is None:
#                 config = saved_config
#         else:
#             loaded_parameters = None
# 
#         # MEMBER VARIABLES
#         self.num_layers = len(config['geometry']) - 1
#         self.config = config
#         self.parameters = initialize_mlp_parameters(
#             config['geometry'],
#             loaded_parameters
#         )
# 
#     def sanity_checks(self, config):
# 
#         model_folder = config.get('model_folder', None)
# 
#         assert bool(config is None) or bool(model_folder is None), \
#             "Need to specify config, model_folder or both"
# 
#         if model_folder is not None:
#             model_file = "%s/config.yml" % model_folder
#             assert os.path.isfile(model_file), "Need to provide %s" % model_file
# 
#     def load(self, model_folder):
#         """
#         Load model
#         """
# 
#         # Configuration un yaml format
#         config_file = "%s/config.yml" % model_folder
#         config = load_config(config_file)
# 
#         # Computation graph parameters as pickle file
#         parameter_file = "%s/parameters.pkl" % model_folder
#         loaded_parameters = load_parameters(parameter_file)
# 
#         return config, loaded_parameters
# 
#     def save(self, model_folder):
#         """
#         Save model
#         """
# 
#         # Create folder if it does not exist
#         if not os.path.isdir(model_folder):
#             os.mkdir(model_folder)
# 
#         # Configuration un yaml format
#         config_file = "%s/config.yml" % model_folder
#         save_config(config_file, self.config)
# 
#         # Computation graph parameters as pickle file
#         parameter_file = "%s/parameters.pkl" % model_folder
#         with open(parameter_file, 'wb') as fid:
#             cPickle.dump(self.parameters, fid, cPickle.HIGHEST_PROTOCOL)
# 
#     def plot_weights(self, show=True, aspect='auto'):
#         """
#         Plots the weights of the newtwork
# 
#         Use show = False to plot various models one after the other
#         """
#         import matplotlib.pyplot as plt
#         plt.figure()
#         for n in range(self.n_layers):
# 
#             # Get weights and bias
#             weight, bias = self.parameters[n]
# 
#             # Plot them
#             plt.subplot(2, self.n_layers, n+1)
#             plt.imshow(weight, aspect=aspect, interpolation='nearest')
#             plt.title('Layer %d Weight' % n)
#             plt.colorbar()
#             plt.subplot(2, self.n_layers, self.n_layers+(n+1))
#             plt.plot(bias)
#             plt.title('Layer %d Bias' % n)
#             plt.colorbar()
# 
#         if show:
#             plt.show()
# 
# Path: lxmls/deep_learning/utils.py
# def index2onehot(index, N):
#     """
#     Transforms index to one-hot representation, for example
# 
#     Input: e.g. index = [1, 2, 0], N = 4
#     Output:     [[0, 1, 0, 0], [0, 0, 1, 0], [1, 0, 0, 0]]
#     """
#     L = index.shape[0]
#     onehot = np.zeros((L, N))
#     for l in np.arange(L):
#         onehot[l, index[l]] = 1
#     return onehot
# 
# def logsumexp(a, axis=None, keepdims=False):
#     """
#     This is an improvement over the original logsumexp of
#     scipy/maxentropy/maxentutils.py that allows specifying an axis to sum
#     It also allows keepdims=True.
#     """
#     if axis is None:
#         a = np.asarray(a)
#         a_max = a.max()
#         return a_max + np.log(np.exp(a-a_max).sum())
#     else:
#         a_max = np.amax(a, axis=axis, keepdims=keepdims)
#         return a_max + np.log((np.exp(a-a_max)).sum(axis, keepdims=keepdims))


# Path: lxmls/deep_learning/numpy_models/mlp.py
import numpy as np
from lxmls.deep_learning.mlp import MLP
from lxmls.deep_learning.utils import index2onehot, logsumexp



class NumpyMLP(MLP):
    """
    Basic MLP with forward-pass and gradient computation in Numpy
    """

    def __init__(self, **config):

        # This will initialize
        # self.config
        # self.parameters

        MLP.__init__(self, **config)