/* object orientation š¤¢ based neural net */
class NeuralNetwork {
constructor(...args) {
[
this.input_nodes, /* input neurons */
this.hidden_nodes, /* hidden neurons */
this.output_nodes /* output neurons */
] = args
this.epochs = 50000
this.activation = sigmoid
this.lr = .5 /* learning rate */
this.output = 0
/* from input to hidden layer */
this.synapse0 = random([this.input_nodes, this.hidden_nodes], -1.0, 1.0)
/* from hidden layer to output */
this.synapse1 = random([this.hidden_nodes, this.output_nodes], -1.0, 1.0)
}
setEpochs(numEpochs) { this.epochs = numEpochs }
setLearningRate(lr) { this.lr = lr }
train(input, target) {
for (let i = 0; i < this.epochs; i++) {
/* foward propagation */
let input_layer = input
let hidden_layer = multiply(input_layer, this.synapse0).map(v => this.activation(v, false))
let output_layer = multiply(hidden_layer, this.synapse1).map(v => this.activation(v, false))
/* backward propagation */
let output_error = subtract(target, output_layer)
let output_delta = dotMultiply(output_error, output_layer.map(v => this.activation(v, true)))
let hidden_error = multiply(output_delta, transpose(this.synapse1))
let hidden_delta = dotMultiply(hidden_error, hidden_layer.map(v => this.activation(v, true)))
/* gradient descent */
this.synapse1 = add(this.synapse1, multiply(transpose(hidden_layer), multiply(output_delta, this.lr)))
this.synapse0 = add(this.synapse0, multiply(transpose(input_layer), multiply(hidden_delta, this.lr)))
this.output = () => output_layer
(i % 10000 === 0) && console.log(`Error: ${ mean(abs(output_error)) }`)
}
}
predict(input) {
let input_layer = input
let hidden_layer = multiply(input_layer, this.synapse0).map(v => this.activation(v, false))
let output_layer = multiply(hidden_layer, this.synapse1).map(v => this.activation(v, false))
return output_layer
}
}