casualjavascript / blog

A collection of javascript articles stored as Github issues.
https://casualjavascript.com
MIT License
34 stars 1 forks source link

A tiny neural network #9

Open mateogianolio opened 8 years ago

mateogianolio commented 8 years ago

The code in this post is functionally equivalent to A Neural Network in 11 lines of Python. The JavaScript translation was originally written by @lucidrains.

Vectorious is an open-source linear algebra library which I am currently maintaining. We'll use it as a replacement for Python's numpy.

This is the source presented at the top of the Python article:

X = np.array([[0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]])
y = np.array([[0, 1, 1, 0]]).T
syn0 = 2 * np.random.random((3, 4)) - 1
syn1 = 2 * np.random.random((4, 1)) - 1
for j in xrange(60000):
    l1 = 1 / (1 + np.exp(-(np.dot(X, syn0))))
    l2 = 1 / (1 + np.exp(-(np.dot(l1, syn1))))
    l2_delta = (y - l2) * (l2 * (1 - l2))
    l1_delta = l2_delta.dot(syn1.T) * (l1 * (1 - l1))
    syn1 += l1.T.dot(l2_delta)
    syn0 += X.T.dot(l1_delta)

Below is the JavaScript translation. To make it a bit more readable I extracted the sigmoid function and its derivative, which can be mapped to the elements of a matrix using matrix.map(fn).

function sigmoid(ddx) {
  return function (x) {
    return ddx ?
      x * (1 - x) :
      1.0 / (1 + Math.exp(-x));
  };
}

var X = new Matrix([[0, 0, 1], [0, 1, 1], [1, 0, 1], [1, 1, 1]]),
    y = new Matrix([[0, 1, 1, 0]]).T,
    syn0 = Matrix.random(3, 4, 2, -1),
    syn1 = Matrix.random(4, 1, 2, -1),
    l1, l2, l1_delta, l2_delta, i;
for (i = 0; i < 60000; i++) {
  l1 = X.multiply(syn0).map(sigmoid());
  l2 = l1.multiply(syn1).map(sigmoid());
  l2_delta = Matrix.subtract(y, l2).product(l2.map(sigmoid(true)));
  l1_delta = l2_delta.multiply(syn1.T).product(l1.map(sigmoid(true)));
  syn1.add(l1.T.multiply(l2_delta));
  syn0.add(X.T.multiply(l1_delta));
}

Almost the same and above code can be used both in Node.js and the browser! The final prediction is in the l2 variable and should be close to y.

Here is the full example with comments.