lib/NeuralNetwork/NeuralNetwork.test.js
import assert from 'assert';
import { arraysDeepEqual, Matrix } from 'stones';
import { NeuralNetwork } from './NeuralNetwork';
describe('A NeuralNetwork Class', () => {
const networkWithEqualWeights = (inputNodes, hiddenNodes, outputNodes, weight = 1) => {
let network = new NeuralNetwork(inputNodes ,hiddenNodes, outputNodes, 0.1);
network.inputToHiddenMatrix = network.inputToHiddenMatrix.map(() => weight);
network.hiddenToOutputMatrix = network.hiddenToOutputMatrix.map(() => weight);
return network;
}
describe('#constructor()', () => {
it('should throw an error if there is a missing argument', () => {
let testPassed = false;
try {
//Missing final argument
let neuralNetwork = new NeuralNetwork(1,2,3);
} catch(e) {
testPassed = true;
}
assert(testPassed);
})
it('should initialize random values for inputToHiddenMatrix property', () => {
const warning = "This test has a chance of systematically failing. Please run again in the case of failure";
let matrixA = new NeuralNetwork(4,3,2,0.1).inputToHiddenMatrix;
let matrixB = new NeuralNetwork(4,3,2,0.1).inputToHiddenMatrix;
assert(arraysDeepEqual(matrixA, matrixB), warning);
})
it('should initialize random values for hiddenToOutputMatrix property', () => {
const warning = "This test has a chance of systematically failing. Please run again in the case of failure";
let matrixA = new NeuralNetwork(4,3,2,0.1).hiddenToOutputMatrix;
let matrixB = new NeuralNetwork(4,3,2,0.1).hiddenToOutputMatrix;
assert(arraysDeepEqual(matrixA, matrixB), warning);
})
});
describe('#copy()', () => {
it('should return a NeuralNetwork', () => {
const network = new NeuralNetwork(4,3,2,0.1);
assert(network.copy() instanceof NeuralNetwork);
})
it('should return a new NeuralNetwork with the same properties', () => {
const network = new NeuralNetwork(4,3,2,0.1);
const networkCopy = network.copy();
const networksAreDifferent = network != networkCopy;
const propertiesAreTheSame = network.inputNodes == networkCopy.inputNodes &&
network.hiddenNodes == networkCopy.hiddenNodes &&
network.outputNodes == networkCopy.outputNodes &&
network.learningRate == networkCopy.learningRate &&
arraysDeepEqual(network.inputToHiddenMatrix, networkCopy.inputToHiddenMatrix) &&
arraysDeepEqual(network.hiddenToOutputMatrix, networkCopy.hiddenToOutputMatrix);
assert(networksAreDifferent && propertiesAreTheSame);
})
})
describe('#train()', () => {
const inputA = [1,2,3,4,5,6];
const targetA = [0,0,0,0,0,1];
it('should alter weights based on the inputs', () => {
let neuralNetwork = new NeuralNetwork(6,4,6,0.1);
const inputToHidden = neuralNetwork.copy().inputToHiddenMatrix.matrix;
const hiddenToOutput = neuralNetwork.copy().hiddenToOutputMatrix.matrix;
neuralNetwork.train(inputA, targetA);
assert(!arraysDeepEqual(inputToHidden, neuralNetwork.inputToHiddenMatrix.matrix) &&
!arraysDeepEqual(hiddenToOutput, neuralNetwork.hiddenToOutputMatrix.matrix))
})
it('should return an object with the property "errors"', () => {
let neuralNetwork = new NeuralNetwork(6,2,6,0.1);
assert(neuralNetwork.train(inputA,targetA).errors);
})
it('should return an object with the property "hiddenErrors"', () => {
let neuralNetwork = new NeuralNetwork(6,2,6,0.1);
assert(neuralNetwork.train(inputA,targetA).hiddenErrors);
})
})
describe('#eval()', () => {
const neuralNetwork = networkWithEqualWeights(2,2,3);
const inputArr = [1,2];
const result = neuralNetwork.eval(inputArr);
const expectedOutputMatrix = [
[ 0.8704730975500355 ],
[ 0.8704730975500355 ],
[ 0.8704730975500355 ],
];
it('should return an object', () => {
assert(result instanceof Object);
})
it('should include an inputMatrix matrix as a property in the returned object', () => {
assert(result.inputMatrix instanceof Matrix);
})
it('should include an hiddenOutputMatrix matrix as a property in the returned object', () => {
assert(result.hiddenOutputMatrix instanceof Matrix);
})
it('should include an outputMatrix matrix as a property in the returned object', () => {
assert(result.outputMatrix instanceof Matrix);
})
it('should return the expected output given weights in the network', () => {
assert(arraysDeepEqual(result.outputMatrix.matrix, expectedOutputMatrix));
})
})
})