Note: Deprecated!
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 words 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:
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
- in the middle is a list box containing the current conversation: all the text you sent interleaved with the answers of the network.
- 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.
- with a toolbar on top of it containing
- a button to send the text to the sin.
- a combo box to select the way the sin splits up the input strings into neurons
- Some editing commands to cut, save or clean the conversation log
- a toggle button for turning the speakers on/off
If you make certain that ‘Speaker‘ is pressed and your loud speakers are turned on, you should hear ‘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:
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. There is another echo demo, called ‘echo letters’ which is programmed to ‘Use letters’ by the way. If you want, you can open this and try it to see the difference. In the ‘echo words’ demo, the 2 words are converted into text neurons (by searching 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 newly 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.
- The 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 3 items: a mind map (more on that later) and 2 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)‘.
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 other code clusters).
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 (actions), 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:
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. Of 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’.![]()
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 variables 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 it generates so the code can be called after all other links were executed. 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.
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 but predictable 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…
Editorial Note: This was one of the first neural algorithms I ever wrote. In fact, it was even used to get the initial engine running. As the core and my skills progressed, it became clear that this little example can actually be written in many different ways, some of which better and faster then this example. As of version 0.6 of the designer, I’ve included an improved version of this algorithm, which uses the minimum nr of statements (I can think of) to achieve a simple echo: 4
- Output(CurrentSin, BeginTextBlock)
- Output(CurrentSin, CurrentTo, ‘ ‘)
- Output(CurrentSin, EndTextBlock)
- Delete(CurrentFrom)