def setup_layers(self, batch_shape):
        '''Iterates over all layers to instantiate them in the simulator.'''

        self.add_input_layer(batch_shape)

        for layer in self.parsed_model.layers[1:]:
            print("Instantiating layer: {}".format(layer.name))
            self.add_layer(layer)

            layer_type = get_type(layer)
            print("Building layer: {}".format(layer.name))
            if layer_type == 'Flatten':
                self.flatten_shapes.append(
                    (layer.name, get_shape_from_label(self.layers[-1].label)))
                self.build_flatten(layer)
                continue
            if layer_type in {'Dense', 'Sparse'}:
                self.build_dense(layer)
            elif layer_type in {
                    'Conv1D', 'Conv2D', 'DepthwiseConv2D', 'SparseConv2D',
                    'SparseDepthwiseConv2D'
            }:
                self.build_convolution(layer)
                self.data_format = layer.data_format
            elif layer_type in {'MaxPooling2D', 'AveragePooling2D'}:
                self.build_pooling(layer)

            elif layer_type == 'ZeroPadding':
                padding = layer.padding
                if set(padding).issubset((1, (1, 1))):
                    self.change_padding = True
                    return
                else:
                    raise NotImplementedError(
                        "Border_mode {} not supported.".format(padding))
    def add_layer(self, layer):
        from snntoolbox.parsing.utils import get_type
        spike_layer_name = getattr(self.sim, 'Spike' + get_type(layer))
        # noinspection PyProtectedMember
        inbound = [self._spiking_layers[inb.name] for inb in
                   layer._inbound_nodes[0].inbound_layers]
        if len(inbound) == 1:
            inbound = inbound[0]
        layer_kwargs = layer.get_config()
        layer_kwargs['config'] = self.config

        # Check if layer uses binary activations. In that case, we will want to
        # tell the following to MaxPool layer because then we can use a
        # cheaper operation.
        if 'Conv' in layer.name and 'binary' in layer.activation.__name__:
            self._binary_activation = layer.activation.__name__

        if 'MaxPool' in layer.name and self._binary_activation is not None:
            layer_kwargs['activation'] = self._binary_activation
            self._binary_activation = None

        # Replace activation from kwargs by 'linear' before initializing
        # superclass, because the relu activation is applied by the spike-
        # generation mechanism automatically. In some cases (quantized
        # activation), we need to apply the activation manually. This
        # information is taken from the 'activation' key during conversion.
        activation_str = str(layer_kwargs.pop(str('activation'), None))

        spike_layer = spike_layer_name(**layer_kwargs)
        spike_layer.activation_str = activation_str
        self._spiking_layers[layer.name] = spike_layer(inbound)
示例#3
0
    def load(self, path, filename):

        dirpath = os.path.join(path, filename, 'brian2-model')
        npz_files = [f for f in sorted(os.listdir(dirpath))
                     if os.path.isfile(os.path.join(dirpath, f))]
        print("Loading spiking model...")

        self.parsed_model = load_model(
            os.path.join(self.config.get('paths', 'path_wd'),
                         self.config.get('paths',
                                         'filename_parsed_model') + '.h5'))
        self.num_classes = int(self.parsed_model.layers[-1].output_shape[-1])
        self.top_k = min(self.num_classes, self.config.getint('simulation',
                                                              'top_k'))

        # Get batch input shape
        batch_shape = list(self.parsed_model.layers[0].batch_input_shape)
        batch_shape[0] = self.batch_size
        if self.config.get('conversion', 'spike_code') == 'ttfs_dyn_thresh':
            batch_shape[0] *= 2

        self.add_input_layer(batch_shape)

        # Iterate over layers to create spiking neurons and connections.
        for layer, f in zip(self.parsed_model.layers[1:], npz_files):
            print("Building layer: {}".format(layer.name))
            self.add_layer(layer)
            layer_type = get_type(layer)
            filepath = os.path.join(dirpath, f)
            print("Using layer-weights stored in: {}".format(filepath))
            print("Loading stored weights...")
            input_file = np.load(filepath)
            weights = input_file['arr_0']
            if layer_type == 'Dense':
                self.build_dense(layer, weights=weights)
            elif layer_type == 'Conv2D':
                self.build_convolution(layer, weights=weights)
                if layer.data_format == 'channels_last':
                    self.data_format = layer.data_format
            elif layer_type in {'MaxPooling2D', 'AveragePooling2D'}:
                self.build_pooling(layer, weights=weights)
            elif layer_type == 'Flatten':
                self.build_flatten(layer)

        print("Compiling spiking model...\n")
        self.compile()

        # Compute number of operations of ANN.
        if self.fanout is None:
            self.set_connectivity()
            self.operations_ann = get_ann_ops(self.num_neurons,
                                              self.num_neurons_with_bias,
                                              self.fanin)
            print("Number of operations of ANN: {}".format(
                self.operations_ann))
            print("Number of neurons: {}".format(sum(self.num_neurons[1:])))
            print("Number of synapses: {}\n".format(self.num_synapses))

        self.is_built = True
 def get_type(self, layer):
     from snntoolbox.parsing.utils import get_type
     return get_type(layer)
    def build_convolution(self, layer):

        # If the parsed model contains a ZeroPadding layer, we need to tell the
        # Conv layer about it here, because ZeroPadding layers are removed when
        # building the pyNN model.
        if self.change_padding:
            if layer.padding == 'valid':
                self.change_padding = False
                layer.padding = 'ZeroPadding'
            else:
                raise NotImplementedError(
                    "Border_mode {} in combination with ZeroPadding is not "
                    "supported.".format(layer.padding))

        delay = self.config.getfloat('cell', 'delay')
        transpose_kernel = \
            self.config.get('simulation', 'keras_backend') == 'tensorflow'

        if get_type(layer) in ['Conv2D', 'SparseConv2D']:
            weights, biases = build_convolution(layer, delay, transpose_kernel)
        elif get_type(layer) in ['DepthwiseConv2D', 'SparseDepthwiseConv2D']:
            weights, biases = build_depthwise_convolution(
                layer, delay, transpose_kernel)
        elif get_type(layer) == 'Conv1D':
            weights, biases = build_1d_convolution(layer, delay)
        else:
            ValueError("Layer {} of type {} unrecognised here. "
                       "How did you get into this function?".format(
                           layer.name, get_type(layer)))

        self.set_biases(biases)
        weights = self.scale_weights(weights)

        exc_connections = [c for c in weights if c[2] > 0]
        inh_connections = [c for c in weights if c[2] < 0]

        if self.config.getboolean('tools', 'simulate'):
            self.connections.append(
                self.sim.Projection(
                    self.layers[-2],
                    self.layers[-1], (self.sim.FromListConnector(
                        exc_connections, ['weight', 'delay'])),
                    receptor_type='excitatory',
                    label=self.layers[-1].label + '_excitatory'))

            self.connections.append(
                self.sim.Projection(
                    self.layers[-2],
                    self.layers[-1], (self.sim.FromListConnector(
                        inh_connections, ['weight', 'delay'])),
                    receptor_type='inhibitory',
                    label=self.layers[-1].label + '_inhibitory'))
        else:
            # The spinnaker implementation of Projection.save() is not working
            # yet, so we do save the connections manually here.
            filepath = os.path.join(self.config.get('paths', 'path_wd'),
                                    self.layers[-1].label)
            # noinspection PyTypeChecker
            np.savetxt(filepath + '_excitatory',
                       np.array(exc_connections),
                       ['%d', '%d', '%.18f', '%.3f'],
                       header="columns = ['i', 'j', 'weight', 'delay']")
            # noinspection PyTypeChecker
            np.savetxt(filepath + '_inhibitory',
                       np.array(inh_connections),
                       ['%d', '%d', '%.18f', '%.3f'],
                       header="columns = ['i', 'j', 'weight', 'delay']")
示例#6
0
 def get_type(self, layer):
     return get_type(layer)