Saturday, November 12, 2011

EclipseFP helper executables for Windows

Since people had sometimes problems building Haskell executables we use in EclipseFP, I thought I'd help by putting versions of the current Windows executables on sourceforge. So in you run Windows and have trouble building scion-browser or buildwrapper, you can grab them from here.

I know this isn't really in the spirit of "build from sources so you can check them yaddi yadda", but since even Cabal does it...

As usual, use at your own risk, etc.

Happy Haskell Hacking!

Friday, November 11, 2011

EclipseFP 2.2.0 released!

I'm glad to announce that EclipseFP 2.2.0 has been released. EclipseFP is a set of Eclipse plugins for Haskell development.

The minor version increase is justified by the replacement of the Scion library for the backend by the BuildWrapper executable. I appreciate that lots of work went and is still going into Scion, but I decided that building my own Haskell backend was better for EclipseFP. It calls cabal directly for building, which allows EclipseFP to support things like new style component dependencies (the executable in a project depends on its own library), c files (now my HJVM project, which call Java from Haskell can build, and even report errors in the C code), etc. Note the the haskell code is not bundled with EclipseFP anymore but gets downloaded and installed from Hackage.

This version also comes with a new view, allowing the installation of cabal packages from Hackage. There are also bug fixes and small enhancements all round.

To install, just use the built-in Eclipse install/update functionality. The update site URL is http://eclipsefp.sourceforge.net/updates. The release notes can be found here.

Happy Haskell Hacking with EclipseFP!

Thursday, October 20, 2011

GUI Testing using OCR: project Sikuli

I had a great idea this morning... and then realized that there was an open source project already doing it.
I thought: instead of using specific testing frameworks for each UI technology I have (a tool for the web, a tool for SWT UIs, etc) what about a tool that could recognize the text on screen and click or type in the proper places. The same technology for everything type of UI, and something that doesn't rely on pixel perfect positioning to work! Turns out (surprise!) I'm not the first one that had the idea, and looking around I stumbled on Project Sikuli. This looks great: it uses images to find "interesting" parts of your UI and there's also support for text recognition. So potentially you could say "click on the button that says 'Submit'"! It integrates with Java code so you can easily have JUnit tests using it.
Unfortunately, for my own purposes I couldn't get very far easily because of lack of support for transparent images (or, more precisely, it takes into account transparent areas for images, so it doesn't recognize an image if the background changes, which happens if your desktop theme changes, if you use the same icon in different contexts in your UI, etc). But it still looks like a promising tool!

Thursday, October 13, 2011

Manage Cabal packages from inside EclipseFP

I'm thinking the new version of EclipseFP will not bundle the Haskell code we use, but will download it from Hackage, which would make sense: we would be able to update the Haskell side without requiring a EclipseFP upgrade, and vice versa. I would expect Haskell developers would be quite used to install packages from Hackage using cabal install. However, let's try to minimize the number of things that a user would need to go outside of EclipseFP to do on a normal Haskell project. So I've added another view:


This view lets you see the list of packages you've installed, with their version, or the full list from Hackage, that you can filter by typing the prefix of the name you're looking for. From there you can install the packages as either Global or User, see the package information, or click on the "More Information" link to open the Hackage page directly.
You can also update the list. This GUI is only a wrapper above the cabal list and cabal info commands.
Hopefully this will be useful to people! Should I add a text field somewhere to be able to specify more options to cabal install, or is that overkill for a GUI?

Friday, October 07, 2011

New backend for EclipseFP

A while ago I was wondering how I could enhance EclipseFP, regarding things like memory usage, support for multi components projects, etc. I now have a working version for adventurous testers!

The main thing is the removal of Scion. EclipseFP now uses another backend component called "buildwrapper". There is no server, buildwrapper is only an executable that can be launched with flags, and writes a JSON result on the standard output. This means no more huge memory usage, and less synchronization headaches.

Buildwrapper uses a copy of the project inside a hidden folder. This means that when we want to get say build errors on a dirty editor content, we can write the dirty content to the file inside the hidden folder, and launch a build process on these files, thus avoiding the limitations that the GHC API has on building from a StringBuffer (doesn't work for files requiring preprocessing, etc).

We only use the GHC API to get the types of things in a source file, but we use Cabal to build the project. Buildwrapper actually launches the cabal executable and parses the results. I know, sounds crude compare to an API only approach, but I have the feeling it just works better. Basically the IDE will now behave a lot close to what you get if you were building your project from the command line. And then you get additional goodies, like multi component support (so you can have the executable of your project reference the library in the same project, and it works!).

Buildwrapper uses haskell-src-exts for outline. I've actually seen cases where it needed language pragmas to parse correctly that GHC didn't need, but such is life.

Performance seems to be quite good, except for things that use the GHC API, where there's a little lag. Hopefully the fact that we don't use gigs of memory any more will make up for it.
I'm also thinking about distribution. EclipseFP came with Scion and Scion-browser bundled, if only because we used a different version of scion than the one on Hackage. I think that moving forward we'll rely on cabal install and Haskage. I'm going to add a simple interface to run cabal install inside EclipseFP, so you shouldn't have to go outside to install a package. So the EclipseFP preferences will just ask the user for the path to the buildwrapper and scion-browser executables, with an option to install them from hackage.

If people want to start testing, just go on github, and grab the BuildWrapper repository (main branch) and the EclipseFP project (buildwrapper branch). For the moment, BuildWrapper probably only builds on GHC 7.0. Once I have the feeling it's robust enough and there's no big flaw in the new architecture, I can work on enhancing portability.

Friday, September 02, 2011

EclipseFP 2.1.0 released!

It's been a little while, but finally a new version of EclipseFP has been released! This version is mainly the work of Alejandro Serrano, who has worked on EclipseFP (and the underlying utilities) during his GSoC project. There are lots of new features in that version, mainly :

  • A package/module browser
  • Hoogle integration
  • Support for running tests
  • HLint warnings
  • Support for running executables and get profiling graphs
  • SourceGraph generation
  • Better auto completion information

Lots, I'm telling you. There are also fixes and internal enhancements that hopefully should make your life easier.
You can just run the update from your Eclipse IDE. You can find the full release notes there.
Note that Alejandro has also created a new web site for EclipseFP, that you can find there. Alejandro, big thanks for your hard work and your dedication!


Any feedback is welcome, and of course bug reports and requests for enhancements!


Happy Haskell hacking in Eclipse!

Wednesday, August 31, 2011

Hoogle Command Line on Windows

The new upcoming version of EclipseFP will feature Hoogle integration, thanks to the work of Alejandro Serrano, so I was doing some testing on one of my Windows machine (yes, I'm a Haskell hacker and a Windows user, so what?)... No real problem using Hoogle via the command line, but since it does require some other things to be installed, I though I'd post them there for reference.

Unlike Cabal, Hoogle uses external tools for some of its operations. These tools are I'd say part of any self-respecting Unix distribution, but not of Windows. So you'll need:

wget: http://gnuwin32.sourceforge.net/packages/wget.htm
At time of writing, the download page is http://sourceforge.net/projects/gnuwin32/files/wget/1.11.4-1/wget-1.11.4-1-setup.exe/download

gzip: http://gnuwin32.sourceforge.net/packages/gzip.htm
At time of writing, the download page is http://sourceforge.net/projects/gnuwin32/files/gzip/1.3.12-1/gzip-1.3.12-1-setup.exe/download

tar: http://gnuwin32.sourceforge.net/packages/gtar.htm
At time of writing, the download page is http://sourceforge.net/projects/gnuwin32/files/tar/1.13-1/tar-1.13-1-bin.exe/download

Install everything in the same directory and put the bin subdirectory in your PATH. hoogle data should run fine.

Note also that since it's using wget, if you have an HTTP proxy you need to configure wget to use it (Cabal uses the internet explorer connection settings and finds the proxy settings from that). The files is etc\wgetrc in the directory you installed wget, find the http_proxy entry and adapt to your settings.

Friday, June 24, 2011

EclipseFP: the way forward??

This is not the usual "hey I managed to get some code to work, check it out" blog post. Bear with me as I'm just thinking out loud. This is about EclipseFP and how we can move it forwards.

At the moment EclipseFP works pretty well for simple, smallish Haskell projects. People have noted some performance issues on large projects, and part of it is the huge memory footprint of GHC when used through its API. After a couple of hours of working on a yesod project (so we're talking quasi quotation, template haskell, etc), the scion server takes 1Gb of memory... Restarting brings it back to reasonable levels, which seems to point to memory leaks in the GHC API.
Maybe more critically, people are now asking for features that get increasingly harder to implement using Scion:
- static GHC flags like -threaded (Nominolo's working on a version of Scion that could handle these)
- C or HSC sources (or other kind of stuff requiring a preprocessor)
- Having executables or test suites referencing the library component directly in the Cabal file

The main thing with these is that Cabal handles them fine, so basically typing cabal build at the command prompt solves these issues, which undermines the usefulness of having an IDE in the first place... But they require more than just calling the GHC API: building and linking a library in-place, calling a c compiler, hsc2hs, etc...
Of course Cabal publishes an API. So for example the code used by Cabal to build an in-place version of the library I could access, in theory, from Scion. But then Cabal calls the ghc executable, so the Cabal API gives me no easy way to get back errors from GHC, etc...

What does accessing the GHC API gives us? An AST, that can be generated from an unsaved file (so you don't need to save your haskell source file to see your errors, our up to date outline, etc). All the rest (syntax highlighting, jump to definition, etc) could probably be done from the AST.

So I'm wondering now if scrapping scion totally would not be a good idea. A rough outline of how things could work would be:
- create a temp folder in which we will work, copy in it all the project files (sources, etc)
- use cabal to build in that folder
- parse cabal output to get errors and their location
- unsaved files in the EclipseFP editor could have their unsaved contents copied into that folder (that folder represent the current state of the project, which may not be what is really saved on disk)
- have only a simple Haskell executable that given a module file, loads it using all the built files in the temp folder, and return the AST in some easy to parse format. Firing and getting the result would ensure GHC cannot grab loads of memory and not release it
- the IDE code then gets the AST and does all it needs to it
- the AST could even be saved in that temp folder in some format, so that the Java code would only request it when the original file is more recent, which would allow easy parsing of dependent modules AST (for example to retrieve all the symbols exported, etc)

There are a lot of ugly bits in there, maybe, but that would solve my problems... I suppose all of that could be written in Haskell and we could keep a similar enough API to scion, so that the Java code wouldn't need change too much...

For the moment I'm not going to reach into things anyway, but if anybody has some feedback, I'll gladly take any opinion on board!

Sunday, May 22, 2011

Haskell + FFI + Java + SWT: crazy, maybe, but working!

A few years ago I noted that being able to mix Haskell code and a Java GUI might be a good idea, since Java UIs have matured enormously, and Haskell UI library are still struggling to gain wide adoption, a recent thread on cafe being proof. SWT bindings were mentioned, so I had a look at both the Java and the C SWT code, for windows. Two immediate things sprang to view:
1. The SWT C library is using JNI, duh. It relies on JNI for some operations so you can't just use the SWT.dll in your haskell code that easily
2. The SWT C bindings are very low level, and there is a wealth of Java code on top of that to provide a lot ow glue and boilerplate code for all kind of widgets, and it would be long and painful to rewrite it all in Haskell.

My Java to Haskell code converter only being a dream at the moment (one day...), the next reasonable (ahem) option was then obvious: start a few blown JVM from Haskell and use it to drive SWT classes.
I'm a Java expert, I can say, and my Haskell is slowly coming on, but the glue in between has to be C, so it wasn't a smooth ride, but I finally got it working! So what's happening is this:
- The Haskell applications starts as they all do, in a main :: IO() function
- Haskell invokes some C code that starts a new JVM, passing it a classpath. The C code acts then as a facade hiding some of the intricacies of accessing the JVM
- Haskell uses the foreign C functions to create ands manipulate the SWT Java objects
- I even got callbacks working, meaning you can register a Haskell listener on a SWT button, and hence have Haskell code calculate the results of that button click.

And I have proof! Here's a simple SWT Shell with one button:
When you click the button:

And the handler for the button click is written in Haskell (I have a MVar called count for the number of times the user clicked):
do
    modifyMVar count (\c->do
        let nc=c+1
        let s=if nc==1 then "once." else ((show nc)++ " times.")
        text3<-toJString ("Clicked "++s)
        voidMethod button "setText" "(Ljava/lang/String;)V" [JObj text3]
        return(nc,())
        )


You can see here the invocation of the setText method of the SWT Button, which for the moment requires knowing the exact JNI signature, and the translation from Haskell strings to Java strings.

Of course, there is still loads to do. I probably need to automatically generate bindings to the Java objects to simplify greatly their manipulation, wrap stateful operations in a monad, etc. But this may open a new way for Haskell GUI. Or it may just be a crazy idea that has already taught me a lot about FFI and JNI...

Monday, April 18, 2011

Pirates 0.2: fixes and a chat interface

I released a little update to my Pirates Yesod/Canvas game. Nothing too dramatic, but the new version, still at http://pirates.dyndns-free.com boasts:

  • Fixes in the collision detection code
  • A chat interface, so you can talk to the other ship you're fighting with. Stock up on pirates insults!
  • Fixes in handling of games when a ship leaves the game before it's finished
As I said, nothing too fancy, but I find that polishing off bugs and adding unplanned features is often a good exercise, especially for personal projects where the temptation is great to just move to something else when it kinda works. The chat interface was interesting: the server side code was done in a few minutes, using the same event system as the rest, but I struggled longer with the HTML to get the right positions for everything, as usual... Now it's on the right hand side, outside of the canvas area, which makes the full game area much bigger than the original 800x600, but I don't think I get a lot of mobile users anyways (-;.

I could probably make the game more appealing long term by having a bigger area where more than 2 ships could battle, and have more of a RPG feel to it (maybe be able to log in and out so you keep your ship, be able to repair it in harbours, etc...). I'll see what I have time to do. Any suggestions welcome!

Friday, April 08, 2011

Pirates!! A multi-player browser game with Yesod and Canvas

I can finally open to the public a little game I've made! You can now go to http://pirates.dyndns-free.com and play!
The game is simple: you're sailing a pirate ship, and you have to sink your opponent. You can use cannons, ram the other ship, board it with your blood-thirsty crew. Your speed depends of course on the direction and strength of the wind. You can play alone versus a very dumb AI (mainly to get the hang of the controls), against a friend in a private game, or against any dog on the internet. 
The technology stack is as follows:

  • Hosting is on a free Amazon EC2 instance. Performance is probably not going to be great, but should be sufficient I hope for the traffic I'll be getting!
  • Server side is Yesod 0.7. Coming from the Java/JSP/Struts world it was such a pleasure to work in Haskell, with type safe templates. I have no web server, just warp, since there are very few static files (a few sprites and the tile image).
  • Client side uses Canvas with a sprinkling of JQuery.

As you can see, no database. Information about current games is purely in memory, and I don't keep any long term information about players. I suppose that allowing players to log in with their Google or Facebook id, and keep statistics on their battles would be good, but I'm not sure this little game will get enough traction to warrant it, really... 
The AI also is not great shake, there are only two bots: The Sitting Duck turns to face the wind and stays there. The Drunken Sailor just goes randomly through all possible actions. But hey, it's a multi-player game!
I'm not too sure if I chose the best route for concurrency. I use MVars and modifyMVar.
In fact the more difficult bit was to design the control. I didn't want to a do a full 3D environment, and opted for a top view, but the velocity of the ships was essential, and so providing just direction keys as in more static games wouldn't have worked. Hopefully the way the control works, being disposed on a copy of the boat icon at the top of screen, that turns when you boat turns, will work well. The icons are probably a bit small, it's fine for a mouse but I don't think it could work on a touch screen, unless you have tiny fingers.


A little bit of personal info: inspiration from this game comes from the French magazine "Jeux et Stratégies", that my dad used to get when I was young, and that got me into games. We have still kept all the issues, and issue 22 from August 1983 describes a simple ship battle game, rules written by Michel Brassinne (French warning!). Thanks!


Still it was fun to do!! Hope you enjoy playing it a little!

Friday, April 01, 2011

Install GHC7 and Yesod on Amazon Linux

I've been working lately on a multi-player web game, to actually get to know HTML Canvas (on the client) and Yesod (on the server) properly. I have a first fully functional version of the game, so now is the time to think about hosting. Michael initiated a discussion about it, and in the meantime I decided to investigate Amazon since they offer free instances now on EC2.
The free AMIs (images) come with a version of Linux specific to Amazon, but apparently binary compatible with CentOS, on which GHC and the Haskell Platform have been reported to successfully build.
These are the steps I followed to get everything working, hopefully they can be useful to somebody else. So as per the Amazon Getting Started guide, you connect to your instance with the ec2-user.
First we install through the package manager some useful packages:

sudo yum install make
sudo yum install gcc
sudo yum install zlib-devel
sudo yum install glut
sudo yum install glut-devel

I didn't find gmp, so I downloaded and installed in the default location:

curl -O ftp://ftp.gnu.org/gnu/gmp/gmp-4.3.2.tar.bz2
tar -xjvf gmp-4.3.2.tar.bz2
cd gmp-4.3.2
./configure
make
sudo make install

But afterwards I had issues building some Haskell packages because it didn't like the default install folder of /usr/local/lib, it preferred /usr/lib, so I did:
sudo cp /usr/local/lib/libgmp.* /usr/lib/
But I suppose ./configure --prefix=/usr/lib/ would be the preferred way to do that.

Libbsd is also required otherwise unix-compat fails:

curl -O http://libbsd.freedesktop.org/releases/libbsd-0.2.0.tar.gz
tar -xzvf libbsd-0.2.0.tar.gz
cd libbsd-0.2.0
sudo make install

Then for GHC, I just downloaded the generic binary and installed that. I decided to install Haskell under my home folder.

curl -O http://haskell.org/ghc/dist/7.0.2/ghc-7.0.2-i386-unknown-linux.tar.bz2
tar -xjvf ghc-7.0.2-i386-unknown-linux.tar.bz2
cd ghc-7.0.2
./configure --prefix=/home/ec2-user/haskell
make install

Make sure we know how to find it:
export PATH=$PATH:/home/ec2-user/haskell/bin

Then get the Haskell Platform source and build that, since there is no binary (yet) for our platform:

curl -O http://lambda.galois.com/hp-tmp/2011.2.0.0/haskell-platform-2011.2.0.0.tar.gz
tar -xzvf haskell-platform-2011.2.0.0.tar.gz
cd haskell-platform-2011.2.0.0
./configure --prefix=/home/ec2-user/haskell
make
make install

Once you're there, it's back to familiar ground:

cabal update
cabal install yesod

And there we are!! My deployment platform is ready!

Monday, March 21, 2011

EclipseFP 2.0.4 released: supports GHC 7!

Hello, the demand was HUGE (well, everything is relative :-)) for a version of EclipseFP that could build and run on GHC7. Since the 2.0.3 release there is now a Haskell Platform release that contains GHC7, so we had no excuse... And there it is! Thanks have to go mainly to Alejandro Serrano, for getting Scion to compile with GHC7 and to Thomas Schilling and Matti Niemenmaa, who upgraded their libraries for GHC7.


So what we have is a scion backend that should build both with 6.12 and 7.0, and hopefully work the same on both. We now support test-suite sections in Cabal files, with limited support for running test suites (running just cabal test with no options).


On my To Do list are full support for test-suites (having full launch configurations for Cabal defined tests) and HLint integration. But I'd also like to work on my own project, so don't expect that a release every two weeks is going to be our normal cruising speed.


As usual, just install from the Eclipse update site: http://eclipsefp.sf.net/updates, and bug reports or feature requests should go to the SourceForge forum or the development mailing list.


Happy Haskell Hacking!

Monday, March 07, 2011

EclipseFP 2.0.3 released

It's my pleasure to release EclipseFP version 2.0.3. EclipseFP is a set of Eclipse plugins for Haskell development. Scooter and I have tried to add a few features and hopefully to fix the bugs that were reported by users.

Main things in this version are code completion templates, which enables you to code even quicker!! We also enhanced the Cabal support (you can now set Cabal flags from the project properties, run Cabal install on the project) and simplified the installation (more settings are auto detected).

EclipseFP is alive and well (I use it for all my Haskell work) so please send us all your feedback, bug reports, feature requests!

Use the standard Eclipse Updates Site  or download files. Enjoy!

Friday, January 21, 2011

Evolving a computer with TECS and Genprog

I've started reading The Elements of Computer Systems since it was recommended on Reddit and it's a great read. After the section on boolean gates I decided to have a quick go at build the gates in Haskell. Just implement Nand with pattern matching, and implement all the other gates just in term of functions calls to previously defined gates. The book mentioned "think positive" about implementing Not, so I just T as the second parameter, did't think more about it, even though I wasn't sure having a constant value was OK.



Then I moved on to the other gates. It was interesting to think about boolean logic without Or, for example, after years of only reasoning in terms of And Or and Not. But at some stage I thought "why am I doing this by hand?". I remembered a thread about a new genetic programming library on an Haskell group. Surely generating the gates would be simple enough?
So I got genprog from hackage, and adapted the example for my needs. I started with a very simple system to determine the implementation of Not:



And of course, the result came quickly enough: not a=nand(a,a). No need for a Const at all! Evolution has beaten me! (OK, I'm only a not-so-intelligent designer, I suppose...)
Now, I'm going to see if this approach can take me all the way to the arithmetic unit...

Wednesday, December 01, 2010

EclipseFP 2.0.2 released

I am pleased to announce another release of EclipseFP. Version 2.0.2 should make installation of Scion easier, improve stability and performance of the parsing and building operations, and provide a few new functionalities. You can now configure where the "Open Definition" action will look for definitions (these can be in Haskell source code or Haddock pages): by default it will look in the dependent projects, in your GHC install doc folder, and on Hackage, but you can add more locations in the preferences. You can also generate source distribution via a project export command (that calls cabal sdist).


The release notes are here. To install or upgrade, just point your Eclipse to http://eclipsefp.sf.net/updates. Be sure to configure both the GHC path and the Cabal path in the preferences.


Happy Haskell hacking!

Thursday, November 25, 2010

A simple game in Haskell + SDL

I wanted to play a bit with SDL, and it's always good to step away from actually working on EclipseFP to use it for a "real" project. So I wrote a very primitive game using SDL and SDL_TTF. It's a typing speed game (hence the, ahem, clever pun on the name: TypeClass): you see letters scrolling down the screen and you need to type them, and of course they go faster and faster. Maybe my children will learn to type with it. Maybe not.


I had SDL installed earlier, but of course SDL_TTF proved challenging on my windows machine, but I think it's was all my fault, I probably didn't read the instructions properly or something. Anyway, I only forgotten to set the LIBS variable. When I ran export LIBS=/usr/local/lib/libSDL_ttf.dll.a in my MSYS environment then configure worked fine!


Afterwards it was all plain sailing, really. Just remember to add enableUnicode True in your initialization code so you can get the actual Unicode character typed (I'm on a French keyboard, so typing M gives me the SDL key ;). And of course you need a font file, so I include a GNU FreeFont file with the package. It needs to be in the same folder as the executable.


For some reason, after seeing code that was blocking for SDL events in a loop, I started building the game with two threads, one blocking for events and one looping and drawing, and a MVar in the middle. It worked, but rewriting it in a single normal game loop: process event, update game state, draw made things a lot easier.


This brilliant piece of software that has already made its mark in video game history can be found on Hackage here!


As usual, all feedback is welcome. Possible enhancements are a high score screen, difficulty levels, choosing letters by frequency in English, using Markov chains so that the flow of letters look more natural... The list is infinite!

Thursday, September 30, 2010

EclipseFP 2.0.0 released!

Hello all,

I'm proud to announce version 2.0.0 of EclipseFP, the Eclipse plugin for Haskell coding. The change in the major version number shows that some big changes have been made, even if under the hood:
- the Antlr parsing has been removed
- the JFace based syntax highlighter has been removed
We now rely solely on Scion and the GHC API to provide lexer tokens! This fixes some long standing syntax highlighting bugs while giving us more options for coloring.
Also, we now communicate to the Scion library via standard streams instead of network calls, which should solve some headaches.

There are also loads of bug fixes and small enhancements peppered a bit everywhere, either things that people asked or things that I did for myself, since EclipseFP is (of course) my IDE of choice for my Haskell coding. The release notes can be found here.

Another good news is that I'm not alone in hacking at EclipseFP, scooter has helped a lot with Helios, Cabal 1.6, GHC 6.10 and Mac OS X support, and has a few new features coming up soon!

Just point your Eclipse to the EclipseFP update site, and happy Haskell hacking!!

Friday, September 24, 2010

Haskell Neural Network: plugging a space leak


First, the good news: last week when I posted about my little digit recognition program I had made a mistake in my test code: when I give a rounded eight to my network, it does recognize it, even though it's been trained only with a square eight! Yoohoo!


Also, a few people pointed to online database of handwritten digits so that I could get more data to train my network. I dully downloaded and started working with some files. Soon I knew I had a problem. Not only was the learning slow, but the memory usage of the program showed exponential growth, like using 400MB after a few iterations. Ha ha, I thought, so it's me against lazy evaluation again!


Well, I was right. A couple of strictness annotation in the neuron output calculation function helped performance, nearly making the code twice as fast, but didn't help the memory consumption. Going mad with ! (BangPatterns is your friend) didn't help any more. WTF?


Then I started to read a bit more about seq and Weak Head Normal Form. So when I put a BangPattern in front of a tuple, it evaluates the tuple but not what's inside it. And, lo and behold, if at each learning iteration I traced the network to the standard output, memory usage stayed constant! So I needed to tell Haskell to fully evaluate the network each time, so as not to keep thunks full of arithmetic operations hanging round. A distant memory of a package called deepseq provided me the final help I needed. I didn't use the package itself because I wanted to understand really what's going on, so I just roll out a few lines of my own:



And by calling deepSeq on my network in each iteration, my program runs in constant space! And I looked at the flat line of memory usage in my task manager, and I was pleased. Now, I can try to improve the speed of the dang thing, but that's another set of problems...

Friday, September 17, 2010

Digit recognition with a neural network. First attempt!

I bought myself "On Intelligence", and I thought as the first step on the long road to building an intelligent machine I would go back to neural networks. I have my own little library that seems to work (kind of), so I decided I was going to try to write a little number recognition program. I was inspired of course by ai-junkie, but it was a bit short on details...
So here is the problem: I have a 5x5 grid of LEDs that can be on or off, and I want to recognize the digit that they show. 
The input will be a list of 25 numbers, either 0 (off) or 1 (on)
The output will be a list of 10 numbers, either 0 or 1. The first position of a 1 indicates the result (so if the first element is a 1, it's number 0, etc).
I arbitrarily decide to set the number of hidden neurons to 50, twice the input neurons. So my topology is 25-50-10. 
I train the network with only one version of each digit. For example 3 would be:
*****
    *
 ****
    *
*****
Wrote a few lines of Haskell code to read the training sets (moving from the representation with *, spaces and new lines to the list of 1 and 0, so that 3 becomes: [1.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,1.0,1.0,1.0,1.0,0.0,0.0,0.0,0.0,1.0,1.0,1.0,1.0,1.0,1.0]).
Then I train the network. It learns after 200 iterations, and successfully recognizes the training sets (ok, so things are working as they should be).
Then the real test: can my network recognize small variants of the training set?
Lets's try with:
****
    *
 ***
    *
****
(a slightly rounded 3): the network answers 3!!
Works also for a slightly rounded 6. But then:
 ***
*   *
 ***
*   *
 ***
(rounded 8) gives me 6. Oh dear... I could probably add more cases in the training sets and hopefully resolve the ambiguities, but there are bigger issues (I know I know, I'm very candid, but it's one thing being told something in a book, and another to build something to actually show it to you). For example:
***
* *
***
Is a small zero that doesn't take the full 5 LED width. My network recognizes 0 when it fills the full square, not when it's smaller (tells me it's a 5).
And of course, 1 is a disaster. The training "1" is a vertical row of LEDs on the left. A vertical row of LEDs on the right gives me 9, usually (and I suppose, 9 has all the LEDs on the right on).
So not only is basic training not sufficient to detect simple variations, but also the fact that we deal with absolute positioning of leds mean than scaling and simple side translations are not supported. So I suppose the next step is to not work with absolute positions, but relative positions of "on" LEDs. Another day's work...