class ExperimentParameters(object):

    def __init__(self, use_default_values=True):
        self.parameters = deepcopy(reference_parameters)
        self._load_custom_definitions()
        if use_default_values:
            self.parameters = self._init_default_values(self.parameters)

    def _init_default_values(self, node):
        if isinstance(node, Parameter):
            if node.default is not None or node.optional:
                return node.default
        elif isinstance(node, dict):
            for name, value in node.items():
                node[name] = self._init_default_values(value)
        return node

    def _load_custom_definitions(self):
        for name, definition in get_custom_layers().items():
            self.layer_parameter(name, definition[1])
            self.add_layer_type(name, definition[2])

        for name in get_custom_activations().keys():
            self.add_activation(name)

    def get_parameter(self, *path):
        node = self.parameters
        path = expand_param_path(path)
        for elem in path:
            if not elem in node:
                return None
            node = node[elem]
        return node

    def _set_parameter(self, _id, value):
        self.parameters = self._set_node_parameter(
            self.parameters,
            _id,
            value)

    def _set_node_parameter(self, node, path, value):
        node = node or dict()
        path = expand_param_path(path)
        if len(path) > 1:
            node[path[0]] = self._set_node_parameter(
                node[path[0]],
                path[1:],
                value)
        else:
            node[path[0]] = value
        return node

    def layout_parameter(self, name, value):
        return self._set_parameter(
            ['layout', name],
            value)

    def get_layout_parameter(self, name):
        return self.get_parameter('layout', name)

    def layer_parameter(self, name, value):
        return self._set_parameter(
            ['layers', name],
            value)

    def add_activation(self, name):
        for _layer_name, parameters in self.get_parameter('layers').items():
            for param_name, param_value in parameters.items():
                if 'activation' == param_name and isinstance(param_value, Parameter):
                    param_value.values.append(name)

    def get_layer_types(self):
        param = self.get_layout_parameter('layer.type')
        if isinstance(param, list):
            return param
        elif isinstance(param, str):
            return [param]
        return self.get_layout_parameter('layer.type').values

    def layer_types(self, layer_types):
        self.layout_parameter('layer.type', layer_types)

    def add_layer_type(self, layer_type, stackable=False):
        layer_type_param = self.get_layout_parameter('layer.type')
        layer_type_param.values = list(set(layer_type_param.values + [layer_type]))
        if stackable:
            layer_stackable_param = self.get_layout_parameter('layer.stackable')
            layer_stackable_param.values = list(set(layer_stackable_param.values + [layer_type]))

    def get_layer_parameter(self, name):
        return self.get_parameter('layers', name)

    def get_layer_parameters(self, layer):
        return self.get_parameter('layers', str_param_name(layer))

    def optimizer_parameter(self, name, value):
        return self._set_parameter(
            ['optimizers', name],
            value)

    def get_optimizer_parameters(self, name):
        return self.get_parameter('optimizers', name)

    def get_optimizers_parameters(self):
        return self.get_parameter('optimizers') class Experiment(object):

    def __init__(self, label, layout=None, training=None,
                 batch_iterator=None, test_batch_iterator=None,
                 environment=None, settings=None, parameters=None, resume=False):
        self.label = label
        self.layout = layout
        self.training = training
        self.batch_iterator = batch_iterator
        self.test_batch_iterator = test_batch_iterator
        self.environment = environment or Environment()
        self.settings = settings or ExperimentSettings()
        self.parameters = parameters or ExperimentParameters()

    def get_experiment_data_dir(self):
        return join(
            self.environment.data_dir,
            self.label)

    def get_log_filename(self):
        return path.join(
            self.get_experiment_data_dir(),
            'experiment.log')

    def get_step_log_filename(self, step):
        return path.join(
            self.get_experiment_data_dir(),
            'experiment.step.%d.log' % step)

    def get_step_data_filename(self, step):
        return path.join(
            self.get_experiment_data_dir(),
            'experiment.step.%d.data' % step)

    def get_checkpoint_filename(self):
        return path.join(
            self.get_experiment_data_dir(),
            'experiment.chkpt')

    def evaluate(self, blueprints):
        from minos.train.trainer import MultiProcessModelTrainer
        model_trainer = MultiProcessModelTrainer(
            self.batch_iterator,
            self.test_batch_iterator,
            self.environment)
        return [
            [result[1]]
            for result in model_trainer.build_and_train_models(blueprints)] def check_experiment_parameters(experiment):
    if not experiment.settings.is_layout_search()\
            and not experiment.layout.block:
        raise InvalidParametersException(
            'You have to specify a block template '
            + ' if you disable layout search')
    if experiment.settings.is_layout_search()\
            and not experiment.settings.is_parameters_search():
        raise InvalidParametersException(
            'If you do a layout search, '
            + ' you have to enable parameters search too')
    _assert_valid_training_parameters(experiment) class InvalidParametersException(Exception):

    def __init__(self, detail):
        super().__init__('Invalid parameters: %s' % detail) class Training(object):

    def __init__(self, objective, optimizer, metric,
                 stopping, batch_size, class_weight=None):
        self.objective = objective
        self.optimizer = optimizer
        self.metric = metric
        self.stopping = stopping
        self.batch_size = batch_size
        self.class_weight = class_weight

    def todict(self):
        return {
            'objective': self.objective.todict(),
            'optimizer': self.optimizer.todict(),
            'metric': self.metric.todict(),
            'stopping': self.stopping.todict(),
            'batch_size': self.batch_size,
            'class_weight': self.class_weight} def random_param_value(param):
    if isinstance(param, dict):
        return _random_dict_param_value(param)
    if isinstance(param, list) or isinstance(param, tuple):
        return _random_list_param_value(param)
    if not isinstance(param, Parameter):
        return param
    value = 0
    if param.values:
        value = random_list_element(param.values)
    elif param.lo is not None and param.hi is not None:
        if param.param_type == int:
            value = rand.randint(param.lo, param.hi)
        else:
            value = param.lo + (rand.random() * (param.hi - param.lo))
    elif param.lo is not None:
        value = param.lo * (1 + rand.random())
    elif param.hi is not None:
        value = rand.random() * param.hi
    return param.param_type(value) def int_param(lo=0, hi=100, default=None, values=None, optional=False):
    return Parameter(
        int,
        lo=lo,
        hi=hi,
        values=values,
        default=default,
        optional=optional) def float_param(lo=0., hi=1., default=None, values=None, optional=False):
    return Parameter(
        float,
        lo=lo,
        hi=hi,
        values=values,
        default=default,
        optional=optional) def string_param(values, default=None, optional=False, mutable=True):
    return Parameter(
        str,
        values=values,
        default=default,
        optional=optional,
        mutable=mutable) def is_custom_layer(name):
def is_custom_activation(name):
def get_custom_layers():
def get_custom_layer(name):
def get_custom_activations():
def get_custom_activation(name):
def register_custom_layer(name, layer, params=None, stackable=False):
def register_custom_activation(name, activation):
import unittest
from keras.layers.core import Dense
from minos.experiment.experiment import ExperimentParameters, Experiment,\
    check_experiment_parameters, InvalidParametersException
from minos.experiment.training import Training
from minos.model.parameter import random_param_value, int_param, float_param,\
    string_param
from minos.model.parameters import reference_parameters,\
    register_custom_activation, register_custom_layer
'''
Created on Feb 7, 2017

@author: julien
'''




class ParametersTest(unittest.TestCase):

    def test_parameters(self):
        experiment_parameters = ExperimentParameters(use_default_values=False)

        for layer in reference_parameters['layers'].keys():