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
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