• Stars
    star
    180
  • Rank 213,097 (Top 5 %)
  • Language
    Haskell
  • License
    BSD 3-Clause "New...
  • Created over 7 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Heterogeneous automatic differentiation ("backpropagation") in Haskell

backprop

backprop on Hackage backprop on Stackage LTS 11 backprop on Stackage Nightly Build Status

Join the chat at https://gitter.im/haskell-backprop/Lobby

Documentation and Walkthrough

Automatic heterogeneous back-propagation.

Write your functions to compute your result, and the library will automatically generate functions to compute your gradient.

Differs from ad by offering full heterogeneity -- each intermediate step and the resulting value can have different types (matrices, vectors, scalars, lists, etc.).

Useful for applications in differentiable programming and deep learning for creating and training numerical models, especially as described in this blog post on a purely functional typed approach to trainable models. Overall, intended for the implementation of gradient descent and other numeric optimization techniques. Comparable to the python library autograd.

Currently up on hackage, with haddock documentation! However, a proper library introduction and usage tutorial is available here. See also my introductory blog post. You can also find help or support on the gitter channel.

If you want to provide backprop for users of your library, see this guide to equipping your library with backprop.

MNIST Digit Classifier Example

My blog post introduces the concepts in this library in the context of training a handwritten digit classifier. I recommend reading that first.

There are some literate haskell examples in the source, though (rendered as pdf here), which can be built (if stack is installed) using:

$ ./Build.hs exe

There is a follow-up tutorial on using the library with more advanced types, with extensible neural networks a la this blog post, available as literate haskell and also rendered as a PDF.

Brief example

(This is a really brief version of the documentation walkthrough and my blog post)

The quick example below describes the running of a neural network with one hidden layer to calculate its squared error with respect to target targ, which is parameterized by two weight matrices and two bias vectors. Vector/matrix types are from the hmatrix package.

Let's make a data type to store our parameters, with convenient accessors using lens:

import Numeric.LinearAlgebra.Static.Backprop

data Network = Net { _weight1 :: L 20 100
                   , _bias1   :: R 20
                   , _weight2 :: L  5  20
                   , _bias2   :: R  5
                   }

makeLenses ''Network

(R n is an n-length vector, L m n is an m-by-n matrix, etc., #> is matrix-vector multiplication)

"Running" a network on an input vector might look like this:

runNet net x = z
  where
    y = logistic $ (net ^^. weight1) #> x + (net ^^. bias1)
    z = logistic $ (net ^^. weight2) #> y + (net ^^. bias2)

logistic :: Floating a => a -> a
logistic x = 1 / (1 + exp (-x))

And that's it! neuralNet is now backpropagatable!

We can "run" it using evalBP:

evalBP2 runNet :: Network -> R 100 -> R 5

If we write a function to compute errors:

squaredError target output = error `dot` error
  where
    error = target - output

we can "test" our networks:

netError target input net = squaredError (auto target)
                                         (runNet net (auto input))

This can be run, again:

evalBP (netError myTarget myVector) :: Network -> Double

Now, we just wrote a normal function to compute the error of our network. With the backprop library, we now also have a way to compute the gradient, as well!

gradBP (netError myTarget myVector) :: Network -> Network

Now, we can perform gradient descent!

gradDescent
    :: R 100
    -> R 5
    -> Network
    -> Network
gradDescent x targ n0 = n0 - 0.1 * gradient
  where
    gradient = gradBP (netError targ x) n0

Ta dah! We were able to compute the gradient of our error function, just by only saying how to compute the error itself.

For a more fleshed out example, see the documentaiton, my blog post and the MNIST tutorial (also rendered as a pdf)

Benchmarks and Performance

Here are some basic benchmarks comparing the library's automatic differentiation process to "manual" differentiation by hand. When using the MNIST tutorial as an example:

benchmarks

Here we compare:

  1. "Manual" differentiation of a 784 x 300 x 100 x 10 fully-connected feed-forward ANN.
  2. Automatic differentiation using backprop and the lens-based accessor interface
  3. Automatic differentiation using backprop and the "higher-kinded data"-based pattern matching interface
  4. A hybrid approach that manually provides gradients for individual layers but uses automatic differentiation for chaining the layers together.

We can see that simply running the network and functions (using evalBP) incurs virtually zero overhead. This means that library authors could actually export only backprop-lifted functions, and users would be able to use them without losing any performance.

As for computing gradients, there exists some associated overhead, from three main sources. Of these, the building of the computational graph and the Wengert Tape wind up being negligible. For more information, see a detailed look at performance, overhead, and optimization techniques in the documentation.

Note that the manual and hybrid modes almost overlap in the range of their random variances.

Comparisons

backprop can be compared and contrasted to many other similar libraries with some overlap:

  1. The ad library (and variants like diffhask) support automatic differentiation, but only for homogeneous/monomorphic situations. All values in a computation must be of the same type --- so, your computation might be the manipulation of Doubles through a Double -> Double function.

    backprop allows you to mix matrices, vectors, doubles, integers, and even key-value maps as a part of your computation, and they will all be backpropagated properly with the help of the Backprop typeclass.

  2. The autograd library is a very close equivalent to backprop, implemented in Python for Python applications. The difference between backprop and autograd is mostly the difference between Haskell and Python --- static types with type inference, purity, etc.

  3. There is a link between backprop and deep learning/neural network libraries like tensorflow, caffe, and theano, which all all support some form of heterogeneous automatic differentiation. Haskell libraries doing similar things include grenade.

    These are all frameworks for working with neural networks or other gradient-based optimizations --- they include things like built-in optimizers, methods to automate training data, built-in models to use out of the box. backprop could be used as a part of such a framework, like I described in my A Purely Functional Typed Approach to Trainable Models blog series; however, the backprop library itself does not provide any built in models or optimizers or automated data processing pipelines.

See documentation for a more detailed look.

Todo

  1. Benchmark against competing back-propagation libraries like ad, and auto-differentiating tensor libraries like grenade

  2. Write tests!

  3. Explore opportunities for parallelization. There are some naive ways of directly parallelizing right now, but potential overhead should be investigated.

  4. Some open questions:

    a. Is it possible to support constructors with existential types?

    b. How to support "monadic" operations that depend on results of previous operations? (ApBP already exists for situations that don't)

    c. What needs to be done to allow us to automatically do second, third-order differentiation, as well? This might be useful for certain ODE solvers which rely on second order gradients and hessians.

More Repositories

1

auto

Haskell DSL and platform providing denotational, compositional api for discrete-step, locally stateful, interactive programs, games & automations. http://hackage.haskell.org/package/auto
Haskell
176
star
2

hamilton

Simulate physics on generalized coordinate systems using Hamiltonian Mechanics and automatic differentiation. Don't throw away your shot.
Haskell
134
star
3

advent-of-code-2020

πŸŽ…πŸŒŸβ„οΈβ˜ƒοΈπŸŽ„πŸŽ
Haskell
98
star
4

advent-of-code-2018

Advent of Code 2018 Solutions (Spoilers!)
Haskell
83
star
5

inCode

Source for personal blog.
Haskell
74
star
6

advent-of-code-2019

Advent of Code 2019 Solutions (Spoilers!)
Haskell
66
star
7

tensor-ops

Type-safe tensor manipulation operations in Haskell with tensorflow-style automatic differentiation
Haskell
60
star
8

advent-of-code-2017

Advent of Code 2017 (Warning: Spoilers)
Haskell
49
star
9

advent-of-code-2021

πŸŽ…πŸŒŸβ„οΈβ˜ƒοΈπŸŽ„πŸŽ
Haskell
43
star
10

mutable

Automatic piecewise-mutable references for your types
Haskell
42
star
11

functor-combinators

Combine and enhance Functors
Haskell
38
star
12

backprop-learn

Combinators and types for easily building trainable neural networks using the backprop library
Haskell
33
star
13

servant-cli

Generate a command line client from a servant API
Haskell
29
star
14

uncertain

Manipulating numbers with inherent measurement/experimental uncertainty.
Haskell
25
star
15

setup-stack

Github action for setting up haskell stack
JavaScript
24
star
16

nonempty-containers

Efficient non-empty variants of containers data types, with full API
Haskell
23
star
17

advent-of-code-dev

Interactive development environment and runner for Advent of Code challenges
Haskell
23
star
18

ghcjs-websockets

GHCJS interface for the Javascript Websocket API (DEPRECATED: use ghcjs-base's native websockets!)
Haskell
22
star
19

corona-charts

Ultimate interactive COVID-19 data plotter
PureScript
21
star
20

typelits-printf

Type-safe printf from parsing GHC TypeLits Symbol
Haskell
20
star
21

auto-examples

Example projects using the auto library.
Haskell
19
star
22

lens-typelevel

Type-level lenses using singletons because why not
Haskell
15
star
23

opto

Numerical optimization with support for stochastic optimization, mostly for my own experimental usage
Haskell
14
star
24

advent-of-code-api

Haskell bindings to Advent of Code REST API
Haskell
14
star
25

interactive-plot

Quick interactive time series terminal plots usable in ghci
Haskell
14
star
26

hmatrix-backprop

backprop primitives for hmatrix
Haskell
13
star
27

advent-of-code-2022

πŸŽ…πŸŒŸβ„οΈβ˜ƒοΈπŸŽ„πŸŽ
Haskell
12
star
28

prompt

Monad and transformer for deferred-effect pure prompt-response queries
Haskell
12
star
29

decidable

Combinators for manipulating dependently-typed predicates.
Haskell
12
star
30

servant-validate

Validate well-formed servant APIs at compile time
Haskell
10
star
31

typelits-witnesses

Existential witnesses, singletons, and classes for operations on GHC TypeLits
Haskell
9
star
32

hakyll-dhall

Dhall compiler for Hakyll
Haskell
8
star
33

conduino

Lightweight composable continuation-based stream processors
Haskell
8
star
34

tic-tac-typed

Exploring a "type-safe" Tic-Tac-Toe in Haskell
Haskell
8
star
35

emd

Hilbert-Huang Transform (Empirical Mode Decomposition) in pure Haskell
Haskell
7
star
36

blog

Source for blog engine/static website. Haskell Web Development learning project.
Haskell
7
star
37

talks

Collection of slides, notes, and posters for public talks I've given.
HTML
6
star
38

wavelets

wavelet decomposition in haskell
Haskell
6
star
39

bins

Aggregate continuous variables into discrete bins
Haskell
6
star
40

one-liner-instances

Default implementations for common typeclasses using one-liner
Haskell
6
star
41

get-package

Github action for installing packages from OS package managers
JavaScript
6
star
42

log.sh

Simple command line note/logging script for one-off notes
Shell
6
star
43

data-diff

Derivable diffing and patching on arbitrary data types using GHC Generics
Haskell
5
star
44

purdle

wordle clone in purescript for fun
JavaScript
5
star
45

advent-of-code-ocr

Parsing ASCII art word solutions for advent of code
Haskell
5
star
46

dhallscript

Embedded scripting language in dhall
Haskell
5
star
47

pandoc-sync

Automatic one- and two-way syncing of pandoc sources and renders
Haskell
5
star
48

tic-tac-miso

type-safe tic tac toe with Miso GUI
Haskell
4
star
49

santabot

Source for the freenode ##adventofcode irc bot monitoring Advent of Code
Haskell
4
star
50

type-combinators-singletons

Interop between type-combinators and singletons library
Haskell
4
star
51

dhall-typed

Manipulate typed dhall expressions
Haskell
4
star
52

otp-authenticator

OTP Authenticator (ala Google Authenticator) cli app
Haskell
4
star
53

cluster

Clustering algorithms for fun
Haskell
4
star
54

quotiented

Quotient types in Haskell using smart constructors, associated types, and MPTCs
Haskell
3
star
55

eggvisor

Finds optimal research path for a desired end goal, for the Auxbrain game Egg, Inc.
Haskell
3
star
56

tagged-binary

Provides tools for serializing data tagged with type information
Haskell
3
star
57

auto-chatbot

Chatbot framework over the auto library
Haskell
2
star
58

backpack-tensor

backpack signatures and implements for tensor operations
Haskell
2
star
59

generics-lift

GHC Generics for deriving numeric typeclasses, Monoid, and other similar classes.
Haskell
2
star
60

forms-applicative

playing around with free applicatives/alternatives for validated forms
Haskell
2
star
61

auto-frp

Implementation of the FRP programming model providing the ability to work with real-time semantics using tools from the auto library
Haskell
2
star
62

cv-static

Source for static CV
Dhall
2
star
63

jlebot2

General-purpose chatbot, re-written to use the "auto" library
Haskell
2
star
64

neural-tests

tests and benchmarks for experimental neural networks
Haskell
2
star
65

netwire-experiments

Experiments and learning with the Haskell FRP Library Netwire
Haskell
2
star
66

dashboard

Personal dashboard for my OSS projects
Dhall
2
star
67

advent-of-code-2016

Solutions for Advent of Code 2016 (Spoilers!)
Haskell
2
star
68

corona-analysis

Collection of some simple personal scripts for COVID-19 data analysis
Haskell
2
star
69

dhall-text-shell

dhall text but provide shell commands as function arguments
Haskell
2
star
70

functor-products

Generalized functor products based on lifted foldables
Haskell
2
star
71

memotag

Memoized function application tuples with convenient lens interface
Haskell
1
star
72

expr-gadt

Expression and Lambda Calc type experiments using GADTs for complete type safety
Haskell
1
star
73

typescript-json

Type-safe bidirectional serializers to and from typescript-compatible json
Haskell
1
star
74

jlscript

Object-oriented, statically & duck typed, mixed-purity interpreted scripting language.
Haskell
1
star
75

connection-logger.sh

Short bash script to monitor the host server's internet connection and log latencies/disconnections to stdout.
Shell
1
star
76

hmatrix-sized

hmatrix wrapper with GHC TypeLits-based length-encoded types
Haskell
1
star
77

dmats

Dependently typed compiled programming language for matrix manipulation
Haskell
1
star
78

jlebot

simple irc bot in haskell, for fun
Haskell
1
star
79

traversablet

Instant monad transformers for any Traversable
Haskell
1
star
80

phys108L

Source for "Electromagnetism Physics Labs" that can be done at home with household items
Haskell
1
star
81

vector-algorithms-sized

vector-sized wrapper for vector-algorithms
Haskell
1
star
82

jle-utils

Suite of general utility scripts I use to navigate life
Haskell
1
star
83

pi-monte-carlo

Path Integral Monte Carlo simulation pet project for learning Haskell
Haskell
1
star
84

hackerrank

Hackerrank Fun (for livestream)
Haskell
1
star
85

hmatrix-vector-sized

Conversion between hmatrix and vector-sized types
Haskell
1
star
86

aurum

Fast, lightweight, pull-based FRP
Haskell
1
star
87

Emerge

Project exploring emergent behavior in an environment governed run by natural selection and competition
Ruby
1
star
88

como

Numerical analysis and algorithm platform in Haskell powered by comonads and cokleisli composition.
Haskell
1
star
89

neural

Playing with neural networks in haskell just for fun
Haskell
1
star
90

bff-mono

Fork of https://bitbucket.org/kztk/bff-mono
Haskell
1
star
91

dhall-cv-latex

latex output for dhall-cv project
Dhall
1
star
92

list-witnesses

Inductive dependently-typed witnesses for working with type-level lists.
Haskell
1
star
93

slicer

Haskell
1
star
94

CPSC229-03-WI16-Course-Materials

Course materials (lecture slides, live code records, notes) for CPSC229-03 Functional Programming and Haskell at Chapman University
Haskell
1
star
95

configurator-export

Pretty printer and exporter for configurations from the 'configurator' library
Haskell
1
star
96

cm-dip

Some experiments with comonads for digital image processing. Warning: pretty messy, not really intended for presentation :)
Haskell
1
star