def afferent(self, src_properties, dest_properties): channel = dest_properties['SF'] if 'SF' in dest_properties else 1 centerg = imagen.Gaussian( size=0.07385 * self.sf_spacing**(channel - 1), aspect_ratio=1.0, output_fns=[transferfn.DivisiveNormalizeL1()]) surroundg = imagen.Gaussian( size=(4 * 0.07385) * self.sf_spacing**(channel - 1), aspect_ratio=1.0, output_fns=[transferfn.DivisiveNormalizeL1()]) on_weights = imagen.Composite(generators=[centerg, surroundg], operator=numpy.subtract) off_weights = imagen.Composite(generators=[surroundg, centerg], operator=numpy.subtract) #TODO: strength=+strength_scale/len(cone_types) for 'On' center #TODO: strength=-strength_scale/len(cone_types) for 'Off' center #TODO: strength=-strength_scale/len(cone_types) for 'On' surround #TODO: strength=+strength_scale/len(cone_types) for 'Off' surround return Model.SharedWeightCFProjection.params( delay=0.05, strength=2.33 * self.strength_factor, name='Afferent', nominal_bounds_template=sheet.BoundingBox( radius=self.lgnaff_radius * self.sf_spacing**(channel - 1)), weights_generator=on_weights if dest_properties['polarity'] == 'On' else off_weights)
def update_ibl(self): num = len(self.ibls) if num == 0: black = np.zeros((256, 512, 3)) self.set_img(black) return gs = ig.Composite(operator=np.add, generators=[ ig.Gaussian( size=self.ibls[i].radius, scale=self.ibls[i].scale, x=self.ibls[i].pos[0] - 0.5, y=self.ibls[i].pos[1] - 0.5, aspect_ratio=1.0, ) for i in range(num) ], xdensity=512) self.ibl_img = np.repeat(gs()[:, :, np.newaxis], 3, axis=2) w = self.ibl_img.shape[1] tmp = self.ibl_img.copy() ret = tmp.copy() ret[:, :w // 2], ret[:, w // 2:] = tmp[:, w // 2:], tmp[:, :w // 2] plt.imsave("test_sharp.png", np.clip(ret, 0.0, 1.0)) self.set_img(self.ibl_img) self.parent_handle.render_layers()
def get_pattern(self, w, h, num=50, scale=3.0, size=0.1, energy=3500, mitsuba=False, seed=None, dataset=False): if seed is None: seed = random.randint(0,19920208) else: seed = seed + int(time.time()) if num == 0: ibl = np.zeros((256,512)) else: # factor = 80/256 factor = 1.0 gs = ig.Composite(operator=np.add, generators=[ig.Gaussian( size=size*ng.UniformRandom(seed=seed+i+4), scale=scale*(ng.UniformRandom(seed=seed+i+5)+1e-3), x=ng.UniformRandom(seed=seed+i+1)-0.5, y=(ng.UniformRandom(seed=seed+i+2)-0.5)*factor, aspect_ratio=0.7, orientation=np.pi*ng.UniformRandom(seed=seed+i+3), ) for i in range(num)], position=(0, 0), xdensity=512) ibl = self.normalize(gs(), energy) # prepare to fix energy inconsistent if dataset: ibl = self.to_dataset(ibl, w, h) if mitsuba: return ibl, self.to_mts_ibl(np.copy(ibl)) else: return ibl
def lateral_excitatory(self, src_properties, dest_properties): return Model.CFProjection.params( delay=0.05, name='LateralExcitatory', weights_generator=imagen.Gaussian(aspect_ratio=1.0, size=0.05), strength=self.exc_strength, learning_rate=self.exc_lr, nominal_bounds_template=sheet.BoundingBox(radius=self.latexc_radius))
def lr_lateral_excitatory(self, src_properties, dest_properties): return Model.CFProjection.params( delay=0.1, name='LRExcitatory', activity_group=(0.9, MultiplyWithConstant()), weights_generator=imagen.Gaussian(aspect_ratio=1.0, size=self.lateral_size), strength=self.latexc_strength, learning_rate=self.latexc_lr, nominal_bounds_template=sheet.BoundingBox(radius=self.lateral_radius))
def lateral_gain_control(self, src_properties, dest_properties): #TODO: Are those 0.25 the same as lgnlateral_radius/2.0? return Model.SharedWeightCFProjection.params( delay=0.05, dest_port=('Activity'), activity_group=(0.6, DivideWithConstant(c=0.11)), weights_generator=imagen.Gaussian( size=0.25, aspect_ratio=1.0, output_fns=[transferfn.DivisiveNormalizeL1()]), nominal_bounds_template=sheet.BoundingBox(radius=0.25), name=('LateralGC' + src_properties['eye'] if 'eye' in src_properties else 'LateralGC'), strength=0.6 / len(self.attrs.Eyes))
def get_cur_ibl(self): num = len(self.ibl_cmds) if num == 0: return np.zeros((256, 512, 3)) gs = ig.Composite(operator=np.add, generators=[ ig.Gaussian( size=self.ibl_cmds[i][2], scale=self.ibl_cmds[i][3], x=self.ibl_cmds[i][0] - 0.5, y=self.ibl_cmds[i][1] - 0.5, aspect_ratio=1.0, ) for i in range(num) ], xdensity=512) return np.repeat(gs()[:, :, np.newaxis], 3, axis=2)
def afferent_surround(self, src_properties, dest_properties): surrounds=[] for color, color_code in self.ColorToChannel.items(): if color in dest_properties['surround']: surrounds.append(color_code) return [Model.SharedWeightCFProjection.params( delay=0.05, strength=(4.7/2.33)*self.lgnaff_strength/len(surrounds)*(-1 if dest_properties['polarity'] == 'On' else 1), src_port='Activity%d'%surround, dest_port='Activity', weights_generator=imagen.Gaussian(size=0.07385*(4 if dest_properties['opponent'] is not 'Blue' else 1), aspect_ratio=1.0, output_fns=[transferfn.DivisiveNormalizeL1()]), name='AfferentSurround'+str(surround), nominal_bounds_template=sheet.BoundingBox(radius=self.lgnaff_radius)) for surround in surrounds]
def afferent_surround(self, src_properties, dest_properties): #TODO: strength=-strength_scale for 'On', +strength_scale for 'Off' #TODO: strength=-strength_scale/2 for dest_properties['opponent']=='Blue' # dest_properties['surround']=='RedGreen' and dest_properties['polarity']=='On' #TODO: strength=+strength_scale/2 for above, but 'Off' #TODO: strength=-strength_scale/len(cone_types) for Luminosity 'On' #TODO: strength=+strength_scale/len(cone_types) for Luminosity 'Off' return Model.SharedWeightCFProjection.params( delay=0.05, strength=2.33 * self.strength_factor, weights_generator=imagen.Gaussian( size=4 * 0.07385, aspect_ratio=1.0, output_fns=[transferfn.DivisiveNormalizeL1()]), name='AfferentSurround' + src_properties['cone'], nominal_bounds_template=sheet.BoundingBox( radius=self.lgnaff_radius))
def lateral_gain_control(self, src_properties, dest_properties): #TODO: Are those 0.25 the same as lgnlateral_radius/2.0? name='LateralGC' if 'eye' in src_properties: name+=src_properties['eye'] if 'SF' in src_properties and self.gain_control_SF: name+=('SF'+str(src_properties['SF'])) return Model.SharedWeightCFProjection.params( delay=0.05, dest_port=('Activity'), activity_group=(0.6,DivideWithConstant(c=0.11)), weights_generator=imagen.Gaussian(size=self.gain_control_size, aspect_ratio=1.0, output_fns=[transferfn.DivisiveNormalizeL1()]), nominal_bounds_template=sheet.BoundingBox(radius=self.gain_control_size), name=name, strength=0.6/(2 if self['binocular'] else 1))
def afferent_center(self, src_properties, dest_properties): #TODO: It shouldn't be too hard to figure out how many retina sheets it connects to, # then all the below special cases can be generalized! #TODO: strength=+strength_scale for 'On', strength=-strength_scale for 'Off' #TODO: strength=+strength_scale for dest_properties['opponent']=='Blue' # dest_properties['surround']=='RedGreen' and dest_properties['polarity']=='On' #TODO: strength=-strength_scale for above, but 'Off' #TODO: strength=+strength_scale/len(cone_types) for Luminosity 'On' #TODO: strength=-strength_scale/len(cone_types) for Luminosity 'Off' return Model.SharedWeightCFProjection.params( delay=0.05, strength=2.33 * self.strength_factor, weights_generator=imagen.Gaussian( size=0.07385, aspect_ratio=1.0, output_fns=[transferfn.DivisiveNormalizeL1()]), name='AfferentCenter' + src_properties['cone'], nominal_bounds_template=sheet.BoundingBox( radius=self.lgnaff_radius))
def get_ibl_numpy(self): num = len(self.ibls) gs = ig.Composite(operator=np.add, generators=[ ig.Gaussian( size=self.ibls[i].radius, scale=self.ibls[i].scale, x=self.ibls[i].pos[0] - 0.5, y=self.ibls[i].pos[1] * 0.3 + 0.2, aspect_ratio=1.0, ) for i in range(num) ], xdensity=512) # rotate by 180 degree tmp = gs() h, w = tmp.shape[0], tmp.shape[1] ret = tmp.copy() ret[:, :w // 2], ret[:, w // 2:] = tmp[:, w // 2:], tmp[:, :w // 2] return ret
#aff_ratio, inh_ratio, lr, threshold # Sheets retina = InputSheet('Retina',2.4,25,None) lgn_on = NoTimeconstantSheet('LGN_ON',1.6,25,None) lgn_off = NoTimeconstantSheet('LGN_OFF',1.6,25,None) #V1 = Sheet('V1',1.0,50,0.002,threshold=float(sys.argv[4])) V1 = HomeostaticSheet('V1',1.0,50,0.002,init_threshold=float(sys.argv[4]),mu=float(sys.argv[5])) print sys.argv #Projections # DoG weights for the LGN centerg = imagen.Gaussian(size=0.07385,aspect_ratio=1.0,output_fns=[DivisiveNormalizeL1()]) surroundg = imagen.Gaussian(size=0.29540,aspect_ratio=1.0,output_fns=[DivisiveNormalizeL1()]) on_weights = imagen.Composite(generators=[centerg,surroundg],operator=numpy.subtract) off_weights = imagen.Composite(generators=[surroundg,centerg],operator=numpy.subtract) retina_to_lgn_on = FastConnetcionFieldProjection("RetinaToLgnOn",retina,lgn_on,1.0,0.001,0.375,on_weights) retina_to_lgn_off = FastConnetcionFieldProjection("RetinaToLgnOff",retina,lgn_off,1.0,0.001,0.375,off_weights) lgn_on_to_V1 = FastConnetcionFieldProjection("LGNOnToV1",lgn_on,V1,0.5,0.001,0.27083,imagen.random.GaussianCloud(gaussian_size=2*0.27083)) lgn_off_to_V1 = FastConnetcionFieldProjection("LGNOffToV1",lgn_off,V1,0.5,0.001,0.27083,imagen.random.GaussianCloud(gaussian_size=2*0.27083)) center_lat = imagen.Gaussian(size=0.05,aspect_ratio=1.0,output_fns=[DivisiveNormalizeL1()],xdensity=V1.density+1,ydensity=V1.density+1,bounds = BoundingBox(radius=V1.size/2.0))()[14:-14,14:-14] surround_lat = imagen.Gaussian(size=0.15,aspect_ratio=1.0,output_fns=[DivisiveNormalizeL1()],xdensity=V1.density+1,ydensity=V1.density+1,bounds = BoundingBox(radius=V1.size/2.0))()[14:-14,14:-14] center_lat = center_lat / numpy.sum(center_lat) surround_lat = surround_lat / numpy.sum(surround_lat)
class KernelMax(TransferFn): """ Replaces the given matrix with a kernel function centered around the maximum value. This operation is usually part of the Kohonen SOM algorithm, and approximates a series of lateral interactions resulting in a single activity bubble. The radius of the kernel (i.e. the surround) is specified by the parameter 'radius', which should be set before using __call__. The shape of the surround is determined by the neighborhood_kernel_generator, and can be any PatternGenerator instance, or any function accepting bounds, density, radius, and height to return a kernel matrix. """ kernel_radius = param.Number(default=0.0, bounds=(0, None), doc=""" Kernel radius in Sheet coordinates.""") neighborhood_kernel_generator = param.ClassSelector( imagen.PatternGenerator, default=imagen.Gaussian(x=0.0, y=0.0, aspect_ratio=1.0), doc="Neighborhood function") crop_radius_multiplier = param.Number(default=3.0, doc=""" Factor by which the radius should be multiplied, when deciding how far from the winner to keep evaluating the kernel.""") density = param.Number(1.0, bounds=(0, None), doc=""" Density of the Sheet whose matrix we act on, for use in converting from matrix to Sheet coordinates.""") def __call__(self, x): rows, cols = x.shape radius = self.density * self.kernel_radius crop_radius = int(max(1.25, radius * self.crop_radius_multiplier)) # find out the matrix coordinates of the winner wr, wc = array_argmax(x) # convert to sheet coordinates wy = rows - wr - 1 # Optimization: Calculate the bounding box around the winner # in which weights will be changed cmin = max(wc - crop_radius, 0) cmax = min(wc + crop_radius + 1, cols) rmin = max(wr - crop_radius, 0) rmax = min(wr + crop_radius + 1, rows) ymin = max(wy - crop_radius, 0) ymax = min(wy + crop_radius + 1, rows) bb = BoundingBox(points=((cmin, ymin), (cmax, ymax))) # generate the kernel matrix and insert it into the correct # part of the output array kernel = self.neighborhood_kernel_generator(bounds=bb, xdensity=1, ydensity=1, size=2 * radius, x=wc + 0.5, y=wy + 0.5) x *= 0.0 x[rmin:rmax, cmin:cmax] = kernel
k_rows, k_cols = kernel.shape rolled = np.roll(np.roll(convolved_raw, -(k_cols // 2), axis=-1), -(k_rows // 2), axis=-2) convolved = rolled / float(kernel.sum()) if trim: padding = (arr.shape[0] - kernel.shape[0]) / 2 width = arr.shape[0] - 2 * padding convolved = convolved[padding - 1:padding + width, padding - 1:padding + width] return Image.fromarray(np.uint8(convolved * 255.0)) anisotropic_kernel = imagen.Gaussian(aspect_ratio=10.0, size=0.05, xdensity=128, ydensity=128, orientation=math.pi / 2.0) def generate_GR(images_dir, kernel_pattern=anisotropic_kernel, name='V_GR', trim=True): """ Generates a convolved dataset using the given kernel. Returns a list of the convolved image filenames. If no kernel is supplied, uses the default kernel of vertical anisotropic blur to simulate the vertical goggle rearing condition.