In [1]:
from matplotlib import pylab
import nengo
import random
import numpy as np
import gzip as gz
import cPickle
from cPickle import load
try:
    import Image
except ImportError:
    from PIL import Image
from scipy.sparse.linalg import svds
import scipy
from scipy import ndimage
import matplotlib.pyplot as plt
import matplotlib.animation as animation

#%matplotlib inline #Want animation to popup as new window

In [2]:
def load_img(path, dims):
    """Load the image at path and return an array representing the raster.
    Flattens image. Shifts pixel activations such that 0 represents gray,
    normalizes the output array.
    Keyword arguments:
    path -- str, path of the image to be loaded.
    dims -- (w, h), where w,h are ints indicating dimensions of the image (in
        px)."""

    img = Image.open(path).resize(dims).getdata()
    img.convert('L')
    img = subtract(array(img).flatten(), 127.5)
    return img/norm(img)


def load_data(filename):
    """Uncompress, unpickle and return a .pkl.gz file.
    Keyword arguments:
    filename -- str, a valid file path"""

    return load(gz.open(filename))

def load_mini_mnist(option=None):
    """Load and return the first \%10 of the images in the mnist dataset.
    Does not return labels. Pass in 'train', 'valid' or 'test' if you want to
    load a specific subset of the dataset.
    Keyword arguments:
    option -- str (default=None)."""

    mini_mnist = load(gz.open('./mini_mnist.pkl.gz', 'rb'))
    if option == 'train':
        return mini_mnist[0]
    elif option == 'valid':
        return mini_mnist[1]
    elif option == 'test':
        return mini_mnist[2]
    else:
        return mini_mnist

In [3]:
def rotate_img(img, degrees):
    '''Rotates image the degrees passed in counterclockwise
    Reshapes image to original
    '''
    original = img.shape
    
    newImg = scipy.ndimage.interpolation.rotate(np.reshape(img, (dim,dim), 'F'),degrees,reshape=False)
    newImg = np.reshape(newImg, original, 'F')
    return newImg

In [4]:
conn_synapse = 0.1
probe_synapse = 0.01
multiplier = 2
n_neurons = 5000
direct = False
stop_time = 1.0
run_time = 1.2 #in seconds

In [5]:
dim = 28
mnist = load_mini_mnist()
train = mnist[0]
img = mnist[1][0]
compress_size = 400
basis, S, V = svds(train.T, k=compress_size)

angle =60

In [6]:
expanded_basis = np.array([random.choice(basis.T) for _ in range(n_neurons)])

In [7]:
def stim_func(t):
    '''returns the image'''
    if t < stop_time:
        return img
    else:
        return [0 for _ in range(len(img))]

In [8]:
def stim_func2(t):
    '''returns the image rotated 60 degrees'''
    if t < stop_time:
        return rotate_img(img,60)
    else:
        return [0 for _ in range(len(img))]

In [9]:
def stim_func3(t):
    '''returns original image, the rotated 45, the rotated 90'''
    if t < 0.2:
        return img
    elif t < 0.4:
        return rotate_img(img,45)
    elif t < stop_time: 
        return rotate_img(img,90)
            
        
    else:
        return [0 for _ in range(len(img))]

In [10]:
def stim_func4(t):
    '''returns the image rotated at 60 degrees per second (indefinitely until stop time)
    Could change function to stop at specific angle'''
    if t < stop_time:
        return rotate_img(img,((t*10)//1)*6) #60 deg per sec, 6 degrees per 0.1 sec
    else:
        return [0 for _ in range(len(img))]

In [11]:
with nengo.Network() as net:
    
    if direct:
        neuron_type = nengo.Direct()
    else:
        neuron_type = nengo.LIF()        

    #ipt = nengo.Node(stim_func)
    #ipt2 = nengo.Node(stim_func2)
    #ipt3 = nengo.Node(stim_func3)
    ipt4 = nengo.Node(stim_func4)
    
    
    ens = nengo.Ensemble(n_neurons,
                         dimensions=dim**2,
                         encoders=expanded_basis,
                         eval_points=expanded_basis,
                         n_eval_points=n_neurons,
                         neuron_type=neuron_type)

    nengo.Connection(ipt4, ens, synapse=None, transform=1)
    conn = nengo.Connection(ens, ens, synapse=conn_synapse)

    probe = nengo.Probe(ens, attr='decoded_output',
                        synapse=probe_synapse)
    #sample_every=0.01?

In [12]:
sim = nengo.Simulator(net)

In [13]:
sim.run(run_time)


Simulation finished in 0:00:11.                                                 

In [14]:
pylab.imshow(np.reshape(img, (dim,dim), 'F'), cmap='Greys_r')


Out[14]:
<matplotlib.image.AxesImage at 0xa9c1e48>

In [15]:
'''Image at stop time'''
im = pylab.imshow(np.reshape([0. if x < 0.00001 else x for x in sim.data[probe][int(stop_time*1000)]], 
                             (dim, dim), 'F'), cmap=plt.get_cmap('Greys_r'),animated=True)

In [14]:
'''Animation for Probe output'''
fig = plt.figure()
#num = 0

def updatefig(i):
#    global num
#    num +=1
    im = pylab.imshow(np.reshape([0. if x < 0.00001 else x 

                              for x in sim.data[probe][i]], (dim, dim), 'F'), cmap=plt.get_cmap('Greys_r'),
                  animated=True)
    return im,

ani = animation.FuncAnimation(fig, updatefig, interval=1, blit=True)
plt.show()



#pylab.imshow(np.reshape([0. if x < 0.00001 else x 
#                        for x in sim.data[probe][4]], (dim, dim), 'F'), cmap='Greys_r')
#im = plt.imshow(f(x, y), cmap=plt.get_cmap('viridis'), animated=True)

In [15]:
# save the output
cPickle.dump(sim.data[probe], open( "Buffer_rotations_stimulus.p", "wb" ) )