nn.el is a zero dependancy emacs lisp library to build and train
neural networks.
Firstly clone the directory, and then run make to build the emacs
modules matrix.c and ops.c. Then add the directory to your load
path with something like
(add-to-list 'load-path "~/where/you/cloned")Below is an example on how to train a (relatively large) neural network on some randomly generated data
(require 'nn)
(require 'matrix)
(require 'ops)
(setq model `(,(nn-layer 100 80 'ops-relu)
,(nn-layer 80 10 'ops-relu)
,(nn-layer 10 8 'ops-relu)
,(nn-layer 8 3)))
(setq x (matrix-random 100 2))
(setq y (matrix-transpose (vconcat [[1 0 0]] [[0 0 1]])))
(let* ((s (ops-softmax (nn-forward-layers x model)))
(loss (nn-crossentropy y s)))
(message "Initial loss: %s" loss))
(defun nn--apply-gradient-sgd-layer (grad layer)
"Apply GRAD to LAyER using gradient descent"
(let ((w (nth 0 layer))
(b (nth 1 layer))
(wg (nth 0 grad))
(bg (nth 1 grad)))
(setf (nth 0 layer) (matrix-subtract w (matrix-scalar-mul 0.01 wg)))
(setf (nth 1 layer) (matrix-subtract b (matrix-scalar-mul 0.01 bg)))))
(dotimes (counter 100)
;; this is the train step; essentially just do this as many times
(let ((grads (nn-gradient x y model)))
(seq-mapn #'nn--apply-gradient-sgd-layer grads model)))
(let* ((s (ops-softmax (nn-forward-layers x model)))
(loss (nn-crossentropy y s)))
(message "after training loss: %s" loss))