ANNarchy 5.0.3
  • ANNarchy
  • Installation
  • Tutorial
  • Manual
  • Notebooks
  • Reference

ANN-to-SNN conversion - MLP

  • List of notebooks
  • Rate-coded networks
    • Echo-state networks
    • Neural field
    • Bar Learning
    • Miconi network
    • Structural plasticity
  • Spiking networks
    • AdEx
    • PyNN/Brian
    • GIF I
    • GIF II
    • Izhikevich
    • Synaptic transmission
    • Gap junctions
    • Hodgkin-Huxley
    • COBA/CUBA
    • STP
    • STDP I
    • STDP II
    • Homeostatic STDP - Ramp
    • Homeostatic STDP - SORF
  • Advanced features
    • Hybrid networks
    • Parallel run
    • Bayesian optimization
  • Extensions
    • Image
    • Tensorboard
    • BOLD monitor I
    • BOLD monitor II
    • ANN to SNN I
    • ANN to SNN II

On this page

  • Training an ANN in tensorflow/keras
  • Initialize the ANN-to-SNN converter

ANN-to-SNN conversion - MLP

Download JupyterNotebook Download JupyterNotebook

This notebook demonstrates how to transform a fully-connected neural network trained using tensorflow/keras into an SNN network usable in ANNarchy.

The methods are adapted from the original models used in:

Diehl et al. (2015) “Fast-classifying, high-accuracy spiking deep networks through weight and threshold balancing” Proceedings of IJCNN. doi: 10.1109/IJCNN.2015.7280696

#!pip install ANNarchy
import numpy as np
import matplotlib.pyplot as plt

import tensorflow as tf
print(f"Tensorflow {tf.__version__}")
2026-07-22 07:23:48.839839: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:485] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered
2026-07-22 07:23:49.150802: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:8454] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered
2026-07-22 07:23:49.246375: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1452] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered
2026-07-22 07:23:49.968483: I tensorflow/core/platform/cpu_feature_guard.cc:210] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.
2026-07-22 07:23:53.212583: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:38] TF-TRT Warning: Could not find TensorRT
Tensorflow 2.17.0

First we need to download and process the MNIST dataset provided by tensorflow.

# Download data
(X_train, t_train), (X_test, t_test) = tf.keras.datasets.mnist.load_data()

# Normalize inputs
X_train = X_train.reshape(X_train.shape[0], 784).astype('float32') / 255.
X_test = X_test.reshape(X_test.shape[0], 784).astype('float32') / 255.

# One-hot output vectors
T_train = tf.keras.utils.to_categorical(t_train, 10)
T_test = tf.keras.utils.to_categorical(t_test, 10)

Training an ANN in tensorflow/keras

The tensorflow.keras network is build using the functional API.

The fully-connected network has two fully connected layers with ReLU, no bias, dropout at 0.5, and a softmax output layer with 10 neurons. We use the standard SGD optimizer and the categorical crossentropy loss for classification.

def create_mlp():
    # Model
    inputs = tf.keras.layers.Input(shape=(784,))
    x= tf.keras.layers.Dense(128, use_bias=False, activation='relu')(inputs)
    x = tf.keras.layers.Dropout(0.5)(x)
    x= tf.keras.layers.Dense(128, use_bias=False, activation='relu')(x)
    x = tf.keras.layers.Dropout(0.5)(x)
    x=tf.keras.layers.Dense(10, use_bias=False, activation='softmax')(x)

    model= tf.keras.Model(inputs, x)

    # Optimizer
    optimizer = tf.keras.optimizers.SGD(learning_rate=0.05)

    # Loss function
    model.compile(
        loss='categorical_crossentropy', # loss function
        optimizer=optimizer, # learning rule
        metrics=['accuracy'] # show accuracy
    )
    print(model.summary())

    return model

We can now train the network and save the weights in the HDF5 format.

# Create model
model = create_mlp()

# Train model
history = model.fit(
    X_train, T_train,       # training data
    batch_size=128,          # batch size
    epochs=20,              # Maximum number of epochs
    validation_split=0.1,   # Percentage of training data used for validation
    verbose=2)

model.save("runs/mlp.keras")

# Test model
predictions_keras = model.predict(X_test, verbose=0)
test_loss, test_accuracy = model.evaluate(X_test, T_test, verbose=0)
print(f"Test accuracy: {test_accuracy}")
WARNING: All log messages before absl::InitializeLog() is called are written to STDERR
I0000 00:00:1784697838.326815 4092498 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
I0000 00:00:1784697838.327324 4092498 cuda_executor.cc:1015] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero. See more at https://github.com/torvalds/linux/blob/v6.0/Documentation/ABI/testing/sysfs-bus-pci#L344-L355
2026-07-22 07:23:58.632826: W tensorflow/core/common_runtime/gpu/gpu_device.cc:2343] Cannot dlopen some GPU libraries. Please make sure the missing libraries mentioned above are installed properly if you would like to use GPU. Follow the guide at https://www.tensorflow.org/install/gpu for how to download and setup the required libraries for your platform.
Skipping registering GPU devices...
Model: "functional"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer (InputLayer)        │ (None, 784)            │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense (Dense)                   │ (None, 128)            │       100,352 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout (Dropout)               │ (None, 128)            │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_1 (Dense)                 │ (None, 128)            │        16,384 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_1 (Dropout)             │ (None, 128)            │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_2 (Dense)                 │ (None, 10)             │         1,280 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 118,016 (461.00 KB)
 Trainable params: 118,016 (461.00 KB)
 Non-trainable params: 0 (0.00 B)
None
Epoch 1/20
422/422 - 2s - 5ms/step - accuracy: 0.6506 - loss: 1.0740 - val_accuracy: 0.9090 - val_loss: 0.3351
Epoch 2/20
422/422 - 1s - 3ms/step - accuracy: 0.8333 - loss: 0.5543 - val_accuracy: 0.9312 - val_loss: 0.2444
Epoch 3/20
422/422 - 1s - 3ms/step - accuracy: 0.8662 - loss: 0.4560 - val_accuracy: 0.9418 - val_loss: 0.2082
Epoch 4/20
422/422 - 1s - 3ms/step - accuracy: 0.8833 - loss: 0.4019 - val_accuracy: 0.9463 - val_loss: 0.1864
Epoch 5/20
422/422 - 1s - 3ms/step - accuracy: 0.8940 - loss: 0.3686 - val_accuracy: 0.9528 - val_loss: 0.1660
Epoch 6/20
422/422 - 1s - 3ms/step - accuracy: 0.9033 - loss: 0.3395 - val_accuracy: 0.9550 - val_loss: 0.1589
Epoch 7/20
422/422 - 1s - 3ms/step - accuracy: 0.9089 - loss: 0.3139 - val_accuracy: 0.9602 - val_loss: 0.1441
Epoch 8/20
422/422 - 1s - 3ms/step - accuracy: 0.9146 - loss: 0.2975 - val_accuracy: 0.9622 - val_loss: 0.1342
Epoch 9/20
422/422 - 1s - 3ms/step - accuracy: 0.9182 - loss: 0.2847 - val_accuracy: 0.9638 - val_loss: 0.1307
Epoch 10/20
422/422 - 1s - 3ms/step - accuracy: 0.9215 - loss: 0.2736 - val_accuracy: 0.9632 - val_loss: 0.1268
Epoch 11/20
422/422 - 1s - 3ms/step - accuracy: 0.9233 - loss: 0.2634 - val_accuracy: 0.9657 - val_loss: 0.1236
Epoch 12/20
422/422 - 1s - 3ms/step - accuracy: 0.9265 - loss: 0.2542 - val_accuracy: 0.9680 - val_loss: 0.1156
Epoch 13/20
422/422 - 1s - 3ms/step - accuracy: 0.9310 - loss: 0.2416 - val_accuracy: 0.9688 - val_loss: 0.1089
Epoch 14/20
422/422 - 1s - 3ms/step - accuracy: 0.9321 - loss: 0.2374 - val_accuracy: 0.9680 - val_loss: 0.1093
Epoch 15/20
422/422 - 1s - 3ms/step - accuracy: 0.9351 - loss: 0.2254 - val_accuracy: 0.9692 - val_loss: 0.1064
Epoch 16/20
422/422 - 1s - 3ms/step - accuracy: 0.9365 - loss: 0.2220 - val_accuracy: 0.9705 - val_loss: 0.1037
Epoch 17/20
422/422 - 1s - 3ms/step - accuracy: 0.9382 - loss: 0.2146 - val_accuracy: 0.9720 - val_loss: 0.0998
Epoch 18/20
422/422 - 1s - 3ms/step - accuracy: 0.9390 - loss: 0.2153 - val_accuracy: 0.9725 - val_loss: 0.0992
Epoch 19/20
422/422 - 1s - 3ms/step - accuracy: 0.9400 - loss: 0.2070 - val_accuracy: 0.9717 - val_loss: 0.0976
Epoch 20/20
422/422 - 1s - 3ms/step - accuracy: 0.9392 - loss: 0.2059 - val_accuracy: 0.9737 - val_loss: 0.0991
Test accuracy: 0.9656000137329102
plt.figure(figsize=(12, 6))
plt.subplot(121)
plt.plot(history.history['loss'], '-r', label="Training")
plt.plot(history.history['val_loss'], '-b', label="Validation")
plt.xlabel('Epoch #')
plt.ylabel('Loss')
plt.legend()

plt.subplot(122)
plt.plot(history.history['accuracy'], '-r', label="Training")
plt.plot(history.history['val_accuracy'], '-b', label="Validation")
plt.xlabel('Epoch #')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

Initialize the ANN-to-SNN converter

We first create an instance of the ANN-to-SNN conversion object. The function receives the input_encoding parameter, which is the type of input encoding we want to use.

By default, there are intrinsically bursting (IB), phase shift oscillation (PSO) and Poisson (poisson) available.

from ANNarchy.extensions.ann_to_snn_conversion import ANNtoSNNConverter

snn_converter = ANNtoSNNConverter(
    input_encoding='IB', 
    hidden_neuron='IaF',
    read_out='spike_count',
)
ANNarchy 5.0 (5.0.3) on linux (posix).

After that, we provide the TensorFlow model stored as a .keras file to the conversion tool. The print-out of the network structure of the imported network is suppressed when show_info=False is provided to load_keras_model.

net = snn_converter.load_keras_model("runs/mlp.keras", show_info=True)
WARNING: Dense representation is an experimental feature for spiking models, we greatly appreciate bug reports. 
* Input layer: input_layer, (784,)
* InputLayer skipped.
* Dense layer: dense, 128 
    weights: (128, 784)
    mean -0.0038855434395372868, std 0.05275190994143486
    min -0.3399130702018738, max 0.22397100925445557
* Dropout skipped.
* Dense layer: dense_1, 128 
    weights: (128, 128)
    mean 0.0033791367895901203, std 0.10158202797174454
    min -0.26398149132728577, max 0.33888253569602966
* Dropout skipped.
* Dense layer: dense_2, 10 
    weights: (10, 128)
    mean -0.0020518447272479534, std 0.2154923677444458
    min -0.4908585250377655, max 0.4569709300994873

When the network has been built successfully, we can perform a test using all MNIST training samples. Using duration_per_sample, the duration simulated for each image can be specified. Here, 200 ms seem to be enough.

predictions_snn = snn_converter.predict(X_test, duration_per_sample=200)
  0%|                                                                                       | 0/10000 [00:00<?, ?it/s]  0%|▍                                                                            | 50/10000 [00:00<00:20, 497.01it/s]  1%|▊                                                                           | 111/10000 [00:00<00:17, 561.46it/s]  2%|█▎                                                                          | 172/10000 [00:00<00:16, 582.71it/s]  2%|█▊                                                                          | 234/10000 [00:00<00:16, 594.41it/s]  3%|██▏                                                                         | 295/10000 [00:00<00:16, 599.55it/s]  4%|██▋                                                                         | 356/10000 [00:00<00:16, 601.53it/s]  4%|███▏                                                                        | 418/10000 [00:00<00:15, 605.90it/s]  5%|███▋                                                                        | 479/10000 [00:00<00:15, 606.22it/s]  5%|████                                                                        | 540/10000 [00:00<00:15, 606.22it/s]  6%|████▌                                                                       | 601/10000 [00:01<00:15, 602.17it/s]  7%|█████                                                                       | 662/10000 [00:01<00:15, 600.50it/s]  7%|█████▌                                                                      | 724/10000 [00:01<00:15, 603.44it/s]  8%|█████▉                                                                      | 786/10000 [00:01<00:15, 605.44it/s]  8%|██████▍                                                                     | 848/10000 [00:01<00:15, 607.87it/s]  9%|██████▉                                                                     | 909/10000 [00:01<00:14, 607.08it/s] 10%|███████▍                                                                    | 971/10000 [00:01<00:14, 609.52it/s] 10%|███████▋                                                                   | 1033/10000 [00:01<00:14, 611.15it/s] 11%|████████▏                                                                  | 1095/10000 [00:01<00:14, 611.68it/s] 12%|████████▋                                                                  | 1157/10000 [00:01<00:14, 610.72it/s] 12%|█████████▏                                                                 | 1219/10000 [00:02<00:14, 612.70it/s] 13%|█████████▌                                                                 | 1281/10000 [00:02<00:14, 613.57it/s] 13%|██████████                                                                 | 1343/10000 [00:02<00:14, 614.35it/s] 14%|██████████▌                                                                | 1405/10000 [00:02<00:13, 614.56it/s] 15%|███████████                                                                | 1467/10000 [00:02<00:13, 612.64it/s] 15%|███████████▍                                                               | 1529/10000 [00:02<00:13, 608.87it/s] 16%|███████████▉                                                               | 1590/10000 [00:02<00:13, 603.86it/s] 17%|████████████▍                                                              | 1651/10000 [00:02<00:13, 605.28it/s] 17%|████████████▊                                                              | 1714/10000 [00:02<00:13, 610.08it/s] 18%|█████████████▎                                                             | 1776/10000 [00:02<00:13, 609.99it/s] 18%|█████████████▊                                                             | 1838/10000 [00:03<00:13, 612.86it/s] 19%|██████████████▎                                                            | 1900/10000 [00:03<00:13, 612.25it/s] 20%|██████████████▋                                                            | 1963/10000 [00:03<00:13, 614.77it/s] 20%|███████████████▏                                                           | 2025/10000 [00:03<00:12, 615.53it/s] 21%|███████████████▋                                                           | 2087/10000 [00:03<00:12, 613.14it/s] 21%|████████████████                                                           | 2149/10000 [00:03<00:12, 611.78it/s] 22%|████████████████▌                                                          | 2211/10000 [00:03<00:12, 610.05it/s] 23%|█████████████████                                                          | 2273/10000 [00:03<00:12, 608.90it/s] 23%|█████████████████▌                                                         | 2335/10000 [00:03<00:12, 609.77it/s] 24%|█████████████████▉                                                         | 2396/10000 [00:03<00:12, 609.61it/s] 25%|██████████████████▍                                                        | 2457/10000 [00:04<00:12, 609.34it/s] 25%|██████████████████▉                                                        | 2518/10000 [00:04<00:12, 608.82it/s] 26%|███████████████████▎                                                       | 2580/10000 [00:04<00:12, 609.52it/s] 26%|███████████████████▊                                                       | 2641/10000 [00:04<00:12, 608.98it/s] 27%|████████████████████▎                                                      | 2703/10000 [00:04<00:11, 611.35it/s] 28%|████████████████████▋                                                      | 2765/10000 [00:04<00:11, 610.63it/s] 28%|█████████████████████▏                                                     | 2827/10000 [00:04<00:11, 608.98it/s] 29%|█████████████████████▋                                                     | 2888/10000 [00:04<00:11, 608.46it/s] 29%|██████████████████████                                                     | 2949/10000 [00:04<00:11, 608.42it/s] 30%|██████████████████████▌                                                    | 3011/10000 [00:04<00:11, 611.21it/s] 31%|███████████████████████                                                    | 3073/10000 [00:05<00:11, 605.52it/s] 31%|███████████████████████▌                                                   | 3135/10000 [00:05<00:11, 608.61it/s] 32%|███████████████████████▉                                                   | 3196/10000 [00:05<00:11, 608.69it/s] 33%|████████████████████████▍                                                  | 3258/10000 [00:05<00:11, 609.22it/s] 33%|████████████████████████▉                                                  | 3320/10000 [00:05<00:10, 609.79it/s] 34%|█████████████████████████▎                                                 | 3382/10000 [00:05<00:10, 609.89it/s] 34%|█████████████████████████▊                                                 | 3444/10000 [00:05<00:10, 610.81it/s] 35%|██████████████████████████▎                                                | 3506/10000 [00:05<00:10, 610.66it/s] 36%|██████████████████████████▊                                                | 3568/10000 [00:05<00:10, 608.64it/s] 36%|███████████████████████████▏                                               | 3629/10000 [00:05<00:10, 607.74it/s] 37%|███████████████████████████▋                                               | 3691/10000 [00:06<00:10, 610.50it/s] 38%|████████████████████████████▏                                              | 3753/10000 [00:06<00:10, 610.66it/s] 38%|████████████████████████████▌                                              | 3815/10000 [00:06<00:10, 609.50it/s] 39%|█████████████████████████████                                              | 3876/10000 [00:06<00:10, 607.61it/s] 39%|█████████████████████████████▌                                             | 3938/10000 [00:06<00:09, 609.25it/s] 40%|█████████████████████████████▉                                             | 3999/10000 [00:06<00:09, 605.26it/s] 41%|██████████████████████████████▍                                            | 4061/10000 [00:06<00:09, 608.83it/s] 41%|██████████████████████████████▉                                            | 4122/10000 [00:06<00:09, 608.13it/s] 42%|███████████████████████████████▍                                           | 4184/10000 [00:06<00:09, 609.26it/s] 42%|███████████████████████████████▊                                           | 4246/10000 [00:06<00:09, 610.50it/s] 43%|████████████████████████████████▎                                          | 4308/10000 [00:07<00:09, 613.20it/s] 44%|████████████████████████████████▊                                          | 4371/10000 [00:07<00:09, 615.64it/s] 44%|█████████████████████████████████▏                                         | 4433/10000 [00:07<00:09, 613.73it/s] 45%|█████████████████████████████████▋                                         | 4495/10000 [00:07<00:08, 614.09it/s] 46%|██████████████████████████████████▏                                        | 4557/10000 [00:07<00:08, 610.58it/s] 46%|██████████████████████████████████▋                                        | 4619/10000 [00:07<00:08, 609.93it/s] 47%|███████████████████████████████████                                        | 4680/10000 [00:07<00:08, 609.37it/s] 47%|███████████████████████████████████▌                                       | 4742/10000 [00:07<00:08, 611.18it/s] 48%|████████████████████████████████████                                       | 4804/10000 [00:07<00:08, 612.29it/s] 49%|████████████████████████████████████▍                                      | 4866/10000 [00:07<00:08, 612.12it/s] 49%|████████████████████████████████████▉                                      | 4928/10000 [00:08<00:08, 610.39it/s] 50%|█████████████████████████████████████▍                                     | 4990/10000 [00:08<00:08, 611.47it/s] 51%|█████████████████████████████████████▉                                     | 5052/10000 [00:08<00:08, 607.65it/s] 51%|██████████████████████████████████████▎                                    | 5113/10000 [00:08<00:08, 606.99it/s] 52%|██████████████████████████████████████▊                                    | 5174/10000 [00:08<00:07, 605.53it/s] 52%|███████████████████████████████████████▎                                   | 5237/10000 [00:08<00:07, 609.76it/s] 53%|███████████████████████████████████████▋                                   | 5298/10000 [00:08<00:07, 607.46it/s] 54%|████████████████████████████████████████▏                                  | 5359/10000 [00:08<00:07, 605.08it/s] 54%|████████████████████████████████████████▋                                  | 5420/10000 [00:08<00:07, 604.02it/s] 55%|█████████████████████████████████████████                                  | 5481/10000 [00:09<00:07, 601.12it/s] 55%|█████████████████████████████████████████▌                                 | 5542/10000 [00:09<00:07, 600.38it/s] 56%|██████████████████████████████████████████                                 | 5603/10000 [00:09<00:07, 598.01it/s] 57%|██████████████████████████████████████████▍                                | 5665/10000 [00:09<00:07, 601.85it/s] 57%|██████████████████████████████████████████▉                                | 5726/10000 [00:09<00:07, 603.33it/s] 58%|███████████████████████████████████████████▍                               | 5787/10000 [00:09<00:06, 605.27it/s] 58%|███████████████████████████████████████████▊                               | 5848/10000 [00:09<00:06, 604.13it/s] 59%|████████████████████████████████████████████▎                              | 5910/10000 [00:09<00:06, 606.06it/s] 60%|████████████████████████████████████████████▊                              | 5971/10000 [00:09<00:06, 604.55it/s] 60%|█████████████████████████████████████████████▏                             | 6032/10000 [00:09<00:06, 599.68it/s] 61%|█████████████████████████████████████████████▋                             | 6092/10000 [00:10<00:06, 594.65it/s] 62%|██████████████████████████████████████████████▏                            | 6152/10000 [00:10<00:06, 588.32it/s] 62%|██████████████████████████████████████████████▌                            | 6211/10000 [00:10<00:06, 585.20it/s] 63%|███████████████████████████████████████████████                            | 6271/10000 [00:10<00:06, 588.29it/s] 63%|███████████████████████████████████████████████▍                           | 6330/10000 [00:10<00:06, 587.19it/s] 64%|███████████████████████████████████████████████▉                           | 6389/10000 [00:10<00:06, 585.41it/s] 64%|████████████████████████████████████████████████▎                          | 6449/10000 [00:10<00:06, 588.95it/s] 65%|████████████████████████████████████████████████▊                          | 6508/10000 [00:10<00:05, 585.23it/s] 66%|█████████████████████████████████████████████████▎                         | 6569/10000 [00:10<00:05, 591.92it/s] 66%|█████████████████████████████████████████████████▋                         | 6632/10000 [00:10<00:05, 602.17it/s] 67%|██████████████████████████████████████████████████▏                        | 6694/10000 [00:11<00:05, 604.87it/s] 68%|██████████████████████████████████████████████████▋                        | 6755/10000 [00:11<00:05, 598.20it/s] 68%|███████████████████████████████████████████████████                        | 6815/10000 [00:11<00:05, 596.82it/s] 69%|███████████████████████████████████████████████████▌                       | 6876/10000 [00:11<00:05, 597.75it/s] 69%|████████████████████████████████████████████████████                       | 6938/10000 [00:11<00:05, 601.45it/s] 70%|████████████████████████████████████████████████████▍                      | 6999/10000 [00:11<00:04, 600.34it/s] 71%|████████████████████████████████████████████████████▉                      | 7060/10000 [00:11<00:04, 602.44it/s] 71%|█████████████████████████████████████████████████████▍                     | 7121/10000 [00:11<00:04, 602.54it/s] 72%|█████████████████████████████████████████████████████▊                     | 7182/10000 [00:11<00:04, 601.52it/s] 72%|██████████████████████████████████████████████████████▎                    | 7244/10000 [00:11<00:04, 604.64it/s] 73%|██████████████████████████████████████████████████████▊                    | 7305/10000 [00:12<00:04, 604.02it/s] 74%|███████████████████████████████████████████████████████▏                   | 7366/10000 [00:12<00:04, 600.38it/s] 74%|███████████████████████████████████████████████████████▋                   | 7427/10000 [00:12<00:04, 596.09it/s] 75%|████████████████████████████████████████████████████████▏                  | 7489/10000 [00:12<00:04, 602.01it/s] 76%|████████████████████████████████████████████████████████▋                  | 7550/10000 [00:12<00:04, 600.80it/s] 76%|█████████████████████████████████████████████████████████                  | 7611/10000 [00:12<00:03, 600.37it/s] 77%|█████████████████████████████████████████████████████████▌                 | 7672/10000 [00:12<00:03, 599.64it/s] 77%|█████████████████████████████████████████████████████████▉                 | 7732/10000 [00:12<00:03, 599.12it/s] 78%|██████████████████████████████████████████████████████████▍                | 7792/10000 [00:12<00:03, 589.13it/s] 79%|██████████████████████████████████████████████████████████▉                | 7851/10000 [00:12<00:03, 584.32it/s] 79%|███████████████████████████████████████████████████████████▎               | 7910/10000 [00:13<00:03, 579.49it/s] 80%|███████████████████████████████████████████████████████████▊               | 7968/10000 [00:13<00:03, 578.37it/s] 80%|████████████████████████████████████████████████████████████▏              | 8026/10000 [00:13<00:03, 577.94it/s] 81%|████████████████████████████████████████████████████████████▋              | 8084/10000 [00:13<00:03, 578.17it/s] 81%|█████████████████████████████████████████████████████████████              | 8143/10000 [00:13<00:03, 581.38it/s] 82%|█████████████████████████████████████████████████████████████▌             | 8202/10000 [00:13<00:03, 582.94it/s] 83%|█████████████████████████████████████████████████████████████▉             | 8262/10000 [00:13<00:02, 586.21it/s] 83%|██████████████████████████████████████████████████████████████▍            | 8322/10000 [00:13<00:02, 588.19it/s] 84%|██████████████████████████████████████████████████████████████▊            | 8382/10000 [00:13<00:02, 589.13it/s] 84%|███████████████████████████████████████████████████████████████▎           | 8442/10000 [00:13<00:02, 590.57it/s] 85%|███████████████████████████████████████████████████████████████▊           | 8502/10000 [00:14<00:02, 589.31it/s] 86%|████████████████████████████████████████████████████████████████▏          | 8561/10000 [00:14<00:02, 583.62it/s] 86%|████████████████████████████████████████████████████████████████▋          | 8621/10000 [00:14<00:02, 586.93it/s] 87%|█████████████████████████████████████████████████████████████████          | 8682/10000 [00:14<00:02, 592.40it/s] 87%|█████████████████████████████████████████████████████████████████▌         | 8742/10000 [00:14<00:02, 590.58it/s] 88%|██████████████████████████████████████████████████████████████████         | 8802/10000 [00:14<00:02, 590.34it/s] 89%|██████████████████████████████████████████████████████████████████▍        | 8862/10000 [00:14<00:01, 589.42it/s] 89%|██████████████████████████████████████████████████████████████████▉        | 8922/10000 [00:14<00:01, 591.50it/s] 90%|███████████████████████████████████████████████████████████████████▎       | 8982/10000 [00:14<00:01, 588.52it/s] 90%|███████████████████████████████████████████████████████████████████▊       | 9042/10000 [00:15<00:01, 589.62it/s] 91%|████████████████████████████████████████████████████████████████████▎      | 9101/10000 [00:15<00:01, 587.23it/s] 92%|████████████████████████████████████████████████████████████████████▋      | 9160/10000 [00:15<00:01, 583.88it/s] 92%|█████████████████████████████████████████████████████████████████████▏     | 9219/10000 [00:15<00:01, 582.72it/s] 93%|█████████████████████████████████████████████████████████████████████▌     | 9278/10000 [00:15<00:01, 583.29it/s] 93%|██████████████████████████████████████████████████████████████████████     | 9340/10000 [00:15<00:01, 593.27it/s] 94%|██████████████████████████████████████████████████████████████████████▌    | 9401/10000 [00:15<00:01, 595.69it/s] 95%|██████████████████████████████████████████████████████████████████████▉    | 9461/10000 [00:15<00:00, 596.50it/s] 95%|███████████████████████████████████████████████████████████████████████▍   | 9521/10000 [00:15<00:00, 596.49it/s] 96%|███████████████████████████████████████████████████████████████████████▊   | 9581/10000 [00:15<00:00, 595.05it/s] 96%|████████████████████████████████████████████████████████████████████████▎  | 9641/10000 [00:16<00:00, 596.44it/s] 97%|████████████████████████████████████████████████████████████████████████▊  | 9702/10000 [00:16<00:00, 600.37it/s] 98%|█████████████████████████████████████████████████████████████████████████▏ | 9763/10000 [00:16<00:00, 601.32it/s] 98%|█████████████████████████████████████████████████████████████████████████▋ | 9825/10000 [00:16<00:00, 605.22it/s] 99%|██████████████████████████████████████████████████████████████████████████▏| 9888/10000 [00:16<00:00, 610.11it/s]100%|██████████████████████████████████████████████████████████████████████████▋| 9950/10000 [00:16<00:00, 609.23it/s]100%|██████████████████████████████████████████████████████████████████████████| 10000/10000 [00:16<00:00, 601.83it/s]

Using the recorded predictions, we can now compute the accuracy using scikit-learn for all presented samples.

from sklearn.metrics import classification_report, accuracy_score

print(classification_report(t_test, predictions_snn))
print("Test accuracy of the SNN:", accuracy_score(t_test, predictions_snn))
              precision    recall  f1-score   support

           0       0.97      0.99      0.98       980
           1       0.98      0.99      0.98      1135
           2       0.96      0.96      0.96      1032
           3       0.96      0.96      0.96      1010
           4       0.97      0.94      0.96       982
           5       0.97      0.95      0.96       892
           6       0.96      0.98      0.97       958
           7       0.96      0.96      0.96      1028
           8       0.96      0.95      0.95       974
           9       0.94      0.95      0.95      1009

    accuracy                           0.96     10000
   macro avg       0.96      0.96      0.96     10000
weighted avg       0.96      0.96      0.96     10000

Test accuracy of the SNN: 0.9629

For comparison, here is the performance of the original ANN in keras:

print(classification_report(t_test, predictions_keras.argmax(axis=1)))
print("Test accuracy of the ANN:", accuracy_score(t_test, predictions_keras.argmax(axis=1)))
              precision    recall  f1-score   support

           0       0.97      0.99      0.98       980
           1       0.98      0.99      0.98      1135
           2       0.96      0.96      0.96      1032
           3       0.96      0.96      0.96      1010
           4       0.97      0.96      0.96       982
           5       0.96      0.96      0.96       892
           6       0.96      0.97      0.97       958
           7       0.96      0.97      0.96      1028
           8       0.97      0.95      0.96       974
           9       0.96      0.95      0.95      1009

    accuracy                           0.97     10000
   macro avg       0.97      0.97      0.97     10000
weighted avg       0.97      0.97      0.97     10000

Test accuracy of the ANN: 0.9656
BOLD monitor II
ANN to SNN II
 

Copyright Julien Vitay, Helge Ülo Dinkelbach, Fred Hamker