def test_synMem(self): """Test issue where nxcompiler runs out of synMem. The problem is that whenever the number of syn bits is an exact multiple of 64, nxcompiler requires an extra mem word. E.g. 128 bits would count as 3 words. Normally, this test would fail due to an assertion in the nxcompiler that checks for number of syn mem words to be smaller than 2**14. We have implemented a check in the NxTF compiler that allocates an extra mem word when it detects that the numBits are an exact multiple of 64. So this test should pass. """ np.random.seed(123) inputLayer = NxInputLayer((1, 1, 256)) x = NxConv2D(256, (1, 1), name='conv1')(inputLayer.input) model = NxModel(inputLayer.input, x) model.compileModel() model.run(1) model.disconnect()
def test_partitionModel3(self): """Test partitioning of a NxModel. After completion of the algorithm, the partitioner reconstructs the kernelIdMap from the synapses and axons generated during partitioning. An exception is thrown if the reconstructed map does not equal the original map. """ inputShape = (73, 81, 3) inputLayer = NxInputLayer(inputShape) hiddenLayer = NxConv2D(11, 3, strides=(2, 2), padding='same', validatePartitions=True)(inputLayer.input) hiddenLayer = NxAveragePooling2D(4, validatePartitions=True)(hiddenLayer) hiddenLayer = NxFlatten()(hiddenLayer) outputLayer = NxDense(50, validatePartitions=True)(hiddenLayer) model = NxModel(inputLayer.input, outputLayer) model.partition() model.clearTemp()
def test_synMem2(self): """Test issue where nxcompiler runs out of synMem. The problem is that whenever the number of syn bits is an exact multiple of 64, nxcompiler requires an extra mem word. E.g. 128 bits would count as 3 words. We have implemented a check in the NxTF compiler that allocates an extra mem word when it detects that the numBits are an exact multiple of 64. So this test should pass. """ inputLayer = NxInputLayer((1, 1, 1)) x = NxConv2D(6, (1, 1), name='conv1', kernel_initializer='ones', synapseEncoding='dense1', useSharedSign=False)(inputLayer.input) model = NxModel(inputLayer.input, x, saveOutput=False) model.compileModel() model.run(1) model.disconnect() layers = model.partitionOptimizer.getLayers() assert layers[1].numSynMemWords == 2
def test_getMultiplicityMap(self): """Test generating a multiplicity map from a coreIdMap.""" inputShape = (10, 10, 2) inputLayer = NxInputLayer(inputShape) layer = NxConv2D(2, 3) layer(inputLayer.input) coreShape = np.array([4, 3, 2]) layerShape = layer.output_shape[1:] numCoresPerAxis = np.ceil(layerShape / coreShape).astype(int) coreIdMap = getCoreIdMapFromCoreShape(coreShape, layerShape, numCoresPerAxis) multiplicityMap = layer.getMultiplicityMap(coreIdMap) if self.verbose: plotMat(multiplicityMap, title='MultiplicityMap') target = [[1, 1, 1, 2, 2, 1, 2, 2, 1, 1], [1, 1, 1, 2, 2, 1, 2, 2, 1, 1], [1, 1, 1, 2, 2, 1, 2, 2, 1, 1], [1, 1, 1, 2, 2, 1, 2, 2, 1, 1], [2, 2, 2, 4, 4, 2, 4, 4, 2, 2], [2, 2, 2, 4, 4, 2, 4, 4, 2, 2], [1, 1, 1, 2, 2, 1, 2, 2, 1, 1], [1, 1, 1, 2, 2, 1, 2, 2, 1, 1], [1, 1, 1, 2, 2, 1, 2, 2, 1, 1], [1, 1, 1, 2, 2, 1, 2, 2, 1, 1]] self.assertTrue(np.array_equal(multiplicityMap, target))
def test_compileNxModel(self): """Check that NxModel can be compiled with Keras.""" inputShape = (7, 7, 1) inputLayer = NxInputLayer(inputShape) outputLayer = NxConv2D(2, 3)(inputLayer.input) model = NxModel(inputLayer.input, outputLayer) model.clearTemp()
def _setup_2layer_stimulus_net(inputImage, vTh, padding='same', verbose=False): """Helper method to set up a 2-layer CNN. The output layer has a single kernel with all weights equal to 1. """ assert isinstance(inputImage, np.ndarray) inputShape = inputImage.shape inputLayer = NxInputLayer(inputShape, vThMant=vTh, biasExp=0, visualizePartitions=False) outputLayer = NxConv2D(filters=1, kernel_size=3, padding=padding, vThMant=1000, weightExponent=0, synapseEncoding='sparse', kernel_initializer='ones', bias_initializer='zeros', visualizePartitions=False) model = NxModel(inputLayer.input, outputLayer(inputLayer.input), numCandidatesToCompute=1) mapper = model.compileModel() if verbose: hiddenCore = model.board.n2Chips[0].n2CoresAsList[1] outputCore = model.board.n2Chips[0].n2CoresAsList[0] mapper.printCore(hiddenCore, compartments=True) mapper.printCore(outputCore, compartments=True) outputShape = model.output_shape[1:] # Define probes to read out current and voltages vProbes1 = [] uProbes2 = [] for i in range(int(np.asscalar(np.prod(inputShape)))): vProbes1.append(inputLayer[i].probe(state=ProbableStates.VOLTAGE)) for i in range(int(np.asscalar(np.prod(outputShape)))): uProbes2.append(outputLayer[i].probe(state=ProbableStates.CURRENT)) # Set bias currents for i, b in enumerate(np.ravel(inputImage, 'F')): inputLayer[i].biasMant = b inputLayer[i].phase = 2 return model, vProbes1, uProbes2
def test_partitionPooling(self): """Test partitioning a single pooling layer.""" inputShape = (5, 5, 4) inputLayer = NxInputLayer(inputShape) outputLayer = NxAveragePooling2D(2, validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(inputLayer.input)) model.partition() model.clearTemp()
def test_partition1(self): """Test partitioning a single NxConv1D layer.""" inputShape = (5, 4) inputLayer = NxInputLayer(inputShape) outputLayer = NxConv1D(2, 3, validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(inputLayer.input)) model.partition() model.clearTemp()
def test_partition1(self): """Test partitioning a single fully-connected layer.""" inputShape = (3, 3, 2) inputLayer = NxInputLayer(inputShape) flattenLayer = NxFlatten()(inputLayer.input) outputLayer = NxDense(10, validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(flattenLayer)) model.partition() model.clearTemp()
def test_evaluateNxModel(self): """Check that NxModel can be evaluated like a Keras Model.""" batchSize = 10 batchInputShape = (batchSize, 7, 7, 1) inputLayer = NxInputLayer(batch_input_shape=batchInputShape) layer = NxConv2D(2, 3)(inputLayer.input) model = NxModel(inputLayer.input, layer) model.compile('sgd', 'mse') model.evaluate(np.random.random_sample(model.input_shape), np.random.random_sample(model.output_shape)) model.clearTemp()
def test_partition2(self): """Test partitioning two fully-connected layers.""" inputShape = (40, 32, 2) inputLayer = NxInputLayer(inputShape) flattenLayer = NxFlatten()(inputLayer.input) hiddenLayer = NxDense(100, validatePartitions=True) outputLayer = NxDense(10, validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(hiddenLayer(flattenLayer))) model.partition() model.clearTemp()
def test_partition2(self): """Test partitioning two NxConv1D layers.""" inputShape = (500, 4) inputLayer = NxInputLayer(inputShape) hiddenLayer = NxConv1D(20, 3, strides=2, padding='same', validatePartitions=True) outputLayer = NxConv1D(10, 2, padding='same', validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(hiddenLayer(inputLayer.input))) model.partition() model.clearTemp()
def test_partitionPooling2(self): """Test partitioning two pooling layers.""" inputShape = (30, 40, 4) inputLayer = NxInputLayer(inputShape) hiddenLayer = NxAveragePooling2D(2, padding='same', validatePartitions=True) outputLayer = NxAveragePooling2D(3, strides=(1, 1), validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(hiddenLayer(inputLayer.input))) model.partition() model.clearTemp()
def test_partition2(self): """Test partitioning two DepthwiseConv2D layers.""" inputShape = (50, 20, 4) inputLayer = NxInputLayer(inputShape) hiddenLayer = NxDepthwiseConv2D(3, strides=(2, 2), padding='same', validatePartitions=True) outputLayer = NxDepthwiseConv2D(2, padding='same', validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(hiddenLayer(inputLayer.input))) model.partition() model.clearTemp()
def test_getCoreIdMapFromCoreShape2(self): """Test generating the coreIdMap given a coreShape.""" inputShape = (4, 4, 2) inputLayer = NxInputLayer(inputShape) layer = NxConv2D(2, 3) layer(inputLayer.input) coreShape = np.array([2, 1, 2]) layerShape = layer.output_shape[1:] numCoresPerAxis = np.ceil(layerShape / coreShape).astype(int) coreIds = getCoreIdMapFromCoreShape(coreShape, layerShape, numCoresPerAxis) target = np.array([[[0, 0], [1, 1]], [[0, 0], [1, 1]]]) self.assertTrue(np.array_equal(coreIds, target)) if self.verbose: plotMat(coreIds[:, :, 0], title='coreIds[:, :, 0]') plotMat(coreIds[:, :, 1], title='coreIds[:, :, 1]')
def setUpDNN(self) -> ComposableDNN: """Sets up a DNN""" # Specify input shape of network. inputShape = (16, 16, 3) ################# # BUILD NETWORK # ################# inputLayer = NxInputLayer(inputShape) x = NxConv2D(4, (3, 3))(inputLayer.input) x = NxAveragePooling2D()(x) x = NxFlatten()(x) x = NxDense(10)(x) DNNModel = NxModel(inputLayer.input, x) composableDNNModel = ComposableDNN(model=DNNModel, num_steps_per_img=100) return composableDNNModel
def create_snn_model(): """ Create a Spiking Model of the MNIST dnn :return: Spiking Model """ vth_mant = 2**9 bias_exp = 6 weight_exponent = 0 synapse_encoding = 'sparse' inputLayer = NxInputLayer(input_shape, vThMant=vth_mant, biasExp=bias_exp) layer = NxConv2D(filters=16, kernel_size=(5, 5), strides=(2, 2), input_shape=input_shape, vThMant=vth_mant, weightExponent=weight_exponent, synapseEncoding=synapse_encoding)(inputLayer.input) layer = NxConv2D(filters=32, kernel_size=(3, 3), vThMant=vth_mant, weightExponent=weight_exponent, synapseEncoding=synapse_encoding)(layer) layer = NxConv2D(filters=64, kernel_size=(3, 3), strides=(2, 2), vThMant=vth_mant, weightExponent=weight_exponent, synapseEncoding=synapse_encoding)(layer) layer = NxConv2D(filters=10, kernel_size=(4, 4), activation='softmax', vThMant=vth_mant, weightExponent=weight_exponent, synapseEncoding=synapse_encoding)(layer) spiking_model = NxModel(inputLayer.input, layer, numCandidatesToCompute=1) spiking_model.summary() return spiking_model
def test_compile(self): """Check compilation of NxModel and retrieval of cxResourceMap.""" # Create an arbitrary model inputShape = (31, 35, 2) inputLayer = NxInputLayer(inputShape) hiddenLayer = NxConv2D(4, 3) outputLayer = NxConv2D(7, 3) model = NxModel(inputLayer.input, outputLayer(hiddenLayer(inputLayer.input)), numCandidatesToCompute=1) model.compileModel() if self.verbose: hiddenLayer.exclusionCriteria.print() outputLayer.exclusionCriteria.print() for l in model.layers: if isinstance(l, NxConv2D): print(l._cxResourceMap)
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))
def test_partitionModel2(self): """Test partitioning of a NxModel. After completion of the algorithm, the partitioner reconstructs the kernelIdMap from the synapses and axons generated during partitioning. An exception is thrown if the reconstructed map does not equal the original map. """ inputShape = (2, 2, 128) inputLayer = NxInputLayer(inputShape) hiddenLayer = NxConv2D(128, 2, padding='same', validatePartitions=True) hiddenLayer.exclusionCriteria.maxNumCompartments /= 4 outputLayer = NxConv2D(256, 3, padding='same', validatePartitions=True) outputLayer.exclusionCriteria.maxNumCompartments /= 4 model = NxModel(inputLayer.input, outputLayer(hiddenLayer(inputLayer.input))) model.partition() model.clearTemp()
def test_CompartmentInterface_probe(self): """Check probe generation.""" # Create an arbitrary model inputShape = (16, 16, 1) inputLayer = NxInputLayer(inputShape) outputLayer = NxConv2D(1, 3, padding='same', validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(inputLayer.input), numCandidatesToCompute=3) model.compileModel() uProbe = outputLayer[0].probe(ProbableStates.CURRENT) sProbe = outputLayer[0].probe(ProbableStates.SPIKE) aProbe = outputLayer[0].probe(ProbableStates.ACTIVITY) pProbe = outputLayer[2].probe(ProbableStates.PHASE) self.assertTrue(isinstance(uProbe, N2Probe)) self.assertTrue(isinstance(sProbe, N2SpikeProbe)) self.assertTrue(isinstance(aProbe, N2Probe)) self.assertTrue(isinstance(pProbe, N2Probe)) self.assertEqual(uProbe.chipId, outputLayer._cxResourceMap[0, 0]) self.assertEqual(uProbe.coreId, outputLayer._cxResourceMap[0, 1]) self.assertEqual(uProbe.nodeId, outputLayer._cxResourceMap[0, 2]) self.assertEqual(sProbe.chipId, outputLayer._cxResourceMap[0, 0]) self.assertEqual(sProbe.coreId, outputLayer._cxResourceMap[0, 1]) self.assertEqual(sProbe.cxId, outputLayer._cxResourceMap[0, 2]) self.assertEqual(aProbe.chipId, outputLayer._cxResourceMap[0, 0]) self.assertEqual(aProbe.coreId, outputLayer._cxResourceMap[0, 1]) self.assertEqual(aProbe.nodeId, outputLayer._cxResourceMap[0, 2]) self.assertEqual(pProbe.chipId, outputLayer._cxResourceMap[2, 0]) self.assertEqual(pProbe.coreId, outputLayer._cxResourceMap[2, 1]) self.assertEqual(pProbe.nodeId, outputLayer._cxResourceMap[2, 2] // 4)
def test_setter_getter(self): """Check setter and getter methods of CompartmentInterface.""" # Create an arbitrary model inputShape = (16, 16, 1) inputLayer = NxInputLayer(inputShape) outputLayer = NxConv2D(1, 3, padding='same', validatePartitions=True) model = NxModel(inputLayer.input, outputLayer(inputLayer.input), numCandidatesToCompute=3) model.compileModel() # Set ome arbitrary values outputLayer[0].current = 1 outputLayer[0].voltage = 2 outputLayer[0].activity = 3 outputLayer[0].biasMant = 4 outputLayer[0].biasExp = 5 outputLayer[0].phase = 1 outputLayer[1].phase = 2 outputLayer[2].phase = 3 outputLayer[3].phase = 4 outputLayer[4].phase = 5 # Check values self.assertEqual(outputLayer[0].current, 1) self.assertEqual(outputLayer[0].voltage, 2) self.assertEqual(outputLayer[0].activity, 3) self.assertEqual(outputLayer[0].biasMant, 4) self.assertEqual(outputLayer[0].biasExp, 5) self.assertEqual(outputLayer[0].phase, 1) self.assertEqual(outputLayer[1].phase, 2) self.assertEqual(outputLayer[2].phase, 3) self.assertEqual(outputLayer[3].phase, 4) self.assertEqual(outputLayer[4].phase, 5)
def test_partitionModel4(self): """Test partitioning of a NxModel. After completion of the algorithm, the partitioner reconstructs the kernelIdMap from the synapses and axons generated during partitioning. An exception is thrown if the reconstructed map does not equal the original map. """ inputShape = (15, 15, 3) inputLayer = NxInputLayer(inputShape) outputLayer = NxConv2D(3, 3, strides=(2, 2), padding='same', validatePartitions=True)(inputLayer.input) model = NxModel(inputLayer.input, outputLayer, numCandidatesToCompute=10) model.partition() model.clearTemp()
# os.environ['PARTITION'] = 'nahuku08' compartment_kwargs = { 'vThMant': 1, 'compartmentVoltageDecay': 4095, 'compartmentCurrentDecay': 4095, 'functionalState': 0, 'enableSomaTrace': True, 'refractoryDelay': 0, } num_input_neurons = 1024 num_output_neurons = 1 input_layer = NxInputLayer(num_input_neurons, compartmentKwargs=compartment_kwargs, inputMode=InputModes.AEDAT) layer = NxDense(num_output_neurons, compartmentKwargs=compartment_kwargs)(input_layer.input) nxmodel = NxModel(input_layer.input, layer) nxmodel.summary() nxmodel.compile() num_steps_per_img = num_input_neurons + 1 nxmodel_composable = ComposableDNN(nxmodel, num_steps_per_img) input_generator = SpikeInputGenerator(name='SpikeGen',
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.")
def test_Flatten(self): """Test correlation between ANN activations and SNN spikerates. The network consists of a 3D input layer, followed by a flatten layer, which has 1-to-1 connections to the output layer. The input pixel values are set to ascending integers in Fortran style. 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. """ visualizePartitions = False doPlot = False # Height, width, depth inputShape = (3, 4, 5) numInputNeurons = int(np.asscalar(np.prod(inputShape))) numOutputNeurons = numInputNeurons - 1 inputScale = 255 thrToInputRatio = 2**7 thrGain = 2**6 # No need to divide by thrGain because spike input receives equal gain. vThMant = 1 vThMantInput = thrToInputRatio * inputScale // thrGain maxNumSpikes = 100 numSteps = thrToInputRatio * maxNumSpikes weights = np.eye(numInputNeurons, numOutputNeurons, dtype=int) biases = np.zeros(numOutputNeurons, int) nxInput = NxInputLayer(inputShape, vThMant=vThMantInput, visualizePartitions=visualizePartitions) nxLayer = NxDense(numOutputNeurons, weights=[weights, biases], vThMant=vThMant, validatePartitions=True, probeSpikes=True) nxModel = NxModel(nxInput.input, nxLayer(NxFlatten()(nxInput.input))) nxModel.compileModel() kerasInput = Input(inputShape) kerasLayer = Dense(numOutputNeurons, weights=[weights, biases])(Flatten()(kerasInput)) kerasModel = Model(kerasInput, kerasLayer) # Define probes to read out currents. sProbes = [] for i in range(numOutputNeurons): sProbes.append(nxLayer[i].probe(ProbableStates.ACTIVITY)) # Set bias currents inputImage = np.reshape(np.arange(numInputNeurons), inputShape, 'F') inputImage = inputImage % 255 for i, b in enumerate(np.ravel(inputImage, 'F')): nxInput[i].biasMant = b nxInput[i].phase = 2 nxModel.run(numSteps) nxModel.disconnect() data = extract(sProbes) spikecount = _data_to_img(data // 127, nxLayer.output_shape[1:]) spikerates = spikecount / numSteps * thrToInputRatio batchInputImage = np.expand_dims(inputImage, 0) activations = \ kerasModel.predict(batchInputImage)[0] / (vThMant * thrGain) if doPlot: 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() 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.")
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)
def test_NxInputLayer(self): """ Test input layer in soft-reset mode. """ plot = False verbose = False resetMode = 'soft' neuronSize = 2 if resetMode == 'soft' else 1 input_shape = (32, 32, 3) inputSize = np.prod(input_shape) inputLayer = NxInputLayer(input_shape, probeSpikes=True, vThMant=255, resetMode=resetMode) out = inputLayer.input model = NxModel(out, out) model.compile('adam', 'categorical_crossentropy', ['accuracy']) model.summary() layers = [inputLayer] input_image = np.linspace( 0, 256, endpoint=False, num=inputSize).reshape(input_shape).astype(int) x_test = [input_image] y_test = [0] mapper = model.compileModel() if verbose: printLayerMappings(layers, mapper, synapses=True, inputAxons=True) printLayers(layers) layerProbes = [] numProbes = 32 for i, layer in enumerate(layers): shape = layer.output_shape[1:] # Define probes to read out currents. vProbes = [] sProbes = [] uProbes = [] toProbe = numProbes if i == (len(layers) - 1) else numProbes * neuronSize toProbe = min(toProbe, int(np.asscalar(np.prod(shape))) * neuronSize) for j in range(toProbe): vProbes.append(layer[j].probe(ProbableStates.VOLTAGE)) sProbes.append(layer[j].probe(ProbableStates.ACTIVITY)) uProbes.append(layer[j].probe(ProbableStates.CURRENT)) layerProbes.append([uProbes, vProbes, sProbes]) # How many time steps to run each sample. num_steps = 1000 # How many samples to test. num_samples_to_test = 1 # Iterate over samples in testset. for i, (input_image, target) in enumerate(zip(x_test, y_test)): if i == num_samples_to_test: break if plot: plt.hist(input_image.ravel()) plt.show() # Set input bias currents. for j, b in enumerate(np.ravel(input_image, 'F')): inputLayer[j * neuronSize].biasMant = b inputLayer[j * neuronSize].biasExp = 6 inputLayer[j * neuronSize].phase = 2 # Run model. model.run(num_steps) # Clean up. data = [[extract(probe) for probe in lp] for lp in layerProbes] spikesRates = [] for i, (layer, d) in enumerate(zip(layers, data)): sData = d[2][:, (neuronSize - 1)::neuronSize] spikecount = (sData // 127).sum(0) spikesRates.append(spikecount / num_steps) model.disconnect() layer_activations = [x_test[0]] if plot: for activations, spikerate in zip(layer_activations, spikesRates): plt.figure() scale = np.max(activations) spikesFlat = spikerate #spikerate.flatten() plt.plot( activations.flatten('F')[:len(spikesFlat)] / scale, spikesFlat, '.') plotLayerProbes(layers, data, neuronSize) cor = np.corrcoef(np.ravel(spikesRates[-1]), np.ravel(layer_activations[0], 'F')[:numProbes // 2])[0, 1] self.assertGreater(cor, 0.99)
# WEIGHTS # ########### # Get SLAYER weights. path_weights = os.path.join(Slayer2Loihi.getModels(), '03_IBMGesture', 'Trained') # Empty container for weights of pooling layers. pool_weights = {} # MODEL # ######### # INPUT LAYER input_layer = NxInputLayer(input_shape, resetMode=reset_mode, compartmentKwargs=compartment_kwargs_input, connectionKwargs=connection_kwargs, inputMode=InputModes.AEDAT) # We apply the pooling on the input events directly so we can skip this layer. # name = 'pool1' # weights = np.load(os.path.join(path_weights, name + '.npy')) # shape = weights.shape + (filters, filters) # weights = np.broadcast_to(np.expand_dims(weights, (-2, -1)), shape) # layer = NxAveragePooling2D(4, 4, # compartmentKwargs=compartment_kwargs, # connectionKwargs=connection_kwargs, # resetMode = reset_mode, # name=name)(input_layer.input) # pool_weights[name] = [weights, np.zeros(filters)]
def test_compressConnections(self): """Check axon compression.""" inputShapes = np.array([[7, 7, 2], [32, 32, 3], [32, 32, 3], [27, 26, 2], [32, 30, 2], [30, 35, 2], [7, 7, 2], [20, 25, 2], [7, 7, 2], [30, 35, 2], [7, 7, 2], [30, 35, 2]]) layerArgs = np.array([[2, 3], [2, 3], [2, 3], [2, 1], [2, 2], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3]]) layerKwargs = np.array([ { 'synapseEncoding': 'sparse' }, { 'synapseEncoding': 'sparse' }, { 'synapseEncoding': 'sparse', 'strides': 2 }, { 'synapseEncoding': 'sparse', 'strides': 2 }, { 'synapseEncoding': 'sparse', 'strides': 2 }, { 'synapseEncoding': 'sparse', 'strides': 2, 'padding': 'same' }, { 'synapseEncoding': 'runlength' }, { 'synapseEncoding': 'runlength', 'strides': 2, 'padding': 'same' }, { 'synapseEncoding': 'dense1' }, { 'synapseEncoding': 'dense1', 'strides': 2, 'padding': 'same' }, { 'synapseEncoding': 'dense2' }, { 'synapseEncoding': 'dense2', 'strides': 2, 'padding': 'same' }, ]) coreShapes = np.array([[5, 5, 2], [30, 10, 2], [10, 5, 2], [7, 13, 2], [16, 5, 2], [8, 9, 2], [5, 5, 2], [6, 9, 2], [5, 5, 2], [15, 10, 2], [5, 5, 2], [6, 9, 2]]) # numOutputAxons (second column) is expected to be zero because we are # looking at the output layer. expectedResults = np.array([[14, 0, 900, 281, 378], [108, 0, 29160, 6873, 10080], [198, 0, 4050, 2430, 2592], [52, 0, 56, 42, 28], [60, 0, 768, 528, 384], [144, 0, 1408, 808, 868], [14, 0, 900, 288, 371], [104, 0, 928, 524, 580], [14, 0, 900, 660, 427], [72, 0, 1408, 1226, 840], [14, 0, 3587, 290, 700], [216, 0, 2920, 874, 1052]]) doTest = np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], bool) np.random.seed(0) for inputShape, args, kwargs, coreShape, expectedResult in \ zip(inputShapes[doTest], layerArgs[doTest], layerKwargs[doTest], coreShapes[doTest], expectedResults[doTest]): with self.subTest(inputShape=inputShape, args=args, kwargs=kwargs, coreShape=coreShape, expectedResult=expectedResult): # The Keras layer initializer does not know how to handle # np.int types. Convert to builtin int manually. args = list(args) args[1] = int(args[1]) inputLayer = NxInputLayer(tuple(inputShape)) layer = NxConv2D(*args, **kwargs) layer(inputLayer.input) # Assumes that this layer will never go beyond one chip. layer.coreCounter = 0 layerShape = layer.output_shape[1:] numCoresPerAxis = np.ceil(layerShape / coreShape).astype(int) coreIdMap = getCoreIdMapFromCoreShape(coreShape, layerShape, numCoresPerAxis) multiplicityMapPre = np.ones(layer.input_shape[1:-1], int) postLayerPartition = getDummyLayer(layer.output_shape[1:]) partitionCandidate = Layer(layer.name, '', layer.compartmentKwargs, layer.connectionKwargs, coreIdMap, multiplicityMapPre, postLayerPartition) partitionCandidate = layer.compile(partitionCandidate) try: layer.validatePartition(partitionCandidate) finally: layer.deleteKernelIdMap() layer.deleteKernelIdMap() result = [ partitionCandidate.numInputAxons, partitionCandidate.numOutputAxons, partitionCandidate.numSyn, partitionCandidate.numSynEntries, partitionCandidate.numSynMemWords ] self.verbose = True if self.verbose: print(result) for er, r in zip(expectedResult, result): self.assertEqual(er, r)