Skip to content

Commit

Permalink
Minor fixes, documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Qwinpin committed May 18, 2019
1 parent 9cc8eb2 commit 222c226
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 16 deletions.
68 changes: 52 additions & 16 deletions neuvol/individs/structure/structure.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,35 +19,51 @@
class Structure:
def __init__(self, root):
self.current_depth = 0
self.current_width = 1
self.branch_count = 1

# dict form of architecture, which is used for initialization of tensor graph
self.tree = {}

# matrix form of architecture, which is used for mutations, crossing, etc
self.matrix = None

# current endings (layer) of each branch
self.branchs_end = {}

# layer dict layer_name: layer_object
self.layers = {}

# map layer_name: layer_index, monotonically increasing
self.layers_indexes = {}
# map layer_index: layer_name
self.layers_indexes_reverse = {}
self.layers_counter = 0

# final layer of the whole network
self.finisher = None

def _register_new_layer(self, new_layer_name):
"""Add new layer to the indexers and increase the size of layers matrix
Args:
new_layer_name {str} - name of new layer
"""
tmp_matrix = np.zeros((self.matrix.shape[0] + 1, self.matrix.shape[1] + 1))
tmp_matrix[:self.matrix.shape[0], :self.matrix.shape[1]] = self.matrix

self.matrix = tmp_matrix

self.layers_indexes[new_layer_name] = len(self.layers_indexes)
self.layers_indexes_reverse[len(self.layers_indexes_reverse)] = new_layer_name

self.matrix = tmp_matrix

def add_layer(self, layer, branch, branch_out=None):
"""
Add layer to the last layer of the branch
Args:
layer (instance of the Layer)
branch (int) - number of the branch to be connected to
branch_out (int) - number of the branch after this new layer: if branch is splitted
layer {instance of the Layer}
branch {int} - number of the branch to be connected to
branch_out {int} - number of the branch after this new layer: if branch is splitted
"""
# branch_out used if you add new layer as a separate branch
if layer is None:
Expand Down Expand Up @@ -75,14 +91,16 @@ def add_layer(self, layer, branch, branch_out=None):

new_name = '{}_{}'.format(self.current_depth, branch)

# add new layer to the tree form
if self.tree.get(add_to) is None:
self.tree[add_to] = []
self.tree[add_to].append(new_name)

# increase matrix shape and add new connection
self._register_new_layer(new_name)

self.matrix[self.layers_indexes[add_to], self.layers_indexes[new_name]] = 1

self.tree[add_to].append(new_name)
# change branch ending
self.branchs_end[branch] = new_name
self.layers[new_name] = layer

Expand All @@ -92,9 +110,23 @@ def add_layer(self, layer, branch, branch_out=None):
return new_name

def merge_branches(self, layer, branches=None):
"""
Concat a set of branches to one single layer
Args:
layer {instance of the Layer}
Keyword Args:
branches {list{int}} -- list of branches to concat (default: {None})
Returns:
[type] -- [description]
"""
# now we prepare list if branch endings: names and objects itself
add_to = [self.branchs_end[branch] for branch in branches]
add_to_objects = [self.layers[to] for to in add_to]

# calculate shapes if necessary
modifier, shape_modifiers = merger_mass(add_to_objects)

if shape_modifiers is not None:
Expand Down Expand Up @@ -128,9 +160,9 @@ def split_branch(self, left_layer, right_layer, branch):
Split branch into two new branches
Args:
left_layer (instance of the Layer) - layer, which forms a left branch
right_layer (instance of the Layer) - layer, which forms a right branch
branch (int) - branch, which should be splitted
left_layer {instance of the Layer} - layer, which forms a left branch
right_layer {instance of the Layer} - layer, which forms a right branch
branch {int} - branch, which should be splitted
"""
# call simple add for each branch
self.add_layer(right_layer, branch, branch_out=self.branch_count + 1)
Expand All @@ -143,6 +175,7 @@ def recalculate_shapes(self):

def _recalculate_shapes(self, heap=None):
if heap is None:
# if heap is undefined - start it from the known finisher
target_index = self.layers_indexes[self.finisher]
else:
target_index = self.layers_indexes[heap]
Expand All @@ -152,6 +185,7 @@ def _recalculate_shapes(self, heap=None):
source_objects = [(int(source), self.layers[self.layers_indexes_reverse[int(source)]])
for source in sources_indexes[0]]

# in case of merger layer
if self.layers_indexes_reverse[target_index][0] == 'm':
for source_index, source_object in source_objects:
if source_object.config['shape'] is None:
Expand Down Expand Up @@ -188,8 +222,8 @@ def __init__(self, root, embedding):
Initialize the architecture of the individual
Args:
root (instance of the Layer) - input layer type
embedding (instance of the Layer) - embedding layer type
root {instance of the Layer} - input layer type
embedding {instance of the Layer} - embedding layer type
"""
super().__init__(root)

Expand All @@ -216,7 +250,9 @@ class StructureImage(Structure):
def __init__(self, root):
super().__init__(root)

self.tree['root']
self.branchs_end[1] = 'root'

self.layers['root'] = root

self.matrix = np.zeros((1, 1))

# add new layers to the indexes
self._register_new_layer('root')
7 changes: 7 additions & 0 deletions neuvol/layer/reshaper.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@
def calculate_shape(prev_layer, layer):
"""
Calculate shape and rank of the output tensor
Args:
prev_layer {instance of the Layer} - layer to which we connect the new
layer {instance of the Layer} - layer which we connect
Returns:
{tuple} - (rank, shape) of the new layer
"""
prev_shape = prev_layer.config['shape']
prev_rank = prev_layer.config['rank']
Expand Down

0 comments on commit 222c226

Please sign in to comment.