Brain.js: Value1.concat is not a function error

Created on 11 Jul 2018  ·  15Comments  ·  Source: BrainJS/brain.js

Hi Guys I Just started Exploring brain.js and facing some issue

const brain                 = require('brain.js');
const faker                 = require('faker');
const co                    = require('co');



let payload = [];

const generateData = function () { 
    return new Promise((resolve,reject) => {
        const result = {input: {
            color:  faker.commerce.color(),
            price:  faker.commerce.price()
        },  output: { [faker.commerce.product()] : 1 } }
        return resolve(result);
    })
}

for (let index = 0; index < 100; index++) {
    payload.push(generateData());
}

Promise.all(payload).then(result => {
    console.log(result);
    var net = new brain.recurrent.LSTM();
    net.train(result)
    var output = net.run({ color: faker.commerce.color, price: faker.commerce.price });
    console.log(output);
})

Above is My Code where i am trying to Generate Some Fake eCommerce Data of Product with price and color attribute and output as a name of product

But i am getting following Error

UnhandledPromiseRejectionWarning: TypeError: value1.concat is not a function
    at DataFormatter.toIndexesInputOutput (F:\demo\brain.js-demo\node_modules\brain.js\dist\utilities\data-formatter.js:103:40)
    at LSTM.formatDataIn (F:\demo\brain.js-demo\node_modules\brain.js\dist\recurrent\rnn.js:766:35)
    at LSTM.setupData (F:\demo\brain.js-demo\node_modules\brain.js\dist\recurrent\rnn.js:750:26)
    at LSTM.train (F:\demo\brain.js-demo\node_modules\brain.js\dist\recurrent\rnn.js:460:21)
    at Promise.all.then.result (F:\demo\brain.js-demo\server.js:26:9)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)
    at Function.Module.runMain (module.js:695:11)
    at startup (bootstrap_node.js:191:16)
    at bootstrap_node.js:612:3
(node:12504) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch
block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:12504) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Can Anyone Help me out Understanding What am i Doing Wrong in my code ???

in progress

All 15 comments

This:

brain.run

Should be

net.run

@mubaidr I tried with net.run but still i am acing same issue

Here is My Sample Data that is getting generated from faker

[ 
    { input: { color: 'azure', price: '575.00' },​​​​​output: { Table: 1 } }​​​​​
]

I think your result variable looks like it needs to be changed from an object to an array with an object inside.

Can you please create a working fiddle with the same code? We will happily debug it.

Here is a Stackblitz link please have a look
https://stackblitz.com/edit/js-djf45m

Sorry for the delay, I am working on the provided example, thank you for that.

On the first glance, I think the issue lies here:

return resolve(result);

You just need to call resolve should not return it. i.e. like this:

resolve(result)

Change this: const result = {input: {...}} to this: const result = [{input: {...}}].

Nope, I'm wrong.

Here is a New Stackblitz i have created
https://stackblitz.com/edit/brain-js-demo

Lemme know if found any solutions

@techitesh Here is the fixed version: https://gist.github.com/mubaidr/145ddaef84280a137e0a4126ba8de9df

I have switched to RNN from LSTM because RNN is more suitable for simple mathematical data sets where LSTM is more suited to string/text data sets.

But please note that network does not train well because data is not good (either repetitive or not conclusive enough).

I am closing this issue, in case you need further help, please don't hesitate to re-open this issue or create a anew one.

Thnx for Help

@techitesh I am sorry, there was an issue the above gist, I have fixed it. More specifically:

parseInt(faker.internet.color().replace('#', ''), 16), //convert color to integer

To keep this issue alive, I'm experiencing the same issue also with an LSTM model. Reads in the content of 10 short files, into two outputs. After one or two iterations, sometimes immediately, I get the same error as OP.

Gist of my code - https://gist.github.com/fauliath/d57660dfa78167b8acc63eb90e0d7974

My full error output is:

TypeError: value1.concat is not a function
    at DataFormatter.toIndexesInputOutput (Z:\Development\Javascript\NodeJS\Neural Networks\Brain.JS\002\node_modules\brain.js\dist\utilities\data-formatter.js:107:40)
    at LSTM.formatDataIn (Z:\Development\Javascript\NodeJS\Neural Networks\Brain.JS\002\node_modules\brain.js\dist\recurrent\rnn.js:767:35)
    at LSTM.setupData (Z:\Development\Javascript\NodeJS\Neural Networks\Brain.JS\002\node_modules\brain.js\dist\recurrent\rnn.js:751:26)
    at LSTM.train (Z:\Development\Javascript\NodeJS\Neural Networks\Brain.JS\002\node_modules\brain.js\dist\recurrent\rnn.js:460:21)
    at Object.<anonymous> (Z:\Development\Javascript\NodeJS\Neural Networks\Brain.JS\002\index.js:32:5)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)

Clarity and direction for myself and the lib.

The original use case is for this data shape, which (from my naive guess) was just converted directly to brain.recurrent.LSTM:

Overly simplified origin example:

const trainingData = [
  {
    input: {
      color:  faker.commerce.color(),
      price:  faker.commerce.price()
    },
    output: { [faker.commerce.product()] : 1
  }
];
const net = new brain.NeuralNetwork();
net.train(trainingData);

The reason this was failing was specifically because faker.commerce.color() returns a string, which isn't a slam to faker.commerce.color(), but because color is essentially infinite (and more specifically because the net doesn't support it) we result in:

  • in the existing version, training logs NaN
  • in newer versions of brain.js this throws an error that training goes to NaN

Note: faker.commerce.price() also goes to string, but brain.js tries to handle this by casting to a decimal gracefully.

One could surmise that the brain.recurrent.LSTM class supports strings, and could thus just use that, and that _might_ work, but when one does change the software over, they arrive at an obtrusive value1.concat is not a function error, because brain.recurrent.LSTM by default has a nifty string encoder and only supports strings for inputs and outputs, with the option to extend however you like. In short, the reason it fails is that the input { color: number, price: number } simply doesn't have a .concat() method, and thus fails on preparing data.

BUT! Taking a step back, consider your data shape:

{
  input: {
    color:  number,
    price:  number
  },
  output: { [type] : number
}

There isn't really anything about this data shape that is recurrent. Think of recurrence like memory of what is going on. If all we are doing is classifying a color & price as an output, then the most appropriate network is likely the already used brain.NeuralNetwork, or more specifically, a FeedForward neural network.

However, what you may find advantageous is to _encode your data_ so that network can read it, or simply convert it appropriately. This part has been left out of brain.js because, well, there are a lot of different types of data, and it can be read a lot of different ways.

One of the suggestions (added price casting as well for help) was to simply perform the following data conversions (ty @mubaidr & @techitesh):

Overly simplified suggested example:

const trainingData = [
  {
    input: {
      color:  parseInt(faker.commerce.color().replace('#', ''), 16),
      price:  parseFloat(faker.commerce.price())
    },
    output: { [faker.commerce.product()] : 1
  }
];
const net = new brain.NeuralNetwork();
net.train(trainingData);

Unrelated note: Did you guys know the inverse of parseInt('#509cd6'.replace('#', ''), 16) is (parseInt('#509cd6'.replace('#', ''), 16) >>> 0).toString(16)? Using bits directly in js is too fun.

And this works fairly well for running the net. But training stops fairly quick:

screen shot 2018-11-23 at 1 17 45 pm

Taking a much further step back, and for the sanity of those that may find this issue in the future: It is almost like the data is completely random (https://www.npmjs.com/package/faker), and that it is hard to classify things by _just random color and price_... :trollface:

Seriously, _really_ hard to do. Likely impossible. So short of building a lookup table, the net cannot learn this type of data without likely be over-fitting it.

If anyone else has this problem in the future, would you be so kind to include a sample of your training data?

Ty guys, sorry it took me a while to get to this one.

Today I start to train Fibi net not for input color data, (sorry bad
english) prinetstvie
And Fibi cant undestand it in whole. I need you help to finish this train,
please.

пт, 23 нояб. 2018 г., 21:45 Robert Plummer [email protected]:

Clarity and direction for myself and the lib.

The original use case is for this data shape, which (from my naive guess)
was just converted directly to brain.recurrent.LSTM:

Overly simplified origin example:

const trainingData = [
{
input: {
color: faker.commerce.color(),
price: faker.commerce.price()
},
output: { [faker.commerce.product()] : 1
}
];const net = new brain.NeuralNetwork();net.train(trainingData);

The reason this was failing was specifically because
faker.commerce.color() returns a string, which isn't a slam to
faker.commerce.color(), but because color is essentially infinite (and
more specifically because the net doesn't support it) we result in:

  • in the existing version, training logs NaN
  • in newer versions of brain.js this throws an error that training
    goes to NaN

Note: faker.commerce.price() also goes to string, but brain.js tries to
handle this by casting to a decimal gracefully.

One could surmise that the brain.recurrent.LSTM class supports strings,
and could thus just use that, and that might work, but when one does
change the software over, they arrive at an obtrusive value1.concat is
not a function error, because brain.recurrent.LSTM by default has a nifty
string encoder and only supports strings for inputs and outputs, with the
option to extend however you like. In short, the reason it fails is that
the input { color: number, price: number } simply doesn't have a .concat()
method, and thus fails on preparing data.

BUT! Taking a step back, consider your data shape:

{
input: {
color: number,
price: number
},
output: { [type] : number
}

There isn't really anything about this data shape that is recurrent. Think
of recurrence like memory of what is going on. If all we are doing is
classifying a color & price as an output, then the most appropriate network
is likely the already used brain.NeuralNetwork, or more specifically, a
FeedForward neural network.

However, what you may find advantageous is to encode your data so that
network can read it, or simply convert it appropriately. This part has been
left out of brain.js because, well, there are a lot of different types of
data, and it can be read a lot of different ways.

One of the suggestions (added price casting as well for help) was to
simply perform the following data conversions (ty @mubaidr
https://github.com/mubaidr & @techitesh https://github.com/techitesh):

Overly simplified suggested example:

const trainingData = [
{
input: {
color: parseInt(faker.commerce.color().replace('#', ''), 16),
price: parseFloat(faker.commerce.price())
},
output: { [faker.commerce.product()] : 1
}
];const net = new brain.NeuralNetwork();net.train(trainingData);

Unrelated note: Did you guys know the inverse of parseInt('#509cd6'.replace('#',
''), 16) is (parseInt('#509cd6'.replace('#', ''), 16) >>> 0).toString(16)?
Using bits directly in js is too fun.

And this works fairly well for running the net. But training stops fairly
quick:

[image: screen shot 2018-11-23 at 1 17 45 pm]
https://user-images.githubusercontent.com/679099/48956679-5479e000-ef22-11e8-9110-9408dfb5e3bf.png

Taking a much further step back, and for the sanity of those that may find
this issue in the future: It is almost like the data is completely random (
https://www.npmjs.com/package/faker), and that it is hard to classify
things by just random color and price... [image: :trollface:]

Seriously, really hard to do. Likely impossible. So short of building a
lookup table, the net cannot learn this type of data without likely be
over-fitting it.

If anyone else has this problem in the future, would you be so kind to
include a sample of your training data?

Ty guys, sorry it took me a while to get to this one.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/BrainJS/brain.js/issues/231#issuecomment-441302233,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ApO_K9A8ljCfYGZShv3xi6D9Fc5y2HEqks5uyEJfgaJpZM4VKlKb
.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

shopsoy picture shopsoy  ·  3Comments

AkashGutha picture AkashGutha  ·  5Comments

timendez picture timendez  ·  3Comments

lucaspojo picture lucaspojo  ·  5Comments

nezzard picture nezzard  ·  5Comments