Live data from Hacker News

Building a neural network from scratch in Haskell

www-cs-students.stanford.edu

31–38 of 38 posts

Re: Building a neural network from scratch in Haskell

#31

Maybe it's just me, but this looks like a bunch of incomprehensible gibberish code. I'm sure I could understand it if I spent many hours pouring over it, but why would you ever do that? When written out in Python (or even in JS!), the whole thing is so much simpler looking and more closely resembles the underlying math. This is especially true if you use a package like Numpy. I know he said he didn't want to use any…

I've never found a functional programming language that's easy to read.

The best way to understand functional programming without learning it is to learn an imperative language like Ruby that everyone says is easy but that is actually hard. Then it's:

programming you know -> experience you don't have yet -> code everyone uses

Ruby makes the jump to the last step without explaining the middle one. That's what the whole convention over configuration part is about.

Functional programming languages do the exact same thing. All of those arrows and symbols and syntactic sugar transpile directly to Lisp. They're basically shorthand. Unfortunately, I've never seen tutorials talk about that translation.

To get the middle part, it's probably best to start with the low-hanging fruit. Probably learn something like spreadsheets, then Scheme, then ClojureScript, then F#. I never made it as far as Haskell or Scala.

I always get lost somewhere around monads and impurity. And all FP languages fall down at that point in similar ways anyway. You either treat mutable variables as imaginary numbers that aren't examined until they must be (lazily), or throw the rules out the window and let variables be reassigned or renamed to themselves with new values, which breaks the whole point of using FP in the first place. It's pretty much an open problem, and the failure to solve it satisfactorily is why no FP language has caught on yet in the mainstream IMHO.

Re: Building a neural network from scratch in Haskell

#32

Maybe it's just me, but this looks like a bunch of incomprehensible gibberish code. I'm sure I could understand it if I spent many hours pouring over it, but why would you ever do that? When written out in Python (or even in JS!), the whole thing is so much simpler looking and more closely resembles the underlying math. This is especially true if you use a package like Numpy. I know he said he didn't want to use any…

This will probably shock you not at all, but I find this way easier to read than Python code. You can’t really compare with Numpy code since the author deliberately avoids loading libraries.

Of course, I’m more familiar with Haskell. The fact you’re more familiar with imperative languages isn’t the argument for readability you think it is.

Re: Building a neural network from scratch in Haskell

#33
post #19

Maybe it's just me, but this looks like a bunch of incomprehensible gibberish code. I'm sure I could understand it if I spent many hours pouring over it, but why would you ever do that? When written out in Python (or even in JS!), the whole thing is so much simpler looking and more closely resembles the underlying math. This is especially true if you use a package like Numpy. I know he said he didn't want to use any…

but if the underlying primitives in the problem are vectors/matrices, then it seems like you are reinventing the wheel in a very substandard way that doesn't aid in understanding in any way and results in something that isn't beautiful, isn't high performance, and is confusing for someone to read You mean like...both of the languages you listed? There's an obviously superior, faster, simpler language when working wit…

> Why not demo it in Python?

Not OP, but here: https://gist.github.com/stfwn/62e51d86ca4ff155becd3c6a14adf6...

You should be able to wget the file and run it (Python 3) from start to finish without any set-up and get ~88% accuracy on the test set.

It uses all the data (not one-sixth like in the blog posts) and does 200 iterations by default, so here's the loss plot on the training set if you want to skip all the fun: https://i.imgur.com/F57zmXV.png

Re: Building a neural network from scratch in Haskell

#34
post #25

Earlier quoted context omitted.

I have been casually playing around with TensorFlow for Swift since it was announced. It shows promise but I question long term support and development. The Julia language with the Flux deep learning library is another very interesting but not mainstream path to take.

What are your concerns around the support / dev? Google has a fairly sizable team around it, it has a fast path to adoption by the large pool of swift devs and fast.ai, and of course, google hype. Chris leaving doesn't seem to be an issue: https://twitter.com/clattner_llvm/status/1222032740897284097

I hope there is no long term support problem, but I don’t know. I am sort-of addicted to Lisp languages, but I admit there is a lot to like about Swift, and TensorFlow turtles all the way down in Swift is a great idea.

Re: Building a neural network from scratch in Haskell

#35
I love haskell as much as the next PL nerd, but the community has a real code golf problem. An example from the blog post:

    deltas :: [Float] -> [Float] -> [([Float], [[Float]])] -> ([[Float]], [[Float]])
    deltas xv yv layers = let
      (avs@(av:_), zv:zvs) = revaz xv layers
      delta0 = zipWith (*) (zipWith dCost av yv) (relu'  zv)
      in (reverse avs, f (transpose . snd  reverse layers) zvs [delta0]) where
        f _ [] dvs = dvs
        f (wm:wms) (zv:zvs) dvs@(dv:_) = f wms zvs $ (:dvs) $
          zipWith (*) [(sum $ zipWith (*) row dv) | row  zv)
    
    ...

    descend av dv = zipWith (-) av ((eta *)  dv)

    learn :: [Float] -> [Float] -> [([Float], [[Float]])] -> [([Float], [[Float]])]
    learn xv yv layers = let (avs, dvs) = deltas xv yv layers
      in zip (zipWith descend (fst  layers) dvs) $
        zipWith3 (\wvs av dv -> zipWith (\wv d -> descend wv ((d*)  av)) wvs dv)
          (snd  layers) avs dvs

Writing this in 2-3x as many lines with clear variable names for some intermediate expressions would make it so much clearer. Haskell has a nasty reputation for "you have to study the shit out of it to make heads or tails of the code" and I'm pretty certain that 90% of it comes from how terse haskellers try to make code.

Just add intermediate expressions and annotate their types, maybe even with some type synonyms for intermediate types, because code is for humans.

Re: Building a neural network from scratch in Haskell

#36
post #30

played with this for ~5 mins and it's insanely bad (maybe it "guessed" right 3/15 tries?) i.e. slightly better than random guesses, even with very clear handwriting :(

You had bad luck I guess. I just did 15 tries and it only got one wrong. Not really sure what this says though.

Are you talking about the "Sample" button, or drawing the digits yourself? It seems to have a very good accuracy on the samples, but gets a lot of my hand-drawn digits wrong.

Seems like a classic case of overfitting to be honest.

Re: Building a neural network from scratch in Haskell

#37

I love haskell as much as the next PL nerd, but the community has a real code golf problem. An example from the blog post: deltas :: [Float] -> [Float] -> [([Float], [[Float]])] -> ([[Float]], [[Float]]) deltas xv yv layers = let (avs@(av:_), zv:zvs) = revaz xv layers delta0 = zipWith (*) (zipWith dCost av yv) (relu' zv) in (reverse avs, f (transpose . snd reverse layers) zvs [delta0]) where f _ [] dvs = dvs f (wm:wm…

Your wish is my command:

http://h2.jaguarpaw.co.uk/posts/refactoring-neural-network/

Re: Building a neural network from scratch in Haskell

#38
post #30

Earlier quoted context omitted.

You had bad luck I guess. I just did 15 tries and it only got one wrong. Not really sure what this says though.

Are you talking about the "Sample" button, or drawing the digits yourself? It seems to have a very good accuracy on the samples, but gets a lot of my hand-drawn digits wrong. Seems like a classic case of overfitting to be honest.

Ah I didn’t know you could draw yourself. That explains the difference.
Post reply on HN