Re: Testing Inline::C Modules
by PodMaster (Abbot) on Feb 11, 2004 at 18:26 UTC
|
| [reply] [d/l] |
|
|
| [reply] |
Re: Testing Inline::C Modules
by Abigail-II (Bishop) on Feb 11, 2004 at 18:29 UTC
|
I've found valgrind a useful tool to check whether
memory is accessed properly. It keeps track where you have
allocated memory, where you have freed it, and where you
step out of line. It can produce reports of unreachable
memory, and unfreed memory when the program ends.
Abigail | [reply] |
|
|
| [reply] |
Re: Testing Inline::C Modules
by chance (Beadle) on Feb 11, 2004 at 17:54 UTC
|
assertions are your friend.
If you pass -DNDEBUG into C-compiler at C-compile-time, the assertions will not be compiled. However, except for your inner-number-crunching loops I'd suggest leaving them on.
once you get an assertion to core dump, assuming you have compiled with debugging on, I believe (haven't actually done it though ...) that you can fire up gdb with the core file and at hopefully get a pretty good idea of the state of things with just up,down, and print.
If things get hairy enough so that the above still doesn't cut it, I think what you want to do is try to make the actual C code that appears in the Inline:: part as small as possible, making it just Interface code to a library. Then make a separate C 'client' for the same library and do all your C debugging in a normal C way. If problems persist then you can be pretty sure its an interface problem.
I'm reinventing this particular wheel slowly at home (The neural net wheel... not the Inline::C wheel). Out of curiosity, how much is done in C and how much in perl? Based on a purely anecdotal analysis (i.e. I've been too lazy to profile it) I think the matrix-vector multiplication and multiplication by the transpose is about the only part that really needs to be done in C. | [reply] |
|
|
I push virtually everything down to the C level. The only reason Perl is there is to allow Perl programmers to have an easy API. I wrote this module to teach myself how neural networks work since the existing CPAN modules that I saw assumed that you already knew what you were doing. It's sort of a "training" module for both myself and the programmers who might use it.
To be quite frank, while I roughly understand what's going on, I still have a lot of work to do. For example, I use a sigmoid activation function. I don't understand quite how that differs from linear (useless for a backprop network like the one I use) or Tahn activation functions. Also, this NN only seems useful for a "winner take all" strategy, thus you must have a fixed number of possible outputs. I'm hoping to figure out how to adapt it to be more flexible, but I'm playing with deep magic that I don't understand terribly well.
What I really would like to understand is how I can map multiple inputs to a single output. In other words, let's say a particular product grosses $X million in direct sales. Given the possible variables (cost, advertising budget, demographics of buyers, etc.), project rentals of said product (I'm being deliberately vague). With a winner take all strategy, I can't do that. I'm wondering if it's something as simple as choosing an appropriate activation function?
| [reply] |
|
|
I'll have to read your module sometime. The documentation seems to be the introductory overview I need before tackling some real source matter -- I've wanted to play with neural nets seriously since they were omitted during my A.I. class in college, and Russel and Norvig (still shelved, mostly unread), while canonical, isn't exactly clear-as-mud on the subject. This should be a good excuse to play with Inline::C as well (yet another module I have been ignoring).
I good quote somewhere, that is entirely irrelevant, and mostly forgotten, went something like this: "The two worst ways to solve a problem are neural networks and genetic algorithms". It's not really an insult, but more of a statement of the A.I. pathology: The former must know when it has found the answer, and the later must know the solution and works on how to get there from the problem. In all, this impresses as me as being insanely cool in a computational overkill sort of way. But this is the sort of theory and weirdness I love to play with.
Without a doubt though, it's safer to play with this massive structures in something that has some decent garbage collection and memory management. Your choice on Inline::C shows extreme bravery -- but I guess the speed is required for something which is, by definition, inefficient. If you know how to solve a problem without a Neural Net or genetic algorithm, then you don't need the neural net.
I can't find it, but there was a neural net somewhere used to reproduce circuits humans had already invented. The designs left some extra resistors in strange places, and in many cases, scientists weren't exactly sure what they did. It is possible, in the future, to see more of this kind of work -- many problems exist where we can define the inputs and the outputs, but can't invent the middle layer.
Game on.
| [reply] |
|
|
|
|
|
|
|
|
|
What I really would like to understand is how I can map multiple inputs to a single output.
hidden layer sigmoids are fine to nonlinearize things.
but if you want your output to be one real number, you should have your output layer only have one node, and use linear activation.
| [reply] |
|
|
|
|
Re: Testing Inline::C Modules
by adrianh (Chancellor) on Feb 11, 2004 at 22:14 UTC
|
I'm also rather unclear about how to test the C functions. I only have 18 tests for the module, but it needs heavy redesign internally (such as not using globals in C) and while testing through the Perl interface will catch bugs, it won't tell me where the bugs are. I suppose I could use assert(), but I have no idea how to remove #include <assert.h> when the module gets installed (or even if I should remove it).
You might want to consider using a separate testing frameworks for the C code - you can find some on xprogramming.com. I find it easier to test libraries using the same language they're written in.
It's also very easy to write some quick C code to chuck out test results in the format that Test::Harness expects. You can then have a normal *.t script fire it off and get your C tests integrated into your Perl test suite.
| [reply] |
|
|
It's also very easy to write some quick C code to chuck out test results in the format that Test::Harness expects. You can then have a normal *.t script fire it off and get your C tests integrated into your Perl test suite.
I wonder if that's more difficult than it sounds. I seem to recall that there's a lot of special case code in the Test:: modules to deal with VMS quirks (and a quick grep confirms this). I suppose I could just forget about VMS, but I don't like that thought. Have you any experience with this?
| [reply] |
|
|
No experience of doing it on VMS boxes, but I can't really see how it would cause problems. All you're doing is printing "ok" and "no ok" to STDOUT after all.
I've used C and even (gasp) PHP in this sort of way in the past without problems on various Unix boxes.
| [reply] |