def run_snn(model, x_test, y_test, params_load_path, iteration, timesteps=50, scale_firing_rates=1000, synapse=0.01, batch_size=16): """ Run model in spiking setting :param batch_size: batch size :param model: model reference :param x_test: testing features :param y_test: testing labels :param params_load_path: path to load parameters :param iteration: number of current iteration :param timesteps: number of timesteps :param scale_firing_rates: firing rate scaling :param synapse: synaptic smoothing :return: accuracy, precision, recall, f1 and confusion matrix from the testing data """ converter = nengo_dl.Converter( model, swap_activations={tf.nn.relu: nengo.SpikingRectifiedLinear()}, scale_firing_rates=scale_firing_rates, synapse=synapse ) # create a Nengo converter object and swap all relu activations with spiking relu with converter.net: nengo_dl.configure_settings(stateful=False) output_layer = converter.outputs[model.get_layer( 'output_layer')] # output layer for simulator x_test_tiled = np.tile(x_test, (1, timesteps, 1)) # tile test data to timesteps with nengo_dl.Simulator(converter.net) as simulator: simulator.load_params(params_load_path) # Get the statistics accuracy, precision, recall, f1, confusion_matrix = get_metrics( simulator, output_layer, x_test_tiled, y_test, batch_size, f'{iteration}. CNN (SNN conversion)') return { 'accuracy': accuracy, 'precision': precision, 'recall': recall, 'f1': f1, 'confusion_matrix': confusion_matrix }
def train(params_file="./keras_to_loihi_params", epochs=1, **kwargs): converter = nengo_dl.Converter(model, **kwargs) with nengo_dl.Simulator(converter.net, seed=0, minibatch_size=100) as sim: sim.compile( optimizer=tf.keras.optimizers.Adam(), loss={ converter.outputs[output]: tf.keras.losses.MeanSquaredError() }, metrics={ converter.outputs[output]: tf.keras.metrics.MeanSquaredError() }, ) sim.fit( {converter.inputs[inp]: train_data}, {converter.outputs[output]: train_truth}, epochs=epochs, ) # save the parameters to file sim.save_params(params_file)
def train(params_file="./keras_to_loihi_params", epochs=1, **kwargs): converter = nengo_dl.Converter(model, **kwargs) with nengo_dl.Simulator(converter.net, seed=0, minibatch_size=200) as sim: sim.compile( optimizer=tf.optimizers.RMSprop(0.001), loss={ converter.outputs[dense1]: tf.losses.SparseCategoricalCrossentropy(from_logits=True) }, metrics={ converter.outputs[dense1]: tf.metrics.sparse_categorical_accuracy }, ) sim.fit( {converter.inputs[inp]: train_images}, {converter.outputs[dense1]: train_labels}, epochs=epochs, ) # save the parameters to file sim.save_params(params_file)
def convert(self, add_probes=True, synapse=None, **kwargs): """ Run the NengoDL Converter on the above Keras net add_probes : bool, optional (Default: True) if False, no probes are added to the model, reduces simulation overhead """ converter = nengo_dl.Converter(self.model, **kwargs) # create references to some nengo objects in the network IO objects self.nengo_input = converter.inputs[self.input] self.nengo_dense = converter.outputs[self.dense] net = converter.net self.input = converter.layers[self.input] self.conv0 = converter.layers[self.conv0] self.conv1 = converter.layers[self.conv1] self.output = converter.layers[self.dense] with net: # set our biases to non-trainable to make sure they're always 0 net.config[self.conv0].trainable = False net.config[self.conv1].trainable = False if add_probes: # set up probes so to add the firing rates to the cost function self.probe_conv0 = nengo.Probe(self.conv0, label="probe_conv0") self.probe_conv1 = nengo.Probe(self.conv1, label="probe_conv1") self.probe_dense = nengo.Probe(self.output, label="probe_dense", synapse=synapse) sim = nengo_dl.Simulator(net, minibatch_size=self.minibatch_size, seed=self.seed) return sim, net
def run_network(activation, params_file="./keras_to_loihi_params", n_steps=30, scale_firing_rates=1, synapse=None, n_test=100, n_plots=1, plot_idx=-1): # convert the keras model to a nengo network nengo_converter = nengo_dl.Converter( model, scale_firing_rates=scale_firing_rates, swap_activations={tf.nn.relu: activation}, synapse=synapse, ) print_neurons_type(nengo_converter) # get input/output objects nengo_input = nengo_converter.inputs[inp] nengo_output = nengo_converter.outputs[output] # add probes to layers to record activity with nengo_converter.net: probes = collections.OrderedDict([ [L1_layer, nengo.Probe(nengo_converter.layers[L1])], [L2_layer, nengo.Probe(nengo_converter.layers[L2])], [L3_layer, nengo.Probe(nengo_converter.layers[L3])], ]) # repeat inputs for some number of timesteps tiled_test_data = np.tile(test_data[:n_test], (1, n_steps, 1)) # set some options to speed up simulation with nengo_converter.net: nengo_dl.configure_settings(stateful=False) # build network, load in trained weights, run inference on test images with nengo_dl.Simulator(nengo_converter.net, minibatch_size=1, progress_bar=False) as nengo_sim: nengo_sim.load_params(params_file) data = nengo_sim.predict({nengo_input: tiled_test_data}) # compute accuracy on test data, using output of network on last timestep test_predictions = np.argmax(data[nengo_output][:, -1], axis=-1) correct = test_truth[:n_test, 0, 0] print("Test accuracy: %.2f%%" % (100 * np.mean(test_predictions == correct))) predicted = np.array(test_predictions, dtype=int) correct = np.array(correct, dtype=int) # Plot normalized confusion matrix plot_confusion_matrix(correct, predicted, classes=class_names, normalize=True, title='Normalized confusion matrix') plt.savefig(outdir + f'/{plot_idx}_confusion_matrix.jpg') # plot the results mean_rates = [] for i in range(n_plots): plt.figure(figsize=(12, 6)) plt.subplot(1, 2, 1) # TODO: add a plot of current input signal # plt.title("Input signal") # plt.axis("off") n_layers = len(probes) mean_rates_i = [] for j, layer in enumerate(probes.keys()): probe = probes[layer] plt.subplot(n_layers, 3, (j * 3) + 2) plt.suptitle("Neural activities") outputs = data[probe][i] # look at only at non-zero outputs nonzero = (outputs > 0).any(axis=0) outputs = outputs[:, nonzero] if sum(nonzero) > 0 else outputs # undo neuron amplitude to get real firing rates outputs /= nengo_converter.layers[ layer].ensemble.neuron_type.amplitude rates = outputs.mean(axis=0) mean_rate = rates.mean() mean_rates_i.append(mean_rate) print('"%s" mean firing rate (example %d): %0.1f' % (layer.name, i, mean_rate)) if is_spiking_type(activation): outputs *= 0.001 plt.ylabel("# of Spikes") else: plt.ylabel("Firing rates (Hz)") # plot outputs of first 100 neurons plt.plot(outputs[:, :100]) mean_rates.append(mean_rates_i) plt.xlabel("Timestep") plt.subplot(1, 3, 3) plt.title("Output predictions") plt.plot(tf.nn.softmax(data[nengo_output][i])) plt.legend([str(j) for j in range(10)], loc="upper left") plt.xlabel("Timestep") plt.ylabel("Probability") plt.tight_layout() # take mean rates across all plotted examples mean_rates = np.array(mean_rates).mean(axis=0) return mean_rates
run_network(activation=nengo_loihi.neurons.LoihiSpikingRectifiedLinear(), scale_firing_rates=100, params_file="./keras_to_loihi_loihineuron_params", synapse=0.005, plot_idx=plot_no) plt.savefig(outdir + f'/{plot_no}.jpg') plot_no += 1 pres_time = 0.03 # how long to present each input, in seconds n_test = 100 # how many samples to test # convert the keras model to a nengo network nengo_converter = nengo_dl.Converter( model, scale_firing_rates=400, swap_activations={ tf.nn.relu: nengo_loihi.neurons.LoihiSpikingRectifiedLinear() }, synapse=0.005, ) net = nengo_converter.net # get input/output objects nengo_input = nengo_converter.inputs[inp] nengo_output = nengo_converter.outputs[output] # build network, load in trained weights, save to network with nengo_dl.Simulator(net) as nengo_sim: nengo_sim.load_params("keras_to_loihi_loihineuron_params") nengo_sim.freeze_params(net) with net:
history.append(hist.history["loss"]) np.save("./" + args.model + "Loss", np.array(hist.history["loss"])) print("Plotting training results") plt.figure(figsize=(6, 4), dpi=100) plt.plot(hist.history["loss"]) plt.xlabel("Epochs") plt.ylabel("MSE") plt.title("Loss Curve") plt.savefig("./Images/LossCurve") else: #Otherwise load the pre-trained model from memory print("Loading existing model...") model = tf.keras.models.load_model(modelPath) print("Creating nengo nengo model...") snnConverter = nengo_dl.Converter(model) snnModel = snnConverter.net with snnModel: outProbe = nengo.Probe(snnModel.ensembles[2]) snnEnsembleProbe = snnModel.probes[0] snnInLayer = [snnConverter.inputs[key] for key in snnConverter.inputs][0] #If evaluation flag is specified if args.evaluate: print("Loading single example input...") singleInput, singleTarget = iter(trainSet).next() singleInput = singleInput.numpy() singleTarget = singleTarget.numpy().reshape((-1, 1)) print("Calculating ANN output") sigOut = model.predict(singleInput)
def run_ann(model, train, test, params_save_path, iteration, optimizer, loss, callbacks=None, valid=None, shuffle_training=True, batch_size=16, num_epochs=30): """ Run analog network with cross-validation :param batch_size: batch size during training :param model: reference to the tensorflow model :param train: pair of training data (x_train, y_train) :param valid: pair of validation data (x_val, y_val) :param test: pair of testing data (x_test, y_test) :param params_save_path: output path to save weights of the network :param iteration: number of the iteration in CV :param shuffle_training: shuffle samples :param num_epochs: number of epochs to train for :return: accuracy, precision, recall, f1 and confusion matrix from the testing data """ x_train, y_train = train[0], train[1] x_test, y_test = test[0], test[1] if valid is not None: x_valid, y_valid = valid[0], valid[1] converter = nengo_dl.Converter(model) with nengo_dl.Simulator(converter.net, minibatch_size=batch_size) as simulator: simulator.compile(optimizer=optimizer, loss=loss, metrics=['accuracy']) input_layer = converter.inputs[model.get_layer( 'input_layer')] # get the input layer reference output_layer = converter.outputs[model.get_layer( 'output_layer')] # get the output layer reference # fit the model with the training data simulator.fit(x={input_layer: x_train}, y={output_layer: y_train}, validation_data=({ input_layer: x_valid }, { output_layer: y_valid }) if valid is not None else None, epochs=num_epochs, shuffle=shuffle_training, callbacks=callbacks # early stop to avoid overfitting ) simulator.save_params(params_save_path) # save weights to the file # Get the statistics accuracy, precision, recall, f1, confusion_matrix = get_metrics( simulator, output_layer, x_test, y_test, batch_size, f'{iteration}. CNN') return { 'accuracy': accuracy, 'precision': precision, 'recall': recall, 'f1': f1, 'confusion_matrix': confusion_matrix }