- Source For This Article: Download source files and projects - 292 Kb
- 2. Introducing BrainNet Library - Developing A Simple Neural Digital Gate
- 2.1 Some Very Basic Facts
- 2.2 Using the BrainNet Library to Develop a 2-2-1 Network
- 2.3 Saving and Loading a Network
- 3. Developing an Image/Pattern Detection System
- 4. Conclusion
Dumb (And Lazy) Programmer: "No. Oh, probably yes - let me search whether I can I get a component or library for that"
|The most important objective of this article series is to
- Give you tips regarding how to use this neural network library in your own projects.
- Explain in simple English what exactly is a neural network.
- Explain the concept of a neuron, and a neural network.
- Introduce and explain the programming model and design of the BrainNet library.
- Introduce and explain Neural XML (NXML), an XML based programming language (which is a part of BrainNet library), for creating, training and running Neural Networks.
- Obtain a fair understanding regarding Neurons and neural networks
- Gain a good concept regarding intelligent systems
- Learn how to play with this neural network library to use it in your projects.
- Understand how to develop some cool neural network programs
What we can do with this library
- The answer to this question will give you proper understanding regarding how to use the library in your projects.
What is inside the library or the actual implementation and design of the library
- The answer to this question will give you proper understanding regarding how to extend the library yourself, and modify it to suit your needs.
- I'll give you a very high level view regarding neural networks
- I'll explain how to use BrainNet library in your projects to implement Neural Network logic.
- DigitalNeuralGate - A Two input neural digital gate which can be trained to perform functions of various digital gates (like XOR, AND, OR etc)
- PatternDetector - A simple handwriting/pattern detection program which can analyze an image to detect it.
These days Biologically inspired computing projects are getting very popular. They are used in various spheres, including learning and recognition systems, business prediction, data mining, pattern detection etc, to name a few.
This article is the first one in the series of articles related to biologically inspired computing. I am planning to discuss more topics like Genetic Algorithm, Conway's Game Of Life etc in my future articles. My most important objective is to create an awareness in the programming community regarding the possibilities of merging these diverse technologies and logics together - to invent better systems with more accuracy. For sure, the future is heading towards hybrid systems.
For me, the major inspiration in learning these topics is simply the 'natural' beauty in these topics. As we all know, nature is a mystery, and we can learn a lot from nature, and when we can transform this knowledge about nature to application (using computers), a programmer is attaining the level of an artist. Just as an artist gets inspired by nature, I believe that a scientist and a programmer can also get intuitions in the same way. If you ask a poet how he wrote a poem, he may say - "It came to me from a silent corner in my mind". Similarly - I believe - if you ask yourself how you got the most wonderful programming logic or idea you ever formulated in your life - you may utter the same words.
- I will explain some basic facts about neural networks
- We will develop a simple digital neural gate - i.e, a gate with two inputs and one output which can be trained to perform the functions of various gates like AND gate, OR gate, XOR gate etc.
- A Neural Network consists of various layers
- Each layer can any number of neurons in it.
- The first layer of the network is called an input layer, and it is here we apply the input
- The last layer is called the output layer, and it is from here we take the output.
- A neural network can have any number of hidden layers, between the input and output layer.
- In most neural network models, a neuron in one layer is connected to all neurons in the next layer.
Fig: A 2-2-1 NetworkFor example, in the above network, N1 and N2 are neurons in input layer, N3 and N4 are neurons in hidden layer, and N5 is the neuron in output layer. We provide the inputs to N1 and N2. Each neuron in each layer is connected to all neurons in next layer. The above network can be called a 2-2-1 network, based on the number of neurons in each layer.
Now, some basic facts about training.
- You can train a neural network by providing inputs and outputs.
- The network will actually learn from the inputs and outputs - this is explained in detail later.
- Once training is over, you can provide the inputs to obtain the outputs.
The important point to note is that, we can train the same network to learn the functions of various gates. The network will learn which output to produce for a given input, from the truth table of a gate - after a number of training rounds.
Note: This project is included in the source code zip attached above with this article. Extract the zip, open the solution in from Visual Studio.NET, set the startup project as "NeuralGate" and run the project.
The DigitalNeuralGate ClassTo use BrainNet library in your project, you should create a reference from your project to the BrainNet.NeuralFramework.Dll library file.
Let us see the code of
DigitalNeuralGateclass. In the constructor of the class, we are basically creating a Neural network with two neurons in first layer, two neurons in the hidden layer, and one neuron in the output layer. The
Trainfunction will pass a training data object (consists of inputs and outputs) to the
TrainNetworkfunction of the library. The
Runfunction will pass an array list as input to the
RunNetworkfunction of the library.
Public Class DigitalNeuralGate
Public Sub New()
'Create the factory to create a Backward
'Propagation Neural Network
'Backward Propagation neural network is
'a commonly used neural
Dim factory As _
'This is an array list which holds
'the number of neurons in each layer
Dim layers As New ArrayList()
'We need 2 neurons in first layer
'We need 2 neurons in the second layer
'(the second layer is the first
'We need one neuron in the output layer
'Provide the arraylist as the parameter, to create
network = factory.CreateNetwork(layers)
'Now, network holds a 2-2-1 neural network object in it.
Public Sub Train(ByVal input1 As Long, _
ByVal input2 As Long, _
ByVal output As Long)
'Create a training data object
Dim td As New TrainingData()
'Add inputs to the training data object
'Add expected output to the
'training data object
'Train the network one time
Public Function Run(ByVal input1 As Long, _
ByVal input2 As Long) As Double
'Declare an arraylist to provide
'as input to the Run method
Dim inputs As New ArrayList()
'Add the first input
'Add the second input
'Get the output, by calling the
'network() 's RunNetwork method
Dim outputs As ArrayList = network.RunNetwork(inputs)
'As we have only one neuron in the output layer,
'let us return its output
The code is self explanatory, and it is heavily commented. However, here are some more points.
Explanation of code inside Sub New() - Creating a neural network using BrainNet libraryYou can create a network by creating an object of type
BrainNet.NeuralFramework.BackPropNetworkFactoryand by calling the
CreateNetworkfunction of the factory object.
- Kindly have a look at the constructor of the class, we used the
CreateNetworkfunction of the factory object of type
BrainNet.NeuralFramework.BackPropNetworkFactoryto create our neural network object.
- We provided the number of neurons in each layers as the input to the
CreateNetworkfunction, using an ArrayList.
CreateNetworkfunction will return an object of type
- If you need to understand more about factory pattern (and its use), reading my article regarding Design Patterns [Click Here] may help.
Explanation of code inside Train() function
- Training can be done by calling the
TrainNetworkfunction of the network. The input to the train network function is a
TrainingDataobject consist of two array lists - Inputs and Outputs.
- The number of elements in TrainingData.Inputs should match exactly with the number of neurons in your input layer.
- The number of elements in TrainingData.Outputs should match exactly with the number of neurons in your output layer.
Explanation of code inside Run() function
- You can call the
RunNetworkfunction of the network, to run the network after training it. The input parameter to the Run function is an array list which consists of the inputs to the input layer. Again, the number of elements in this array list should match the number of neurons in input layer.
- The Run function will return an array list which consists of the output values. The number of elements in this array list will be equal to the number of elements in the output layer.
A User Interface To Test Our DigitalNeuralGate ClassTo test the digital neural gate, let us create a simple interface which can create a gate, read the inputs to train the gate, and obtain the output to display it.
Fig: User Interface To Test Our GateHere, we create a new object of our DigitalNeuralGate when the form loads (See the Form Load event in source code). Also, the user can create a new DigitalNeuralGate by clicking the 'Reset Gate' button. In the beginning, the Truth Table provided in the training text boxes are initialized to match the Truth Table of XOR gate (I hope you still remember simple Boolean Algebra). However, you can change the truth table by clicking the links, or you can provide custom truth table by entering directly in the text boxes. Run the project and see.
To begin with, Reset the Gate by clicking 'Reset Gate', and just click the 'Run Network' button and see the output. The output doesn't match the truth table output. Now, we can train the network using the values in the truth table. Click the 'Train 1000 Times' button and click the 'Run Network' button. You can see the output is getting closer to the expected output - that is, the network is learning. Do this a couple of times, and see the improvement in accuracy.
To try with a different truth table, Click 'Reset Gate', change the truth table, and repeat the above steps as required.
The source code is included in the zip file. Kindly open it and have a look at the project.
TrainOnce is a simple function which calls the Train function of the gate we just developed above.
'Train the network once, by using the inputs and output Sub TrainOnce() 'Train the network using the training data, by passing 'inputs and outputs to the train function of the gate 'inp11, inp12, out1 etc are textbox names gate.Train(CLng(Me.inp11.Text), CLng(Me.inp12.Text), CLng(Me.out1.Text)) gate.Train(CLng(Me.inp21.Text), CLng(Me.inp22.Text), CLng(Me.out2.Text)) gate.Train(CLng(Me.inp31.Text), CLng(Me.inp32.Text), CLng(Me.out3.Text)) gate.Train(CLng(Me.inp41.Text), CLng(Me.inp42.Text), CLng(Me.out4.Text)) End SubThis function handles the click event of 'Train 1000 times' button. It simply calls the above TrainOnce function 1000 times
'Train the network 1000 times Private Sub cmdTrain1000_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdTrain1000.Click Dim i As Integer Try 'Call the TrainOnce function 1000 times For i = 0 To 1000 TrainOnce() Next Catch ex As Exception MsgBox("Error. Check whether the input is valid - " + ex.Message) End Try End SubThis function handles the click event of 'Run Network' button, to run the network by providing inputs and setting the outputs to the output text boxes
'Run the network to get the output, and show it in the text boxes Private Sub cmdRun_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdRun.Click Try 'rout1, rinp11, rinp12 etc are textbox names rout1.Text = gate.Run(CLng(Me.rinp11.Text), CLng(Me.rinp12.Text)) rout2.Text = gate.Run(CLng(Me.rinp21.Text), CLng(Me.rinp22.Text)) rout3.Text = gate.Run(CLng(Me.rinp31.Text), CLng(Me.rinp32.Text)) rout4.Text = gate.Run(CLng(Me.rinp41.Text), CLng(Me.rinp42.Text)) Catch ex As Exception MsgBox(ex.Message) End Try End SubNow, I hope, you have noticed a very important fact. That is:
- You haven't changed any algorithm inside the DigitalNeuralGate, but DigitalNeuralGate is producing almost correct outputs when you teach it with various truth table. For example, the logics, AND, OR, XOR etc can be implemented, by training the system externally with the logic, rather than changing the system internally.
NetworkSerializerclass in the BrainNet library.
To demonstrate this feature, let us add two functions to our DigitalNeuralGate class.
'<summary>This is the function is for saving this gate to 'an xml file </summary> Public Sub Save(ByVal file As String) Dim ser As New BrainNet.NeuralFramework.NetworkSerializer() ser.SaveNetwork(file, network) End Sub '<summary>This is the function is for loading this gate 'from an xml file </summary> Public Sub Load(ByVal file As String) Dim ser As New BrainNet.NeuralFramework.NetworkSerializer() ser.LoadNetwork(file, network) End SubThe
SaveNetworkmethod with in
NetworkSerializerclass will save the network to a specified path, and the
LoadNetworkfunction will load the network back.
Surprisingly, the project is pretty easy to develop. This is because, BrainNet library provides some functionalities to deal directly with images. This project will demonstrate:
- Built in support for image processing/detection and pattern processing in BrainNet library
- Built in support for advanced training using Training Queues in BrainNet library.
First of all, you need to train the network. To train the network, give some images and corresponding ASCII character value from the 'Train This Network' section.
Fig: Training - Adding images and corresponding character
To provide training data
- Click 'Browse' to load an image to the picture box (You can find some images in the 'bin' folder of PatternDetector - Also, you can create 20 x 20 monochrome images in Paintbrush if you want).
- Enter the ASCII character that corresponds to the image - for example, if you are loading image of character 'A', enter 'A' in the text box.
Click 'Add To Queue' button
To train the network
- After adding the images to the training queue as explained earlier, click 'Start Training' button. Train the network at least 1000 times, for a below average accuracy. When you click the 'Start Training' button, training will start.
- You will see a progress bar, indicating the training progress.
Detecting A Pattern
- Once the training is completed, go to the 'Detect using Network' pane.
- Load an image by clicking the browse button, and click 'Detect This Image Now' button to detect the pattern
- If you trained the Network sufficient number of times, and if you provided enough samples, you will get the correct output.
Fig: Detecting The Image
InitNetworkmethod to create/initialize the network
TrainPatternmethod to train the network
DetectPatternmethod to detect an image
- We are using a 400-400-8 network (400 neurons in input layer, 400 neurons in hidden layer, and 8 neurons in output layer) to perform the required operations
- First of all, we will convert the 20 x 20 image (i.e, as you know a 20 x 20 image consists of 400 pixels) to an array of 1s and 0s. A white pixel is taken as 1 and a black pixel is taken as 0. This is fed to the input layer
- As you know, we should give the output along with the input, during training phase. For this, the character's ASCII value's binary representation is fed to the output layer.
'A private variable to hold our network. Private network As BrainNet.NeuralFramework.INeuralNetwork '<summary> Initialize our network </summary> Sub InitNetwork() 'We are analyzing a 20x20 pixel picture, so let us take the number 'of total inputs as 20 x 20 = 400 neurons 'So let us initialize a 400-400-8 network. I.e, 400 neurons in 'input layer, 400 neurons in hidden layer and 8 neurons in output layer 'We've chosen 8 neurons in output because we need 8 bits to 'represent an ASCII character 'Create the factory to create a Backward Propagation Neural Network '(Backward Propagation neural network is a commonly used neural 'network model) Dim factory As New BrainNet.NeuralFramework.BackPropNetworkFactory() 'This is an arralist which holds the number of neurons in each layer Dim layers As ArrayList = New ArrayList() 'We need 400 neurons in first layer layers.Add(400) 'We need 400 neurons in the second layer (the second layer is the first 'hidden layer) layers.Add(400) 'We need 8 neurons in the output layer layers.Add(8) 'Provide the arraylist as the parameter, to create a network network = factory.CreateNetwork(layers) End Sub '<summary> Routine to train the network </summary> Sub TrainPattern() 'This routine demonstrates how easily you can train 'a network using a NetworkHelper object 'Here, we are using a NetworkHelper object to train the 'network. 'Create a helper object Dim helper As BrainNet.NeuralFramework.NetworkHelper helper = New BrainNet.NeuralFramework.NetworkHelper(network) 'A helper object helps you to train the network more 'efficiently. First of all, you add each training data to the 'Training Queue using the helper. For this, you can use the 'AddTrainingData method of the helper 'Next, you can call the Train function of the helper to 'randomize entries to the training queue and train the network more 'efficiently 'Step 1 - Add the training data from our list view box to the helper Dim item As ListViewItem For Each item In Me.lvMain.Items Dim img As Image = imlMain.Images(item.ImageIndex) Dim asciiVal As Long = Asc(item.Text) 'The AddTrainingData method of Network helper helps you to 'add an image and its corresponding ASCII value directly helper.AddTrainingData(img, asciiVal) Next 'Step 2 - Train the network using the helper 'Get the number of times Dim rounds As Long = Val(Me.txtTrainTimes.Text) 'Add the handler of ShowProgress delegate, to get 'the progress training progress StopTraining = False AddHandler helper.TrainingProgress, AddressOf ShowProgress 'Start training helper.Train(rounds) RemoveHandler helper.TrainingProgress, AddressOf ShowProgress End Sub '<summary> Routine to detect an image </summary> Sub DetectPattern() 'Step 1 : Convert the image to detect to an arraylist Dim imgHelper As New BrainNet.NeuralFramework.ImageProcessingHelper() Dim input As ArrayList input = imgHelper.ArrayListFromImage(Me.picImgDetect.Image) 'Step 2: Run the network and obtain the output Dim output As ArrayList output = network.RunNetwork(input) 'Step 3: Convert the output arraylist to long value 'so that we will get the ascii character code Dim patternHelper As New BrainNet.NeuralFramework.PatternProcessingHelper() Dim character As String = Chr(patternHelper.NumberFromArraylist(output)) Dim bitpattern As String = patternHelper.PatternFromArraylist(output) 'Display the result Me.txtAsciiDetect.Text = character Me.txtPatternDetect.Text = bitpattern End SubThe code is heavily commented, but here is some more explanation.
Training Using Network HelperExamine the
TrainPatternfunction. Instead of training the Network directly (as we did in the case of our Binary Neural Gate), we are using a Network Helper object to train the network. Using a network helper object, you can add images and the corresponding ASCII codes directly.
NetworkHelperclass is gracefully overloaded, so that it can accept various parameters (more about this later).
Here, we are iterating each element in our list view (i.e, the training queue) - and add it to the helper. Then we initiate the training by calling the 'Train' method of the helper. The input to the 'Train' method is the number of rounds we need to train the network. For more details, have a look the help file of BrainNet library (included in the zip file).
PatternProcessingHelper and ImageProcessingHelperExamine the
DetectPatternfunction. Here, we should provide the input to the network, to obtain the output. To convert an image to an array of 1s and 0s, we use the
ArrayListFromImagefunction inside the
ImageProcessingHelperclass. After obtaining the output from the network, we should convert this to the equivalent ASCII code to display the character in the textbox - for this, we use the
NumberFromArrayListfunction in the
PatternProcessingHelperclass. Similarly, the
PatternFromArrayListfunction converts an array list to a string (normally, a string of 1s and 0s).
Other than the above functions, the code for handling the user interface is also present in the PatternDetector project. Open the project, and have a look at the source code (it is commented heavily) for a better understanding.
I hope you enjoyed this article, and related projects. The attached zip file contains BrainNet Framework assembly file, BrainNet library Documentation in CHM format, and source code of the above two projects. Download and experiment.