Skip to content

Commit

Permalink
Merge pull request BrainJS#155 from BrainJS/154-testing-times
Browse files Browse the repository at this point in the history
# If applied, this commit will make life better for everyone
  • Loading branch information
freddyC authored Feb 18, 2018
2 parents f0097ee + 1724805 commit 9da27e7
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 217 deletions.
36 changes: 1 addition & 35 deletions test/base/bitwise.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,38 +67,4 @@ describe('bitwise functions sync training', () => {
{input: [1, 1], output: [1]}];
testBitwise(and, 'and');
});
});

describe('bitwise functions async training', () => {

it('NOT function', (done) => {
let not = [{input: [0], output: [1]},
{input: [1], output: [0]}];
testBitwiseAsync(not, 'not', done);
}).timeout(10000);

it('XOR function', (done) => {
let xor = [{input: [0, 0], output: [0]},
{input: [0, 1], output: [1]},
{input: [1, 0], output: [1]},
{input: [1, 1], output: [0]}];
testBitwiseAsync(xor, 'xor', done);
}).timeout(10000);

it('OR function', (done) => {
let or = [{input: [0, 0], output: [0]},
{input: [0, 1], output: [1]},
{input: [1, 0], output: [1]},
{input: [1, 1], output: [1]}];
testBitwiseAsync(or, 'or', done);
}).timeout(10000);

it('AND function', (done) => {
let and = [{input: [0, 0], output: [0]},
{input: [0, 1], output: [0]},
{input: [1, 0], output: [0]},
{input: [1, 1], output: [1]}];
testBitwiseAsync(and, 'and', done);
}).timeout(10000);
});

});
94 changes: 1 addition & 93 deletions test/base/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,96 +80,4 @@ describe('hash input and output', () => {
let output = net.run({x: 1, z: 1});
assert.ok(output.answer > 0.9);
});
});

describe('async hash input and output', () => {
it('runs correctly with array input and output', (done) => {
let net = new brain.NeuralNetwork();
net.trainAsync([
{ input: [0, 0], output: [0] },
{ input: [0, 1], output: [1] },
{ input: [1, 0], output: [1] },
{ input: [1, 1], output: [0] }])
.then(_ => {
let output = net.run([1, 0]);
assert.ok(output[0] > 0.9, 'output: ' + output[0]);
done();
});
}).timeout(15000);

it('runs correctly with hash input', (done) => {
let net = new brain.NeuralNetwork();

net.trainAsync([
{ input: { x: 0, y: 0 }, output: [0] },
{ input: { x: 0, y: 1 }, output: [1] },
{ input: { x: 1, y: 0 }, output: [1] },
{ input: { x: 1, y: 1 }, output: [0] }
])
.then(() => {
let output = net.run({x: 1, y: 0});
assert.ok(output[0] > 0.9, 'output: ' + output[0]);
done();
});
}).timeout(15000);

it('runs correctly with hash output', (done) => {
let net = new brain.NeuralNetwork();
net.trainAsync([
{ input: [0, 0], output: { answer: 0 } },
{ input: [0, 1], output: { answer: 1 } },
{ input: [1, 0], output: { answer: 1 } },
{ input: [1, 1], output: { answer: 0 } }
])
.then(() => {
let output = net.run([1, 0]);
assert.ok(output.answer > 0.9, 'output: ' + output.answer);
done();
});
}).timeout(15000);

it('runs correctly with hash input and output', (done) => {
let net = new brain.NeuralNetwork();
net.trainAsync([
{ input: { x: 0, y: 0 }, output: { answer: 0 } },
{ input: { x: 0, y: 1 }, output: { answer: 1 } },
{ input: { x: 1, y: 0 }, output: { answer: 1 } },
{ input: { x: 1, y: 1 }, output: { answer: 0 } }
])
.then(() => {
let output = net.run({x: 1, y: 0});
assert.ok(output.answer > 0.9, 'output: ' + output.answer);
done();
});
}).timeout(15000);

it('runs correctly with sparse hashes', (done) => {
let net = new brain.NeuralNetwork();
net.trainAsync ([
{ input: {}, output: {} },
{ input: { y: 1 }, output: { answer: 1 } },
{ input: { x: 1 }, output: { answer: 1 } },
{ input: { x: 1, y: 1 }, output: {} }
])
.then(() => {
let output = net.run({x: 1});
assert.ok(output.answer > 0.9);
done();
});
}).timeout(15000);

it('runs correctly with unseen input', (done) => {
let net = new brain.NeuralNetwork();
net.trainAsync ([
{ input: {}, output: {} },
{ input: { y: 1 }, output: { answer: 1 } },
{ input: { x: 1 }, output: { answer: 1 } },
{ input: { x: 1, y: 1 }, output: {} }
])
.then(() => {
let output = net.run({x: 1, z: 1});
assert.ok(output.answer > 0.9);
done();
});
}).timeout(15000);
});
});
3 changes: 0 additions & 3 deletions test/base/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,4 @@ describe('log', () => {

it('should call log method', () => { trainWithLog(logFunction, true); });
it('should not call log method', () => { trainWithLog(false, false); });

it('ASYNC should call log method', done => { trainWithLogAsync(logFunction, true, done); }).timeout(5000);
it('ASYNC should not call log method', done => { trainWithLogAsync(false, false, done); }).timeout(5000);
});
166 changes: 80 additions & 86 deletions test/base/trainopts.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import assert from 'assert';
import brain from '../../src';
import sinon from 'sinon'

let data = [{input: [0, 0], output: [0]},
{input: [0, 1], output: [1]},
Expand Down Expand Up @@ -74,102 +75,95 @@ describe('train() options', () => {
});
});


describe('async train() options', () => {
it('train until error threshold reached', (done) => {
let net = new brain.NeuralNetwork();
let p1 = net
.trainAsync(data, { errorThresh: 0.2 })
.then (res => {
assert.ok(res.error < 0.2, `[res.error, ${res.error}] should have been less then 0.2`);
describe('train() and trainAsync() use the same private methods', () => {
let trainingData = [{ input: [0, 0], output: [0] }];
let opts = { iterations:1 };
let net = new brain.NeuralNetwork();
let methodsChecked = [
'_prepTraining',
'_updateTrainingOptions',
'_formatData',
'_verifyIsInitialized',
'_trainingTick'
];

beforeEach(() => { methodsChecked.forEach(m => sinon.spy(net, m)); })
afterEach(() => { methodsChecked.forEach(m => net[m].restore()); })

it('_prepTraining()', (done) => {
net.train(trainingData, opts);
assert(net._prepTraining.calledOnce, `_prepTraining was expected to be called once but was called ${net._prepTraining.callCount}`);
net
.trainAsync(trainingData, opts)
.then(() => {
assert(net._prepTraining.calledTwice, `_prepTraining was expected to be called twice but was called ${net._prepTraining.callCount}`);
done();
})
.catch(err => { assert.ok(false, err.toString()) });
}).timeout(10000);
.catch(e => {
assert.ok(false, e.toString());
done()
});
});

it('train until max iterations reached', (done) => {
let net = new brain.NeuralNetwork();
let res = net
.trainAsync(data, { iterations: 25 })
.then(res => {
assert.equal(res.iterations, 25, `[res.iterations, ${res.iterations}] should have been less then 25`);
it('_updateTrainingOptions()', (done) => {
net.train(trainingData, opts);
assert(net._updateTrainingOptions.calledOnce, `_updateTrainingOptions was expected to be called once but was called ${net._updateTrainingOptions.callCount}`);
net
.trainAsync(trainingData, opts)
.then(() => {
assert(net._updateTrainingOptions.calledTwice, `_updateTrainingOptions was expected to be called twice but was called ${net._prepTraining.callCount}`);
done();
})
.catch(err => { assert.ok(false, err.toString()) });
}).timeout(10000);

it('asyinc training callback called with training stats', (done) => {
let iters = 100;
let period = 20;
let target = iters / period;

let calls = 0;

let net = new brain.NeuralNetwork();
net.trainAsync(data, {
iterations: iters,
callbackPeriod: period,
callback: (res) => {
assert.ok(res.iterations % period == 0);
calls++;
}
})
.then (res => {
assert.ok(target === calls, `[calls, ${calls}] should be the same as [target, ${target}]`);
done();
})
.catch(err => { assert.ok(false, err.toString()) });
}).timeout(10000);

it('learningRate ASYNC - higher learning rate should train faster', (done) => {
let data = [
{ input: [0, 0], output: [0] },
{ input: [0, 1], output: [1] },
{ input: [1, 0], output: [1] },
{ input: [1, 1], output: [1] }
];

let net = new brain.NeuralNetwork();
let net2 = new brain.NeuralNetwork();

let p1 = net.trainAsync(data, { learningRate: 0.5 });
let p2 = net2.trainAsync(data, { learningRate: 0.8 });
.catch(e => {
assert.ok(false, e.toString());
done()
});
});

Promise
.all([p1, p2])
.then(values => {
let res = values[0];
let res2 = values[1];
assert.ok(res.iterations > (res2.iterations * 1.1), `${res.iterations} !> ${res2.iterations * 1.1}`);
it('_formatData()', (done) => {
net.train(trainingData, opts);
assert(net._formatData.calledOnce, `_formatData was expected to be called once but was called ${net._formatData.callCount}`);
net
.trainAsync(trainingData, opts)
.then(() => {
assert(net._formatData.calledTwice, `_formatData was expected to be called twice but was called ${net._prepTraining.callCount}`);
done();
})
.catch(err => {
assert.ok(false, err.toString())
.catch(e => {
assert.ok(false, e.toString());
done()
});
}).timeout(10000);

it('momentum ASYNC - higher momentum should train faster', (done) => {
let data = [
{ input: [0, 0], output: [0] },
{ input: [0, 1], output: [1] },
{ input: [1, 0], output: [1] },
{ input: [1, 1], output: [1] }
];

let net = new brain.NeuralNetwork({ momentum: 0.1 });
let net2 = new brain.NeuralNetwork({ momentum: 0.5 });
});

let p1 = net.trainAsync(data);
let p2 = net2.trainAsync(data);
it('_verifyIsInitialized()', (done) => {
net.train(trainingData, opts);
assert(net._verifyIsInitialized.calledOnce, `_verifyIsInitialized was expected to be called once but was called ${net._verifyIsInitialized.callCount}`);
net
.trainAsync(trainingData, opts)
.then(() => {
assert(net._verifyIsInitialized.calledTwice, `_verifyIsInitialized was expected to be called twice but was called ${net._prepTraining.callCount}`);
done();
})
.catch(e => {
assert.ok(false, e.toString());
done()
});
});

Promise.all([p1, p2])
.then(values => {
let res = values[0];
let res2 = values[1];
assert.ok(res.iterations > (res2.iterations * 1.1), `${res.iterations} !> ${res2.iterations * 1.1}`);
it('_trainingTick()', (done) => {
net.train(trainingData, opts);
// The loop calls _trainingTick twice and returns imidiatly on second call
assert(net._trainingTick.calledTwice, `_trainingTick was expected to be called twice but was called ${net._prepTraining.callCount}`);
net
.trainAsync(trainingData, opts)
.then(() => {
// trainAsync only calls _trainingTick once
assert(net._trainingTick.calledThrice, `_trainingTick was expected to be called thrice but was called ${net._prepTraining.callCount}`);
done();
}).catch(err => {
assert.ok(false, err.toString())
})
.catch(e => {
assert.ok(false, e.toString());
done()
});
}).timeout(10000);
});
});
});

0 comments on commit 9da27e7

Please sign in to comment.