Example #1
0
    def get_decoder_NxN(self,func=None,noise=None):
        if noise is None: noise=self.activation_noise

        name='decoderNxN'
        name_gamma='gamma'
        name_gammainv='gammainv'
        name_upsilon='upsilon'
        if func:
            hash_info=make_hash_info(func)
            n='-%s-%08x'%(func.__name__,hash(tuple(hash_info)))#hash(tuple(func_id)))
            n=n.replace('<','_').replace('>','_')
            name_upsilon+=n
            name+=n
        name+='-%4.2f'%noise
        name_gammainv+='-%4.2f'%noise
        if noise>0:
            if self.decoder_noise_use_gamma: 
                name+='g'
                name_gammainv+='g'
            if self.decoder_noise_use_limit: 
                name+='l'
                name_gammainv+='l'
            if self.decoder_noise_use_activity: 
                name+='a'
                name_gammainv+='a'
                name_upsilon+='-%4.2fa'%noise
                name_gamma+='-%4.2fa'%noise
            

        if name in self.decoders: return self.decoders[name]
        decoder=self.storage.get(name,(self.neurons,-1))
        if decoder is not None:
            self.decoders[name]=decoder
            return decoder


        warning=False
        if self.neurons>self.decoder_size_warning:
            warning=True
            print('Warning: calculating decoder for size %d neural group.  This may take a while.'%self.neurons)


        upsilon=None
        upsilon=self.storage.get(name_upsilon,(self.neurons,-1))

        need_gammainv=False
        need_gamma=False
        gamma_inv=self.storage.get(name_gammainv,(self.neurons,self.neurons))
        if gamma_inv is None:
            need_gammainv=True
            gamma=self.storage.get(name_gamma,(self.neurons,self.neurons))
            if gamma is None: need_gamma=True

        if need_gamma or upsilon is None:
          if self.dimensions>=3 and self.use_hd:
            gamma,moments=calc_gamma_moments(self,dr=0.01)
            gamma*=self.sample_count
            ups=self.basis*moments[1].reshape((moments[1].shape[0],1))*self.sample_count
            
          else:
        
            self.sample_generator.reset()
            count=self.sample_count
            ups=None
            while count>0:
                s=min(count,self.sample_step_size)
                if not self.sample_generator.can_continue(self.dimensions):
                    s=count
                if warning:
                    print('processing %d of %d samples (%d left)'%(s,self.sample_count,count))
                samples=self.sample_generator.get(s)
                count-=s

                curr=self.arrays_to_currents(samples)
                curr=curr.T+self.Jbias
                actv=self.current_to_activity(curr.T)
                if self.decoder_noise_use_activity:
                    actv=numpy.random.normal(actv,noise*self.saturation_range[1])
                    actv=numpy.maximum(0,actv)
                    actv=numpy.array(actv,dtype=numpy.float32)

                if need_gamma:
                    g=numpy.dot(actv,actv.T)
                    if gamma is None: gamma=g
                    else: gamma+=g
                    
                if upsilon is None:
                    samples=samples.T
                    if func is not None:
                        if self.dimensions==1:
                            samples=samples[:,0]
                        samples=numpy.array([self.value_to_array(func(self.array_to_value(x))) for x in samples],dtype=numpy.float32)
                    u=numpy.dot(actv,samples)
                    if ups is None: ups=u
                    else: ups+=u
          if need_gamma:
                self.storage.set(name_gamma,gamma)                
          if upsilon is None:
                upsilon=ups
                self.storage.set(name_upsilon,upsilon)
                
        error_flag=False
        if need_gammainv:   
            if self.decoder_noise_use_gamma:
                if noise>0:
                    gamma+=numpy.identity(gamma.shape[0])*(((noise*self.saturation_range[1])**2)*self.sample_count)
        
            if warning:
                print('inverting %dx%d gamma matrix'%gamma.shape)
                    
            w,v=numpy.linalg.eigh(gamma)
            limit=svd_limit*max(w)
            
            if self.decoder_noise_use_limit:
                if noise>0: limit=noise*noise*max(w)
                
            for i in range(len(w)):
                if w[i]<limit: w[i]=0
                else: w[i]=1.0/w[i]
            gamma_inv=numpy.dot(v,numpy.multiply(w[:,numpy.core.newaxis],v.T))
            self.storage.set(name_gammainv,gamma_inv)                
        
        decoder=numpy.dot(gamma_inv,upsilon)
        if len(decoder.shape)==1:
            decoder.shape=decoder.shape[0],1

        self.decoders[name]=decoder
        self.storage.set(name,decoder)
        return decoder
    def get_decoder_NxN(self,func=None,noise=None):
        if noise is None: noise=self.activation_noise

        name='decoderNxN'
        name_gamma='gamma'
        name_gammainv='gammainv'
        name_upsilon='upsilon'
        if func:
            hash_info=make_hash_info(func)
            n='-%s-%08x'%(func.__name__,hash(tuple(hash_info)))#hash(tuple(func_id)))
            n=n.replace('<','_').replace('>','_')
            name_upsilon+=n
            name+=n
        name+='-%4.2f'%noise
        name_gammainv+='-%4.2f'%noise
        if noise>0:
            if self.decoder_noise_use_gamma: 
                name+='g'
                name_gammainv+='g'
            if self.decoder_noise_use_limit: 
                name+='l'
                name_gammainv+='l'
            if self.decoder_noise_use_activity: 
                name+='a'
                name_gammainv+='a'
                name_upsilon+='-%4.2fa'%noise
                name_gamma+='-%4.2fa'%noise
            

        if name in self.decoders: return self.decoders[name]
        decoder=self.storage.get(name,(self.neurons,-1))
        if decoder is not None:
            self.decoders[name]=decoder
            return decoder


        warning=False
        if self.neurons>self.decoder_size_warning:
            warning=True
            print 'Warning: calculating decoder for size %d neural group.  This may take a while.'%self.neurons


        upsilon=None
        upsilon=self.storage.get(name_upsilon,(self.neurons,-1))

        need_gammainv=False
        need_gamma=False
        gamma_inv=self.storage.get(name_gammainv,(self.neurons,self.neurons))
        if gamma_inv is None:
            need_gammainv=True
            gamma=self.storage.get(name_gamma,(self.neurons,self.neurons))
            if gamma is None: need_gamma=True

        if need_gamma or upsilon is None:
          if self.dimensions>=3 and self.use_hd:
            gamma,moments=calc_gamma_moments(self,dr=0.01)
            gamma*=self.sample_count
            ups=self.basis*moments[1].reshape((moments[1].shape[0],1))*self.sample_count
            
          else:
        
            self.sample_generator.reset()
            count=self.sample_count
            ups=None
            while count>0:
                s=min(count,self.sample_step_size)
                if not self.sample_generator.can_continue(self.dimensions):
                    s=count
                if warning:
                    print 'processing %d of %d samples (%d left)'%(s,self.sample_count,count)
                samples=self.sample_generator.get(s)
                count-=s

                curr=self.arrays_to_currents(samples)
                curr=curr.T+self.Jbias
                actv=self.current_to_activity(curr.T)
                if self.decoder_noise_use_activity:
                    actv=numpy.random.normal(actv,noise*self.saturation_range[1])
                    actv=numpy.maximum(0,actv)
                    actv=numpy.array(actv,dtype=numpy.float32)

                if need_gamma:
                    g=numpy.dot(actv,actv.T)
                    if gamma is None: gamma=g
                    else: gamma+=g
                    
                if upsilon is None:
                    samples=samples.T
                    if func is not None:
                        if self.dimensions==1:
                            samples=samples[:,0]
                        samples=numpy.array([self.value_to_array(func(self.array_to_value(x))) for x in samples],dtype=numpy.float32)
                    u=numpy.dot(actv,samples)
                    if ups is None: ups=u
                    else: ups+=u
          if need_gamma:
                self.storage.set(name_gamma,gamma)                
          if upsilon is None:
                upsilon=ups
                self.storage.set(name_upsilon,upsilon)
                
        error_flag=False
        if need_gammainv:   
            if self.decoder_noise_use_gamma:
                if noise>0:
                    gamma+=numpy.identity(gamma.shape[0])*(((noise*self.saturation_range[1])**2)*self.sample_count)
        
            if warning:
                print 'inverting %dx%d gamma matrix'%gamma.shape
                    
            w,v=numpy.linalg.eigh(gamma)
            limit=svd_limit*max(w)
            
            if self.decoder_noise_use_limit:
                if noise>0: limit=noise*noise*max(w)
                
            for i in range(len(w)):
                if w[i]<limit: w[i]=0
                else: w[i]=1.0/w[i]
            gamma_inv=numpy.dot(v,numpy.multiply(w[:,numpy.core.newaxis],v.T))
            self.storage.set(name_gammainv,gamma_inv)                
        
        decoder=numpy.dot(gamma_inv,upsilon)
        if len(decoder.shape)==1:
            decoder.shape=decoder.shape[0],1

        self.decoders[name]=decoder
        self.storage.set(name,decoder)
        return decoder
Example #3
0
    def get_decoder(self, func=None, noise=None):
        if noise is None: noise = self.activation_noise

        name = ''
        name_without_noise = ''
        if func:
            hash_info = make_hash_info(func)
            name = '-%s-%08x' % (func.__name__, hash(tuple(hash_info))
                                 )  #hash(tuple(func_id)))
            name = name.replace('<', '_').replace('>', '_')
            #print 'name',name
            name_without_noise = name
        name += '-%4.2f' % noise

        if name in self.decoders: return self.decoders[name]
        decoder = self.storage.get('decoder' + name, (self.neurons, -1))
        if decoder is not None:
            self.decoders[name] = decoder
            return decoder

        warning = False
        if self.neurons > self.decoder_size_warning:
            warning = True
            print 'Warning: calculating decoder for size %d neural group.' % self.neurons
            if self.neurons > self.decoder_size_limit:
                print '  Gamma matrices will be created, but they are too large for one machine to invert.'
            else:
                print '  This may take a few minutes.'

        noise *= self.saturation_range[1]

        upsilon = None
        upsilon = self.storage.get('upsilon' + name_without_noise,
                                   (self.neurons, -1))

        gamma_inv = None
        need_gamma = True
        gamma_s = self.storage.get('gamma.s', self.neurons)
        if gamma_s is not None:
            gamma_v = self.storage.get('gamma.v', (self.neurons, self.neurons))
            if svd_limit is not None:
                gamma_s = gamma_s[gamma_s > gamma_s[0] * svd_limit]
                gamma_v = gamma_v[:len(gamma_s), :]
            s_inv = numpy.diag(1.0 /
                               (gamma_s + noise * noise * self.sample_count))
            gamma_inv = numpy.dot(numpy.dot(gamma_v.T, s_inv), gamma_v)
            need_gamma = False
        else:
            gamma = self.storage.get('gamma', (self.neurons, self.neurons))
            if gamma is not None: need_gamma = False

        if need_gamma or upsilon is None:
            if self.dimensions >= 3 and self.use_hd:
                gamma, moments = calc_gamma_moments(self, dr=0.01)
                gamma *= self.sample_count
                ups = self.basis * moments[1].reshape(
                    (moments[1].shape[0], 1)) * self.sample_count

            else:

                self.sample_generator.reset()
                count = self.sample_count
                ups = None
                while count > 0:
                    s = min(count, self.sample_step_size)
                    if not self.sample_generator.can_continue(self.dimensions):
                        s = count
                    if warning:
                        print 'processing %d of %d samples (%d left)' % (
                            s, self.sample_count, count)
                    samples = self.sample_generator.get(s)
                    count -= s

                    curr = self.arrays_to_currents(samples)
                    curr = curr.T + self.Jbias
                    actv = self.current_to_activity(curr.T)
                    #actv=self.array_to_activity(samples)

                    if need_gamma:
                        g = numpy.dot(actv, actv.T)
                        if gamma is None: gamma = g
                        else: gamma += g

                    if upsilon is None:
                        samples = samples.T
                        if func is not None:
                            if self.dimensions == 1:
                                samples = samples[:, 0]
                            samples = numpy.array([
                                self.value_to_array(
                                    func(self.array_to_value(x)))
                                for x in samples
                            ],
                                                  dtype=numpy.float32)
                        u = numpy.dot(actv, samples)
                        if ups is None: ups = u
                        else: ups += u
            if need_gamma:
                self.storage.set('gamma', gamma)
            if upsilon is None:
                upsilon = ups
                self.storage.set('upsilon' + name_without_noise, upsilon)

        error_flag = False
        if gamma_inv is None:
            if gamma.shape[0] > self.decoder_size_limit:
                print 'Need other program to invert ' + self.storage.path(
                    'gamma')
                gamma_inv = numpy.zeros(gamma.shape, dtype=numpy.float32)
                error_flag = True
            else:
                if noise > 0:
                    gamma += numpy.identity(
                        gamma.shape[0]) * (noise * noise) * self.sample_count
                if gamma.shape[0] > self.decoder_size_warning:
                    print 'inverting %dx%d gamma matrix' % gamma.shape
                gamma_inv = numpy.linalg.pinv(gamma)

        decoder = numpy.dot(gamma_inv, upsilon)
        if len(decoder.shape) == 1:
            decoder.shape = decoder.shape[0], 1

        self.decoders[name] = decoder
        if not error_flag:
            self.storage.set('decoder' + name, decoder)
        return decoder