🤖 GPU accelerated Neural networks in JavaScript for Browsers and Node.js

Overview

Logo

brain.js

GPU accelerated Neural networks in JavaScript for Browsers and Node.js

GitHub npm js-standard-style Backers on Open Collective Sponsors on Open Collective Gitter Slack CI codecov Twitter

NPM

About

brain.js is a GPU accelerated library for Neural Networks written in JavaScript.

💡 This is a continuation of the harthur/brain, which is not maintained anymore. More info

Table of Contents

Installation and Usage

NPM

If you can install brain.js with npm:

npm install brain.js

CDN

<script src="//unpkg.com/brain.js"></script>

Download

Download the latest brain.js for browser

Installation note

Brain.js depends on a native module headless-gl for gpu support. In most cases installing brain.js from npm should just work. However, if you run into problems, this mean prebuilt binaries are not able to download from github repositories and you might need to build it yourself.

Building from source

Please make sure the following dependencies are installed and up to date and then run:

npm rebuild
System dependencies
Mac OS X
Ubuntu/Debian
sudo apt-get install -y build-essential libxi-dev libglu1-mesa-dev libglew-dev pkg-config
Windows

* If you are using Build Tools 2017 then run npm config set msvs_version 2017

Examples

Here's an example showcasing how to approximate the XOR function using brain.js: more info on config here.

💡 A fun and practical introduction to Brain.js

// provide optional config object (or undefined). Defaults shown.
const config = {
  binaryThresh: 0.5,
  hiddenLayers: [3], // array of ints for the sizes of the hidden layers in the network
  activation: 'sigmoid', // supported activation types: ['sigmoid', 'relu', 'leaky-relu', 'tanh'],
  leakyReluAlpha: 0.01, // supported for activation type 'leaky-relu'
};

// create a simple feed forward neural network with backpropagation
const net = new brain.NeuralNetwork(config);

net.train([
  { input: [0, 0], output: [0] },
  { input: [0, 1], output: [1] },
  { input: [1, 0], output: [1] },
  { input: [1, 1], output: [0] },
]);

const output = net.run([1, 0]); // [0.987]

or more info on config here.

// provide optional config object, defaults shown.
const config = {
  inputSize: 20,
  inputRange: 20,
  hiddenLayers: [20, 20],
  outputSize: 20,
  learningRate: 0.01,
  decayRate: 0.999,
};

// create a simple recurrent neural network
const net = new brain.recurrent.RNN(config);

net.train([
  { input: [0, 0], output: [0] },
  { input: [0, 1], output: [1] },
  { input: [1, 0], output: [1] },
  { input: [1, 1], output: [0] },
]);

const output = net.run([0, 0]); // [0]
output = net.run([0, 1]); // [1]
output = net.run([1, 0]); // [1]
output = net.run([1, 1]); // [0]

However, there is no reason to use a neural network to figure out XOR. (-: So, here is a more involved, realistic example: Demo: training a neural network to recognize color contrast.

More Examples

You can check out this fantastic screencast, which explains how to train a simple neural network using a real world dataset: How to create a neural network in the browser using Brain.js.

Training

Use train() to train the network with an array of training data. The network has to be trained with all the data in bulk in one call to train(). More training patterns will probably take longer to train, but will usually result in a network better at classifying new patterns.

Note

Training is computationally expensive, so you should try to train the network offline (or on a Worker) and use the toFunction() or toJSON() options to plug the pre-trained network into your website.

Data format

For training with NeuralNetwork

Each training pattern should have an input and an output, both of which can be either an array of numbers from 0 to 1 or a hash of numbers from 0 to 1. For the color contrast demo it looks something like this:

const net = new brain.NeuralNetwork();

net.train([
  { input: { r: 0.03, g: 0.7, b: 0.5 }, output: { black: 1 } },
  { input: { r: 0.16, g: 0.09, b: 0.2 }, output: { white: 1 } },
  { input: { r: 0.5, g: 0.5, b: 1.0 }, output: { white: 1 } },
]);

const output = net.run({ r: 1, g: 0.4, b: 0 }); // { white: 0.99, black: 0.002 }

Here's another variation of the above example. (Note that input objects do not need to be similar.)

net.train([
  { input: { r: 0.03, g: 0.7 }, output: { black: 1 } },
  { input: { r: 0.16, b: 0.2 }, output: { white: 1 } },
  { input: { r: 0.5, g: 0.5, b: 1.0 }, output: { white: 1 } },
]);

const output = net.run({ r: 1, g: 0.4, b: 0 }); // { white: 0.81, black: 0.18 }

For training with RNNTimeStep, LSTMTimeStep and GRUTimeStep

Each training pattern can either:

  • Be an array of numbers
  • Be an array of arrays of numbers

Example using an array of numbers:

const net = new brain.recurrent.LSTMTimeStep();

net.train([[1, 2, 3]]);

const output = net.run([1, 2]); // 3

Example using an array of arrays of numbers:

const net = new brain.recurrent.LSTMTimeStep({
  inputSize: 2,
  hiddenLayers: [10],
  outputSize: 2,
});

net.train([
  [1, 3],
  [2, 2],
  [3, 1],
]);

const output = net.run([
  [1, 3],
  [2, 2],
]); // [3, 1]

For training with RNN, LSTM and GRU

Each training pattern can either:

  • Be an array of values
  • Be a string
  • Have an input and an output
    • Either of which can have an array of values or a string

CAUTION: When using an array of values, you can use ANY value, however, the values are represented in the neural network by a single input. So the more distinct values has the larger your input layer. If you have a hundreds, thousands, or millions of floating point values THIS IS NOT THE RIGHT CLASS FOR THE JOB. Also, when deviating from strings, this gets into beta

Example using direct strings: Hello World Using Brainjs

  const net = new brain.recurrent.LSTM();

  net.train(['I am brainjs, Hello World!']);

  const output = net.run('I am brainjs');
  alert(output);
const net = new brain.recurrent.LSTM();

net.train([
  'doe, a deer, a female deer',
  'ray, a drop of golden sun',
  'me, a name I call myself',
]);

const output = net.run('doe'); // ', a deer, a female deer'

Example using strings with inputs and outputs:

const net = new brain.recurrent.LSTM();

net.train([
  { input: 'I feel great about the world!', output: 'happy' },
  { input: 'The world is a terrible place!', output: 'sad' },
]);

const output = net.run('I feel great about the world!'); // 'happy'

Training Options

train() takes a hash of options as its second argument:

net.train(data, {
  // Defaults values --> expected validation
  iterations: 20000, // the maximum times to iterate the training data --> number greater than 0
  errorThresh: 0.005, // the acceptable error percentage from training data --> number between 0 and 1
  log: false, // true to use console.log, when a function is supplied it is used --> Either true or a function
  logPeriod: 10, // iterations between logging out --> number greater than 0
  learningRate: 0.3, // scales with delta to effect training rate --> number between 0 and 1
  momentum: 0.1, // scales with next layer's change value --> number between 0 and 1
  callback: null, // a periodic call back that can be triggered while training --> null or function
  callbackPeriod: 10, // the number of iterations through the training data between callback calls --> number greater than 0
  timeout: Infinity, // the max number of milliseconds to train for --> number greater than 0
});

The network will stop training whenever one of the two criteria is met: the training error has gone below the threshold (default 0.005), or the max number of iterations (default 20000) has been reached.

By default training will not let you know how it's doing until the end, but set log to true to get periodic updates on the current training error of the network. The training error should decrease every time. The updates will be printed to console. If you set log to a function, this function will be called with the updates instead of printing to the console. However, if you want to use the values of the updates in your own output, the callback can be set to a function to do so instead.

The learning rate is a parameter that influences how quickly the network trains. It's a number from 0 to 1. If the learning rate is close to 0, it will take longer to train. If the learning rate is closer to 1, it will train faster, but training results may be constrained to a local minimum and perform badly on new data.(Overfitting) The default learning rate is 0.3.

The momentum is similar to learning rate, expecting a value from 0 to 1 as well, but it is multiplied against the next level's change value. The default value is 0.1

Any of these training options can be passed into the constructor or passed into the updateTrainingOptions(opts) method and they will be saved on the network and used during the training time. If you save your network to json, these training options are saved and restored as well (except for callback and log, callback will be forgotten and log will be restored using console.log).

A boolean property called invalidTrainOptsShouldThrow is set to true by default. While the option is true, if you enter a training option that is outside the normal range, an error will be thrown with a message about the abnormal option. When the option is set to false, no error will be sent, but a message will still be sent to console.warn with the related information.

Async Training

trainAsync() takes the same arguments as train (data and options). Instead of returning the results object from training, it returns a promise that when resolved will return the training results object.

const net = new brain.NeuralNetwork();
net
  .trainAsync(data, options)
  .then((res) => {
    // do something with my trained network
  })
  .catch(handleError);

With multiple networks you can train in parallel like this:

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

const p1 = net.trainAsync(data, options);
const p2 = net2.trainAsync(data, options);

Promise.all([p1, p2])
  .then((values) => {
    const res = values[0];
    const res2 = values[1];
    console.log(
      `net trained in ${res.iterations} and net2 trained in ${res2.iterations}`
    );
    // do something super cool with my 2 trained networks
  })
  .catch(handleError);

Cross Validation

Cross Validation can provide a less fragile way of training on larger data sets. The brain.js api provides Cross Validation in this example:

const crossValidate = new brain.CrossValidate(
  brain.NeuralNetwork,
  networkOptions
);
crossValidate.train(data, trainingOptions, k); //note k (or KFolds) is optional
const json = crossValidate.toJSON(); // all stats in json as well as neural networks
const net = crossValidate.toNeuralNetwork(); // get top performing net out of `crossValidate`

// optionally later
const json = crossValidate.toJSON();
const net = crossValidate.fromJSON(json);

Use CrossValidate with these classes:

  • brain.NeuralNetwork
  • brain.RNNTimeStep
  • brain.LSTMTimeStep
  • brain.GRUTimeStep

An example of using cross validate can be found in examples/javascript/cross-validate.js

Train Stream

Streams are a very powerful tool in node for massive data spread across processes and are provided via the brain.js api in the following way:

const net = new brain.NeuralNetwork();
const trainStream = new brain.TrainStream({
  neuralNetwork: net,
  floodCallback: function () {
    flood(trainStream, data);
  },
  doneTrainingCallback: function (stats) {
    // network is done training!  What next?
  },
});

// kick it off
readInputs(trainStream, data);

function readInputs(stream, data) {
  for (let i = 0; i < data.length; i++) {
    stream.write(data[i]);
  }
  // let it know we've reached the end of the inputs
  stream.endInputs();
}

An example of using train stream can be found in examples/javascript/stream-example.js

Methods

train(trainingData) -> trainingStatus

The output of train() is a hash of information about how the training went:

{
  error: 0.0039139985510105032,  // training error
  iterations: 406                // training iterations
}

run(input) -> prediction

Supported on classes:

  • brain.NeuralNetwork
  • brain.NeuralNetworkGPU -> All the functionality of brain.NeuralNetwork but, ran on GPU (via gpu.js in WebGL2, WebGL1, or fallback to CPU)
  • brain.recurrent.RNN
  • brain.recurrent.LSTM
  • brain.recurrent.GRU
  • brain.recurrent.RNNTimeStep
  • brain.recurrent.LSTMTimeStep
  • brain.recurrent.GRUTimeStep

Example:

// feed forward
const net = new brain.NeuralNetwork();
net.fromJSON(json);
net.run(input);

// time step
const net = new brain.LSTMTimeStep();
net.fromJSON(json);
net.run(input);

// recurrent
const net = new brain.LSTM();
net.fromJSON(json);
net.run(input);

forecast(input, count) -> predictions

Available with the following classes. Outputs a array of predictions. Predictions being a continuation of the inputs.

  • brain.recurrent.RNNTimeStep
  • brain.recurrent.LSTMTimeStep
  • brain.recurrent.GRUTimeStep

Example:

const net = new brain.LSTMTimeStep();
net.fromJSON(json);
net.forecast(input, 3);

toJSON() -> json

Serialize neural network to json

fromJSON(json)

Deserialize neural network from json

Failing

If the network failed to train, the error will be above the error threshold. This could happen if the training data is too noisy (most likely), the network does not have enough hidden layers or nodes to handle the complexity of the data, or it has not been trained for enough iterations.

If the training error is still something huge like 0.4 after 20000 iterations, it's a good sign that the network can't make sense of the given data.

RNN, LSTM, or GRU Output too short or too long

The instance of the net's property maxPredictionLength (default 100) can be set to adjust the output of the net;

Example:

const net = new brain.recurrent.LSTM();

// later in code, after training on a few novels, write me a new one!
net.maxPredictionLength = 1000000000; // Be careful!
net.run('Once upon a time');

JSON

Serialize or load in the state of a trained network with JSON:

const json = net.toJSON();
net.fromJSON(json);

Standalone Function

You can also get a custom standalone function from a trained network that acts just like run():

const run = net.toFunction();
const output = run({ r: 1, g: 0.4, b: 0 });
console.log(run.toString()); // copy and paste! no need to import brain.js

Options

NeuralNetwork() takes a hash of options:

const net = new brain.NeuralNetwork({
  activation: 'sigmoid', // activation function
  hiddenLayers: [4],
  learningRate: 0.6, // global learning rate, useful when training using streams
});

activation

This parameter lets you specify which activation function your neural network should use. There are currently four supported activation functions, sigmoid being the default:

Here's a table (thanks, Wikipedia!) summarizing a plethora of activation functions — Activation Function

hiddenLayers

You can use this to specify the number of hidden layers in the network and the size of each layer. For example, if you want two hidden layers - the first with 3 nodes and the second with 4 nodes, you'd give:

hiddenLayers: [3, 4];

By default brain.js uses one hidden layer with size proportionate to the size of the input array.

Streams

The network now has a WriteStream. You can train the network by using pipe() to send the training data to the network.

Example

Refer to stream-example.js for an example on how to train the network with a stream.

Initialization

To train the network using a stream you must first create the stream by calling net.createTrainStream() which takes the following options:

  • floodCallback() - the callback function to re-populate the stream. This gets called on every training iteration.
  • doneTrainingCallback(info) - the callback function to execute when the network is done training. The info param will contain a hash of information about how the training went:
{
  error: 0.0039139985510105032,  // training error
  iterations: 406                // training iterations
}

Transform

Use a Transform to coerce the data into the correct format. You might also use a Transform stream to normalize your data on the fly.

Utilities

likely

const likely = require('brain/likely');
const key = likely(input, net);

Likely example see: simple letter detection

toSVG

<script src="../../src/utilities/svg.js"></script>

Renders the network topology of a feedforward network

document.getElementById('result').innerHTML = brain.utilities.toSVG(
  network,
  options
);

toSVG example see: network rendering

The user interface used: screenshot1

Neural Network Types

Why different Neural Network Types

Different neural nets do different things well. For example:

  • A Feedforward Neural Network can classify simple things very well, but it has no memory of previous actions and has infinite variation of results.
  • A Time Step Recurrent Neural Network remembers, and can predict future values.
  • A Recurrent Neural Network remembers, and has a finite set of results.

Get Involved

W3C machine learning standardization process

If you are a developer or if you just care about how ML API should look like - please take a part and join W3C community and share your opinions or simply support opinions you like or agree with.

Brain.js is a widely adopted open source machine learning library in the javascript world. There are several reasons for it, but most notable is simplicity of usage while not sacrificing performance. We would like to keep it also simple to learn, simple to use and performant when it comes to W3C standard. We think that current brain.js API is quite close to what we could expect to become a standard. And since supporting doesn't require much effort and still can make a hudge difference feel free to join W3C community group and support us with brain.js like API.

Get involved into W3C machine learning ongoing standardization proces here. You can also join our open discussion about standardization here.

Issues

If you have an issue, either a bug or a feature you think would benefit your project let us know and we will do our best.

Create issues here and follow the template.

brain.js.org

Source for brain.js.org is available at Brain.js.org Repository. Built using awesome vue.js & bulma. Contributions are always welcome.

Contributors

This project exists thanks to all the people who contribute. [Contribute].

Backers

Thank you to all our backers! 🙏 [Become a backer]

Sponsors

Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [Become a sponsor]

Comments
  • Migrate to TypeScript

    Migrate to TypeScript

    We plan to gradually migrate brain.js to TypeScript, code base is pretty large, so we would love your help! 💪

    How to contribute?

    • Convert a file from .js to .ts
    • Add types, fix all type errors.
    • Submit a PR! 🎉

    Here you can find a guide on how to contribute.

    Want to convert something, let us know in the comment and go ahead! 😎

    To avoid duplicate work please comment on which part you want to work on (as long as nobody else is working on it) so we can mark it as taken.

    Reach out to us! Feel free to reach if you have questions or need help getting started. You can leave comments here or you can tag me in your PR if you need any help or you're not sure about something!

    You can also get in touch on our Gitter & Slack.

    Happy Coding! 🤟


    UPDATE:

    Wohoooo!!! 🎉

    All files inside src directory are migrated to typescript. (Except few ones which are already taken up and being worked on), though we are still looking on improvements to types in these files and removing any types from the source. You are welcome to contribute. 😊

    __tests__ directory has still some files left that needs migration to typescript, so feel free to pick em up! 🍭


    UPDATE

    For anyone looking to contribute, here is the list of files that still needs typescript migration:

    https://github.com/BrainJS/brain.js/search?l=javascript&p=1

    enhancement help wanted good first issue hacktoberfest 
    opened by mubaidr 136
  • NodeJS GPU Acceleration

    NodeJS GPU Acceleration

    A GIF or MEME to give some spice of the internet

    What is wrong?

    Nothing, i'm just really psyched about NodeJS GPU acceleration. Gpu.js V2 is in pre-release (https://github.com/gpujs/gpu.js/releases/tag/2.0.0-rc.1), we must wait a official release before expect a BrainJS release where use (in NodeJS) brain.NeuralNetworkGPU ?

    How important is this (1-5)?

    5

    Other Comments

    You're grait guys 👍

    enhancement 
    opened by AndreaFranchini 56
  • LSTM examples?

    LSTM examples?

    Following on the other issue I created #108 , I'm trying to teach an LSTM network to write a simple children's book. I'm getting odd behavior but really don't know what I'm doing to begin with. I'd love to get this example working and added to the readme for others to follow but am hitting lots of little roadblocks. Here's my code:

    const brain = require('brain.js');
    
    const words = new Map();
    words.set('00001', 'Jane');
    words.set('00010', 'Spot');
    words.set('00100', 'Doug');
    words.set('01000', 'saw');
    words.set('10000', '.');
    
    const trainingData = [
      {input: [0,0,0,0,1], output: [0,1,0,0,0]},// Jane -> saw
      {input: [0,0,0,1,0], output: [0,1,0,0,0]},// Spot -> saw
      {input: [0,0,1,0,0], output: [0,1,0,0,0]},// Doug -> saw
      {input: [0,1,0,0,0], output: [0,0,1,0,0]},// saw -> Doug
      {input: [0,1,0,0,0], output: [0,0,0,1,0]},// saw -> Spot
      {input: [0,1,0,0,0], output: [0,0,0,0,1]},// saw -> Jane
      {input: [0,0,0,1,0], output: [1,0,0,0,0]},// Spot -> .
      {input: [0,0,0,0,1], output: [1,0,0,0,0]},// Jane -> .
      {input: [0,0,1,0,0], output: [1,0,0,0,0]},// Doug -> .
      {input: [1,0,0,0,0], output: [0,0,0,0,1]},// . -> Jane
      {input: [1,0,0,0,0], output: [0,0,0,1,0]},// . -> Spot
      {input: [1,0,0,0,0], output: [0,0,1,0,0]},// . -> Doug
    ];
    
    const lstm = new brain.recurrent.LSTM();
    const result = lstm.train(trainingData);
    const run1 = lstm.run([0,0,0,0,1]);// Jane
    const run2 = lstm.run(run1);
    const run3 = lstm.run(run2);
    const run4 = lstm.run(run3);
    
    console.log(words.get('00001'));// start with 'Jane'
    console.log(words.get(run1));// saw
    console.log(words.get(run2));// Jane, Doug or Spot
    console.log(words.get(run3));// .
    console.log(words.get(run4));// Jane, Doug or Spot
    
    console.log('run 1:', run1, typeof run1);
    console.log('run 2:', run2, typeof run2);
    console.log('run 3:', run3, typeof run3);
    console.log('run 4:', run4, typeof run4);
    

    The results in the console:

    Jane
    .
    Jane
    .
    Jane
    run 1: 10000 string
    run 2: 00001 string
    run 3: 10000 string
    run 4: 00001 string
    

    some observations:

    • the output of run is a string. I was expecting an array

    It obviously isn't working as I expected. Since I can't find a good example I really have no idea what I'm doing wrong. I'm wondering if I'm training it wrong? I'm starting to think I should be giving it example sequences as input... like {input: "Jane saw Spot", output: "."} but I can't wrap my head around how to express that as valid input.

    question 
    opened by jrobinson01 44
  • Halt and Resume training

    Halt and Resume training

    I am interested loading a pre-trained JSON from a file and resuming training.

    I have attempted to do just this, though it appears the training is restarted from scratch (based on the training errors for each iteration).

    Is there an easy way to do this?

    1 - Ready 
    opened by joelnet 38
  • Array buffer allocation failed using NeuralNetworkGPU

    Array buffer allocation failed using NeuralNetworkGPU

    afbeelding

    What is wrong?

    I'm trying to train a NN using the NeuralNetworkGPU class, however, it likes to eat all the memory from my PC (24GiB of which 19.3GiB usable for the script), which is fine... if it where to just work...
    As the title of the issue says, at some point, the script dies with an Array buffer allocation failed error.

    This means that it has run out of RAM to use but I wanted to know if theres a way to not hit into this issue (considering I already have a decent amount of memory and can't easily add more, hooray finances).

    Where does it happen?

    Training a NN using my PC with NeuralNetworkGPU

    How do we replicate the issue?

    • Train a neural network (I guess?)

    How important is this (1-5)?

    2

    Expected behavior (i.e. solution)

    The script not crashing (I guess?)

    Other Comments

    Stacktrace:

    (node:15708) UnhandledPromiseRejectionWarning: RangeError: Array buffer allocation failed
        at new ArrayBuffer (<anonymous>)
        at new Float32Array (<anonymous>)
        at zeros (F:\FinlayDaG33k\brainspam\node_modules\brain.js\src\utilities\zeros.js:2:10)
        at NeuralNetworkGPU.initialize (F:\FinlayDaG33k\brainspam\node_modules\brain.js\src\neural-network.js:104:39)
        at NeuralNetworkGPU.initialize (F:\FinlayDaG33k\brainspam\node_modules\brain.js\src\neural-network-gpu.js:127:11)
        at NeuralNetworkGPU.verifyIsInitialized (F:\FinlayDaG33k\brainspam\node_modules\brain.js\src\neural-network.js:295:10)
        at NeuralNetworkGPU.prepTraining (F:\FinlayDaG33k\brainspam\node_modules\brain.js\src\neural-network-gpu.js:436:10)
        at NeuralNetworkGPU.train (F:\FinlayDaG33k\brainspam\node_modules\brain.js\src\neural-network.js:467:39)
        at train (F:\FinlayDaG33k\brainspam\src\train.js:107:7)
    
    opened by FinlayDaG33k 37
  • How normalize discrete data input

    How normalize discrete data input

    Hi! How can I read readme.md, I need normalize input data to range 0..1. That's ok with linear data, same as color, price, year, etc.

    But look at my example: Form in my web page have one field with radio button, like:

    • credit;
    • debet;
    • personal card;
    • other.

    How I need provide this data for train nn? Ok, I can send something like:

    • type__credit: 0;
    • type__debet: 0;
    • type__personal_card: 1;
    • type__other: 0.

    But this make more input columns, even for many fields/values, as i showed. Then I thought, what will be if I will make this:

    • for «credit»: type=0.25;
    • for «debet»: type=0.5;
    • for «personal card»: type=0.75;
    • for «other»: type=1.

    That's save me from many columns, but will be work?

    And what I can do for checkboxes? Maybe:

    var typeForInputBrain = 0;
    
    typeForInputBrain += (typeFromForm.indexOf('credit')) ? 0.04 : 0;
    typeForInputBrain += (typeFromForm.indexOf('debet')) ? 0.08 : 0;
    typeForInputBrain += (typeFromForm.indexOf('personal card')) ? 0.16 : 0;
    typeForInputBrain += (typeFromForm.indexOf('other')) ? 0.32 : 0;
    

    Then even if all values was checked input value save in range between 0 to 1. Ok? Is it working method, or, that's way require something new activation function?

    P.S. Sorry for my english :)

    enhancement question 
    opened by Dok11 34
  • Generate possible results from training

    Generate possible results from training

    Is there a way to train the brain and generate possible results instead of letting the brain analyse a certain input?

    For example: "Give me 4 colors which match 'orange' with at least 80% accuracy".

    As pseudo-code:

    var net = new NeuralNetwork(); //Create neural network
    
    net.train([{input: {r:1, g:0.65, b:0},  output: {orange: 1}}, //This is orange
               {input: {r:0, g:0.54, b:0},  output: {green: 1}}, //This is green
               {input: {r:0.6, g:1, b:0.5}, output: {green: 1}}, //This is also green
               {input: {r:0.67, g:0, b:1},  output: {purple: 1}}]); //This is purple
    
    var output = net.run({"orange": ">0.8", "results": 4}); //return 4 colors which match 'orange' with at least 80% accuracy
    

    Pseudo-output:

    [{r:1,    g:0.65, b:0},
     {r:0.98, g:0.55, b:0},
     {r:1,    g:0.55, b:0.2},
     {r:0.85, g:0.55, b:0}]
    

    A real world example would be: "Tell me the first thing which comes to your mind when I say Internet". You might say something like Tim Berners-Lee or Wikipedia.

    Is something like that possible with BrainJS? Note: I also posted this question on StackOverflow.

    opened by stephanbogner 34
  • changed flood function in stream-example, for loop to '<=' from '<' s…

    changed flood function in stream-example, for loop to '<=' from '<' s…

    updated flood function in stream-example.js so that it will send a null chunk to trainstream.write(). This triggers finish event emitter in write. Original caused a nodejs stream3 error because nodejs object mode true doesn't allow for null data writing.

    Example would throw an error, but the change allows the for loop to send undefined to trainsteam.write, causing the chunk to be false triggering the finished event emitter.

    opened by Kalevera 25
  • Not possible to require or import?

    Not possible to require or import?

    I switched to this maintained library from the old one. Just doing the switch, I am no longer able to use a standard const brain = require('brain.js') (I basically just changed from brain to brain.js in the require), because the module will not be exported but put on the global window variable.

    Is there a reason for this? For now I just access the library using window.brain, but it would be nice to actually import/require the module to achieve a modern build process using e.g. webpack.

    Any info on this and explanation why it is done this way would be nice.

    //edit: I'm using brain inside the browser, I also tried brain.js/browser and it is also adding brain to window instead of exporting it.

    3 - Review 
    opened by embiem 24
  • How to reduce training error

    How to reduce training error

    BrainJs is really awesome for javascript developers. Thanks for this library. Its working as expected but i have some couple of questions that i am unsure how to fix this. I am using LSTMTimeStep to predict the next price of currency market. I have created this const net = new brain.recurrent.LSTMTimeStep({ inputSize: 4, hiddenLayers: [32, 32], outputSize: 4, }); net.train(trainingData, { iterations: 50000, learningRate: 0.001, errorThrash: 0.001, logPeriod: 100, log: stats => console.log(stats), }); I have large data starting from year 2016 daily open high close low values. I have normalised and denormalised as suggested from the tutorial. For every train which i am running on mac 16gb ram it is taking 3 to 4 hours to reach error threshold of 0.021. My question here is there any way to reduce the training error further to 0.01. I have tried changing hidden layers , learning rate, iterations, errorThrash but still my training error is not going below 0.020. Also every time when i add new daily data every train it takes 4 to 5 hours to predict next value. I am sure there is a better solution to fix these problems but am unsure how to do it. I saw using multhreading it will be faster but how to do that any example will be helpful.

    bug question 
    opened by theone3nu 23
  • [Feature request] Typings

    [Feature request] Typings

    What is wrong?

    Brain.js has no typings.

    Where does it happen?

    In VSCode when importing brain.js

    How do we replicate the issue?

    1. Open VSCode
    2. Import brain.js via import brain.js from "brain.js";

    How important is this (1-5)?

    2

    Expected behavior (i.e. solution)

    Typings should have been found and used

    Other Comments

    Please create typings for this module. Using Typescript when working with NN is awesome, because it lets you define shapes of the data you use and catch bugs early, however by using TS you lose IntelliSense because typings don't yet exist for brain.js.

    opened by vacekj 22
  • chore(deps): bump json5 from 1.0.1 to 1.0.2

    chore(deps): bump json5 from 1.0.1 to 1.0.2

    Bumps json5 from 1.0.1 to 1.0.2.

    Release notes

    Sourced from json5's releases.

    v1.0.2

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295). This has been backported to v1. (#298)
    Changelog

    Sourced from json5's changelog.

    Unreleased [code, diff]

    v2.2.3 [code, diff]

    v2.2.2 [code, diff]

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).

    v2.2.1 [code, diff]

    • Fix: Removed dependence on minimist to patch CVE-2021-44906. (#266)

    v2.2.0 [code, diff]

    • New: Accurate and documented TypeScript declarations are now included. There is no need to install @types/json5. (#236, #244)

    v2.1.3 [code, diff]

    • Fix: An out of memory bug when parsing numbers has been fixed. (#228, #229)

    v2.1.2 [code, diff]

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Recurrent neural networks and string arrays

    Recurrent neural networks and string arrays

    A GIF or MEME to give some spice of the internet

    Summary

    Improvement in input/output formats when dealing with arrays of strings / tokens for RNN.

    Basic example

    Currently, the LSTM model for example, can accept different types of data as input and as training data, arrays and strings. While the support for strings out of the box is great, it has some defaults that don't seem to fit so many use cases.

    Current behavior

    • Given raw strings:
    const data = [
      {
        input: 'hello I am an input',
        output: 'hi I am the output'
      }
    ]
    

    This will implicitly use character tokenization behaving as: input.split('') and output.join(''). See #799 which is a common case of LSTM usage I believe, string input and labels output. Because of the default behavior, the labels are being treated as actual text. It is possible to preprocess data by splitting everything to arrays so the model will be mapping words to neurons instead of characters.

    • Given arrays of strings
    const data = [
      {
        input: ['I', 'split', 'my', 'input', 'into', 'tokens']
        output: ['so', 'I', 'expect', 'tokens', 'as', 'output']
      }
    ]
    

    Here, we are using words instead of characters. That helps having simpler data to learn from for our model, and it also assures us of the output being exactly what we expect in term of label names. The problem with this right now is my output would be soIexpecttokensasoutput because of the output.join('') behavior. Working with string arrays is not documented anywhere so it surely causes trouble to some users of the library.

    Current workaround

    For now the most basic workaround I can think of is to add a space to every word in an array so that the output is readable and processable.

    const data = [
      {
        input: ['I ', 'split ', 'my ', 'input ', 'into ', 'tokens ']
        output: ['so ', 'I ', 'expect ', 'tokens ', 'as ', 'output ']
      }
    ]
    

    Possible improvement

    I think the best improvement would be to have the same output format as the input. In the case of #799 where strings are being used as input and arrays as output, it should probably throw an explicit error about the input being a string while the output is an array. Preprocessing the data by splitting it into words input.split(' ') would be a pretty easy step for the user, rather than figuring out both how the input and output are mapped to neurons and how the output formatted.

    Motivation

    Apart from the #799 issue, I have been dealing with that problem and spent some time on it until I could write a lot of extra code to get some workaround. String arrays using RNN are not really documented and don't really provide a lot of customization.

    A lot of the RNN (specifically LSTM) usage seems to be for reading questions or requests and writing a response using words that are related to a topic in a pretty limited vocabulary, as well as usage for mapping labels to a specific textual input which is not really well supported at the moment and has very implicit behavior. We could provide a more flexible RNN that is more easily customizable regarding how it treats the input and output, as well as making it more adapted to more usage.

    enhancement 
    opened by purplnay 0
  • chore(deps): bump json5 and tsconfig-paths

    chore(deps): bump json5 and tsconfig-paths

    Bumps json5 and tsconfig-paths. These dependencies needed to be updated together. Updates json5 from 2.2.0 to 2.2.3

    Release notes

    Sourced from json5's releases.

    v2.2.3

    v2.2.2

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).

    v2.2.1

    • Fix: Removed dependence on minimist to patch CVE-2021-44906. (#266)
    Changelog

    Sourced from json5's changelog.

    v2.2.3 [code, diff]

    v2.2.2 [code, diff]

    • Fix: Properties with the name __proto__ are added to objects and arrays. (#199) This also fixes a prototype pollution vulnerability reported by Jonathan Gregson! (#295).

    v2.2.1 [code, diff]

    • Fix: Removed dependence on minimist to patch CVE-2021-44906. (#266)
    Commits
    • c3a7524 2.2.3
    • 94fd06d docs: update CHANGELOG for v2.2.3
    • 3b8cebf docs(security): use GitHub security advisories
    • f0fd9e1 docs: publish a security policy
    • 6a91a05 docs(template): bug -> bug report
    • 14f8cb1 2.2.2
    • 10cc7ca docs: update CHANGELOG for v2.2.2
    • 7774c10 fix: add proto to objects and arrays
    • edde30a Readme: slight tweak to intro
    • 97286f8 Improve example in readme
    • Additional commits viewable in compare view

    Updates tsconfig-paths from 3.9.0 to 3.10.1

    Changelog

    Sourced from tsconfig-paths's changelog.

    [3.10.1] - 2021-07-06

    Fixed

    • Add register.js to published files

    [3.10.0] - 2021-07-06

    Added

    • feat(tsconfig-loader): extends config from node_modules (#106). Thanks to @​zorji for this PR!

    Fixed

    Commits

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • You need update GPU usage, please

    You need update GPU usage, please

    What is wrong?

    Brain JS use old version of GPU.js with gpu_js class, now gpu library has only GPU class, not gpu_js. Need only overwrite all gpu_js.* to GPU.* and gpu_js.GPU to GPU and all will be work, now GPU mode not work. Thanks!

    bug 
    opened by NeiroNext 0
  • Transformers enabling more efficiency

    Transformers enabling more efficiency

    Hey would be cool if transformers are implemented. Saw this https://medium.com/analytics-vidhya/why-are-lstms-struggling-to-matchup-with-transformers-a1cc5b2557e3

    enhancement 
    opened by bitdom8 0
Releases(1.4.10)
Owner
brain.js
Some cool AI tools. Now the community carries the torch.
brain.js
A javascript Bitcoin library for node.js and browsers.

BitcoinJS (bitcoinjs-lib) A javascript Bitcoin library for node.js and browsers. Written in TypeScript, but committing the JS files to verify. Release

bitcoinjs 4.8k Jan 1, 2023
A JavaScript PDF generation library for Node and the browser

PDFKit A JavaScript PDF generation library for Node and the browser. Description PDFKit is a PDF document generation library for Node and the browser

null 8.5k Jan 2, 2023
Lightweight operating system using Node.js as userspace

NodeOS Lightweight operating system using Node.js as userspace. NodeOS is an operating system built entirely in Javascript and managed by npm. Any pac

NodeOS 6.8k Dec 30, 2022
Streaming torrent client for node.js

peerflix Streaming torrent client for Node.js npm install -g peerflix Usage Peerflix can be used with a magnet link or a torrent file. To stream a vi

Mathias Buus 6k Dec 29, 2022
Node module for creating dat compatible tools on file systems

dat-node dat-node is a high-level module for building Dat applications on the file system. For a lower-level API for building your own applications, u

Dat Project 507 Nov 18, 2022
A modular geospatial engine written in JavaScript

A modular geospatial engine written in JavaScript turfjs.org Turf is a JavaScript library for spatial analysis. It includes traditional spatial operat

turf 7.6k Jan 3, 2023
IPFS implementation in JavaScript

The JavaScript implementation of the IPFS protocol Upgrading from <=0.40 to 0.48? See the release notes for the list of API changes and the migration

IPFS 7.2k Jan 8, 2023
A JavaScript implementation of Git.

JS-Git This project is a collection of modules that helps in implementing git powered applications in JavaScript. The original purpose for this is to

Tim Caswell 3.8k Dec 31, 2022
Graph theory (network) library for visualisation and analysis

Cytoscape.js Graph theory (network) library for visualisation and analysis : https://js.cytoscape.org Description Cytoscape.js is a fully featured gra

Cytoscape Consortium 8.9k Jan 9, 2023
A full stack for bitcoin and blockchain-based applications

Bitcore Infrastructure to build Bitcoin and blockchain-based applications for the next generation of financial technology. Getting Started Requirement

BitPay 4.5k Jan 4, 2023
Yet another Linux distribution for voice-enabled IoT and embrace Web standards

YodaOS is Yet another Linux Distribution for voice-enabled IoT and embrace Web standards, thus it uses JavaScript as the main application/scripting la

YODAOS Project 1.2k Dec 22, 2022
Mad science p2p pipe across the web using webrtc that uses your Github private/public key for authentication and a signalhub for discovery

webcat Mad science p2p pipe across the web using webrtc that uses your Github private/public key for authentication and a signalhub for discovery We a

Mathias Buus 428 Dec 30, 2022
New tab browser extension (aka startpage) with nord colors and a dancing goose.

Nordic goose Nordic goose is a new tab extension (aka startpage) with nord colors and a dancing goose. Features: ?? Look at a dancing goose ?? Beautif

PrettyCoffee 9 Dec 30, 2022
playful fractal flames, GPU accelerated

JWildfire Swan - playful fractal flames, GPU accelerated This is an experimental project and work in progress. Project goals The basic idea is to use

Andreas Maschke 7 Oct 20, 2022
GPU-accelerated Augmented Reality for the web.

MARTINS.js WebAR engine Create amazing Augmented Reality experiences with MARTINS.js, a GPU-accelerated Augmented Reality engine for the web. Get star

Alexandre Martins 19 Dec 16, 2022
🐜 GPU-accelerated ant colony simulation

Ants simulation A simple ant colony GPU-accelerated simulation made with Three.js. Live demo Rules Ants can emit two types of pheromones: to-home pher

null 10 Nov 28, 2022
Deep Learning in Javascript. Train Convolutional Neural Networks (or ordinary ones) in your browser.

ConvNetJS ConvNetJS is a Javascript implementation of Neural networks, together with nice browser-based demos. It currently supports: Common Neural Ne

Andrej 10.4k Dec 31, 2022
DN2A - Digital Neural Networks Architecture in JavaScript

DN2A (JavaScript) Digital Neural Networks Architecture About DN2A is a set of highly decoupled JavaScript modules for Neural Networks and Artificial I

Antonio De Luca 464 Jan 1, 2023
DN2A - Digital Neural Networks Architecture

DN2A (JavaScript) Digital Neural Networks Architecture About DN2A is a set of highly decoupled JavaScript modules for Neural Networks and Artificial I

Antonio De Luca 464 Jan 1, 2023
A lightweight library for neural networks that runs anywhere

Synapses A lightweight library for neural networks that runs anywhere! Getting Started Why Sypapses? It's easy Add one dependency to your project. Wri

Dimos Michailidis 65 Nov 9, 2022