Subscribe

Using the Encog Kernal in Neuroph

  1. 2010-07-19 05:53:25 PDT
    First, let me introduce myself. My name is Jeff Heaton, I am the lead developer for the Encog project. Encog is a Java/C#/Silverlight framework for neural networks and other machine learning structures. I became aware of Neuroph through some articles that benchmarked Neuroph to Encog. I took a look at the Neuroph code and was immediately impressed with the very high-level, neuron-based way that it represents a range of neural network architectures. I also read [url= http://neuroph.sourceforge.net/improving_performance.html]Zoran's article on improving Neuroph performance, where he talked about building a core that hide much of the complexities of multicore, GPU, matrix operations and other performance oriented architecture decisions. This made me start to think, the Encog project is already working on the second generation of just such a core. Could we not share some technology and get the best of both? We were already isolating the core into a separate framework for other reasons. So I sent Zoran an email, and for the past week we've been discussing how we might work together. As a result, I am joining the Neuroph team to help with this integration and other advances as well. I also plan to use Neuroph extensivly in my "Introduction to Neural Networks in Java" book. I don't use Encog for that, because multicore programming, GPU, etc just gets in the way of explaining such things as how a neural network calculates and how backpropagation works. So I will be pushing for wider adoption of Neuroph as well. So now I am looking at how to make Neuroph use the same engine as Encog. This will effectively case both frameworks to produce the same benchmark results. It will also mean that Neuroph will support GPU acceleration and multicore training. I want to present my plan for how to do this here, before I actually implement it. My main goals are to minimize any breakage to Neuroph backwards compatibility, and keep with Neuroph's design philosophy. Here is how I think we should actually do this. I am still evolving this idea, and am not quite ready to write code yet. I want to get input from people here as well. I think we should leave all of the existing Neuroph training and network calculation, as it is now. The Neuroph backpropagation classes are very easy to follow, and really do a good job of showing how backpropagation calculation works. I think at some point soon, and I will help with this, we should add resilient propagation (RPROP) and batch training to Neuroph. Implementing RPROP inside of Neuroph, using only Neuroph technology will also allow RPROP to be demonstrated as effectively as Neuroph demonstrates backprop. But that will be another discussion, and does not have to be done to make use of the kernel. To implement the kernel, we need to cause Neuroph to store a networks weights inside of an Encog flat network. An Encog flat network basically stores weights as a double array. Fundamentally, Encog and Neuroph store neural networks as a bunch of doubles. How they are represented is the difference. Neuroph stores them in Weight classes that are contained in Connection classes. This makes the network easier to visualize, but means much more work for the computer to get to all the values during training. I suggest we create a subclass of Weight, called FlatWeight that would basically hold a reference to a double array and an index. This would be a direct mapping between Neuroph and the Encog flat network's weight array. This way there would be no need to ever translate between Neuroph and Encog neural network formats. The data would already be in Encog format, and ready to go. Neuroph would never know the difference because it would still be weight objects. The getValue on the weight would simply read the weight from the Encog flat network. The Neuroph NeuralNetwork class would be extended to hold a reference to an Encog FlatNetwork, which is what all the FlatWeights would point to. If you want Neuroph to behave as it always has, just put regular Neuroph Weight objects into the Connection objects, and make the flatNetwork attribute of your Neuroph NeuralNetwork class be null, and everything is the same as it always was. Not to train, I will provide a new LearningRule derived class to Neuroph. It will be called something like FlatLearning, or something. But it can be added to the neural network to cause it to take advantage of the Encog Engine's multithreaded or even GPU training. You will also be able to specify if you want backprop, rprop, etc. Once it is set, as the learning rule for the NeuralNetwork class, you work with the neural network just as you would any Neuroph neural network. This is basically how I see it fitting in. There will be additional implementation details. But I think it can be a really clean integration. Any suggestions or comments are very welcome. Jeff
  2. 2010-07-19 06:48:22 PDT
    Hello Jeff, Welcome aboard and the warmest wishes. I have the feeling that this maybe a marriage made in heaven. The best of both worlds and the curse of neither. Best wishes, Elle PS. All above makes sense to me.
  3. 2010-07-19 07:07:16 PDT
    Hi Jeff, welcome aboard. I think I'm the only Neuroph contributor that lives in St. Louis, so if you want to pair program or some other form of collaboration, I'd be happy to try to work it into my schedule. I'm pretty familiar with the core Neuroph code and have been a Java technical advisor on the project since 2008. I'm not familiar with the Encog source code, but I have read a lot of your online articles and have a lot to thank you for.
  4. 2010-07-19 08:49:57 PDT
    Hello Jeff and welcome! As you can see everyone here is happy and enthusiastic about this collaboration. Very nice idea with FlatWeight! It seems really the best and cleanest way to do it, so we should do it like that. Also it seeems like it does not require much work. Regarding aditional learning rules batch mode and rprop those are the next ones on my todo list :) And nice coincidence that Jon is from St Louis too. He is the first Neuroph contributor, familiar with Neuroph code, and he is a kind of Neuroph representative for St Louis :) PS. Elle is friendly to you, so it seems that you have passed the test :))
  5. 2010-07-19 15:33:28 PDT
    Thanks, all, I am looking forward to getting started with things. I probably have about another week on the Encog side of the fence, getting the engine separated and upgraded. But as soon as that is complete, I will start on integration. I really do not see this taking too long. Small world, Jon! Thanks for the offer, we will have to meet sometime, for sure. Glad the articles were helpful. Also, glad to have passed the Elle test. :) Jeff
  6. 2010-07-20 03:54:04 PDT
    One question. In SupervisedTrainingElement and TrainingElement, they both use Vector's of doubles. /** * Desired output for this training element */ private Vector<Double> desiredOutput; What would you say to making that: private double[] desiredOutput That way you skip the boxing/unboxing, and then I can pass the array directly to the Encog engine.
  7. 2010-07-20 04:01:53 PDT
    I think thats already changed, please use v2.5 It is located in /branches/neuroph-2.5 on SVN http://neuroph.svn.sourceforge.net/viewvc/neuroph/branches/neuroph-2.5/ I'll switch this to trunk, sorry about the confusion I forgot to tell you. I'll let you know when its switched
  8. 2010-07-20 13:09:55 PDT
    Ok I have reorganized SVN and now the current development version that we should use from now on is at http://neuroph.svn.sourceforge.net/viewvc/neuroph/trunk/neuroph-2.5/ that is in trunk/neuroph-2.5 folder
  9. 2010-07-21 05:09:15 PDT
    Okay thanks! I will check it out. I am still getting things fixed up on the "engine side". Everything is working now except a few fixes are needed on the GPU side. I benchmarked this to the old version of Encog and it is almost twice as fast! I was surprised to get that much of a gain, as we are probably running out of speed improvements that are possible on a single machine. Once that part checks out, I will start hooking the engine to Neuroph.
  10. 2010-07-21 23:31:38 PDT
    Thats great news about speed optimizations! it may be interesting to to benchmark against NeuroSolutions or Peltarion to get the idea how they relate. Let us know when you get to the integration part I have few ideas like wrapping whole Encog kernel into a single class or using plugins feature of Neuroph NeuralNetwork to hook Encog. Those are just interesting some ideas at the moment. In the meantime I'll deal with the batch mode.
  11. 2010-07-22 07:10:39 PDT
    It will be interesting to compare to NeuroSolutions and Peltarion. I believe both are in C++. The next one that I plan on activly benchmarking against is FANN (Fast Artificial Neural Network), which is written in C. I really think we are getting the Encog engine to the limits of how fast it can really get(at least on a single machine), with Java/C#. So I want to compare to FANN just to see how far behind we are. If we are beating FANN I will be amazed. Then we can provide a special version of the core, that uses C++, and we should move up to FANN level. I will probably do an article when we compare Encog-Engine to FANN. It will also speak to how fast Java is to C++, which is something of an ongoing debate. I know JIT in the later versions of Java do quite a bit for performance. The Encog Engine is working quite well now with the GPU. So everything is pretty much in line with it now. I will do an article explaining how it works soon. Actually more of an on-going wiki than an article. Integration should be able to begin next week. I am still planning on doing this the same way I outlined before. A FlatWeight subclass, a LearningRule subclass, and I guess a NeuralNetwork subclass. I think need a NeuralNetwork subclass so that the flat weights get created(instead of regular weights) somehow. As to how to include the Engcog Engine. I am trying to make the number of external connection points to be minimal. That way code changes to Neuroph will be minimal. The Encog engine is a hierarchy of packages, under org.encog.engine. That package is independent and requires no other classes from the larger Encog framework as a whole. You can see the classes here: http://code.google.com/p/encog-java/source/browse/#svn/trunk/encog-core/src/org/encog/engine We tried to keep the engine(kernel) code to a minimum. But there are a number of classes that support OpenCL, Threading, and RPROP. Future versions will also support grid processing. So we will want to keep it easy to roll future advances into Neuroph.
  12. 2010-07-22 18:51:34 PDT
    How will this affect Neuroph in an Android environment?
  13. 2010-07-22 23:36:39 PDT
    Jeff, go ahead with the integration as you outlined, that was the general way on which we already agreed. I was considering possible ways regarding implementation details, but the one you suggested seems to be the best. Just one thing: FlatNetwork supports MultiLayerPerceptron (at least that was in previous Encog version), so maybe we should consider subclassing from MultiLayerPerceptron (if thats still the case)? jfelrod1960, it should have no affect at all. Applications will continue using the same classes, all these will be added to new classes.
  14. 2010-07-23 06:33:09 PDT
    So far it looks like I will not need to subclass MultiLayerPerceptron. I am just going to create a plugin, using the plugin defined on NeuralNetwork. This should work well, because it leaves it open to use flat networks for other types of networks in the future.
  15. 2010-07-23 22:57:18 PDT
    Thats even better, exactly what I had on mind when I mentioned plugins festure in some of previous posts.
  16. 2010-07-24 18:24:40 PDT
    Yes I saw the previous post about the plugins and checked it out. Exactly what I needed. I am almost done with it. I think it is a pretty clean integration. All that is needed to enable a Neuroph neural network is to use code something like this: NeuralNetwork network = new MultiLayerPerceptron(TransferFunctionType.SIGMOID, WINDOW_SIZE, 10, 1); if( !FlatNetworkPlugin.flattenNeuralNetworkNetwork(network) ) { System.out.println("Failed to flatten network."); } That basically checks to see if the neural network is one of the types that can be flattened. At this time just MLP's. Then all of the weights are replaced with FlatWeights, the plugin is installed on this neural network, and the LearningRule is replaced with a FlatLearningRule. The FlatLearningRule, which extends SupervisedLearning, is using a fair amount of Neuroph code. By default it uses multithreaded RPROP, but it can also be made to use Manhattan Update or Backprop. Also if you want to enable OpenCL and use the GPU, you just call. FlatNetworkPlugin.initCL(); The weights produced are 100% compatible with Neuroph, so you can "unflatten" a network and it becomes a regular Neuroph neural network. And it is quite fast, If I add the above lines of code to the sunspot example, it tears through it in a matter of seconds. I still have some things to add and javadoc, but I think it is looking good.
  17. 2010-07-25 12:37:10 PDT
    Okay, I checked in my first go at this. For now I just included the Encog-Engine as a JAR. Its a fairly small JAR file, relatively speaking, but it is around 40 source files. So I guess this is the easiest way to keep things in sync. There is also a JOCL JAR file, which provides the OpenCL bindings on a variety of platforms. It only gets used if you actually enable the GPU, by calling initCL. For more information on JOCL, here is their site. http://www.jocl.org/ The changes to Neuroph were minor. I added a package, called flat, that contains the plugin and a LearningRule. Also a enum that specifies what type of training you want the flat network to use. I also added an interface to TrainingElement, SupervisedTrainingElement and TrainingSet. Everything is functional. If we need to move/restructure anything, that is fine by me. Just add the command, I gave above, to enable it for any Neuroph MLP. Thats really all that is required. I also modified the Sunspot example to make use of it, and it now trains nearly instantly. Jeff
  18. 2010-07-26 15:54:02 PDT
    Great, cant wait to try it! Everything looks ok, I would just like to restructure few things. First, I moved FlatWeight from org.neuroph.core to org.neuroph.nnet.flat package. org.neuroph.core package is used for base classes org.neuroph.core to org.neuroph.nnet for specific types of neural networks and their components (comp package) Since we have flat package it makes sense to keep everything specific related to flat network there Regarding TrainingElement, SupervisedTrainingElement and TrainingSet I would keep them as they were before, but extend them and add implementation of EngineData, EngineIndexableSet. We can name extended classes something like EncogTrainingElement, EncogSupervisedTrainingElement and EncogTrainingSet to mark them as Encog compatible (feel free to suggest other naming as well). I would just like to keep those base classes free of methods which to the same thing and have different names, and to provide encog compatibility methods in extended classes. As a next step (or maybe now), I think we should define some common interface for data sets which will be supported by both frameworks and provide support for training, test and validation sets (current naming TrainingSet confused some users about can thay be used for testing etc.) I was already thinking about creating some class like DataSet<SupervisedTrainingElement> {... } which would be general data set collection for training and testing, also using generics which will make them free of casting. I think that would be very nice and as I said we can do it now or in future collaboration. Zoran
  19. 2010-07-26 16:38:49 PDT
    Wow, this IS FAST :) You're right, SunSpot example took 85000 iterations and 34 minutes to complete with MomentumBackpropagation and with new FlatNetwork (I guess Resilient backprop) it was 27 iterations an 0 seconds. Classis backprop got to error 0.2 in about four minutes but lowering error to 0.01 took 30 more minutes. That shows the power of resilient backprop you explained in https://sourceforge.net/projects/neuroph/forums/forum/862857/topic/3780364
  20. 2010-07-27 16:03:13 PDT
    Yeah, RPROP totally rocks. Plus the Encog engine is about twice as fast as when that article benchmarked it. RPROP does quite a bit more with an iteration that backprop. And yes, that is what the flat learning rule is using. At least by default. You can use backprop or Manhattan Update. Manhattan Update is really nothing too special, it is useful only in a few cases, but it is easy to add, as you add RPROP. The changes you made sound good, I wasn't totally sure which packages should contain what. Common data classes could be good, that would make it very easy to take source code setup for one dataset and easily switch out which neural network makes use of it. Yes I know what you mean about multiple functions, that do the same thing to support the Engine interfaces. I thought about subclassing them. But then it would mean more modification to any program that wants to quickly make use of the faster engine. An example would have to also switch to using the Encog training set, as well then. I guess it is a tradeoff either way. I am good with either way.
  21. 2010-07-27 18:09:52 PDT
    The changes you made sound good, I wasn't totally sure which packages should contain what. I'll prepare some documentation on that. It will be helpfull for all contributors in future. Common data classes could be good, that would make it very easy to take source code setup for one dataset and easily switch out which neural network makes use of it. I'll make some proposal for that, so we can discuss Yes I know what you mean about multiple functions, that do the same thing to support the Engine interfaces. I thought about subclassing them. But then it would mean more modification to any program that wants to quickly make use of the faster engine. An example would have to also switch to using the Encog training set, as well then. I guess it is a tradeoff either way. I am good with either way. I see what you mean...Then its better to leave them this way.
  22. 2010-08-05 11:02:29 PDT
    What will this mean for the license? It's my understanding that encog is LGPLv3 and Neuroph is APL2.
  23. 2010-08-05 11:31:03 PDT
    What will this mean for the license? It's my understanding that encog is LGPLv3 and Neuroph is APL2. Thats a good question, we havent considered that so far. I guess we have several options: 1. Release Neuroph under dual licence LGPL and APL 2. Release Encog engine under APL or dual licence LGPL and APL For users in open source/free world I guess its ok even now, and also for commecial users who dont modify Encog core, only link to it. The only case which may be issue are the comercial users who might want to modify Encog core and keep the modifications propriatery, right? Since I'm not expert on licencing stuff I would like to hear what ithers think. Maybe we should open thread for this.
  24. 2010-08-05 22:24:54 PDT
    In order to take advantage of the Encog Engine, should I read the Encog documentation, or will Neuroph hide the Encog classes?
  25. 2010-08-06 02:53:23 PDT
    The Neuroph will hide the Encog classes. Check out the SunSpot example from SVN. As Jeff said above all you have to do is: if( !FlatNetworkPlugin.flattenNeuralNetworkNetwork(network) ) { System.out.println("Failed to flatten network."); } and continue using everything as you did so far.
Jump To:
< Previous | 1 | 2 | Next >

Add a Reply

This forum does not allow anonymous participation.

Log in to add a reply. Not registered? Create an account to participate and receive email updates when replies are posted to this topic.