in reply to Testing Inline::C Modules

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.

Replies are listed 'Best First'.
Re: Re: Testing Inline::C Modules
by Ovid (Cardinal) on Feb 11, 2004 at 18:06 UTC

    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?

    Cheers,
    Ovid

    New address of my CGI Course.

      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.

        The quote actually sounds very reasonable. A neural network will frequently be the worst way of solving a problem. However, it has the advantage that, when there is not clear solution, it can frequently offer a reasonable guess, even with incorrect or incomplete information. The example I like to use when I explain it is "Verbal SQL". Imagine the following exchange:

        Ovid: Who's the new guy with the blond hair working in accounting?
        Bob: That's 'Jim', but he's actually a brunette and he works in human resources.

        In this case, I got the hair color and the employee department wrong, but I still get good results. Further, I left out "hire date", but implied that the person was "new". It would be difficult to write an SQL statement that will get me the correct answer.

        On the other hand, what if I were actually meaning the new blond lady working in accounting? Gender probably has a higher chance of being accurate then the department that a person works in, so Bob might have given me the wrong answer. Neural networks are prone to the same types of problems. They can ascertain strange correlations that we might not consider, but they can also give incorrect results, particularly if we ask poor questions.

        Cheers,
        Ovid

        New address of my CGI Course.

        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.

        While R&N is an excellent general textbook, I'd hesitate to call it canonical.

        If you're interested I'd recommend taking a look at Rumelhart & McClelland's classic two volume set "Parallel Distributed Processing: Explorations in the Microstructure of Cognition". While it was first published back in the mid-eighties it's still a great overview of the basics.

        Masters' "Practical Neural Network Recipes in C++" is a good practical introduction.

        Update: You may find the AI Depot a source of useful info and links too.

        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.

        This is a slightly unfair characterisation. GAs progress by having a way of comparing solutions. Knowing whether one thing is better worse than another is very different from knowing what the ideal solution is. The same applies to neural nets.

        The AI "pathology" that I have come across is people ignoring slightly less cool solutions. For example, given equal amounts of time, you'll often find that GAs will lose out to other stochastic methods like simulated annealing.

        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.

        You may be thinking of Adrian Thompson's work (whose robots occasionally prevented me getting to my office back when I worked at Sussex Uni ;-) He evolved hardware solutions by applying evolutionary algorithms to field-programmable gate array's.

        This is from memory - so I may be getting the details wrong.

        As I recall he had evolved a chip to recognise different tones. When he looked at the solution on the chip it turned out that some of the cells were not connected to input or output, but when he disconnected them the chip suddenly stopped recognising the tones.

        It turned out that the solution was taking advantage of capacitive/inductive affects between the connected and disconnected bits. It was hard to investigate because the FGPA only gave digital output so it was impossible to measure directly the analogue values that were causing the affect. Didn't even work if you setup the same configuration on a different chip.

        I think they were going to build some specialised hardware to take analogue measurements - can't remember or never knew if they got anywhere.

        Fascinating stuff.

      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.

        I understand the one node for the output layer, but I can't use a linear activation function for a backprop network because that uses the derivative of the activation function for propogating the error back through the network. Sample error progogation code:

        for (out = 0; out < network.size.output; out++) { network.error.output[out] = (network.neuron.target[out] - network.neuron.output[out] +) * sigmoid_derivative(network.neuron.output[out]); }

        That fails because the derivative of a linear function will be 1.0, thus not allowing the network to learn from errors. Am I missing something basic here?

        Cheers,
        Ovid

        New address of my CGI Course.