def test_modify_hyperparameters(self, lp_mock, io_mock):
        """If a primitive method modifies the hyperparameters, changes should not persist."""

        def primitive(a_list_param):
            a_list_param.append('b')

        io_mock.return_value = primitive

        lp_mock.return_value = {
            'name': 'a_primitive',
            'primitive': 'a_primitive',
            'produce': {
                'args': [],
                'output': []
            }
        }

        mlblock = MLBlock('a_primitive')

        hyperparameters = {
            'a_list_param': ['a']
        }
        mlblock._hyperparameters = hyperparameters

        mlblock.produce()

        assert 'b' not in hyperparameters['a_list_param']
Exemplo n.º 2
0
    def test_get_hyperparameters(self):
        """get_hyperparameters has to return a deepcopy of the _hyperparameters attribute."""
        mlblock = MLBlock('given_primitive_name')

        hyperparameters = {'a_list_param': ['a']}
        mlblock._hyperparameters = hyperparameters

        returned = mlblock.get_hyperparameters()

        assert returned == hyperparameters
        assert returned is not hyperparameters

        returned['a_list_param'].append('b')
        assert 'b' not in hyperparameters['a_list_param']
    def test__get_tunable_no_conditionals(self):
        """If there are no conditionals, tunables are returned unmodified."""

        # setup
        init_params = {
            'an_init_param': 'a_value'
        }
        hyperparameters = {
            'tunable': {
                'this_is_not_conditional': {
                    'type': 'int',
                    'default': 1,
                    'range': [1, 10]
                }
            }
        }

        # run
        tunable = MLBlock._get_tunable(hyperparameters, init_params)

        # assert
        expected = {
            'this_is_not_conditional': {
                'type': 'int',
                'default': 1,
                'range': [1, 10]
            }
        }
        assert tunable == expected
Exemplo n.º 4
0
    def _build_blocks(self):
        blocks = OrderedDict()

        block_names_count = Counter()
        for primitive in self.primitives:
            if isinstance(primitive, str):
                primitive_name = primitive
            else:
                primitive_name = primitive['name']

            try:
                block_names_count.update([primitive_name])
                block_count = block_names_count[primitive_name]
                block_name = '{}#{}'.format(primitive_name, block_count)
                block_params = self.init_params.get(block_name, dict())
                if not block_params:
                    block_params = self.init_params.get(primitive_name, dict())
                    if block_params and block_count > 1:
                        LOGGER.warning(("Non-numbered init_params are being used "
                                        "for more than one block %s."), primitive_name)

                block = MLBlock(primitive, **block_params)
                blocks[block_name] = block

            except Exception:
                LOGGER.exception("Exception caught building MLBlock %s", primitive)
                raise

        return blocks
Exemplo n.º 5
0
    def __init__(self,
                 primitives,
                 init_params=None,
                 input_names=None,
                 output_names=None):
        self.primitives = primitives
        self.init_params = init_params or dict()
        self.blocks = OrderedDict()

        block_names_count = Counter()
        for primitive in primitives:
            try:
                block_names_count.update([primitive])
                block_count = block_names_count[primitive]
                block_name = '{}#{}'.format(primitive, block_count)
                block_params = self.init_params.get(block_name, dict())
                if not block_params:
                    block_params = self.init_params.get(primitive, dict())
                    if block_params and block_count > 1:
                        LOGGER.warning(
                            ("Non-numbered init_params are being used "
                             "for more than one block %s."), primitive)

                block = MLBlock(primitive, **block_params)
                self.blocks[block_name] = block

            except Exception:
                LOGGER.exception("Exception caught building MLBlock %s",
                                 primitive)
                raise

        self.input_names = input_names or dict()
        self.output_names = output_names or dict()
        self._tunable_hyperparameters = self._get_tunable_hyperparameters()
Exemplo n.º 6
0
    def test___init__(self, load_primitive_mock, import_object_mock,
                      set_hps_mock):
        load_primitive_mock.return_value = {
            'primitive': 'a_primitive_name',
            'produce': {
                'args': [{
                    'name': 'argument'
                }],
                'output': []
            }
        }

        mlblock = MLBlock('given_primitive_name', argument='value')

        assert mlblock.name == 'given_primitive_name'
        assert mlblock.primitive == import_object_mock.return_value
        assert mlblock._fit == dict()
        assert mlblock.fit_args == list()
        assert mlblock.fit_method is None

        produce = {'args': [{'name': 'argument'}], 'output': []}
        assert mlblock._produce == produce
        assert mlblock.produce_args == produce['args']
        assert mlblock.produce_output == produce['output']
        assert mlblock.produce_method is None
        assert mlblock._class is False

        assert mlblock._hyperparameters == dict()
        assert mlblock._fit_params == dict()
        assert mlblock._produce_params == {'argument': 'value'}

        assert mlblock._tunable == dict()

        set_hps_mock.assert_called_once_with(dict())
Exemplo n.º 7
0
    def test_get_hyperparameters(self, load_primitive_mock, import_object_mock):
        """get_hyperparameters has to return a copy of the _hyperparameters attribute."""
        load_primitive_mock.return_value = {
            'primitive': 'a_primitive_name',
            'produce': {
                'args': [],
                'output': []
            }
        }

        mlblock = MLBlock('given_primitive_name')

        hyperparameters = dict()
        mlblock._hyperparameters = hyperparameters

        returned = mlblock.get_hyperparameters()

        assert returned == hyperparameters
        assert returned is not hyperparameters
    def test__get_tunable_no_condition(self):
        """If there is a conditional but no condition, the default is used."""

        # setup
        init_params = {
            'an_init_param': 'a_value'
        }
        hyperparameters = {
            'tunable': {
                'this_is_not_conditional': {
                    'type': 'int',
                    'default': 1,
                    'range': [1, 10]
                },
                'this_is_conditional': {
                    'type': 'conditional',
                    'condition': 'a_condition',
                    'default': {
                        'type': 'float',
                        'default': 0.1,
                        'values': [0, 1]
                    },
                    'values': {
                        'not_a_match': {
                            'type': 'str',
                            'default': 'a',
                            'values': ['a', 'b']
                        },
                        'neither_a_match': {
                            'type': 'int',
                            'default': 0,
                            'range': [1, 10]
                        }
                    }
                }
            }
        }

        # run
        tunable = MLBlock._get_tunable(hyperparameters, init_params)

        # assert
        expected = {
            'this_is_not_conditional': {
                'type': 'int',
                'default': 1,
                'range': [1, 10]
            },
            'this_is_conditional': {
                'type': 'float',
                'default': 0.1,
                'values': [0, 1]
            }
        }
        assert tunable == expected
    def test__get_tunable_condition_match(self):
        """If there is a conditional and it matches, only that part is returned."""

        # setup
        init_params = {
            'a_condition': 'a_match'
        }
        hyperparameters = {
            'tunable': {
                'this_is_not_conditional': {
                    'type': 'int',
                    'default': 1,
                    'range': [1, 10]
                },
                'this_is_conditional': {
                    'type': 'conditional',
                    'condition': 'a_condition',
                    'default': {
                        'type': 'float',
                        'default': 0.1,
                        'values': [0, 1]
                    },
                    'values': {
                        'not_a_match': {
                            'type': 'str',
                            'default': 'a',
                            'values': ['a', 'b']
                        },
                        'a_match': {
                            'type': 'int',
                            'default': 0,
                            'range': [1, 10]
                        }
                    }
                }
            }
        }

        # run
        tunable = MLBlock._get_tunable(hyperparameters, init_params)

        # assert
        expected = {
            'this_is_not_conditional': {
                'type': 'int',
                'default': 1,
                'range': [1, 10]
            },
            'this_is_conditional': {
                'type': 'int',
                'default': 0,
                'range': [1, 10]
            }
        }
        assert tunable == expected
Exemplo n.º 10
0
    def test___str__(self, load_primitive_mock, import_object_mock):
        load_primitive_mock.return_value = {
            'primitive': 'a_primitive_name',
            'produce': {
                'args': [],
                'output': []
            }
        }

        mlblock = MLBlock('given_primitive_name')

        assert str(mlblock) == 'MLBlock - given_primitive_name'
    def test__get_tunable_condition_match_null(self):
        """If there is a match and it is null (None), this param is not included.

        This stands even if the default is not null.
        """

        # setup
        init_params = {
            'a_condition': 'a_match'
        }
        hyperparameters = {
            'tunable': {
                'this_is_not_conditional': {
                    'type': 'int',
                    'default': 1,
                    'range': [1, 10]
                },
                'this_is_conditional': {
                    'type': 'conditional',
                    'condition': 'a_condition',
                    'default': {
                        'type': 'float',
                        'default': 0.1,
                        'values': [0, 1]
                    },
                    'values': {
                        'not_a_match': {
                            'type': 'str',
                            'default': 'a',
                            'values': ['a', 'b']
                        },
                        'a_match': None
                    }
                }
            }
        }

        # run
        tunable = MLBlock._get_tunable(hyperparameters, init_params)

        # assert
        expected = {
            'this_is_not_conditional': {
                'type': 'int',
                'default': 1,
                'range': [1, 10]
            }
        }
        assert tunable == expected
Exemplo n.º 12
0
    def build_mlblock(self):
        block_name = self.block_json['name']
        fixed_hyperparams = self.block_json['fixed_hyperparameters']
        tunable_hyperparams = self.get_mlhyperparams(block_name)
        model = self.build_mlblock_model(fixed_hyperparams,
                                         tunable_hyperparams)

        instance = MLBlock(name=block_name,
                           model=model,
                           fixed_hyperparams=fixed_hyperparams,
                           tunable_hyperparams=tunable_hyperparams)

        self.replace_instance_methods(instance)

        return instance
    def test__get_tunable_condition_default_null(self):
        """If there is no match and default is null (None), this param is not included."""

        # setup
        init_params = {
            'a_condition': 'not_a_match'
        }
        hyperparameters = {
            'tunable': {
                'this_is_not_conditional': {
                    'type': 'int',
                    'default': 1,
                    'range': [1, 10]
                },
                'this_is_conditional': {
                    'type': 'conditional',
                    'condition': 'a_condition',
                    'default': None,
                    'values': {
                        'also_not_a_match': {
                            'type': 'str',
                            'default': 'a',
                            'values': ['a', 'b']
                        },
                        'neither_a_match': {
                            'type': 'int',
                            'default': 0,
                            'range': [1, 10]
                        }
                    }
                }
            }
        }

        # run
        tunable = MLBlock._get_tunable(hyperparameters, init_params)

        # assert
        expected = {
            'this_is_not_conditional': {
                'type': 'int',
                'default': 1,
                'range': [1, 10]
            }
        }
        assert tunable == expected