def test_get_number_nodes(): """ Get the number of nodes of a layer """ ii = K.constant(np.random.rand(2, 1)) nodes = 10 layer = Dense(units=nodes) # Keras won't build the layer until it is called with some input _ = layer(ii) # Check that indeed the number of nodes is parsed correctly assert nodes == get_number_nodes(layer)
def test_get_number_nodes(): """ Get the number of nodes of a layer """ nodes = 10 # Tensorflow won't build the layer until it is called in a model input_layer = Input(shape=(1, )) output_layer = Dense(units=nodes, name="test_layer") modelito = EvolModel(input_layer, output_layer(input_layer)) # Check that indeed the number of nodes is parsed correctly assert nodes == get_number_nodes(modelito)
def get_shape(self): """ Study the model to get the shapes of all trainable weight as well as the number of nodes. It also saves a reference to the non-trainable weights in the system. Returns ------- `weight_shapes`: a list of the shapes of all trainable weights """ # Get trainable weight from the model and their shapes trainable_weights = self.model.trainable_weights weight_shapes = [ weight.shape.as_list() for weight in trainable_weights ] weights = [weight for weight in trainable_weights] self.n_nodes = get_number_nodes(self.model) # check compatibility of the shape with the NGA optimizer count_nodes = 0 for num, layer in enumerate(weights): layer_shape = layer.shape.as_list() num += 1 if num % 2 == 0: count_nodes += np.array(layer_shape) if np.array(layer_shape).size != 1: raise ValueError( f"The NGA optimizer expects a (weight-bias)\N{SUPERSCRIPT LATIN SMALL LETTER N} architecture, {layer.name} does not satisfy this condition" ) else: if np.array(layer_shape).size != 2: raise ValueError( f"The NGA optimizer expects a (weight-bias)\N{SUPERSCRIPT LATIN SMALL LETTER N} architecture, {layer.name} does not satisfy this condition" ) if count_nodes != self.n_nodes: raise ValueError( "The number of nodes with a bias attribute differs from the number of trainable nodes found based on the architecture of the trainable weights." ) return weight_shapes
def get_shape(self): """ Study the model to get the shapes of all trainable weight as well as the number of nodes. It also saves a reference to the non-trainable weights in the system. Returns ------- `weight_shapes`: a list of the shapes of all trainable weights """ # Initialize number of nodes self.n_nodes = 0 # Get trainable weight from the model and their shapes trainable_weights = self.model.trainable_weights weight_shapes = [ weight.shape.as_list() for weight in trainable_weights ] # TODO: eventually we should save here a reference to the layer and their # corresponding weights, since the nodes are the output of the layer # and the weights the corresponding to that layer for layer in self.model.layers: self.n_nodes += get_number_nodes(layer) # TODO related to previous TODO: non trianable weights should not be important self.non_training_weights = self.model.non_trainable_weights return weight_shapes