def test_direct_getting_and_setting(self): """ Test the methods used to set and get Parameter values. """ g = Gaussian() f = SomeFrame(Toplevel(),extraPO=g) g.size=0.95 self.assertNotEqual(f.size,g.size) self.assertEqual(f.get_parameter_value('size'),g.size) f.set_parameter_value('size',0.23) self.assertEqual(g.size,0.23) try: f.set_parameter_value('does_not_exist',100) except AttributeError: pass else: raise("Failed to raise AttributeError on setting non-existent *Parameter* 'does_not_exist'") try: f.get_parameter_value('does_not_exist') except AttributeError: pass else: raise("Failed to raise AttributeError on getting non-existent *Parameter* 'does_not_exist'")
def default_analysis_function(): """ Basic example of an analysis command for run_batch; users are likely to need something similar but highly customized. """ # CEBALERT: why are these imports here rather than at the top? import topo from topo.command.analysis import save_plotgroup # Save all plotgroups listed in default_analysis_plotgroups for pg in default_analysis_plotgroups: save_plotgroup(pg, use_cached_results=True) # Plot projections from each measured map measured_sheets = [ s for s in topo.sim.objects(ProjectionSheet).values() if hasattr(s, 'measure_maps') and s.measure_maps ] for s in measured_sheets: for p in s.in_connections: save_plotgroup("Projection", projection=p) # Test response to a standardized pattern from topo.pattern import Gaussian from math import pi pattern_present(inputs=Gaussian(orientation=pi / 4, aspect_ratio=4.7)) save_plotgroup("Activity", saver_params={"filename_suffix": "_45d"})
def basic_save_load_snapshot(self): """ Very basic test to check the activity matrix of a GeneratorSheet comes back ok, and that class attributes are pickled. """ assert topo.sim.name == SIM_NAME topo.sim['R'] = GeneratorSheet(input_generator=Gaussian(), nominal_density=2) topo.sim.run(1) R_act = copy.deepcopy(topo.sim['R'].activity) Line.x = 12.0 topo.sim.startup_commands.append("z=99") save_snapshot(SNAPSHOT_NAME) Line.x = 9.0 exec "z=88" in __main__.__dict__ topo.sim['R'].set_input_generator(Line()) topo.sim.run(1) load_snapshot( resolve_path(SNAPSHOT_NAME, search_paths=[normalize_path.prefix])) # CEBALERT: should also test that unpickling order is correct # (i.e. startup_commands, class attributes, simulation) assert_array_equal(R_act, topo.sim['R'].activity) self.assertEqual(Line.x, 12.0) self.assertEqual(__main__.__dict__['z'], 99)
def test_composite_pattern_basic(self): """ Test that a composite pattern consisting of just one Gaussian is the same as that actual Gaussian pattern, and that a composite pattern of two rectangles is the same as adding the two individual matrices. """ bbox = BoundingBox(radius=0.5) g = Gaussian(size=0.2, aspect_ratio=0.5, orientation=0, x=0.2, y=-0.03) c = Composite(generators=[g], bounds=bbox, xdensity=7, ydensity=7) assert_array_equal(g(bounds=bbox, xdensity=7, ydensity=7), c()) r1 = Rectangle(size=0.2, aspect_ratio=1, x=0.3, y=0.3, orientation=0, smoothing=0.0) r2 = Rectangle(size=0.2, aspect_ratio=1, x=-0.3, y=-0.3, orientation=0, bounds=BoundingBox(radius=0.8), xdensity=2, smoothing=0.0) c_true = r1(bounds=bbox, xdensity=7, ydensity=7) + r2( bounds=bbox, xdensity=7, ydensity=7) c = Composite(generators=[r1, r2], bounds=bbox, xdensity=7, ydensity=7) assert_array_equal(c(), c_true)
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(PatternGenerator, default=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
def test_composite_pattern_moves(self): """ Test that moving a composite pattern yields the correct pattern. """ bbox=BoundingBox(radius=0.5) g = Gaussian(size=0.2,aspect_ratio=0.5,orientation=pi/3,x=0,y=0) c = Composite(generators=[g],x=-0.3,y=0.4,xdensity=4,ydensity=4,bounds=bbox) g_moved = g(x=-0.3,y=0.4,xdensity=4,ydensity=4,bounds=bbox) assert_array_equal(c(),g_moved)
def test_cfsom(self): """ """ gaussian_width = 0.02 gaussian_height = 0.9 input_pattern = Gaussian( bounds=BoundingBox(points=((-0.8, -0.8), (0.8, 0.8))), scale=gaussian_height, aspect_ratio=gaussian_width / gaussian_height, x=numbergen.UniformRandom(lbound=-0.5, ubound=0.5, seed=100), y=numbergen.UniformRandom(lbound=-0.5, ubound=0.5, seed=200), orientation=numbergen.UniformRandom(lbound=-pi, ubound=pi, seed=300)) # input generation params GeneratorSheet.period = 1.0 GeneratorSheet.nominal_density = 5 GeneratorSheet.print_level = param.parameterized.WARNING # cf som parameters CFSheet.nominal_density = 5 ########################################### # build simulation param.parameterized.min_print_level = param.parameterized.WARNING s = Simulation() s.verbose("Creating simulation objects...") s['retina'] = GeneratorSheet(input_generator=input_pattern) s['V1'] = CFSheet() s['V1'].print_level = param.parameterized.WARNING s.connect('retina', 'V1', delay=1, connection_type=CFProjection, learning_fn=CFPLF_Hebbian_opt()) s.print_level = param.parameterized.WARNING self.assertTrue( topo.sim['V1'].projections().get('retinaToV1', None) != None) self.assertTrue( topo.sim['V1'].projections().get('retinaToV1', None) != None) s.run(10)
def test_test_pattern(): """Check that test pattern window is working.""" tp = topo.guimain['Simulation']['Test Pattern']() act = topo.guimain['Plots']['Activity']() tp.gui_set_param('edit_sheet', 'GS') ## Test for state_push bug (simulation not run() before Present pressed) assert len(topo.sim.eps_to_start ) > 0, "test must be run before simulation is run()" from topo.pattern import Gaussian from topo import numbergen topo.sim['GS'].set_input_generator(Gaussian(x=numbergen.UniformRandom())) tp.Present() topo.sim.run(1) act1 = copy.deepcopy(topo.sim['GS'].activity) topo.sim.run(2) assert_array_not_equal(topo.sim['GS'].activity, act1, "GeneratorSheet no longer generating patterns") ## tp.gui_set_param('pattern_generator', 'TwoRectangles') from topo.pattern import TwoRectangles assert isinstance(tp.pattern_generator, TwoRectangles), "Pattern generator did not change." preview = _get_named_plot('GS', tp.plotgroup.plots).view_dict.get( 'Strength', {})['Activity'].top.data two_rectangles = array([[0., 1], [1., 0.]]) assert_array_equal(preview, two_rectangles, "Incorrect pattern in preview plot.") tp.Present() gs_view = _get_named_plot('GS', act.plotgroup.plots).view_dict.get( 'Strength', {})['Activity'] assert gs_view.metadata.src_name == 'GS' gs_plot_array = gs_view.top.data assert_array_equal(gs_plot_array, two_rectangles, "Incorrect pattern in activity plot after Present.") tp.params_frame.gui_set_param('scale', 0.5) preview = _get_named_plot('GS', tp.plotgroup.plots).view_dict.get( 'Strength', {})['Activity'].top.data assert_array_equal(preview, 0.5 * two_rectangles, "Changing pattern parameters did not update preview.") ### Defaults button # first change several more parameters initial_preview = tp.plotgroup.plots[0].view_dict.get( 'Strength', {})['Activity'].top.data new_param_values = [ #('output_fns','Sigmoid'), ('scale', '2') ] for name, value in new_param_values: tp.params_frame.gui_set_param(name, value) changed_preview = _get_named_plot('GS', tp.plotgroup.plots).view_dict.get( 'Strength', {})['Activity'].top.data # and check the preview did change try: assert_array_equal(changed_preview, initial_preview) except AssertionError: pass else: raise AssertionError("Test pattern didn't change.") # test that preview display is correct tp.params_frame.Defaults() preview = _get_named_plot('GS', tp.plotgroup.plots).view_dict.get( 'Strength', {})['Activity'].top.data assert_array_equal( preview, two_rectangles, "Defaults button failed to revert params to default values.")
class CFPLF_HebbianSOM(CFPLF_SOM): """ Hebbian learning rule for CFProjections to Self-Organizing Maps. This implementation is obsolete and will be removed soon. Please see examples/cfsom_or.ty for current SOM support. """ learning_radius = param.Number(default=0.0) 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 updating the weights. """) neighborhood_kernel_generator = param.ClassSelector(PatternGenerator, default=Gaussian(x=0.0,y=0.0,aspect_ratio=1.0), doc="Neighborhood function") def __call__(self, iterator, input_activity, output_activity, learning_rate, **params): cfs = iterator.proj.cfs.tolist() # CEBALERT: convert to use flatcfs rows,cols = output_activity.shape # This learning function does not need to scale the learning # rate like some do, so it does not use constant_sum_connection_rate() single_connection_learning_rate = learning_rate ### JABALERT: The learning_radius is normally set by ### the learn() function of CFSOM, so it doesn't matter ### much that the value accepted here is in matrix and ### not sheet coordinates. It's confusing that anything ### would accept matrix coordinates, but the learning_fn ### doesn't have access to the sheet, so it can't easily ### convert from sheet coords. radius = self.learning_radius crop_radius = max(1.25,radius*self.crop_radius_multiplier) # find out the matrix coordinates of the winner # # NOTE: when there are multiple projections, it would be # slightly more efficient to calculate the winner coordinates # within the Sheet, e.g. by moving winner_coords() to CFSOM # and passing in the results here. However, finding the # coordinates does not take much time, and requiring the # winner to be passed in would make it harder to mix and match # Projections and learning rules with different Sheets. wr,wc = array_argmax(output_activity) # Optimization: Calculate the bounding box around the winner # in which weights will be changed, to avoid considering those # units below. cmin = int(max(wc-crop_radius,0)) cmax = int(min(wc+crop_radius+1,cols)) # at least 1 between cmin and cmax rmin = int(max(wr-crop_radius,0)) rmax = int(min(wr+crop_radius+1,rows)) # generate the neighborhood kernel matrix so that the values # can be read off easily using matrix coordinates. nk_generator = self.neighborhood_kernel_generator radius_int = int(ceil(crop_radius)) rbound = radius_int + 0.5 bb = BoundingBox(points=((-rbound,-rbound), (rbound,rbound))) # Print parameters designed to match fm2d's output #print "%d rad= %d std= %f alpha= %f" % (topo.sim._time, radius_int, radius, single_connection_learning_rate) neighborhood_matrix = nk_generator(bounds=bb,xdensity=1,ydensity=1, size=2*radius) for r in range(rmin,rmax): for c in range(cmin,cmax): cwc = c - wc rwr = r - wr lattice_dist = L2norm((cwc,rwr)) if lattice_dist <= crop_radius: cf = cfs[r][c] rate = single_connection_learning_rate * neighborhood_matrix[rwr+radius_int,cwc+radius_int] X = cf.get_input_matrix(input_activity) cf.weights += rate * (X - cf.weights) # CEBHACKALERT: see ConnectionField.__init__() cf.weights *= cf.mask
def setUp(self): self.g1 = Gaussian(x=numbergen.UniformRandom()) self.g2 = Gaussian(x=numbergen.UniformRandom()) self.s = Selector(generators=[self.g1,self.g2]) self.s.set_dynamic_time_fn(None,'generators')