TypeScript: composing neural-network layers behind an interface

Deep-learning libraries describe a network as a stack of layers. Each layer takes a vector and returns a vector, so they can all implement one interface with a forward method. A Sequential network then just feeds the output of each layer to the next.

TypeScript
interface Layer {
  forward(input: number[]): number[];
}

class Dense implements Layer {
  private weights: number[][];
  private biases: number[];

  constructor(weights: number[][], biases: number[]) {
    this.weights = weights;
    this.biases = biases;
  }

  forward(input: number[]): number[] {
    return this.weights.map((row, j) => row.reduce((sum, w, i) => sum + w * input[i], this.biases[j]));
  }
}

class Sigmoid implements Layer {
  forward(input: number[]): number[] {
    return input.map((z) => 1 / (1 + Math.exp(-z)));
  }
}

class Sequential implements Layer {
  private layers: Layer[];

  constructor(layers: Layer[]) {
    this.layers = layers;
  }

  forward(input: number[]): number[] {
    return this.layers.reduce((value, layer) => layer.forward(value), input);
  }
}

const network = new Sequential([
  new Dense([[20, 20], [20, 20]], [-10, -30]),
  new Sigmoid(),
  new Dense([[20, -20]], [-10]),
  new Sigmoid(),
]);

for (const input of [[0, 0], [0, 1], [1, 0], [1, 1]]) {
  console.log(input[0] + " XOR " + input[1] + " = " + network.forward(input)[0].toFixed(3));
}
Read the full lesson