3 ms·
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] ->
by 6gvONxR4sf7o 7y ago
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 <- wm] (relu' <$> 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.
- tome 7y agoYour wish is my command: http://h2.jaguarpaw.co.uk/posts/refactoring-neural-network/ http://h2.jaguarpaw.co.uk/posts/refactoring-neural-network/