Example #1
0
    def test_saveLoadNxModel(self):
        """Check that NxModel can be saved and loaded like a Keras Model."""

        inputLayer = NxInputLayer(batch_input_shape=(1, 10, 10, 3))
        layer = NxConv2D(2, 3)(inputLayer.input)
        model1 = NxModel(inputLayer.input, layer)
        model1.compile('sgd', 'mse')
        model1.compileModel()
        model1.clearTemp()
        filename = os.path.abspath(
            os.path.join(os.path.dirname(os.path.realpath(__file__)),
                         '../../..', 'temp', str(hash(model1))))
        model1.save(filename)
        model2 = loadNxModel(filename)
        os.remove(filename)

        x = np.random.random_sample(model1.input_shape)
        y1 = model1.predict(x)
        y2 = model2.predict(x)

        self.assertTrue(np.array_equal(y1, y2))
Example #2
0
    def test_Conv2DBiases(self):
        """Test correlation between ANN activations and SNN spikerates.

        The network consists of an input layer connected to a convolution
        layer. The input to the network is a square gray-scale image of random
        integers. The weights are also random integers. Biases are non-zero.

        This test asserts that the spikerates in the output layer are close to
        the ANN activations, by computing the Pearson correlation coefficient.
        A perfect correlation cannot be expected due to quantization errors
        when approximating ANN activations with discrete spikes. However,
        correlations should be higher than 0.99.
        """
        def bias_initializer(shape, dtype=None, biasScale=1):
            """Increasing integer bias initializer for Keras layer.

            :param list | tuple | np.ndarray shape: Shape of biases.
            :param str | type | None dtype: Data type of biases.
            :param int biasScale: Scale factor applied to the biases.

            :return: Bias tensor.
            """

            return k.constant(np.arange(biasScale), dtype, shape)

        numFilters = 16
        kernelShape = (3, 3)
        inputShape = (28, 28, 3)
        vThMant = numFilters * 2**4
        thrGain = 2**6
        visualizePartitions = False
        plotUV = False
        numSteps = 500

        bias_init = partial(bias_initializer, biasScale=numFilters)

        layer = NxConv2D(filters=numFilters,
                         kernel_size=kernelShape,
                         vThMant=vThMant,
                         kernel_initializer='zeros',
                         bias_initializer=bias_init,
                         validatePartitions=True,
                         probeSpikes=True,
                         activation='relu',
                         strides=(2, 2))

        inputLayer = NxInputLayer(batch_input_shape=(1, ) + inputShape,
                                  vThMant=vThMant,
                                  visualizePartitions=visualizePartitions)

        model = NxModel(inputLayer.input, layer(inputLayer.input))

        model.compileModel()

        outputShape = layer.output_shape[1:]

        # Define probes to read out currents.
        vProbes = []
        sProbes = []
        for i in range(int(np.asscalar(np.prod(outputShape)))):
            vProbes.append(layer[i].probe(ProbableStates.VOLTAGE))
            sProbes.append(layer[i].probe(ProbableStates.ACTIVITY))

        model.run(numSteps)
        model.disconnect()

        data = extract(sProbes)
        spikecount = _data_to_img(data // 127, outputShape)
        spikerates = spikecount / numSteps

        batchInputImage = np.expand_dims(np.zeros(inputShape), 0)
        activations = model.predict(batchInputImage)[0] / (vThMant * thrGain)

        if plotUV:
            plt.figure(1)
            _plot_stimulus_response(vProbes, sProbes)
            plt.show()

            plt.figure(2)
            plt.plot(activations.flatten(), spikerates.flatten(), '.')
            plt.show()

            plt.figure(3)
            plt.imshow(normalize_image_dims(activations))
            plt.show()

            plt.figure(4)
            plt.imshow(normalize_image_dims(spikerates))
            plt.show()

        corr = np.corrcoef(np.ravel(spikerates), np.ravel(activations))[0, 1]

        self.assertAlmostEqual(corr,
                               1,
                               2,
                               msg="Correlation between ANN activations "
                               "and SNN spikerates is too low.")
Example #3
0
    def test_random_cor(self):
        """
        Tests the soft reset mode by comparing activations from an ANN
        to spike-rate from the converted SNN. The input and weights
        are randomly initialized.
        """

        seed = 123
        np.random.seed(seed)

        plot = False
        verbose = False

        visualizePartitions = False
        logger = None
        resetMode = 'soft'
        neuronSize = 2 if resetMode == 'soft' else 1

        inputShape = (4, 4, 1)
        inputScale = 255

        inputImage = np.random.randint(int(inputScale * 0.25), int(inputScale),
                                       inputShape)

        maxNumSpikes = 100
        numSteps = int(np.max(inputImage / 255) * maxNumSpikes)

        inputLayer = NxInputLayer(batch_input_shape=(1, ) + inputShape,
                                  vThMant=255,
                                  visualizePartitions=visualizePartitions,
                                  resetMode=resetMode,
                                  probeSpikes=True)
        out = inputLayer.input

        layers = [inputLayer]

        # Conv2D
        kernelShape = (3, 3, 1)
        kernelScale = 4
        # No need to divide by thrGain because spike input receives equal gain.
        vThMant = 2**9 - 1

        kernel_init = partial(kernel_initializer, kernelScale=kernelScale)

        numLayers = 1
        for i in range(numLayers):

            layer = NxConv2D(filters=kernelShape[-1],
                             kernel_size=kernelShape[:-1],
                             vThMant=vThMant,
                             kernel_initializer=kernel_init,
                             bias_initializer='ones',
                             validatePartitions=False,
                             probeSpikes=True,
                             activation='relu',
                             resetMode=resetMode)

            layers.append(layer)
            out = layer(out)

        model = NxModel(inputLayer.input, out, logger=logger)

        for layer in layers[1:]:
            weights, biases = layer.get_weights()
            weights, biases = to_integer(weights, biases, 8,
                                         np.max(weights) // 2)
            layer.set_weights([weights, biases])

        mapper = model.compileModel()

        if verbose:
            printLayerMappings(layers, mapper, synapses=True, inputAxons=True)
            printLayers(layers)
        print(model.summary())

        layerProbes = []

        for layer in layers:
            shape = layer.output_shape[1:]

            # Define probes to read out currents.
            vProbes = []
            sProbes = []
            uProbes = []

            for i in range(int(np.asscalar(np.prod(shape))) * neuronSize):
                vProbes.append(layer[i].probe(ProbableStates.VOLTAGE))
                sProbes.append(layer[i].probe(ProbableStates.ACTIVITY))
                uProbes.append(layer[i].probe(ProbableStates.CURRENT))

            layerProbes.append([uProbes, vProbes, sProbes])

        # Set bias currents
        for i, b in enumerate(np.ravel(inputImage, 'F')):
            inputLayer[i * neuronSize].biasMant = b
            inputLayer[i * neuronSize].phase = 2

        if verbose:
            for layer in layers:
                print(getCompartmentStates(layer, neuronSize))

        model.run(numSteps)

        if verbose:
            for layer in layers:
                print(getCompartmentStates(layer, neuronSize))

        model.disconnect()

        data = [[extract(probe) for probe in lp] for lp in layerProbes]

        if plot:
            plotLayerProbes(layers, data, neuronSize)

        spikesRates = []
        for i, (layer, d) in enumerate(zip(layers, data)):
            sData = d[2][:, (neuronSize - 1)::neuronSize]
            shape = layer.output_shape[1:]
            spikecount = _data_to_img(sData // 127, shape)
            spikesRates.append(spikecount / numSteps)

        batchInputImage = np.expand_dims(inputImage, 0)
        activations = model.predict(batchInputImage)[0]

        if plot:
            plt.figure()
            plt.plot(inputImage.flatten(), spikesRates[0].flatten(), '.')
            plt.show()

            plt.figure()
            plt.plot(activations.flatten(), spikesRates[-1].flatten(), '.')
            plt.show()

            plt.figure()
            plt.imshow(normalize_image_dims(activations))
            plt.show()

            plt.figure()
            plt.imshow(normalize_image_dims(spikesRates[-1]))
            plt.show()

        cor = np.corrcoef(np.ravel(spikesRates[-1]), np.ravel(activations))[0,
                                                                            1]
        self.assertGreater(cor, 0.99)
        if verbose:
            print(cor)
Example #4
0
def runCorrelationRandom(layer,
                         vThMant,
                         insertFlatten=False,
                         inputShape=None,
                         logger=None):
    """Run network to test correlation between ANN and SNN.

    :param NxLayer | Layer layer: NxLayer to test.
    :param int vThMant: Threshold of ``layer``; used to scale activations.
    :param bool insertFlatten: Whether to flatten input before applying it to
        ``layer``.
    :param np.ndarray | tuple | list inputShape: Shape of input to the network.
    :param logging.Logger logger: Logger.

    :return: Pearson correlation coefficient of ANN activations and SNN rates.
    :rtype: float
    """

    seed = 123
    np.random.seed(seed)

    visualizePartitions = False
    plotUV = False

    if inputShape is None:
        inputShape = (7, 7, 1)
    numInputNeurons = int(np.asscalar(np.prod(inputShape)))
    inputScale = numInputNeurons - 1

    thrToInputRatio = 2**7
    thrGain = 2**0

    vThMantInput = thrToInputRatio * inputScale // thrGain

    maxNumSpikes = 100
    numSteps = thrToInputRatio * maxNumSpikes

    inputImage = np.random.randint(0, inputScale, inputShape)

    inputLayer = NxInputLayer(batch_input_shape=(1, ) + inputShape,
                              vThMant=vThMantInput,
                              visualizePartitions=visualizePartitions)

    out = layer(NxFlatten()(inputLayer.input)) \
        if insertFlatten else layer(inputLayer.input)

    model = NxModel(inputLayer.input, out, logger=logger)

    model.compileModel()

    outputShape = layer.output_shape[1:]

    # Define probes to read out currents.
    vProbes0 = []
    for i in range(numInputNeurons):
        vProbes0.append(inputLayer[i].probe(ProbableStates.VOLTAGE))

    vProbes = []
    sProbes = []
    for i in range(int(np.asscalar(np.prod(outputShape)))):
        vProbes.append(layer[i].probe(ProbableStates.VOLTAGE))
        sProbes.append(layer[i].probe(ProbableStates.ACTIVITY))

    # Set bias currents
    for i, b in enumerate(np.ravel(inputImage, 'F')):
        inputLayer[i].biasMant = b
        inputLayer[i].phase = 2

    model.run(numSteps)
    model.disconnect()

    data = extract(sProbes)
    spikecount = _data_to_img(data // 127, outputShape)
    spikerates = spikecount / numSteps * thrToInputRatio

    batchInputImage = np.expand_dims(inputImage, 0)
    activations = model.predict(batchInputImage)[0] / (vThMant * thrGain)

    if plotUV:
        plt.figure(1)
        _plot_stimulus_response(vProbes0, [])
        plt.show()

        plt.figure(2)
        _plot_stimulus_response(vProbes, sProbes)
        plt.show()

        plt.figure(3)
        plt.imshow(normalize_image_dims(inputImage))
        plt.show()

        plt.figure(6)
        plt.plot(activations.flatten(), spikerates.flatten(), '.')
        plt.show()

        plt.figure(7)
        plt.imshow(normalize_image_dims(activations))
        plt.show()

        plt.figure(8)
        plt.imshow(normalize_image_dims(spikerates))
        plt.show()

    return np.corrcoef(np.ravel(spikerates), np.ravel(activations))[0, 1]