neural network in js with no dependencies and training and backpropagation in javascript

Introduction to Neural Networks in JavaScript

A neural network is a series of algorithms that attempt to recognize underlying relationships in a set of data through a process that mimics the way the human brain operates. In this answer, we will create a basic neural network in JavaScript from scratch with no dependencies.

Neural Network Structure

Our neural network will consist of the following components:

  • Input Layer: This layer receives the input data.
  • Hidden Layer: This layer processes the input data.
  • Output Layer: This layer generates the output.

Implementation

index.tsx
class NeuralNetwork {
  constructor(inputNodes, hiddenNodes, outputNodes) {
    this.inputNodes = inputNodes;
    this.hiddenNodes = hiddenNodes;
    this.outputNodes = outputNodes;

    this.weightsIH = this.initializeWeights(inputNodes, hiddenNodes);
    this.weightsHO = this.initializeWeights(hiddenNodes, outputNodes);

    this.biasH = this.initializeBias(hiddenNodes);
    this.biasO = this.initializeBias(outputNodes);
  }

  initializeWeights(input, output) {
    let weights = [];
    for (let i = 0; i < input; i++) {
      weights[i] = [];
      for (let j = 0; j < output; j++) {
        weights[i][j] = this.randomWeight();
      }
    }
    return weights;
  }

  initializeBias(size) {
    let bias = [];
    for (let i = 0; i < size; i++) {
      bias[i] = this.randomWeight();
    }
    return bias;
  }

  randomWeight() {
    return Math.random() * 2 - 1;
  }

  sigmoid(x) {
    return 1 / (1 + Math.exp(-x));
  }

  forwardPass(inputs) {
    let hidden = [];
    for (let i = 0; i < this.hiddenNodes; i++) {
      let sum = 0;
      for (let j = 0; j < this.inputNodes; j++) {
        sum += inputs[j] * this.weightsIH[j][i];
      }
      sum += this.biasH[i];
      hidden[i] = this.sigmoid(sum);
    }

    let outputs = [];
    for (let i = 0; i < this.outputNodes; i++) {
      let sum = 0;
      for (let j = 0; j < this.hiddenNodes; j++) {
        sum += hidden[j] * this.weightsHO[j][i];
      }
      sum += this.biasO[i];
      outputs[i] = this.sigmoid(sum);
    }

    return outputs;
  }

  train(inputs, targets, learningRate) {
    let hidden = [];
    for (let i = 0; i < this.hiddenNodes; i++) {
      let sum = 0;
      for (let j = 0; j < this.inputNodes; j++) {
        sum += inputs[j] * this.weightsIH[j][i];
      }
      sum += this.biasH[i];
      hidden[i] = this.sigmoid(sum);
    }

    let outputs = [];
    for (let i = 0; i < this.outputNodes; i++) {
      let sum = 0;
      for (let j = 0; j < this.hiddenNodes; j++) {
        sum += hidden[j] * this.weightsHO[j][i];
      }
      sum += this.biasO[i];
      outputs[i] = this.sigmoid(sum);
    }

    let outputErrors = [];
    for (let i = 0; i < this.outputNodes; i++) {
      outputErrors[i] = targets[i] - outputs[i];
    }

    let hiddenErrors = [];
    for (let i = 0; i < this.hiddenNodes; i++) {
      let sum = 0;
      for (let j = 0; j < this.outputNodes; j++) {
        sum += outputErrors[j] * this.weightsHO[i][j];
      }
      hiddenErrors[i] = sum;
    }

    for (let i = 0; i < this.hiddenNodes; i++) {
      for (let j = 0; j < this.outputNodes; j++) {
        this.weightsHO[i][j] += learningRate * outputErrors[j] * hidden[i] * (1 - hidden[i]);
      }
    }

    for (let i = 0; i < this.inputNodes; i++) {
      for (let j = 0; j < this.hiddenNodes; j++) {
        this.weightsIH[i][j] += learningRate * hiddenErrors[j] * inputs[i] * (1 - hidden[j]);
      }
    }

    for (let i = 0; i < this.hiddenNodes; i++) {
      this.biasH[i] += learningRate * hiddenErrors[i];
    }

    for (let i = 0; i < this.outputNodes; i++) {
      this.biasO[i] += learningRate * outputErrors[i];
    }
  }
}

// Example usage:
let nn = new NeuralNetwork(2, 2, 1);
let inputs = [0.5, 0.2];
let targets = [0.8];
nn.train(inputs, targets, 0.1);
let output = nn.forwardPass(inputs);
console.log(output);
3317 chars
129 lines

This code defines a basic neural network with one hidden layer and implements the forward pass and backpropagation for training. You can adjust the number of input, hidden, and output nodes, as well as the learning rate, to suit your specific needs.

Explanation

The code consists of the following parts:

  • The NeuralNetwork class represents the neural network.
  • The initializeWeights and initializeBias methods initialize the weights and biases for the network.
  • The sigmoid method implements the sigmoid activation function.
  • The forwardPass method performs the forward pass through the network.
  • The train method trains the network using backpropagation.

The example usage demonstrates how to create a neural network, train it, and use it to make predictions.

Advice

When working with neural networks, it's essential to:

  • Choose the right activation functions for your problem.
  • Experiment with different architectures and hyperparameters.
  • Regularly monitor your network's performance and adjust as needed.

By following these guidelines, you can successfully implement and train a neural network in JavaScript using this basic example as a starting point.

gistlibby LogSnag