exc=exc, inh=inh, dt=dt, nu=[0, 1e-2], norm=78.4) # Voltage recording for excitatory and inhibitory layers. exc_voltage_monitor = Monitor(network.layers['Ae'], ['v'], time=time) inh_voltage_monitor = Monitor(network.layers['Ai'], ['v'], time=time) network.add_monitor(exc_voltage_monitor, name='exc_voltage') network.add_monitor(inh_voltage_monitor, name='inh_voltage') # Load MNIST data. images, labels = MNIST(path=os.path.join('..', '..', 'data', 'MNIST'), download=True).get_train() images = images.view(-1, 784) images *= intensity # Lazily encode data as Poisson spike trains. data_loader = poisson_loader(data=images, time=time, dt=dt) # Record spikes during the simulation. spike_record = torch.zeros(update_interval, time, n_neurons) # Neuron assignments and spike proportions. assignments = -torch.ones_like(torch.Tensor(n_neurons)) proportions = torch.zeros_like(torch.Tensor(n_neurons, 10)) rates = torch.zeros_like(torch.Tensor(n_neurons, 10)) # Sequence of accuracy estimates. accuracy = {'all': [], 'proportion': []}
def main(seed=0, n_epochs=5, batch_size=100, time=50, update_interval=50, plot=False): np.random.seed(seed) if torch.cuda.is_available(): torch.set_default_tensor_type('torch.cuda.FloatTensor') torch.cuda.manual_seed_all(seed) else: torch.manual_seed(seed) print() print('Creating and training the ANN...') print() # Create and train an ANN on the MNIST dataset. ANN = FullyConnectedNetwork() # Get the MNIST data. images, labels = MNIST('../../data/MNIST', download=True).get_train() images /= images.max() # Standardizing to [0, 1]. images = images.view(-1, 784) labels = labels.long() # Specify optimizer and loss function. optimizer = optim.Adam(params=ANN.parameters(), lr=1e-3) criterion = nn.CrossEntropyLoss() # Train the ANN. batches_per_epoch = int(images.size(0) / batch_size) for i in range(n_epochs): losses = [] accuracies = [] for j in range(batches_per_epoch): batch_idxs = torch.from_numpy( np.random.choice(np.arange(images.size(0)), size=batch_size, replace=False) ) im_batch = images[batch_idxs] label_batch = labels[batch_idxs] outputs = ANN.forward(im_batch) loss = criterion(outputs, label_batch) predictions = torch.max(outputs, 1)[1] correct = (label_batch == predictions).sum().float() / batch_size optimizer.zero_grad() loss.backward() optimizer.step() losses.append(loss.item()) accuracies.append(correct.item()) print(f'Epoch: {i+1} / {n_epochs}; Loss: {np.mean(losses):.4f}; Accuracy: {np.mean(accuracies) * 100:.4f}') print() print('Converting ANN to SNN...') # Do ANN to SNN conversion. SNN = ann_to_snn(ANN, input_shape=(784,), data=images) for l in SNN.layers: if l != 'Input': SNN.add_monitor( Monitor(SNN.layers[l], state_vars=['s', 'v'], time=time), name=l ) spike_ims = None spike_axes = None correct = [] print() print('Testing SNN on MNIST data...') print() # Test SNN on MNIST data. start = t() for i in range(images.size(0)): if i > 0 and i % update_interval == 0: print( f'Progress: {i} / {images.size(0)}; Elapsed: {t() - start:.4f}; Accuracy: {np.mean(correct) * 100:.4f}' ) start = t() SNN.run(inpts={'Input': images[i].repeat(time, 1, 1)}, time=time) spikes = {layer: SNN.monitors[layer].get('s') for layer in SNN.monitors} voltages = {layer: SNN.monitors[layer].get('v') for layer in SNN.monitors} prediction = torch.softmax(voltages['5'].sum(1), 0).argmax() correct.append((prediction == labels[i]).item()) SNN.reset_() if plot: spikes = {k: spikes[k].cpu() for k in spikes} spike_ims, spike_axes = plot_spikes(spikes, ims=spike_ims, axes=spike_axes) plt.pause(1e-3)
def main(seed=0, n_epochs=5, batch_size=100, time=50, update_interval=50, plot=False, save=True): np.random.seed(seed) if torch.cuda.is_available(): torch.set_default_tensor_type('torch.cuda.FloatTensor') torch.cuda.manual_seed_all(seed) else: torch.manual_seed(seed) print() print('Loading MNIST data...') print() # Get the CIFAR-10 data. images, labels = MNIST('../../data/MNIST', download=True).get_train() images /= images.max() # Standardizing to [0, 1]. images = images.view(-1, 784) labels = labels.long() test_images, test_labels = MNIST('../../data/MNIST', download=True).get_test() test_images /= test_images.max() # Standardizing to [0, 1]. test_images = test_images.view(-1, 784) test_labels = test_labels.long() if torch.cuda.is_available(): images = images.cuda() labels = labels.cuda() test_images = test_images.cuda() test_labels = test_labels.cuda() ANN = FullyConnectedNetwork() model_name = '_'.join( [str(x) for x in [seed, n_epochs, batch_size, time, update_interval]]) # Specify loss function. criterion = nn.CrossEntropyLoss() if save and os.path.isfile(os.path.join(params_path, model_name + '.pt')): print() print('Loading trained ANN from disk...') ANN.load_state_dict( torch.load(os.path.join(params_path, model_name + '.pt'))) if torch.cuda.is_available(): ANN = ANN.cuda() else: print() print('Creating and training the ANN...') print() # Specify optimizer. optimizer = optim.Adam(params=ANN.parameters(), lr=1e-3, weight_decay=1e-4) batches_per_epoch = int(images.size(0) / batch_size) # Train the ANN. for i in range(n_epochs): losses = [] accuracies = [] for j in range(batches_per_epoch): batch_idxs = torch.from_numpy( np.random.choice(np.arange(images.size(0)), size=batch_size, replace=False)) im_batch = images[batch_idxs] label_batch = labels[batch_idxs] outputs = ANN.forward(im_batch) loss = criterion(outputs, label_batch) predictions = torch.max(outputs, 1)[1] correct = (label_batch == predictions).sum().float() / batch_size optimizer.zero_grad() loss.backward() optimizer.step() losses.append(loss.item()) accuracies.append(correct.item() * 100) outputs = ANN.forward(test_images) loss = criterion(outputs, test_labels).item() predictions = torch.max(outputs, 1)[1] test_accuracy = ((test_labels == predictions).sum().float() / test_labels.numel()).item() * 100 avg_loss = np.mean(losses) avg_acc = np.mean(accuracies) print( f'Epoch: {i+1} / {n_epochs}; Train Loss: {avg_loss:.4f}; Train Accuracy: {avg_acc:.4f}' ) print( f'\tTest Loss: {loss:.4f}; Test Accuracy: {test_accuracy:.4f}') if save: torch.save(ANN.state_dict(), os.path.join(params_path, model_name + '.pt')) outputs = ANN.forward(test_images) loss = criterion(outputs, test_labels) predictions = torch.max(outputs, 1)[1] accuracy = ((test_labels == predictions).sum().float() / test_labels.numel()).item() * 100 print() print( f'(Post training) Test Loss: {loss:.4f}; Test Accuracy: {accuracy:.4f}' ) print() print('Evaluating ANN on adversarial examples from FSGM method...') # Convert pytorch model to a tf_model and wrap it in cleverhans. tf_model_fn = convert_pytorch_model_to_tf(ANN) cleverhans_model = CallableModelWrapper(tf_model_fn, output_layer='logits') sess = tf.Session() x_op = tf.placeholder(tf.float32, shape=( None, 784, )) # Create an FGSM attack. fgsm_op = FastGradientMethod(cleverhans_model, sess=sess) fgsm_params = {'eps': 0.2, 'clip_min': 0.0, 'clip_max': 1.0} adv_x_op = fgsm_op.generate(x_op, **fgsm_params) adv_preds_op = tf_model_fn(adv_x_op) # Run an evaluation of our model against FGSM white-box attack. total = 0 correct = 0 adv_preds = sess.run(adv_preds_op, feed_dict={x_op: test_images}) correct += (np.argmax(adv_preds, axis=1) == test_labels).sum() total += len(test_images) accuracy = float(correct) / total print() print('Adversarial accuracy: {:.3f}'.format(accuracy * 100)) print() print('Converting ANN to SNN...') with sess.as_default(): test_images = adv_x_op.eval(feed_dict={x_op: test_images}) test_images = torch.tensor(test_images) # Do ANN to SNN conversion. SNN = ann_to_snn(ANN, input_shape=(784, ), data=test_images, percentile=100) for l in SNN.layers: if l != 'Input': SNN.add_monitor(Monitor(SNN.layers[l], state_vars=['s', 'v'], time=time), name=l) print() print('Testing SNN on FGSM-modified MNIST data...') print() # Test SNN on MNIST data. spike_ims = None spike_axes = None correct = [] n_images = test_images.size(0) start = t() for i in range(n_images): if i > 0 and i % update_interval == 0: accuracy = np.mean(correct) * 100 print( f'Progress: {i} / {n_images}; Elapsed: {t() - start:.4f}; Accuracy: {accuracy:.4f}' ) start = t() SNN.run(inpts={'Input': test_images[i].repeat(time, 1, 1)}, time=time) spikes = { layer: SNN.monitors[layer].get('s') for layer in SNN.monitors } voltages = { layer: SNN.monitors[layer].get('v') for layer in SNN.monitors } prediction = torch.softmax(voltages['fc3'].sum(1), 0).argmax() correct.append((prediction == test_labels[i]).item()) SNN.reset_() if plot: spikes = {k: spikes[k].cpu() for k in spikes} spike_ims, spike_axes = plot_spikes(spikes, ims=spike_ims, axes=spike_axes) plt.pause(1e-3)
def main(seed=0, n_epochs=5, batch_size=100): np.random.seed(seed) if torch.cuda.is_available(): torch.set_default_tensor_type('torch.cuda.FloatTensor') torch.cuda.manual_seed_all(seed) else: torch.manual_seed(seed) print() print('Creating and training the ANN...') print() # Create and train an ANN on the MNIST dataset. ANN = FullyConnectedNetwork() # Get the MNIST data. images, labels = MNIST(os.path.join( ROOT_DIR, 'data', 'MNIST' ), download=True).get_train() images /= images.max() # Standardizing to [0, 1]. images = images.view(-1, 784) labels = labels.long() # Specify optimizer and loss function. optimizer = optim.Adam(params=ANN.parameters(), lr=1e-3) criterion = nn.CrossEntropyLoss() # Train the ANN. batches_per_epoch = int(images.size(0) / batch_size) for i in range(n_epochs): losses = [] accuracies = [] for j in range(batches_per_epoch): batch_idxs = torch.from_numpy( np.random.choice(np.arange(images.size(0)), size=batch_size, replace=False) ) im_batch = images[batch_idxs] label_batch = labels[batch_idxs] outputs = ANN.forward(im_batch) loss = criterion(outputs, label_batch) predictions = torch.max(outputs, 1)[1] correct = (label_batch == predictions).sum().float() / batch_size optimizer.zero_grad() loss.backward() optimizer.step() losses.append(loss.item()) accuracies.append(correct.item()) print(f'Epoch: {i+1} / {n_epochs}; Loss: {np.mean(losses):.4f}; Accuracy: {np.mean(accuracies) * 100:.4f}') ANN = ANN.eval() fmodel = PyTorchModel( ANN, bounds=(0, 1), num_classes=10 ) # apply attack on source image for i in range(10000): image = images[i].cpu().numpy() label = labels[i].long().item() attack = foolbox.attacks.BoundaryAttack(fmodel) try: adversarial = attack(image, label, verbose=True, iterations=1000) * 1.001 except AssertionError: continue print(f'{i}: adversarial')