Introduction to AI for Ionic developers

Artificial Intelligence is here and will gradually replace some jobs.

Thanks to the open-source community, there are great libraries that can kickstart our AI projects.

This tutorial is an introduction to AI usage in Ionic applications.

In the previous tutorials (here and there), we used the Dialogflow service to create an AI chatbot.

That was quite easy, however, we only focused on a tiny aspect of AI. This technology has an incommensurable scope for the ones that want to master it.

We will start today's tutorial with THE classical XOR example then create a new AI for an Ionic mobile application.

The codeless XOR

To put it simply, an AI is a baby with a very very very big processing power.

You teach it, it learns. If you teach it crap, it will do crap.

Remember HAL from "A Space Odyssey"?

In this tutorial, we are going to use the brain.js library to create our baby.

It's one of the best and simplest library. The project is at the moment unmaintained. If you want a maintained one, you can use Synaptic (we will use this one in the next AI tutorial), the syntax is quite similar so you won't be lost.

As usual we create the Ionic project and install the libraries:

ionic start ionic-ai-intro blank npm i --save brain

Moving on to the home.ts file:

import { Component } from "@angular/core" ; declare var require ; var brain = require ( "brain" ) ; @ Component ( { selector : "page-home" , templateUrl : "home.html" } ) export class HomePage { net ; constructor ( ) { this . trainXOR ( ) ; } }

We first grab the brain library by using the require keyword.

A net property is then created for later use. In the constructor we call the trainXOR method, which starts like this:

trainXOR ( ) { this . net = new brain . NeuralNetwork ( ) ; const data = [ { input : [ 0 , 0 ] , output : [ 0 ] } , { input : [ 0 , 1 ] , output : [ 1 ] } , { input : [ 1 , 0 ] , output : [ 1 ] } , { input : [ 1 , 1 ] , output : [ 0 ] } ] ; . . . }

A new NeuralNetwork is created. Neural Network, brain, that's kinda abstract right?

You can start by viewing a NeuralNetwork as a simple human head instead of a network.

Typically, we, human beings acquire information from some input and sometimes give back an output.

The input can be the eyes (vision), nose (smells), etc. The output can be the mouth (sound).

In our example, the input is an array that contains two elements and the output is an array that contains one element.

In this case we can attribute the input to what two eyes can see and the output to what the mouth has to answer.

The value in the arrays must be between 0 and 1.

If we wanted to use only one element in the input we could use the following system:

We will use those data and parameters to train the AI:

this . net . train ( data , { errorThresh : 1 , iterations : 2 , log : true , logPeriod : 1 , learningRate : 0.1 } ) ; console . log ( this . net . run ( [ 0 , 0 ] ) ) ; console . log ( this . net . run ( [ 0 , 1 ] ) ) ; console . log ( this . net . run ( [ 1 , 0 ] ) ) ; console . log ( this . net . run ( [ 1 , 1 ] ) ) ;

Instead of starting with something that works, let's start with a sh*** AI. The AI that will result from this training will be gar****.

An AI training is stopped when a certain number of iterations is reached or once the AI consistently gives us the right answer.

This AI will be trained for only two iterations and the errorThresh property is set to 1 (which means 100%). If the AI makes a mistake or successfully give the right answer, it will stop training.

We now run some simulations:

As we can see, the AI is spitting nonsense.

Now let's give it some proper training:

this . net . train ( data , { errorThresh : 0.005 , iterations : 200000 , log : true , logPeriod : 1000 , learningRate : 0.1 } ) ;

The log field is set to show the advancement every 1000 iterations:

As the iterations go on, the AI makes less and less errors. We were going for 200000 iterations, however, it only required 14000 iterations to reach the 0.005 error threshold so it didn't go through the remaining iterations.

The results are correct and our AI is now smart enough to give the result of an XOR operation.

Note that we didn't write any code. Normally we would have to code an algorithm (ex: check if a === b, return 1 or 0, ...). All we did there was repeating to the AI the correct answer (just 14000 times).

We can now move to a more complex case.

The Ionic buttons god

AIs are more than XOR machines. They are generally trained to impact the application's flow.

Most of us don't have a robot to create applications:

So, we are going to create a program that will enable some buttons in our Ionic application according to some checkboxes.

Here are the checkboxes in the home.html file:

< ion-list > < ion-item > < ion-label > Up </ ion-label > < ion-checkbox [(ngModel)] = " up " > </ ion-checkbox > </ ion-item > < ion-item > < ion-label > Middle </ ion-label > < ion-checkbox [(ngModel)] = " middle " > </ ion-checkbox > </ ion-item > < ion-item > < ion-label > Down </ ion-label > < ion-checkbox [(ngModel)] = " down " > </ ion-checkbox > </ ion-item > </ ion-list >

And the rest of the template:

< button ion-button (click) = " changeButtons(up, middle, down) " > Change buttons </ button > < div *ngFor = " let value of output.reverse() " > < button ion-button [disabled] = " !value " > </ button > </ div >

The ngFor will create some buttons. Those buttons will be enabled and disabled by the AI.

When the user will tap the "Change buttons" button, the up, middle and down value will go to our AI and it will decide which button requires activation.

The train method is a bit different:

train ( ) { this . net = new brain . NeuralNetwork ( ) ; const data = [ { input : [ 0 , 0 , 0 ] , output : [ 0 , 0 , 0 , 0 , 0 ] } , { input : [ 1 , 0 , 0 ] , output : [ 1 , 0 , 0 , 0 , 0 ] } , { input : [ 1 , 1 , 0 ] , output : [ 1 , 1 , 0 , 0 , 0 ] } , { input : [ 0 , 1 , 0 ] , output : [ 0 , 0 , 1 , 0 , 0 ] } , { input : [ 0 , 1 , 1 ] , output : [ 0 , 0 , 0 , 1 , 1 ] } , { input : [ 0 , 0 , 1 ] , output : [ 0 , 0 , 0 , 0 , 1 ] } ] ; }

The input field represents the up, middle and down checkboxes.

The output field represents the buttons to activate or disable.

We make some changes at the beginning of our home.ts file:

export class HomePage { net ; output = [ true , true , true , true , true ] ; constructor ( ) { this . train ( ) ; } . . . }

By default the buttons will be activated and the train method will be called at start up.

We are close to the end, here is the changeButtons method:

changeButtons ( up , middle , down ) { const input = [ down > > > 0 , middle > > > 0 , up > > > 0 ] ; const output = this . net . run ( input ) ; this . output = this . formatOutput ( output ) ; }

We first convert the checkboxes values (true, false or undefined) to 0 or 1 so our network can understand the information.

An array of floats is then acquired from the AI network.

Those floats will be transformed to booleans thanks to the following method:

formatOutput ( output ) : boolean [ ] { output . forEach ( function ( value , i ) { output [ i ] = ( Math . round ( value ) === 1 ) ; } ) ; return output ; }

Going through each value, they will be rounded to 0 or 1.

And Voila!

We have our Ionic application driven by our AI:

Conclusion

Learning AI programming can seem like an Herculean task, but it shouldn’t.

As usual, we, lucky developers have many great libraries that are ready to be used.

All we need is a generic AI library that can create a network, train it and produce a correct output.

There are many AI libraries out there and more will come in the future. Some of them targets specific problematics (image recognition, natural language), you can find more examples there.