// ta_Dump File v2.0 LeabraProject .projects[0] { Doc_Group @.docs = [10] { taDoc @[0] { }; taDoc @[1] { }; taDoc @[2] { }; taDoc @[3] { }; taDoc @[4] { }; taDoc @[5] { }; taDoc @[6] { }; taDoc @[7] { }; taDoc @[8] { }; taDoc @[9] { }; }; Wizard_Group @.wizards = [1] { LeabraWizard @[0] { UserDataItem_List @*(.user_data_) { UserDataItem @[0] { }; }; LayerWizElList @.layer_cfg = [3] { LayerWizEl @[0] { }; LayerWizEl @[1] { }; LayerWizEl @[2] { }; }; }; }; taBase_Group @.data_proc = [4] { taDataProc @[0] { UserDataItem_List @*(.user_data_) { UserDataItem @[0] { }; }; }; taDataAnal @[1] { UserDataItem_List @*(.user_data_) { UserDataItem @[0] { }; }; }; taDataGen @[2] { UserDataItem_List @*(.user_data_) { UserDataItem @[0] { }; }; }; taImageProc @[3] { UserDataItem_List @*(.user_data_) { UserDataItem @[0] { }; }; }; }; DataViewer_List @.viewers = [1] { MainWindowViewer @[0] { ToolBar_List @.toolbars = [1] { ToolBar @[0] { }; }; FrameViewer_List @.frames = [3] { tabBrowseViewer @[0] { }; PanelViewer @[1] { }; T3DataViewer @[2] { T3DataViewFrame_List @.frames = [1] { T3DataViewFrame @[0] { }; }; }; }; DockViewer_List @.docks = [1] { ToolBoxDockViewer @[0] { }; }; }; }; }; LeabraProject .projects[0] { name="Project_0"; desc=; tags=; templates { name=; el_typ=taBase; el_def=0; }; docs { name=; el_typ=taDoc; el_def=0; taDoc @[0] { name="Introduction"; auto_open=0; text=" = Emergent Tutorial for Building Networks = Today, you're going to build a neural network and train it to learn a set of patterns. '''To return to this document''' at any time, just click the Introduction link under docs to the left of this panel, or click the tab labeled Introduction above this panel. == Introduction == === Emergent's graphical user interface (GUI) === First off, here is some basic terminology about the user interface for Emergent: * '''Left browser panel:''' This is the left portion of the window with a \"tree\" of objects in the simulation (inlcuding the network, and the input/output data, etc). * '''Middle edit panel:''' This is where you are currently reading -- it can display different things depending on the selected tabs at the top, and what is currently selected in the left browser panel. The left-most tab usually shows what is selected in the browser, and the other tabs with \"pins\" down are locked in place and contain this document and the Wizard, which we will be making heavy use of. The right-most tab represents the configuration information for the 3D display shown in the right-most view panel (which is now called \"Frame1\" and is empty). * '''Right view panel:''' This shows 3D displays of various simulation objects, incuding the network, input/output patterns, and graphs of results, etc. === Conceptual terminology === Now let's introduce ourselves to some of the key conceptual terms that we'll frequently encounter, so we can use them to describe things. * '''Emergent''' This is the software framework written by [[.docs.Randy_OReilly]] and colleagues that we'll be using in all of the labs, demonstrations and projects. It's based on Rumelhart & McClelland's earlier Parallel Distributed Processing framework. See the Emergent website for more information about installing it on your home computer. * '''Leabra''' This is the name of the particular learning algorithm used in the course, also developed by Randy O'Reilly. (See the Emergent Documentation site for more information.) * '''Unit''' Units are like neurons. A unit sums up its inputs to calculate a membrane potential. From this, it calculates an activation value (firing rate). * '''Layer''' A layer refers to some group of neighbouring neurons with similar properties, e.g. a functional brain area or cortical layer. * '''Network''' When you have one or more layers, and you connect them up to each other, you have a network. * '''Weight''' The weight is just another word for how much the activity from one unit affects the activity of another. So weight = 'synapse strength'. Don't worry too much about remembering these details now - they'll become much more intuitive after you've played with a few networks. You can always remind yourself of these and other terms by looking at the Glossary. === Today's goal === To understand what pieces you need to build up a network, what they each do and how to edit them to get the network to do what you want it to. The skills you will learn in this lab will lay the groundwork for understanding the pieces of the pre-assembled networks. The more comfortable you become now, the better you will be able to focus on the high level concepts for more complex networks. Here you are going to: # examine a small neural network --- you can think of this as the brain of a little animal; # make a few alterations to this network; # create input patterns (data tables) for this network --- you can think of these as representations of the environment in which our animal lives; # create simple programs that cause the network to process that input and turn it into output --- these programs represent the animal learning and behaving in its world; # train a slightly bigger network on slightly more complex input patterns --- this will help us get the hang of modeling bigger animals. === Questions === At several points in this lab documentation, you'll be asked questions, which you can just answer for yourself. They are meant to make sure you become familiar with some of the key aspects of the software, and answering these will force you to do so (rather than just passively reading through and then likely forgetting how everything works). '''NOTE:''' This documentation will often tell you to ''Right-click'' something using the right mouse button. If you're using a Mac, you should interpret \"Right-click\" as \"Ctrl-click\". Ready to move on? You can click on the links below to move on to the next sections of the lab, or you can click on the name of a section under \"docs\" in the tree view in the left panel. # [[.docs.Building_and_exploring_a_network]] # [[.docs.Customizing_the_network]] # [[.docs.Controlling_the_network]] # [[.docs.Training_patterns_into_the_network]] # [[.docs.Concluding_remarks]] "; }; taDoc @[1] { name="Building_and_exploring_a_network"; auto_open=0; text=" = Building and exploring a network = == Building a network == With Emergent, you can use a graphical interface to build up a neural network piece by piece, with precise control over every aspect of it. But instead of doing this right away, we'll do something easier first. We'll try out a handy tool for creating entire networks with the click of a button. It's called the '''LeabraWizard'''. We'll use it with default settings to create a default network. # '''Before going to Step 2, remember:''' you can always get back to the documentation by clicking on docs/Building_and_exploring_the_network, or by clicking on the tab above this panel with the same name. I mention this because as soon as you carry out the next instruction, you'll momentarily lose sight of this documentation. Another option, if you prefer, is to click on the Object menu above this panel, and select Browse Me. This will open a separate window with this panel's contents in it, so you don't have to keep jumping back and forth. # Click on either the LeabraWizard_1 tab above this panel, or on wizards/LeabraWizard_1 in the left browser panel. # Now we'll tell the wizard to do something different than its default settings. We'll change the parameter called connectivity from '''BIDIRECTIONAL''' to '''FEEDFORWARD'''. Click on the field and select the right option. # Now note the context-menu buttons at the bottom of the LeabraWizard panel: Default, Network, Data, and Programs. # Click on Network, and select Std Network. Ta da! You've created a standard network, with Input, Hidden and Output layers. There's actually kind of a deep reason why this three-layer setup is the standard. It has to do with learning algorithms, but we'll talk about that later. Today's project really boils down to clicking Network, then Data, and then Programs. At each step, just so we know how to do it, we'll also directly manipulate aspects of this network without having the wizard do all the work for us. (In fact, you don't even have to use the graphical interface that you're looking at right now; instead, you could script everything in a low-level programming language. But we won't do anything like that today.) == Exploring a network == Now we'll explore the network using all three panels: === Left browser panel === Click on networks/Network_0. A new panel will open up with all sorts of fields in which you can enter parameter values for your network. For now, just note that the Build button at the bottom of this panel is really important: clicking it is what commits all the changes you've specified and actually changes your network. Also, expand the list of items under Network_0 by clicking on the triangle next to it. This shows you a graphical depiction of the data structure that the low-level code uses to represent a network. There are '''specs''' and '''layers'''. We'll talk about what the means in a little while. Under layers, find the layer labeled Hidden and click on its name. Again, you see a panel with fields for entering all sorts of parameter values that apply just to that layer. '''Question 1:''' What are the four different layer types that this layer can (apparently) have? '''Response:'''
'''Question 2:''' What happens when you move the cursor over the name of the variable pos? '''Response:'''
In general, if you get frustrated at not knowing how to do something in Emergent, tell yourself: \"Don't curse -- use the cursor!\" Seriously, moving the cursor over the names of things is incredibly useful in Emergent, since there is such a bewildering array of options and parameters for everything. === Right view panel === This panel is where all the fancy graphical interaction happens. Let's figure out how to navigate around in this space. We'll do this by examining the tools in the toolbar one by one. The toolbar is at the far right of the right view panel. * '''Red arrow:''' the red arrow is what you use to move objects around in space in the view panel, and to select individual objects so you can do things to them. Click on the green boundary of one of the layers in the network, and notice what happens in the middle edit panel (a new window should open up here). When you click on a layer, a little widget appears in its lower left corner. Clicking on this and dragging will reposition the layer. Mess around with that for a bit. Now, since that can get a little frustrating at times, also note that you can click on the layer, and then go to the window that appears in the middle edit panel to set its position in space with numerical coordinates. Click on the layer, then find the parameter pos in the middle edit panel (it's the fourth parameter from the top). Enter a new number in the x field, hit apply, and see what happens. * '''Talk to the hand:''' Now click on the hand tool below the red arrow. This is what you use to change your view of all the objects. When you do this, you'll see a circular double-arrow symbol. When you click in the space, you'll see all sorts of crazy rotational movement. If you hold shift while you do this, you'll see translational movement. There are also some rotation wheel widgets, Rotx, Roty and Dolly at the lower corners of the right view panel. Click and drag on these to see how they change the view. * '''Coming home:''' When you start moving things around, it can be hard to see everything and also difficult to get back to your original view. If you click on the home tool below the hand tool, you can reset your view to a \"home\" view. You can also define new \"home\" views by clicking on the blueprint icon just below the home icon. That defines the current view as the home view. * '''Eyeball:''' Of course, sometimes you can click that by accident. The eyeball tool always recenters everything to your original viewing coordinates, but also rescales things so that everything fits in the view panel. * '''Spotlight:''' If you want to zoom in on a particular object, you can click on the flashlight tool and then click on the object you want to zoom in on. To zoom out, you have to rely on the Dolly wheel in the lower right corner of the view panel. == Save your work == This software is relatively new, so do not be surprised if it has bugs. So far, we haven't had any problems that were so bad that we couldn't figure out a way around them, and problems have been rare altogether. But it really sucks to work hard and then lose everything because the program crashes. So let's just be safe and get into a regular habit of saving frequently. Go to the File menu at the top of your screen, and select Save Project. When you do this, a window will appear asking you to type in some comments in a Change Log. This is a handy feature actually. Recording what changes you made in a log is a really good way to help you debug a complicated system that isn't working the way you think it should. For now, just type in something like \"This is my first save\", and click OK. Move on to the next sep of the lab when you're done playing around: [[.docs.Customizing_the_network]] "; }; taDoc @[2] { name="Customizing_the_network"; auto_open=0; text=" = Customizing your network = Now you'll customize the standard network that you created with the LeabraWizard. Just so you know, rather than changing a network that we've begun building with the wizard, we can also change the settings of the LeabraWizard itself to create networks of different sizes and with different properties (click on wizards/LeabraWizard_0 to see what settings you can change). But it will often be the case that you don't quite know what you want your network to be when you start out, so we need to know how to customize things on the fly. So now you'll make a few simple adjustments to the network to get a sense of how to do it. Specifically, you'll change the number of layers we have, the number of units each layer has, and how the neurons connect. For each type of object in the network you will learn how to make changes to an instance of the object and the spec of the object - an instance applies to only one object, while a spec can apply to many. ''Notice in the left browser that directly beneath Network_0 are two child objects: specs and layers. Guess which of these refers to specs and which to instances. == Create and delete layers == The first thing you'll do is add -- and then remove -- a layer from our network. This will show you how to handle the basic building blocks of a network. # Go to the left browser, and click on networks/Network_0. In the middle panel, at the bottom, there is a button labeled New Layer. Click it. Bam! A new layer is visible in the right view panel. # Now use the red arrow in the right view panel and click on the new layer's green boundary. Now Right-click on it. A big context menu appears with all sorts of options. Don't select any of them just yet. '''NOTE: Usually, if an object in Emergent can be clicked on in the view panel, then it can also be Right-clicked. This will bring up a context menu with all sorts of possible actions that can be applied to that object. In fact, sometimes that's the only way to perform certain actions.''' Now, you'll do something to see the equivalence of accessing things in the right view panel and the left browser panel. # Click on empty space in the view panel to make the context menu disappear. Now go over to the left browser panel and click on networks/Network_0/LeabraLayer_3. (Actually, the number at the end of that name might be something other than 3, but it should be the only layer named anything remotely like that.) Now Right-click on that name, and you see the same context menu. Select Delete. Now the layer is gone. Another way to do that is --- once you've selected the right layer --- to go the Object menu above this middle panel and select Close (Destroy). # OK, now try to undo that precipitous action . . . good luck. That's right: there's no undo function. We might as well get used to that right now. ('Undo' will be added in future versions of the software.) == Change the number of units in a layer == Now let's change how many units are in our layers. Because the number of units in a layer is specific to a given layer and not a general property of a layer, this can be done by editing the instance of the layer. We want each of our layers to have two units apiece. * In networks/Network_0/layers/Input, find the label un geom. There, change the x field to 2 and the y field to 1 . Then click Apply. '''Question 1:''' What happened? How many units are listed under Input/units? '''Response:'''
* Make sure that you have a 2-unit geometry for the Input layer (i.e., x times y equals 2). Then go to networks/Network_0, and click Build. '''Question 2:''' Now what happened in the right view panel? What about the left browser panel? '''Response:'''
* Now similarly change the number of units in the other two layers. You should now have a three-layer network and each layer should have two units. You should also have a sense of how to select and edit a layer. We will now take a quick look at projections and connections. As you will see, the same basic techniques can be applied to editing any of these objects. == Change projections and connections == Projections are represented as arrows in the network window. There is very little you can edit about a projection as its only job is to determine which units are connected together. Don't take my word for it though ... * Click on a projection arrow in the view panel, and a new window will appear in the middle edit panel. One of the two important projection properties there is the 'spec', which should be set to 'FullPrjnSpec'. 'Fully connected' means that every unit in the sending layer is connected to every unit in the receiving layer. If you click on 'FullPrjnSpec', you can see a somewhat inscrutable list of alternate specs, for varying which units in the sending layer are connected to which units in the receiving layer. Leave it on 'FullPrjnSpec' (i.e., hit Cancel). * This edit window also has a 'Con Spec' property. Click on the triangle next to 'LeabraConSpec_0', and you'll be asked how you want to view this spec: as a panel (in the middle edit panel) or as a dialog (a free floating window). Pick whichever you want. You can now see the characteristics of the weights/synapses in this projection. You can see properties for determining whether they're inhibitory weights, what the learning rate is etc. By moving the cursor over various parameter names, a pop-up will appear that explains what the parameter does. Generally in Emergent, moving the cursor over an icon or word is likely to produce such a pop-up with useful info. == A note about instances vs. specs == Editing the 'instance' of an individual, existing object tells you about its current status. For example, editing the instance properties of an object will tell you its current activation, membrane potential etc. 'Specs' are like templates or blueprints. They determine the ''type'' of an object. For example, a unit's spec might determine what kind of threshold it has or whether it gets tired after it fires a lot. It might help to realize that you can have a spec without any instances that actually use that spec. This mnemonic might help - an instance applies only to a single object, while a spec can apply to one, many or no objects. A common initial frustration with using this software is not knowing where to find a certain property. It will take time and practice to learn how to accurately guess where you might find something. You will notice as you gain more experience that for some objects you will rarely access a spec to edit it, but you will access the corresponding instance regularly. The opposite will be true for other objects. Here are a couple of examples that might help you . . . '''Units''' - Most changes you will want to make ought to be applied to the spec and will be applied to all units. You will rarely/never actually care about the instance. However, changing the spec is useful if you want to affect the parameters shared by all the units in your network. '''Connection''' - Similar to unit, you will rarely/never want to make a change to just one connection, therefore you will only care about the spec. '''Layer''' - You will probably want to access both spec and instance properties equally often. '''Projection''' - You won't edit much about these, mostly you will just remove and add them. Hooray. That was progress. Save your project . Move on to the next sep of the lab when you're done playing around: [[.docs.Controlling_the_network]] "; }; taDoc @[3] { name="Controlling_the_network"; auto_open=0; text=" = Controlling the network = You should now have some idea of what layers, units, projections, and connections are. Ultimately we would like to know how a piece of brain, structured the way our networks are built, would function. We will need a few more tools to help us do this: data tables and programs. == Data tables (input and desired output patterns of activity) == We return to the LeabraWizard_0 tab, and move across to the next menu button on the bottom labeled Data, and select the StdData option. This will bring up a dialog with mostly default information already filled in (and not modifiable because there are no other options), but there is one parameter we need to specify: n_patterns. Enter 2. This will construct a \"data table\" object (much like a spreadsheet or simple data base) that has a column corresponding to the Input layer of the network and another corresponding to the Output layer. It will have 2 rows where we can specify the different input patterns to the network. The Name column is useful for labeling our patterns. You'll see (matrix) in the Input and Output columns, and if you click on one of those, an extra editor shows up at the bottom of the window to allow you to enter values for the \"matrix\" of input and output units. The Name column, in contrast, has just a single value for each row (i.e., a \"scalar\"), so it can be edited directly in the main table view. This data table object is called StdInputData. All data tables are found in the left browser tree under Lab_1/data. This particular table lives in the data/InputData subgroup in the left browser, in case you need to get back to it. Here is what you should enter, where the Input units are ordered left-to-right, bottom-to-top:
Name Input Output
Pat11001
Pat20110
== Visualizing the Data Patterns == The best way to make sure you've entered the right patterns is to create a \"Grid View\" of your input data -- do this by selecting the View/New Grid View option from the menu at the top of the data table editor, which you've been using to enter input patterns. Go ahead and keep the \"New Frame\" default for the dialog that pops up (you can also add multiple view elements together in a single 'frame' in the 3d view -- we'll do that later). This will create a StdInputData tab in the right view panel, and display your input patterns, which hopefully match those shown in the above table. If not, you can correct them by clicking back on StdInputData in the left browser -- you cannot edit values in the grid view display. There is also a new StdInputData middle-panel tab, which contains various parameters for controlling the configuration of the grid view display. You can mouse-over the fields to get more info. Many of these require you to hit the Apply button at the bottom before they take effect on the view. The next step is to create Programs to control the presentation of these input patterns to the network. == Programs == Programs are tools that allow you to present your input patterns to your network and keep logs of your network's behavior as it processes those patterns. They are structured as hierarchies. The most common program we will use is a LeabraEpoch program. Again return to the LeabraWizard_0 wizard panel, and now select StdProgs from the bottom menu. This creates a set of standard programs that organize the presentation of input patterns to the network into a hierarchy of time scales: * '''LeabraBatch''' -- iterates over multiple simulated \"subjects\" in a psychology experiment -- each having their own different random initial weights (we won't use this initially). * '''LeabraTrain''' -- a complete training of the network from random initial weights to final correct performance, by iterating over multiple \"epochs\" * '''LeabraEpoch''' -- one full pass through all of the different task input patterns * '''LeabraTrial''' -- processes one input pattern, using two ''phases'' of settling -- the minus phase presents the input stimulus, and allows the network to come up with its own best guess as to the correct response, and the plus phase presents the correct answer to allow the network to learn to perform the task correctly. * '''LeabraSettle''' -- multiple updates of neural unit activations to process a given input/output pattern. * '''LeabraCycle''' -- a single cycle of updating of neural unit activation states (roughly 5-10msec of simulated real time) There are also some other supporting programs that we'll discuss later. A narrative example will help you understand what each level does. Imagine that the LeabraTrain program is an experiment. In this experiment we have a list of items we would like the network to learn. These items are the patterns in our StdInputData table. When you run the LeabraTrain program, it will run the LeabraEpoch program over and over again. The epoch program will present each pattern in the data table once. Each presentation of a pattern is called a trial and is done with the LeabraTrial program. We have the ability to have the network process each event more than once when it comes up - this is done with multiple iterations of the LeabraSettle program. (We'll explore this feature later.) Finally, as the network processes the pattern, activity must move from neuron to neuron within the network, and this is done over multiple cycles. Again, here's the hierarchy of programs in a typical Leabra-based lab project in Emergent: * Train - loops over epochs * Epoch - goes through all the patterns in a data table * Trial - processes a single pattern, with two learning phases (plus and minus) * Settle - all the timesteps in one phase * Cycle - a single timestep '''Question 1:''' In the case of our environment, how many trials will our epoch process run each time it runs? You should be able to figure this out without using the GUI. '''Response:'''
''For future reference:'' You might notice that the ApplyInputs program is opened up to show the LayerWriter_0 object -- this was auto-configured to apply the input data values to the appropriate (same name) layers in the network. If you change the layer names or add additional layers, etc, you may need to go back to this object and hit the AutoConfig button to reconfigure it. We'll do this later in other labs. == Running the Simulation == First, make sure you're viewing the Network_0 network view tab, and then click on the LeabraTrain program. Press the Init button at the bottom of the window, followed by the Run button. You should then see the network processing each of the input patterns for the task multiple times, as it iterates over epochs of trials of settles of cycles of processing. Depending on your hardware, this may wiz by in quite a blur. In fact, the whole thing will be over before you know it. Once it finishes, you can see more clearly what it is doing by hitting the Step button, which will perform one phase of settling at a time. You should observe that the network gets the correct output unit active in the minus phase (look for MINUS_PHASE or PLUS_PHASE in the text region at the bottom of the network 3d view display. It has successfully learned the task! So what happened? It's great that the software runs quickly, but it would be nice to slow things down and see how activity propagates through the system. Follow the steps below to get a system that proceeds more slowly, and shows you how activity changes on each cycle (or timestep). # Click on programs/LeabraAll_Std subgroup/LeabraTrain. Now in the middle panel, the first thing we'll do is change the value of the field err_stopcrit to -1. Why? Well, this parameter determines how long LeabraTrain runs, by determining how small an error it must achieve between the activity in the Output layer and the patterns we encoded into the data table. If it learns the task quickly (by finding weights between layers that produce the right output patterns for each input pattern), then it stops. If we set the criterion value to something below 0, it can never reach this point, so it just keeps going until it hits a certain number of iterations. # The other important parameter of LeabraTrain that we should change is train_mode. It should have been set to '''TRAIN'''. We can now make this program execute an unending sequence of epochs ''without changing weights'' by changing this parameter to '''TEST'''. This mode is used to observe how a network performs after learning is finished. We just want to see our network perform now, so we don't need learning turned on. # Also, change the field named step_prog to LeabraCycle. Later, we'll try stepping through time, cycle by cycle, rather than letting Emergent run willy-nilly. Changing step_prog tells all the programs in the Leabra program hierarchy what you mean when you tell it to take a step: do you mean, go through one trial? Or go through one settle? In our case, the answer is no: instead, you mean go through one cycle. # Now we need to tell each program in the hierarchy that we want it to display its changes to the network's activations, or weights, or whatever, every time that its called. We're doing this to get a feel for the dynamics underlying everything in Emergent. So, in the left browser, click on LeabraCycle. Then, at the top of the middle edit panel, click on the button labeled Program Ctrl. Then find a checkbox at the bottom labeled '''update_net_view''', and make sure it's checked. Then click Apply. After that, do the same thing for LeabraSettle. # Now, click on LeabraTrain in the left browser. Make sure you are in the Program Ctrl frame (not the Properties frame). # Click the Run button. Now you should see the network activity evolving slowly enough to watch it. You can hit Stop to stop it at any time. Take a look at the the text region at the bottom of the network 3D view display in the right viewer. '''Question 1:''' How many cycles does each trial execute? (You can figure this out by looking at the cycle field in the text region of the network view, and there are other ways too.) '''Response:'''
'''Question 2:''' How many epochs will the LeabraTrain program go through, when err_stopcrit is less than 0? (Hint: the answer is not infinity.) '''Response:'''
OK, now let's figure out how to go step by step through time. In the Program Ctrl panel for LeabraTrain, click Stop. Now, go ahead and click Step. Step through a couple of epochs by clicking repeatedly, and take a look at the text region in the Network_0 frame in the right view panel. This should give you a feel for how things change from cycle to cycle. Each click of step runs one cycle. The first time you click step only the bottom layer's event will be applied to the network. As you continue to click cycle activity will pass from the bottom layer to the top layer. At some point one of the units in the top layer will turn bright yellow. This is when the second settle begins and the network is told the correct answer. If you keep clicking on step eventually you will see the other bottom layer unit turn yellow and activity propagate up into the second layer again. Click away until you are tired or get bored. That was a lot to take in. Move on to the next step when you're done playing around: [[.docs.Exploring_the_weights_of_the_network]] "; }; taDoc @[4] { name="Exploring_the_weights_of_the_network"; auto_open=0; text=" = Exploring the weights of the network = Now that you have seen the network run, let's explore why it behaves the way it does. As you learned in class and in the textbook, a unit becomes active when it receives enough input. As you were watching the network you saw how much activity each unit had. In order to understand which unit in the top layer became active we must look at the weights. This is another thing that we can do by pointing and clicking in the network frame inside the right view panel. But so far, we've been seeing the network display activity as colored rectangles. Now let's find out how to examine other features of a network. # At the top of the middle edit panel, click on the Network_0 tab (alternatively, click on networks/Network_0 in the left browser). This should produce a frame in the middle edit panel that has all sorts of controls for the 3D graphical network view. # In the middle of this panel, you'll find a box with the labels '''Value''' and '''Description'''. Highlighted in the middle of the box should be the word '''act --- activation value --- what the unit communicates to others'''. # We want to look at weights, not activations. So scroll down in the list until you get to '''s.wt'''. You can scroll by hitting the up and down arrow keys on the keyboard. When you get to '''s.wt''', stop. # Now, what do you see depicted in the network viewer? You shouldn't see anything. That's because we haven't told the viewer which unit's weights we want to look at. So click directly on any unit in the right view panel (not the green layer boundary) with the red arrow tool. Now what do you see? When the weights are larger, the rectangles are bigger and more brightly colored. Do the weights make sense, given the mappings from input patterns to output patterns? # OK, we've looked at the weights on connections leading away from a unit into other units. How do we view the weights leading into a given unit from other units? By selecting '''r.wt''' instead of '''s.wt''' in the network settings panel. Go ahead and mess around with that for a little bit, and make sure that everything makes sense to you. '''Question 1:''' Why do you have to click on a unit to see the weights between it and other units? After all, you can see all activations simultaneously without clicking on any units. '''Response:'''
Move on to the next step of the lab when you're done playing around: [[.docs.Training_patterns_into_the_network]] "; }; taDoc @[5] { name="Training_patterns_into_the_network"; auto_open=0; text=" = Training big patterns into a bigger network = In the last part we trained two very simple patterns into a very simple network. Now that you understand the pieces a little better, let's try the same thing in a bigger network with bigger input patterns. This will show you how learning is actually not as easy as it seemed in the first example. === Expand the network === First, we'll add a new layer to the network. We've done this once, so let's do it again. In the left browser, click on networks/Network_0. Then right click, and select New layer. Now give this layer a different (bigger) unit geometry, and change its name to 'NewOutput' (if you make a really huge network, though, it will slow the system down a lot and it will be really hard to see what's going on -- we used a 3x3 geometry while preparing this project). Now we need to connect this new layer to the existing layers in the network. Make a feedforward projection from the old Output layer to NewOutput. Do this by clicking on networks/Network_0/layers/NewOutput/projections. Now Right-click on that again, and select New. This will create a projection for you from the previous layer in the layer list to NewOutput (you could change which layer projects to NewOutput by clicking in the left browser on NewOutput/projections/Fm_Output, and then changing the from type! field to '''CUSTOM'''.) '''Question 1:''' When you want to connect two layers together with a feedforward projection, which layer do you have to edit to create the projection? '''Response:'''
Now, give all the layers bigger geometries (each layer can be a different size than the others if you wish). Finally, in the left browser, click on networks/Network_0, and then click Build. This will take all the graphical and numerical settings that we've entered and commit these changes to Emergent's internal representation of the network. === Change input/output pattern data === OK, now we have changed the layer geometries, so the original Input and Output data patterns aren't the right size for our network anymore. We'll need to make them the same size as their corresponding layers. '''NOTE:''' if you're using a Windows machine, I think the next step is likely to crash Emergent. However, a recovery file will be saved by the program that you can open up, and it will incorporate the changes you intended to make. Just to be safe, save your current progress now. # In the left browser, click on data/InputData subgroup/StdInputData/Input. # Now, at the top of the middle edit panel, click on the Column menu, and select Change Col Cell Geom. # In the edit dialog that appears, type in '2' for the layer dimension (dim). '''This will change the little dialog box, so that x and y size fields show up in the dialog, but you won't be able to see them very well. Be sure to set the dims field to 2, then scroll over and type in the correct x and y dimensions for your new layer size. If you leave either x or y set to 0, everything will crash.''' Nevertheless, Windows-Emergent might crash at this point even if you take this precaution. If so, then just open the recovery file after the crash and things should be OK. # Now edit the input pattern. Click on data/InputData subgroup/StdInputData. Click on the Input column matrix entries, and each matrix will appear at the bottom half of the window. '''Question 2:''' When you change a layer's geometry and the size of its input data table to match, what happens to the old input pattern you entered before? '''Response:'''
OK, now type in some 1's in various places in each of your input data tables. If you want, you can also add new patterns as well. Now, go ahead and change the output data table geometry to match the size of the NewOutput layer, and type in the output patterns that you want the network to learn. If you like, you can create a new GridView of these input patterns, by going to the View menu above the middle edit panel after clicking on StdInputData. Then select NewGridView, and put the grid in a new frame. === Make NewOutput the target of training === We have now made a bigger network and bigger input and output data tables. But remember, the system is set up to be trained based on the activation in its Output layer. Now, however, the NewOutput layer is the real output of the system. We can tell Emergent that this is what we intend by doing two things. # First, go through each layer in the network, and make sure its type is appropriate to its new role. This means making the Output layer into a 'Hidden' layer, and the NewOutput layer into a 'Target'. You can do this with the browser our in the net view in the right view panel with the red arrow tool. # Now, click on programs/ApplyInputs/objs/LayerWriter_0. Click on Output and type 'NewOutput' into the layer name field. This redirects the training algorithm to NewOutput. OK, now we're almost ready to let our system loose. But we need to some way to observe what's going on. "; }; taDoc @[6] { name="Graphing_output_data"; auto_open=0; text=" = Monitoring, Analyzing, and Displaying Output Data = In this section we explore various ways of understanding better how the network is performing. == Graphing Learning Performance over Epochs == To see how your network is learning a given task, the first step is to generate a graph of the learning performance (sum squared error on the training patterns) over epochs. Fortunately, the default programs are already collecting this data for us, so we just need to display the graph. The data is being recorded in the [[.data.gp.OutputData.EpochOutputData]] data table object in the data/OutputData subgroup. You should see a few rows of data from the previous run, and you should notice that the avg_sse column shows a general decrease in average sum-squared-error on the training patterns, ending in a 0, which is what stopped the training. To graph this data, you just generate a graph view of this data table. As a general rule in the software, all view information is always generated by a given main object like a datatable or a network -- you don't create a graph and then associate data with it -- it goes the other way. The menu selection to create the graph view is [[.data.gp.OutputData.EpochOutputData.NewGraphView()|View/New Graph View]]. This time, let's be adventurous and instead of putting this graph in a separate view frame, put it in the Network_0 frame. If you happened to have put it in the wrong frame initially, don't worry -- just do the context menu over the frame view tab on the right (should be called EpochOutputData), and select Delete Frame. Note that there can be multiple views of the same underlying data. You should see a graph appear in the upper right of your network display, showing a decreasing line from left to right. By default the line is (redundantly) color coded for the plot value. You can control this and many other features of the graph display in the graph control panel. But wait, where is that panel? You should only see a [[.PanelTab.Network_0]] tab in the middle panel tabs. If you click on that guy, and look at the bottom, you'll see selectors for the different view objects within this one view frame (Network_0 and EpochOutputData Graph). Select the graph view tab at the bottom, and again mouse over the various controls and play around with them. As you can see, there are many different ways of configuring the graphs -- feel free to explore. Note that there are several other variables that you could plot, including average cycles to settle, and a count of the number of errors made across trials. To see your graph updating in real-time, you can re-init and run the [[.programs.gp.LeabraAll_Std.LeabraTrain]] program: [[.programs.gp.LeabraAll_Std.LeabraTrain.Init()|Init]] [[.programs.gp.LeabraAll_Std.LeabraTrain.Run()|Run]]. '''Question 1:''' How long does it take your network to reach an avg_sse of 0? (If it never reaches 0, boost the max epochs value in the LeabraTrain process. '''Response:'''
"; }; taDoc @[7] { name="Concluding_remarks"; auto_open=0; text=" == Concluding remarks == Whoo hoo! You got through the lab. Well done for getting through all of that. If you have time, why don't you play around with creating different kinds of patterns in the input data table. See if you can create some that it has no trouble learning, and some that it takes longer to learn, to help grow your intuitions about what and how it's learning. "; }; taDoc @[8] { name="Randy_OReilly"; auto_open=0; text=" ''' O'Reilly, Randy ''' Randy wrote the Emergent software, developed the Leabra learning algorithm and wrote [:CecnDefinition:'Computational Explorations in Cognitive Neuroscience'] with [:MunakataDefinition:Yuko Munakata]. See Randy's homepage at http://psych.colorado.edu/~oreilly/ "; }; taDoc @[9] { name="ChangeLog"; auto_open=0; text=" ChangeLog

ChangeLog

"; }; }; wizards { name=; el_typ=LeabraWizard; el_def=0; LeabraWizard @[0] { UserDataItem_List @*(.user_data_) { name=; el_typ=UserDataItemBase; el_def=0; UserDataItem @[0] { name="NO_CLIP"; value 1 0=1; }; }; name="LeabraWizard_0"; auto_open=1; n_layers=3; layer_cfg { name=; el_typ=LayerWizEl; el_def=0; LayerWizEl @[0] { name="Input"; n_units=25; io_type=INPUT; }; LayerWizEl @[1] { name="Hidden"; n_units=25; io_type=HIDDEN; }; LayerWizEl @[2] { name="Output"; n_units=25; io_type=OUTPUT; }; }; connectivity=BIDIRECTIONAL; default_net_type=LeabraNetwork; }; }; edits { name=; el_typ=SelectEdit; el_def=0; }; data { name=; el_typ=DataTable; el_def=0; DataTable_Group @.gp[0] { name="InputData"; el_typ=DataTable; el_def=0; }; DataTable_Group @.gp[1] { name="OutputData"; el_typ=DataTable; el_def=0; }; DataTable_Group @.gp[2] { name="AnalysisData"; el_typ=DataTable; el_def=0; }; }; data_proc { name=; el_typ=taDataProc; el_def=0; taDataProc @[0] { UserDataItem_List @*(.user_data_) { name=; el_typ=UserDataItemBase; el_def=0; UserDataItem @[0] { name="NO_CLIP"; value 1 0=1; }; }; name="data_base"; }; taDataAnal @[1] { UserDataItem_List @*(.user_data_) { name=; el_typ=UserDataItemBase; el_def=0; UserDataItem @[0] { name="NO_CLIP"; value 1 0=1; }; }; name="data_anal"; }; taDataGen @[2] { UserDataItem_List @*(.user_data_) { name=; el_typ=UserDataItemBase; el_def=0; UserDataItem @[0] { name="NO_CLIP"; value 1 0=1; }; }; name="data_gen"; }; taImageProc @[3] { UserDataItem_List @*(.user_data_) { name=; el_typ=UserDataItemBase; el_def=0; UserDataItem @[0] { name="NO_CLIP"; value 1 0=1; }; }; name="image_proc"; }; }; programs { name=; el_typ=Program; el_def=0; step_prog=NULL; tags=; desc=; }; viewers { name=; el_typ=TopLevelViewer; el_def=0; MainWindowViewer @[0] { m_data=.projects[0]$0$; name="Browser3"; visible=1; m_is_root=0; m_is_viewer_xor_browser=0; m_is_proj_viewer=1; m_is_dialog=0; toolbars { name=; el_typ=ToolBar; el_def=0; ToolBar @[0] { m_data=NULL; name="Application"; visible=0; lft=0; top=0; o=Horizontal; }; }; frames { name=; el_typ=FrameViewer; el_def=0; tabBrowseViewer @[0] { m_data=NULL; name="Tree"; visible=1; root_typ=LeabraProject; root_md=NULL; m_root=$0$; }; PanelViewer @[1] { m_data=NULL; name="Panels"; visible=1; }; T3DataViewer @[2] { m_data=NULL; name="T3Frames"; visible=1; frames { name=; el_typ=T3DataViewFrame; el_def=0; T3DataViewFrame @[0] { m_data=NULL; name="Frame4"; visible=1; root_view { m_data=NULL; m_transform=NULL; children { name=; el_typ=T3DataView; el_def=0; }; }; camera_pos {x=0: y=0: z=-1.517074: }; camera_orient {x=0: y=0: z=1: rot=0: }; camera_focdist=2.482926; bg_color {r=0.8: g=0.8: b=0.8: a=1: }; }; }; }; }; docks { name=; el_typ=DockViewer; el_def=0; ToolBoxDockViewer @[0] { m_data=NULL; name="Tools"; visible=1; dock_flags=DV_MOVABLE|DV_FLOATABLE; dock_area=1; }; }; }; }; use_change_log=1; last_change_desc=; networks { name=; el_typ=LeabraNetwork; el_def=0; }; };