Homework 3: Kohonen networks

Due Wednesday, 2009-03-11

Download these eleven Python modules and one data file. You will edit network.py, adding new classes. In addition, you will make a minor edit to thing.py. Unless you make other changes to other modules, you only need to submit network.py.

How the program starts off

In the world this time, there is only one critter, an instance of the class Bug, which continually executes the action turn_move in order to explore its world. It has a Sight sensor, which detects the color and intensity of any Lights in the world and a Smell sensor, which detects the type and intensity of any smells. In addition, there are two lights, a dim red one and a bright green one, a veggie, which emits a smell that the bug can detect, and a horizontal wall, dividing the world in half. Intensity values for lights and smells range between 0 and 1 (though for the green light in this world, 1 is impossible because the bug can't reach the light); they take on values of 0 beyond a particular distance from the object and 1 within a small radius around the object.

The bug has a neural network, which you can see by clicking on it. This starts out as the default neural network, which takes input from the three features that the bug can detect ('red', 'green', and the smell of veggies, displayed in that order) and outputs a value for the single action that the bug takes. This will change once you have implemented Kohonen networks and uncommented Bug.set_network().

There are three parameters relevant to Kohonen network learning that are read in from the world file ("world" unless you pass another filename as an argument after "-w" to "biomorph.py"): KOH_LR, KOH_SIGMA, and KOH_DECAY.

What you have to do

  1. Implement Kohonen learning.

    You will need to create a subclass of Network for competitive networks and a subclass of Layer for Kohonen networks. Notice that the constructor for the Network class takes a name (a string) and a list of layers (instances of the Layer class), and the the constructor for the Layer class takes a name (a string) and either an explicit "size" or an explict value for "dimensions". The "dimensions" option must be a pair of integers specifying the width and height of a rectangular array of units. The "dimensions" option is only relevant for Kohonen networks (and in this case the value for "size" is ignored).

    Any competitive subclass of Network should set the "supervised" option to be False and have these in its constructor:

            self.competitive = True
            self.has_bias = False
    
    You'll also need to override the Network step() method. For a competitive network this should return a tuple consisting of the error (returned by update() in the competitive layer; see below) and the set of winning units (only one for this assignment because there's only one competitive layer).

    Competitive subclasses of Layer should set the "neg_weights" and "has_bias" options to False in their constructor. In addition, competitive layer classes should override update() and learn().

    update() is different for competitive layers because it finds a winner on the basis of the nearness of the weights to the input pattern and then sets the activations to be 1.0 for the winner and smaller values for the losers. These smaller values are equal for competitive learning and derived from the neighborhood function for Kohonen networks. The neighborhood function in turn is based on the distance in output-layer space between the winner and each loser. The dimensions of this space are defined by the "dimensions" option that you must use when you instantiate the output layer for a Kohonen network. The neighborhood also depends on the KOH_SIGMA parameter. update() returns a tuple consisting of the error and the index of the winning unit. For the error, use the negative of the distance of the winning unit from the input pattern.

    learn() for competitive layers differs because it just moves the weight vector of each hidden unit toward the input pattern in proportion to its activation. For Kohonen networks, either update() or learn() must also include the updating of the KOH_LR and KOH_SIGMA parameters. After each step, each of these is just multiplied by the value of the KOH_DECAY parameter.

    To make the bug have a Kohonen network, you need to uncomment Bug.set_network() in the thing module.

    Once the bug has a network for which self.competitive is True, the network will display differently in the window you get by clicking on the bug. You can view the output layer in two different ways, one that shows the arrangement of the units within their output grid and indicates their activation, or, by selecting "Show output units in input space", one that shows the output units' positions in the first two dimensions of input space (the sensed intensities of the two lights), with blue lines connecting units that are adjacent in output space.

    To turn on learning, you will have to select "Learn" in the "Learn/Evolve" menu in the World window.

  2. Once you have debugged learning, explain the shape of the map that develops in the output layer of the network and the distribution of the units within it.
  3. Assume that the veggie sometimes fails to give off a smell. Explain how the bug could use its trained Kohonen network to estimate the intensity of the veggie's smell (and hence its distance from the veggie) when the veggie doesn't smell.

Home

Calendar

Coursework

Notes

Code


IU | INFO | CSCI

Contact instructor