One commonly asked question is how to best use a trained system with new data. There are three basic approaches:
- Using the probe post-processing component .
- Deploying the system (covered in detail by tutorial #2)
- Loading the new data into Synapse
As the first two ways are covered by existing tutorials, this post will cover 3) - how you load and and use new data within a solution in Synapse.
Sometimes you wish to use a deployed Synapse component from software not written in a .NET language. If the software is written in C++ or can make use of native DLLs you can still make use of deployed Synapse components either directly from C++ or by creating a C++ wrapper that exports key functionality.
This post shows how this can be done by writing a simple application in C++ that uses the deployed component from the famous police tutorial. For the steps described in this post we will not need Synapse but will use Microsoft Visual Studio 2010 (Make sure it is the C++ version if you use the express edition).
In order to manage our .NET object in the unmanaged world we will make a class called Client that will handle instantiation and destruction of an instance of the .NET object (in our this case Peltarion.Deployed.GodCopBadCop). In this class we can also implement any access methods to provide communication with the managed object.
We will then use this Client class to instantiate an instance of the deployed Synapse component and evaluate a test sample from the police data file.
Fist off start Visual Studio and create a new C++ project. For this exercise we will use a Win32 Console Application. I'm calling this project NativeSyn. (Check empty project in the second page before you click finish.)
I have copied the Synapse deployment directory GodCopBadCop to the project folder for easy access. To use it though we must add a reference to it. In the Solution Explorer select the NativeSyn project and hit Alt+Enter to bring up the properties window.
Turn on Common Language Runtime Support under configuration properties
Then add a reference to the dll containing the deploys Synapse system. For us that will be GodCopBadCop.dll.
(If you just want the project and source files to play with on your own you can find them at the end of the post)
Now let's add a header file called Client.h and start crafting our Client class. We will need a private void *ref to keep track of the managed .NET object. (We can't point to it directly since it's in managed space but we will get to that.) We will also need an alloc and a free method that will be called from the constructor and destructor respectively. Finally we will need a test method to facilitate the testing of Dutch policemen.
For the actual implementation add a source file called Client.cpp.
Include windows.h , Client.h and in order to comunicate with the managed world, vcclr.h. We will also be using namespaces System and System::Runtime::InteropServices.
Next is the implementation of the constructor and destructor. This is particularly easy as all they have to do is call alloc() and free(). We will however add a #pragma unmanaged prior to their implementation.
The rest of the code will be devoted to dealing with managed interop so #pragma managed this time. To run anything .NET related we need a using directive to mscorlib.dll and we will need another to GodCopBadCop.dll.
The type we go through all this trouble for is Peltarion.Deployed.GodCopBadCop in C++ that becomes Peltarion::Deployed::GoodCopBadCop. Since it is quite long to type let's make a typedef.
alloc(), now the interesting things start. Our .NET type is managed and subject to the CLS garbage collector. If we just instantiate an instance of it and there is no managed pointer to it we can be pretty certain the GC will destroy and collect it so will need to notify the GC we want that object to stay alive. This is done through the concept of internal pointers and GCHandles. I will not go in to details here but the process is to use gcnew to create an object instance and then register it with a GCHandle and finally store a pointer to the GCHandle.
Now, every time we need to use the object we need to go through the GCHandle to find it. When we want to tell the GC we are done with the object, and that it can be safely collected, we need get our GCHandle and call free on it.
The implementation of alloc() and free() looks like this:
The test method also need to access the object so we need to use the Target property of the GCHandle to get an internal pointer to it. After that you can use it access all the methods of the .NET object. We will primarily be interested in the Set_CSV and the StepEpoch methods along with the properties exposing the system output (on this system the output function layer is called FunctionLayer4 so we will access the FunctionLayer4_Port0 property).
Using the Client in an application is strait forward. We add a main.cpp source file to our project, include Client.h and we are god to go. (If you want you can turn off Common Language Runtime Support for the main.cpp file and all other files that don't do explicit interop stuff.)
Now, the moment of truth! Ctrl+F5
This was a small example to get you going. You might want to mimic some of the deployed Synapse components API or if this was a wrapper class to cater for some other interop you would probably export methods for creation, destruction and access methods that suite that particular platform.
The Visual Studio solution that was created for this post can be downloaded here and Microsoft has published a video tutorial covering this same issue over at http://msdn.microsoft.com/en-us/visualc/Video/bb892742
Consuming deployed components as Synapse plugins
We have received questions on how to load a deployed component into Synapse as a plugin and use it as a building block for new systems. This was something that was intended from early on, but was cut from the release and until now we have had few questions on the subject.
This post will almost be in the form of a tutorial and it will explain the interfaces needed to produce a plugin and to allow for standard signal flow. First we will create a minimal plugin, then fill it with a deployed component and lastly add some bells and whistles.
In 2003 the Human Genome Project was completed, mapping the entire human genome. The project was started in 1990 and was estimated to take some 30-40 years to complete. What the initial predictions missed was that DNA sequencing was subject to what Kurzweil refers to as the law of accelerating returns. The power of DNA sequencing has been increasing exponentially while the cost of the sequencing has been falling exponentially. Thus the project was completed much earlier than expected.
The Human Genome Project is however not the only completed full genome mapping. Thanks to the fast and cheap sequencing a wide range of other organisms have had their DNA fully sequenced. In this second part of this tutorial we will look at yeast and how its genes control its metabolic processes. We will use DNA microarray data to look at this problem.
In the first part of the tutorial we introduced competitive algorithms and focused on the Self-Organizing Map (SOM). We showed how it can be used to visualize high-dimensional data in a very intuitive way.
In this part we will move on to meta-clustering: how and why to cluster a SOM using a neural gas. You will also familiarize yourself with the unified distance matrix (U-Matrix). We will then move on to the actual problem involving the microarray data. After we have done our clustering with the SOM Visualizer we will create a standard neural network based classifier based on the results.
If you haven't gone through the first part, it is strongly recommended that you do so before proceeding.
Last year saw the 30th anniversary of Richard Dawkins' famous book, The Selfish Gene, the book that presented gene-centric evolution to a greater public. Controversial at the time, it is today a widely accepted theory that covers the connection between genetics and evolution through natural selection.
Dawkins' selfish gene should have the emphasis on gene - not selfish - as the primary point is that the gene is the basic unit that evolution through natural selection operates on. The selfish part is directly related to natural selection - genes that maximize their survival probabilities (which they do among other things through cooperation with other genes) live on in the gene pool while those less fit go extinct.
The title of this tutorial should be read in a different way: The Self-Organized Gene - emphasis on the self organized part. We are not going to be discussing the properties of the gene itself, but how gene functions can be analyzed using an adaptive method called self-organization. Our basic unit of operation won't be the gene, but the artificial neuron. In a way, there is a connection to the selfish part as well. While our units do not fall victim to natural selection, do not mutate and are not replicated, they do compete and interact which gives rise to the emergent global property of self-organization.
In more practical terms, in the tutorial we are going to explore unsupervised clustering of data. We will apply this to DNA microarrays, an exciting new technology that allows for very rapid expression profiling. We see how using adaptive self-organizing methods we can detect patterns in microarray data that can be used for understanding, detecting and fighting diseases caused by genetic factors.
In the first part of this tutorial we shall familiarize ourselves with the basic concepts of unsupervised learning, competitive learning and self organization. We shall also explore the self-organizing map as a powerful visualization tool and we'll take a look at a few simple examples to illustrate the principles.
In the second part of the tutorial we will cover meta-clustering before we move on to our target: the analysis of DNA microarray data. Once we have done that we will see how we can change our unsupervised clustering system into a supervised classification system in general and specifically in Synapse.
In the first part of this fuzzy logic tutorial we covered some of basics of the fuzzy logic theory. Here instead we will look at how you can use the fuzzy logic component in Synapse to create a fuzzy inference system.
Before proceeding, make sure that you have the latest version of Synapse. If you have automatic updates enabled you will get the latest version automatically.
In this article we will take a closer look at three different classifiers and discuss three different types of classifiers: naive bayesian classifiers, support vector machines and modular multilayer perceptron neural networks.
To help us investigate the relative benefits of the system we're going to use a simple application that uses adaptive systems deployed from Synapse.
I have been asked to post a few words about novelty filtering stock market data. This can also of course be applied to any other system, including, but not limited to forex data and other financial time series.
What anti-Hebbian novelty filters can do for you:
- Detect previously unseen trading patterns
- Give a quantitative measure of how much this new pattern differs from old trading patterns
What anti-Hebbian novelty filters can't do for you:
- Predict what consequence (if any) the new trading pattern will have on for instance the stock price
- Give you the direction of or type of change
So why would you want to use novelty filters if they can't tell you the consequence of the change?
It's simple: You use neural networks and other technology to try to model the market. You don't throw a dice or flip a coin.
When the market exhibits behaviour it hasn't shown earlier and you choose to trade, then you are just picking random actions. All predictive models are based on the assumption that there is an analyzable pattern. You find this pattern by looking at historical data.
If the market is behaving in a way no represented by the historical data, then your model is invalid.
Let's look at a practical example, and I'll then show you how to do it in Synapse.
What we have here is the output of an anti-Hebbian filter (top graph) and the closing price of the Microsoft shares. As you can see, around sample 209-210, the novelty filter detected something was up - three days before the stock went down significantly (on April 27). This would have been a very good signal to get out of the market.
Let's take a closer look on how this is done in Synapse and what it means: