跳到主要内容

使用脑.js构建神经网络

brain.js neural network
+$(Image credit: Getty Images)

+$Brain.js is a fantastic way to build a neural network. Simply put, a neural network is a method of machine learning that works in a similar way to a human brain. Given the correct answer to a question (like ‘which option will this user choose?’), it slowly learns the pattern and relationship between the inputs and answers. One example of a neural network is Facebook’s facial recognition system, DeepFace.

+$But due to the complex domain language of neural networks and seemingly steep learning curve, it can be hard to get started.

+$In this tutorial, we will distil the theory down to need-to-knows and, importantly, get stuck in with actually using brain.js to create a neural network. By the end, you will have a web app that asks multiple-choice questions about a user’s optimism. When they submit, these answers will train a neural network to the probability of our user selecting each option for a brand new question.

+$Download the files you'll need for this tutorial.

+$01. Set up the project

+$Firstly, download and install the necessary dependencies. This tutorial presumes you have a working knowledge of React, or the equivalent mapping to a preferred alternative.

+$Create a React app using your desired method. You can try Facebook’s+$create-react-app+$tool, installed using the following:

+$npm install create-react-app -g

+$02. Start Your App

+$Now we can build, install brain.js, and start our app:

+$npx create-react-app optimism-nn cd optimism-nn npm install brainjs npm start

+$We are going to perform the neural network computation on the browser. Neural networks are resource intensive and should be offloaded to a server. However, this way is quick to set up and fine for our basic needs. Now let’s add brain.js to our entry point (in my case, App.js).

+$import brain from ‘brain.js’;

+$03. Define your training questions

brains.js neural network

+$A visualisation of our neural network. The inputs come from the optimism value of each option for a question. These are then manipulated by the hidden layer to give us the outputs we want – the likelihood of each option being selected

+$(Image credit: Harry Gray)

+$We need to define our training questions next. In a separate+$questions.js+$file, we’ll need a+$trainingQuestions+$validationQuestions+$array. You can find my list on the Git repo or create your own. The more training questions you have, the more accurate your results. Remember to import these into your entry point.

+$export const trainingQuestions = [ { id: ‘q1’, question: ‘Do you often see the best in things?’, options: [ { id: ‘q1a’, label: ‘Not really’, value: 0.2, }, { id: ‘q1b’, label: ‘Always’, value: 1.0, }, { id: ‘q1c’, label: ’Usually, yeah’, value: 0.7, }, { id: ‘q1d’, label: ’Never!’, value: 0.0, }, ], }, ];

+$For both arrays, we need a question, an array of four options that contain a label and an optimism value. This value will be the input for our neural network.

+$Ensure you vary the order and balance of values, or the neural network may focus too much on the index of the options in the array! Our neural network takes four inputs and gives four outputs. Our training data needs to match this, so in our constructor we need some state for the quiz and the user’s options:

+$this.state = { trainingAnswers: trainingQuestions.map(() => Array(4).fill(0)), training: false, predictions: undefined, };

+$04. Initialise the neural network

+$The initialisation of trainingAnswers creates an array for each question containing [0, 0, 0, 0] – our default state with no selection. We’re also going to need to initialise our neural network – just a single line with brain.js:

+$this.net = new brain.NeuralNetwork({ hiddenLayers: [4] });

brains.js neural network

+$Each item in our training set must consist of two arrays; one input with the optimism value of each option and one output containing the selection our user made

+$(Image credit: Harry Gray)

+$05. Build the quiz framework

+$To build the framework for our quiz, we need to loop over our training questions and options. This is quite verbose and not very interesting, so I’ll give an example output for you to aim for instead:

+$render() { return ( 
[. . .] // Iterate over questions & options

{question}

[. . .]
[. . .]
); }

+$If you’re new to React, see the文件+$for Building Forms.

+$We can write our+$isOptionChecked+$onOptionChange+$functions Next:

+$isOptionChecked = (questionIndex, optionIndex) => ( this.state.trainingAnswers[questionIndex][optionIndex] !== 0 ); onOptionChange = (questionIndex, optionIndex) => { this.setState(prevState => { const { trainingAnswers } = Object.assign(prevState, {}); trainingAnswers[questionIndex] = Array(4).fill(0); trainingAnswers[questionIndex][optionIndex] = 1; return { trainingAnswers }; }); };

+$06. Train the neural network

brains.js neural network

+$Our UI so far, showing one of my training questions and its options. I’ve used CSS in order to hide the actual radio buttons and give them a toggle button appearance

+$(Image credit: Harry Gray)

+$Now, when our user clicks an option, we update the relevant+$trainingAnswers+$array to feature a1+$in the selected index and change the state of the radio button to show it as checked.

+$Time to add our+$onSubmit+$function, where we build the training data and train the neural network:

+$onSubmit = e => { e.preventDefault(); const { trainingAnswers } = this.state; const trainingData = trainingQuestions.map((q, i) => ({ input: q.options.map(o => o.value), output: trainingAnswers[i], })); this.setState({ training: true, }); this.net.trainAsync(trainingData) .then(res => { console.log(res); // Log the error rate and # iterations this.getPredictions() }); }

+$Looping Over+$trainingQuestions+$, we create the input and output arrays we need. We get the input data by taking the optimism value of each option and we get the output data from looking in the+$trainingAnswers+$array at the same index as the question.

+$After that, we update the state with+$training: True+$to inform the user that the neural network is learning. Depending on the processing power of the client device and how many questions you have, the process can take seconds, minutes or longer!

+$Finally, we pass the training data over to our neural network and tell it to train asynchronously. This returns a promise that is fulfilled when the network has found the pattern or given up.

+$Keep an eye on the error rate we log in+$trainAsync+$. Ideally it should be between 0 - 0.05. If it’s higher, check your training data.

+$From there, we can get our predictions:

+$getPredictions = () => { const predictions = validationQuestions.map(q => ( this.net.run(q.options.map(o => o.value)) )); this.setState({ training: false, predictions, }); }

运用+$net.run+$, we ask our newly trained neural network to give us its predictions for each of the validation questions we defined earlier.

+$For the grand finale, we add our conditional loading logic and present a finding to the user.

+$render() { const { training, predictions } = this.state; const validationQuestion = validationQuestions[0]; return ( 
{training && (

Loading…

)} {!predictions && !training && ( [. . .] // Training questions form )} {predictions && !training && (

We asked the neural network:

{validationQuestion.question}

{validationQuestion.options.map((o, i) => ( ))}
)}
); } }

+$07. Extend The Network

brains.js neural network

+$Here’s our final results view, with my validation question and options. I’ve passed the probability through to another div to display it as a bar

+$(Image credit: Harry Gray)

+$Now you have the basic framework for the quiz, try extending it with the following:

+$Find the real error rate of your neural network by letting your user answer your validation questions. See how many times they chose your best guess.

+$Train the neural network with these additional answers and see if you can improve the accuracy.

+$Move the neural network calculations over onto a Node server with the brain.js+$toFunction()+$toJSON()方法。

+$This article originally appeared in issue 321 in网络杂志,世界领先的网页设计杂志。+$Buy Issue 321要么订阅网

阅读更多:



翻译字数超限