ioam / topographica

A general-purpose neural simulator focusing on topographic maps.
topographica.org
BSD 3-Clause "New" or "Revised" License
53 stars 32 forks source link

a problem with simulated periodic maps #684

Closed dancehours closed 6 years ago

jbednar commented 6 years ago

I'm not sure why you say that the OFF response area is larger than it should be; the Gaussians that form the OFF RF are larger than those for the ON RF, so it's normal that the OFF response should cover a wider area.

In any case, are you sure that the corners are reliably low in selectivity? Periodic boundary conditions mean that the corners will all be similar to each other, and in this particular run they are low, but it seems like a different random seed could result in them all being high.

jbednar commented 6 years ago

I'm not sure which random Gaussians you mean; for training? In any case, yes, if you are measuring selectivity without using patterns that are wrapped according to your periodic boundary conditions for a map trained with periodic boundaries, then there could be systematic differences. Are you ensuring that map measurement uses periodic patterns as well?

dancehours commented 6 years ago

I mean I use numpy.random.randint to generate the centers of training Gaussian, This function is supposed to generate uniform integers in an interval. I am not sure, because I don't change anything about functions of map measurement. As you said, I can wrap the sine waves to do measurement as well to have a try.

jbednar commented 6 years ago

randint is a strange choice, given that centers can take arbitrarily precise floating-point values. Map measurement does need to change; sine waves are not an x,y, periodic function, so near the edges a neuron in your periodic network will see bits of two different chunks of sine waves, which will by definition be a poor match to any single RF. Thus any RF near the border, and doubly so any RF near the corners, will be poorly stimulated by all the test patterns, and thus will be judged to be unselective. Even if it would be responsive if stimulated by the right kind of pattern that it prefers, that pattern never occurs, and so it won't strongly select between the others. You could do map measurement with a Gaussian pattern that you wrap around periodically, but then you'll need to vary both x and y locations, not just the sine grating phase, making map measurement something like 20 times slower (assuming there are 20 different phases currently being tested). Making the map measurement do this is not hard, as FeatureMapper is written very generally to handle any reasonable map measurement protocol, but I don't think it's documented well and you'll need to make sure that you watch the patterns presenting during map measurement to verify that it's presenting an appropriate set of patterns.

dancehours commented 6 years ago

By "vary both x and y locations, not just the sine grating phase, making map measurement something like 20 times slower", do you mean change the x and y location of a Gaussian 20 times for every orientation in one measurement ?

It seems there is no visualization function in FeatureMapper to watch the presenting of patterns so I may need to write that by my own.

jbednar commented 6 years ago

No on both counts. Usually, the map measurement code will cycle through all orientations and all phases of a Gaussian, as you can see in the measure_or_pref command:

class measure_or_pref(SinusoidalMeasureResponseCommand):
    """Measure an orientation preference map by collating the response to patterns."""

    def _feature_list(self, p):
        return [f.Frequency(values=p.frequencies),
                f.Orientation(steps=p.num_orientation,
                              preference_fn=self.preference_fn),
                f.Phase(steps=p.num_phase)]

where by default frequencies=[2.4], num_orientation=4, and num_phase=18. So you need 1*4*18 test patterns, i.e. 72. If you want to use Gaussians to measure a map, then rather than frequency, orientation, and phase like sine gratings, you'll need to vary size, aspect ratio, orientation, x, and y. You can first pick a good size and aspect ratio (make sure it's a pattern that activates your neurons well), then you'd have 1 size, 1 aspect ratio, 4 orientations, 18 x and 18 y, for a total of 1296 patterns to present when calculating one map.

You also can't use SinusoidalMeasureResponseCommand, but you can start with the PositionMeasurementCommand add Orientation and Aspect_Ratio to the list of what it varies, which shouldn't be hard (it's just a mixture of code already in those two classes, apart from the aspect ratio).

In any case, these classes accept some argument ("display"?) that tells them to update the display in the Tk GUI during measurement, if you're using Tk. (Can't remember what that was called). Map measurement is just the same as any other input presentation, except that it's controlled in a loop and the results are collected, so you should be able to use whatever way you are already viewing input presentations.

jbednar commented 6 years ago

Oops, 18 steps in x and y is probably not enough. It was enough for sine gratings, because that's a periodic pattern, and there were maybe four periods being shown onscreen at once? So you'd need a lot more positions if you wanted to be sure to hit every neuron with something that activates it well. Maybe 100 positions, needing 1*1*4*100*100, i.e. 40000 input presentations. Definitely something you want to debug using a small map, given that 40000 is substantially more than the number of presentations needed to make the map in the first place.

Tell me again why you wanted a periodic map? :-) You can also consider entirely different approaches to map measurement, such as fitting a gaussian to each ON cell RF explicitly.

jbednar commented 6 years ago

If so, you could just not worry about map measurement problems; the actual network shouldn't care how you measure the map, and the current sine-based measurement functions should be accurate anywhere not too close to the borders.

jbednar commented 6 years ago

Have fun, then! :-)

dancehours commented 6 years ago

Thank you very much.

dancehours commented 6 years ago

Hi, I use GUI to show map measurement process so I use the "Orientation Preference" in the menu of "Plots". There the "pre plot hook" is set as "measure_sine_pref", so I want to change this hook to my own one, e.g., "measure_or_pref_special". According to the manual http://ioam.github.io/topographica/User_Manual/plotting.html#changing-existing-plots it needs " adding a new plot" and write some code as it shows, but I am not sure where the code can put. I don't find the script file which can contain these commands.

jbednar commented 6 years ago

The easiest thing to do is probably to edit topo/plotting/plotgroup.py and put it there. Or you can put it in any file you want, as long as that file is executed by the time the GUI is launched. I think e.g. if you put a file in topo/command/ , it will get executed and made available, but don't hold me to that!