From 49e9ca8cda08c90e7d1f3758aca493869568a46b Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 19 Sep 2018 19:01:40 +0300 Subject: [PATCH] Preparation for multi-branches architectures --- neuvol/architecture/individ_base.py | 36 +++++++++++++++++++++++----- neuvol/architecture/individ_image.py | 6 +---- neuvol/constants.py | 7 +++++- neuvol/evolution/evolution.py | 29 +++++++++++++++++++--- 4 files changed, 63 insertions(+), 15 deletions(-) diff --git a/neuvol/architecture/individ_base.py b/neuvol/architecture/individ_base.py index 5386a89..e06a764 100644 --- a/neuvol/architecture/individ_base.py +++ b/neuvol/architecture/individ_base.py @@ -73,14 +73,10 @@ def _random_init(self): self._data_processing = self._random_init_data_processing() self._training_parameters = self._random_init_training() - def _random_init_architecture(self): + def _random_init_branch(self, ): """ - At first, we set probabilities pool and the we change - this uniform distribution according to previous layer + Here we create only branches without input and output layers """ - if self._architecture: - self._architecture = [] - architecture = [] # choose number of layers @@ -110,6 +106,20 @@ def _random_init_architecture(self): block = Block(layer, layers_in_block_number, previous_layer, next_layer, **self.options) architecture.append(block) + return architecture + + def _random_init_architecture(self): + """ + At first, we set probabilities pool and the we change + this uniform distribution according to previous layer + """ + if self._architecture: + self._architecture = [] + + architecture = [] + + architecture.extend(self._random_init_branch) + # Push input layer for functional keras api block = Block('input', layers_number=1, **self.options) architecture.insert(0, block) @@ -435,6 +445,13 @@ def schema(self): return schema + @property + def stage(self): + """ + Get the last stage of evaluation + """ + return self._stage + @property def data_processing(self): """ @@ -470,6 +487,13 @@ def history(self, event): """ self._history.append(event) + @stage.setter + def stage(self, stage): + """ + Change stage + """ + self._stage = stage + def random_init(self): """ Public method for calling the random initialisation diff --git a/neuvol/architecture/individ_image.py b/neuvol/architecture/individ_image.py index 4ff21f5..067af38 100644 --- a/neuvol/architecture/individ_image.py +++ b/neuvol/architecture/individ_image.py @@ -11,11 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import numpy as np - from .individ_base import IndividBase -from ..layer.block import Block -from ..probabilty_pool import Distribution class IndividImage(IndividBase): @@ -62,4 +58,4 @@ def _random_init_data_processing(self): # individ._result = serial['result'] # individ.shape_structure = serial['shape_structure'] - # return individ \ No newline at end of file + # return individ diff --git a/neuvol/constants.py b/neuvol/constants.py index 2d38cc9..4631a7e 100644 --- a/neuvol/constants.py +++ b/neuvol/constants.py @@ -40,7 +40,12 @@ 'vocabular': [30000], 'sentences_length': [i for i in range(1, 150, 1)], 'embedding_dim': [i for i in range(32, 300, 2)], - 'trainable': [False, True]}} + 'trainable': [False, True]}, + 'zeropadding1D': { # set manually + 'padding': []}, + 'reshape': { # set manually + 'target_shape': [] + }} LAYERS_POOL = { 'bi': { diff --git a/neuvol/evolution/evolution.py b/neuvol/evolution/evolution.py index 5a44d13..22cf0b9 100644 --- a/neuvol/evolution/evolution.py +++ b/neuvol/evolution/evolution.py @@ -24,7 +24,6 @@ class Evolution(): """ Simple class that performs evolution process """ - def __init__( self, stages, @@ -37,6 +36,8 @@ def __init__( freeze=None, active_distribution=True, loaded=False, + multiple_gpu=False, + vizualize=False, **kwargs): self._evaluator = evaluator self._mutator = mutator @@ -55,6 +56,8 @@ def __init__( self._mortality_rate = 0.2 self._current_stage = 1 + self._viz_data = [] + if self._data_type == 'text': Distribution.set_layer_status('cnn2', active=False) Distribution.set_layer_status('max_pool2', active=False) @@ -91,16 +94,18 @@ def mutation_step(self): # TODO: more accurate error handling try: self._population[index] = self._mutator.mutate(self._population[index], self._current_stage) - except: + except Exception: pass def step(self): """ Perform one step of evolution, that consists of evaluation and death """ + # TODO: parallel execution for multiple gpus for network in self._population: try: network.result = self._evaluator.fit(network) + network.stage = self._current_stage # NOTE: maybe ArithmeticError ? except Exception: # sorry, but here i dont care about type of exception @@ -125,7 +130,7 @@ def crossing_step(self): new_individ = self._crosser.cross( deepcopy(self._population[index_father]), deepcopy(self._population[index_mother]), self._current_stage) - except: + except Exception: new_individ = cradle(0, self._data_type, self._task_type, freeze=self._freeze, **self._options) self._population.append(new_individ) @@ -173,6 +178,24 @@ def save(self): def dump(self, path): dump(self.save(), path) + def viz(self): + for network in self._population: + tmp = deepcopy(network) + tmp._name = tmp._name + str(self._current_stage) + + # if individ was created rigth now - we dont remove parents to connect them + # if individ was created early - set parents as None to avoid crossconnections + if tmp.history[0].type == 'Birth': + if len(tmp.history) != 1: + tmp._parents = None + else: + tmp._parents[0]._name = tmp._parents[0]._name + str(self._current_stage - 1) + tmp._parents[1]._name = tmp._parents[1]._name + str(self._current_stage - 1) + + self._viz_data.append(tmp.save()) + + + @staticmethod def load(serial, evaluator, mutator, crosser): evolution = Evolution(serial['stages'], evaluator, mutator, crosser, loaded=True)