Bragi's take on neural networks, AI and more RSS 2.0
# Tuesday, March 31, 2009

I've added support for flow editing, which should be the final 'big' editor required to create useful networks. From now on, only finishing functionality and bugfixes. It took a little longer than I had originally planned, mostly because of a struggle with WPF's keyboard navigational system, which is crap. I finally got it working though (it also supports drag and drop, copy-paste still needs implementing), hope you like it.  You can download the program from here. Unfortunately it's still a full install, so it's the whole 40 and some megs download.  I'll try to find some time to create an update installer so that the download size can be minimized.

The editor is still a bit rough, but it should be useful. I've tried to make it more text oriented, so you can easily navigate/add/remove items from the keyboard.  In the background though it's still listboxes so coding the view and data was easy and fast, just that creepy WPF navigation system, off course more importantly, it makes certain no illegal input can be provided.

Anyway, here's a screenshot:

image

Basically, this Flow editor describes how a noun can be found in a stream: a noun should start either with an article (which is either 'a' or 'the') or a number, followed by 0 or more adjectives finalized with a single noun.  Ok, there are gaps here (it's still a sketch to show the editor): what's a number, adjective or noun and how to find them.  These things will be explained in the demo, but basically, you use converters (functions that can transform a neuron into another one, like the object 'house' into the neuron 'noun') or some other info that can be used in a search function which can be attached to the flow items.

To create one yourself, go to 'Insert/Flow editor', use the toolbar button 'Create new flow editor', use the toolbar button on the 'Project' overview tool frame or use it's context menu. Press 'F' to create a new flow followed by a '.' to select a static or '['/'{' for an option/loop (press '|' to add new parts in a loop or option). Here's a complete list of available short cuts:

Shortcut

  Meaning

arrow left

  go to the previous flow item

arrow right

  go to the next flow item.

arrow down

 
  • When on a conditional block: go to the next conditional block
  • When on a static item: go to the first item of the next conditional block.

arrow up

 
  • When on a conditional block: go to the previous conditional block
  • When on a static item: go to the first item of the previous conditional block.

end

  go to the end of the current list, when at end of current list, go to end of parent list, until the end of the flow is reached.

home

  go to the start of the current list, when at start of current list, go to start of parent list, until the start of the flow is reached.

Ctrl + arrow/end/home/mouse click on item

  select multiple neurons.

Alt+arrow down

  go to the next flow

Alt+arrow up

 

go to the previous flow

.

 

open a popup for selecting a 'named' neuron to add at the end of the current list as static.

ctrl+.

 

open a popup for selecting a 'named' neuron to insert at the current pos as static.

{

 

add a loop at the end of the current list.

ctrl+{

 

insert a loop at the current position.

[

 

add an option at the end of the current list.

ctrl+[

 

insert an option at the current position.

}

 

change the currently surrounding option to a loop.

]

 

change the currently surrounding loop to an option.

R

  toggle 'selection Required' for current option/loop

|

  add a new part in the first parent loop or option of the currently selected item.

ctrl + |

  insert a new part in the first parent loop or option of the currently selected item.

del

 

remove the currently selected item from the list, but don't delete the actual neuron.

ctrl+del

 

delete the actual neuron.

O

 

Add a new object (neuron cluster with meaning 'Object') at the end of the current list.

ctrl+O

 

insert a new object (neuron cluster with meaning 'Object') at the current position.

N

  Add a new neuron at the end of the current list.

ctrl+N

  Insert a new neuron at the current position.

Double click on static

  Go to the flow.  This is only available when the static is a reference to another flow.  This is indicated by a line underneath the static.


A final note perhaps on how to use these flows in a neural network.  The thing is, this is really up to you, the application doesn't make any hard-coded use of them. Though, there will probably be a couple of default algorithms that can be reused.  The basic idea is relatively simple: when the first neuron comes in, search all the clusters to which it belongs with the meaning 'Flow', 'FlowItemConditional' or 'FlowItemConditionalPart' and store the result list in a cluster.  When the second comes in, try to find all the clusters of the previous result set that allow the new neuron to follow the previous one, all clusters that don't allow this are removed from the result set.  Various clean ups / lookups can be performed during 2 incoming points. When a 'flow' cluster is found with code attached to it, execute this. This off course, can be made as simple or as complex as you want. More on this in a later post. Fuel is depleted for today.

Tuesday, March 31, 2009 8:11:56 PM (Romance Standard Time, UTC+01:00)  #    Comments [0] -
Getting started | Updates
# Thursday, March 12, 2009

Most development tutorials start out with an 'Hello world' type of application.  This one doesn't.  The issue I had was the fact that a neural network is inherently a responsive system, that is, everything it does is a reaction to input.  So, I figured, to illustrate this better, I could show a simple echo application.  It's just as simple to make as a 'Hello world' thingy, but actually does something: echo back everything sent to it.

To start the demo, go to {Windows start}/N²D/Demos/Echo if N²D isn't already running, otherwise, do File/Open and browse to the folder {My documents}/NND/Demos/Echo. Note that a project is opened by selecting a folder, not through a file (this might still change in the future, if required).  If the project has already been opened, you can reopen it using File/Recent projects. Once opened, you should see something like this:

image

Note that the echo channel (a text channel) is shown by default. This is because I saved the project with the channel opened: visibility of a channel is stored, not for other items at the moment.  You can close this window by right clicking on the tab and selecting the close command. You can also control which channels are visible through the menu: View/Communication Channels. The designer will create a communication channel for each sensory interface in the network.

The Text channel contains the following items:

  • In the bottom: a Text box to enter text you want to send to the network
  • with a toolbar on top of it containing
    • buttons to control the visibility of the top row items,
    • a toggle button for turning the speakers on/off,
    • a combo box to select the way the sin splits up the input strings into neurons
    • a button to send the text to the sin.
  • in the middle is a list box containing the current conversation: all the text you sent interleaved with the answers of the network.
  • and finally the top row contains 2 listboxes which contain visualizations for the neurons that were processed as input by the sin (left one) and received for output (right part).  Note: selecting a line in any of these 2 lists will also select the corresponding line in the conversation section and visa versa.

If you make certain that 'Speaker' is pressed and your loud speakers are turned on, you should here 'Type here' once you press the 'send' button (and haven't changed the input text). Some items should also appear on the screen, something like:

image

What just happened? Well, a whole lot really:

  • The text channel displays the string 'Type here' in the central dialog overview.  This is done by the designer.
  • next, it sends the string to the Echo channel's backing sensory interface which splits it up into 2 words: 'type' and 'here'.  This is because it is in 'Use Words' mode.  This demo is also programmed for 'Use letters' by the way.  If you want, you can try to see the difference. These 2 words are converted into text neurons (by returning the result found in a dictionary of already created text neurons or by creating a new one, which is stored in the dictionary. These 2 text neurons are linked to a freshly created neuron which represents the input event.  This conversion is done by the sin itself.
  • The sin also raises an event to let the channel know about the neuron it just created as input value which is displayed in the top left list.
  • A processor is created and the neuron representing the input event is pushed on it's stack, which starts of the network. Up until now, we haven't really used the neural network yet, everything was done using traditional code. This changes once the processor is started.
  • The processor 'executes' the code attached to the links between the 'input event' neuron and the text neurons (how this code gets there and how it looks like will be dealt with later).  This is the neural network doing it's thing which will eventually execute several 'Output' instructions, sending neurons back to the sin.
  • When the sensory interface receives these neurons, it converts them back into a string and raises an event. And so we get back into the world of regular code.
  • At communication channel, which receives this event, displays the text in the conversation dialog and the neuron(s) that represent the string in the top right list box.

Ok, but what exactly happened in the neural network itself? Truth is, not much as you will see. It's time to show some code. If you select the 'Project' tool-frame, you will notice 4 items: a mind map (more on that later) and 3 code items, each one is simply a reference to a neuron in the network. To open them, double click on the item.  Let's start with 'Code: ContainsWord(in)'.

image

Mmm, interesting. All GUI-like is probably the first thing you'll notice. Indeed, there is currently no textual method for entering code, as more traditional development environments tend to use.  I choose this way for 2 reasons: first, it's faster to develop (at least, in WPF that is) and it lowers the entry barrier since you can visually put items together instead of having to conceptually create a peace of text in your mind, requiring a grater level of knowledge. In the long run though, this technique tends to be slower than writing code and it also somewhat limits the amount of code displayed, but be patient, there is a solution for this.

Lets first go over the 2 lower tabs.  These represent the 2 different code lists that can be assigned to the neuron: the 'Rules' and 'Actions' list. Note that these lists are only created if there is code, for as long as you don't drop any objects on the design surface, there isn't actually a code list assigned to the neuron. The bottom tab-strip also has a context-menu which allows you to toggle wether this neuron is shown in the project tree (under the currently active folder, or the root if there is no folder). You can also create new code clusters from the sub toolbar, but remember these are code clusters (which can also point to code clusters), not neurons with code clusters assigned to them.

Both lists are called at different times, and serve a different purpose. Code in the Rules section, is called when this neuron is used as the meaning for a link that is currently being processed by the processor. The Actions code list is called by the processor when this neuron was processed by the processor and all other links have already been handled. Usually, you don't program on the last tab, it is provided to 'view' the code that was attached to it by the sin that generated it (see further).  Note that there are other tab possibilities, but these have no importance for now and will be explained later on.

So what does this actually mean for our example: well, the 'ContainsWord(in)' neuron is used by the sin as the meaning for the link between the generated neuron and each word in the input string (this is pre defined), so for each word in the input text, it will call this little peace of code.

As you can see there are only 2 statements in this code list. The second statement calls an 'Output' instruction which will send the content of the 'CurrentTo' variable to the content of the 'CurrentSin' variable, in other words, this is the actual echo. Both variables are system defined and are filled in by the processor, they can not be modified, unlike normal variables. You'll notice that they appear to be multiple variables stacked on top of each other.  This is to indicate that the same neuron is used in multiple places.  It's a visual cue to indicate if a code item is used somewhere else or not (ahh yes, unlike regular code, these are neurons, all linked to each other, there is nothing preventing you from literally using the same statement in different places). That's it for doing the echo really.  The rest of the code is simply to make certain that the sin will put all the words in 1 line with spaces in between them. This is spread out over 2 locations: the first statement and the 'Input actions' code list of the sin.

The first one, is a 'Block' statement, which can best be compared to a 'Function call' except that there are no parameters or return value allowed. To view it's content, use the drop down arrow for an inline visualization, or 'View code'  in the context menu to display the code in a new window. You should see something like this:

image

Note that the code is located in the 'Statements' tab this time if you opened a new view. That's because a code block has an extra known code cluster attached to it: the code for the block.  It can also have a rules and actions list, but these are not used in this example (and probably will rarely be used this way on code itself).

Ok, and what exactly does this code do? To explain that, perhaps a note first on how a text sin converts output data. Whenever it receives a neuron, it is converted to a string which is than sent as an event to the outside world.  Off course, in our example, we don't show each word on a separate row, instead, we show the entire input statement on a single line with spaces between the words.  This can only be done if the sin knows where a sentence starts and where it ends, otherwise it simply sees a stream of output data. So to accomplish this, there are 2 special neurons that it recognizes: 'BeginTextBlock' and 'EndTextBlock'. When these are sent to a text-sin, they are not converted, but instead, BeginTextBlock will make it accumulate all the strings until the EndTextBlock neuron is received. So that's what this little bit of code does: it checks if this is the first word being processed, if so, the 'BeginTextBlock' neuron is sent and we store a switch so we know of this event.  If it wasn't the first one, we sent a space to the sin, so we don't concatenate the words. The 'EndTextBlock' is handled in a different way, we'll get back to that later on.

First a bit about the different statements that were used in this little code block.  The top most one is a conditional statement, set to 'if'.  N²D takes conditional statements even further than Gene and completely unites all different conditionals into 1 and the same statement type, with an option to switch between them.  So a Do-while, While-Until, For-Each, For, if, case, and case-loop (not possible in other languages) are all combined into 1 statement, with a single neuron that switches between the 2. This approach is taken because of it's ease in coding: it becomes a lot easier to change an if statement to a loop with multiple if's: simply make it a loop (yes, you can have multiple conditions in a while loop). To design this bit of code, you can simply drag a 'Conditional statement' to the designer and drop 'Conditional parts' in the 'Children' area to the right. A conditional part forms a single trunk of the evaluation tree. It contains a list of code items (which can also be dropped on it's respective 'Children' drop area) and possibly a condition that determines if the part's code is executed or not. This condition should evaluate to the 'True' or 'False' neurons.  Usually this is done by a Boolean expression (as has been done in this example), but this is not required, it could just as well have been a result statement that returns 'True' or 'False'.

image A word perhaps on the little arrows found on the variables to the right of the name.  These allow you to assign a default value to the variables.  In our example, we can't use this cause all of them are system variables who's values are controlled by the processor.  Regular values however don't have a value the first time they are accessed in the context of a processor.  You can use this little drop target to assign a default value.  This can be a constant, or another statement that can be resolved to one or more neurons. 

Another important fact about these variables is that they can point to 1 or more neurons.  They actually function as buckets.  This is very useful in that there is only 1 known type: a list of neurons.  This list can contain 1 item or more.  Often times, you will use a split to resolve multiple values to 1.

The last part of this demo can be found in the 'Code: Echo channel' Project item, which is actually a reference to the text sin.  If you open the 'Input actions' tab, you'll see the final 2 statements for this demo. This tab represents a code cluster that the text-sin attaches to each input neuron that it generates so it can be executed after all other links have been.  In our example, we do 2 things: let the sin know the sentence is closed so the string can be displayed and delete the input neuron, so we don't let the network grow indefinitely. By default, all data is always stored, if you don't want this, like in this example, you will need to manually delete the neuron.  All of it's links and stuff will be cleaned up automatically.

image

The notion that the code is spread out over different locations and called at different times is an important point: a neuron network can not be programmed in a monolithic fashion as a single code block. Code is always divided into small chunks, which run at different times, in an undetermined order.  This is where a lot of it's power comes from.  Once you grasp this, you are a long way into designing something truly beautiful.

Gosh, dear all mighty, this was a climb indeed. I'm glad you were able to get till here, all the way to the end. Even though this is a small demo, it packs a punch when it comes to new ideas. There are plenty more areas to cover, but I am certain that once you become more familiar with the basic concepts explained in this demo, the rest of the ride will be downhill. More demo explanations to come soon...

Thursday, March 12, 2009 9:04:52 PM (Romance Standard Time, UTC+01:00)  #    Comments [0] -
demos | Getting started | N²D
# Monday, March 09, 2009

Despite it's youth, N²D is already quite a large and rather complex application. Things like this tend to have a steep learning curve.  Off course, climbing a mountain is a lot easier if you have a map and proper control over your equipment.  I am working on the map, tools are up to you though.  There are many ways you can play with the application without actually having to design a proper neural network. Here's a short guide.

Viewing and importing thesaurus data

N²D has access to the English version of the WordNet database through a sensory interface (input/output port). Apparently there are WordNet database for other languages, but these are not yet available. To open the view for the WordNet data activate the menu item: View/Communication Channels/WordNet (note: opening for the first time can take a little time as the database needs to be opened, should get fixed somehow in the future).  This should show something similar to (although with less text):

image

You can search for words in the database.  All known meanings will be displayed. You can also select to show a specific relationship type with the drop down list.  If 'As Part' is pressed, all entries that contain the specified text will be shown.  You can either import a single meaning separately or the whole lot, including all the relationships (advised) and see the network grow.  The system should be able to do multiple imports at the same time (you'll notice that a single import can take a long time, depending on how many relationships there are for the word). While the network is learning, the green box in the right bottom corner is filled.

You can browse through all the imported items from the thesaurus view.  You can select the type of relationship you want to see.  All root tree items represent root neurons for the specified relationship. With the text box, you can search for words in the tree. All neurons can be dragged to other locations (like mind maps for instance, see further).  It is also possible to add items to the tree by dropping them on the level they should reside.

Creating Mind maps

Mind maps allow you to draw neurons in a free form manner, similar like vector graphics. There are multiple ways to create new mind maps, you can:

  • use the menu: Insert/Mind map
  • use the toolbar button (4th from left)
  • or when on the 'Project' tool window, use the local toolbar button.  From here, you can also create sub directories, change the name of the project items (F2),... Note: Mind maps (and all other project items) are added to the currently selected folder or the folder that contains the currently selected item.

image

Most of the mind map commands are currently only accessible through it's context menu. For creating new items, you can also use the toolbox. You can add different types of neurons or change them to another one.  Watch out with changing the type though, cause this might loose data sometimes (for instance, when you change a cluster into a regular neuron).

If you select a neuron, you can use different ways for showing 'related' items, like children, incoming or outgoing links and clusters to which the selected item belongs. You can also manage to which clusters it belongs.  If you have multiple items selected, you can quickly create a cluster for them through the 'Make cluster' command.

The easiest way to create a link between 2 items is by selecting them both (the first will be 'From', the second 'To') and activating the 'Link' command. This will show a dialog with From and To already filled in, so you only have to select the meaning of the link.

As a side note, 'Sync with explorer': a very useful command, accessible from the main toolbar, allows you to quickly find the selected item in the explorer.  This can be used from most places in the designer (all items that have a neuron as backing).

Drawing

Yes, N²D is also a drawing application, although some further evolution is clearly needed in this area.  Drawing capability is provided so you can work with the visual sensory interfaces. To create a new image channel, activate the menu command Insert/New Image channel.

Perhaps a word about the difference between a sensory interface and a communication channel: the underlying network has sins, which are also just neurons and have no 'functionality'. N²D, the designer, creates a 'communication channel' for sins so you can work with them. If you use the network in a different application, the communication channel might look completely different, but the sin is still the same.

image 

An image channel currently has 2 sections: the left part to manage/import multiple images (which is not yet fully functional) and a right part that will eventually contain 2 sections: an input and output section.  The output is currently not yet visible, but is supposed to function as the output part of the sin, so you can see images/videos that the network generates.

The input section works as an ink canvas, so you can use a pen table, and apply pen pressure (this can be toggled). The shape, size and color of the pen point can be selected. It is also possible to switch to a gum or selector.

Commenting

All neurons and some other types (like mind maps and frame editors) can have a description.  This is a FlowDocument (rich text format), so you format the text. Spell check is also provided. The description of the currently focused item is shown, you will have to make certain that the 'Description' Tool window is visible. 

image

Standard text editing functionality is present:

  • Select the font type
  • and font size
  • Bold/Italic/underline and Outline
  • Bullets and numbering
  • Spell check

As a side note: The selected item is a NeuronCluster, so it can have child neurons.  The explorer in this screenshot, is set to display it's side panel which contains all the children of the selected cluster. Just like from the explorer, you are able to drag items from the left panel.  It's also possible to drop neurons on the panel, which will add them as children to the selected cluster.

Creating frames

Frames are a form of compound objects (a group of neurons that form a single unit) which can be used to translate input from one form to another and to connect code to these compound objects. They are created in a similar way like mind maps, and can also be managed from within the project tool window.

image

To create a new frame, you basically push the toolbar buttons in sequence:

  • The first one will create a new frame (a frame editor can contain multiple frames, usually they are related to each other somehow).
  • Next, you create a frame element for the selected frame (make certain there is one selected, there are still some bugs in this area). You can also drop items to be used as frame elements.
  • The third button creates a new frame evoker (all neurons in this list are put in a cluster 'Evokers', so you can easily do searches on them, more on that later). Like frame elements, you can also drop already existing items in there.
  • On the last tab, you can edit all the sequences for the frame.  Use the 4th toolbar button to add a new sequence, make certain it is selected and use the buttons to add/remove or move up and down the frame elements from the first tab to build a sequence.
  • The last toolbar button is used to display the 'Import from FrameNet' dialog, with this frame editor already selected.

Importing frames

If you don't feel like creating your own frames, you can always see if they have already been included in FrameNet, which you can import, either from the menu Tools/Import from FrameNet or from the toolbar of a frame editor.

image

You can search FrameNet using the textbox in the upper right corner. The first time you select a row in the upper list might take a little time, this is because he is loading the WordNet database (which takes a little time). This is required to provide a mapping between FrameNet and WordNet data (not provided by default). Some mappings have already been created but most still need to be defined.  Each time you display this dialog and change some mappings, these will be saved.

There are many more things to discover in the designer, but I'm all out of words for today, so I'll continue this on another occasion.  In the mean time, lot's of fun playing with your new toy.

Monday, March 09, 2009 8:20:05 PM (Romance Standard Time, UTC+01:00)  #    Comments [0] -
Getting started | N²D
Categories
Archive
<March 2010>
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910
Blogroll
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2010
Jan Bogaerts
Sign In
Statistics
Total Posts: 10
This Year: 0
This Month: 0
This Week: 0
Comments: 3
Themes
Pick a theme:
All Content © 2010, Jan Bogaerts
DasBlog theme 'Business' created by Christoph De Baene (delarou)