Ensinando um computador a somar com TensorFlow.js e Machine Learning
Tags: machinelearning, javascript, ai, tensorflow
Published: 2020-01-29 01:45:23

Uma das primeiras funções que um programador faz é a **função de soma**. Seja lá qual for a linguagem, é comum a todos nós escrever um método que recebe dois argumentos e retorna a soma desses argumentos.

Em javascript, temos:

```js
function add(a, b) {
  return a + b
}
```

Mas eu quero propor uma nova forma de construir um algoritmo de soma: **Machine Learning**. Ao invés de explicitar como o computador deve fazer a soma, daremos à ele exemplos de somas e ele descobrirá o que é e como fazer uma soma ou pelo menos uma aproximação disso.

## Machine Learning

`Machine Learning`, em português `Aprendizado de Máquina`, se refere à uma ramificação da Inteligência Artificial que tem por objetivo tratar a máquina como um agente inicialmente "burro" e por meio de treinamento com diversos dados, ensiná-lo um algoritmo ou um padrão.

## Ensinando a máquina a somar

Para reproduzir este exemplo, você precisará ter o `npm` e o `nodejs` instalados. Não se preocupe se você não entender os detalhes do TensorFlow.js. O foco deve ser no macro: ensinar a máquina a somar com algumas linhas de código.

Instale o TensorFlow.js para Node.js:

```bash
$ npm install --save @tensorflow/tfjs-node
```

Neste exemplo, para efeitos didáticos, faremos tudo em um arquivo único chamado `index.js`.

Antes de tudo, precisamos importar o TensorFlow.js em nosso arquivo:

```js
// index.js

const tf = require('@tensorflow/tfjs-node')
```

Agora é hora de definir um `model`, que basicamente é o objeto que será treinado com dados. Esse `model` é composto por camadas (`layers`), por uma função de perda (`loss`) e um otimizador (`optimizer`).

Definiremos um `model` sequencial que é o tipo mais simples:

```js
// ...

const model = tf.sequential({
  layers: [
    tf.layers.dense({ units: 1, inputShape: [2] })
  ]
})
```

Definido nosso modelo, que será posteriormente treinado, precisamos compilá-lo definindo uma função de perda e um otimizador:

```js
// ...

model.compile({
  loss: 'meanSquaredError',
  optimizer: tf.train.sgd(0.001)
})
```

Agora temos um modelo compilado. Pronto para aprender a somar!

Mas, para ensiná-lo essa operação, precisamos de dados. E com dados quero dizer **exemplos**. Precisamos de uma lista de argumentos e outra lista de resultados. Nesse artigo colocarei poucos exemplos para ser sucinto. Mas, no universo de `Big Data` que estamos imersos, uma quantidade expressiva de dados é importante quando estamos falando de treinar uma máquina.

Vamos dar uma olhada nos exemplos do meu treino:

```js
// ...

const inputs = tf.tensor([
  [1, 1],
  [2, 2],
  [-4, 5],
  [6, 7],
  [1.5, 6.7],
  [15, 56]
])

const outputs = tf.tensor([
  [2],
  [4],
  [1],
  [13],
  [7.2],
  [71]
])
```

Acima nós temos alguns exemplos de entradas, e quais deveriam ser suas respectivas saídas.

Agora que temos um modelo compilado para ser treinado e temos dados, o que fazemos?

Treinamos o modelo:

```js
// ...

model.fit(inputs, outputs, {
  epochs: 500
})
```

Finalmente temos o nosso modelo treinado. Como executar nossa soma?

Veja a seguir:

```js
// ...

model.fit(inputs, outputs, {
  epochs: 500
})
  .then(() => {
    const test = tf.tensor([10, 10])
    const result = model.predict(test)

    result.print()
  })
```

Alguns detalhes:

1. Pelo fato de o treinamento (`.fit()`) ser uma operação que pode demorar, a implementação dela é assíncrona (Em termos técnicos, ela retorna uma `Promise`). Por isso, só existe garantia de que o modelo está completamente treinado dentro do `.then()`;
2. Um fato em Machine Learning é que um modelo nunca alcança 100% de precisão. Ou seja, erros mínimos são toleráveis. No exemplo acima, muito provavelmente o resultado não será exatamente 20 (Soma entre 10 e 10), mas um número muito próximo disso. O objetivo é minimizar o erro ao máximo tendo em mente que nunca será 0.

## Somar é muito fácil!

Uma soma entre dois números é um algoritmo ridiculamente fácil! Não precisamos de `Machine Learning` para esse tipo de objetivo. No entanto, o mundo que vivemos tem problemas muito mais complexos que podem ser resolvidos baseando-se na mesma ideia usada para esse modelo de soma. O que parece ser um simples exemplo, na verdade, traz consigo uma técnica extremamente recomendada para resolver problemas complexos: ensinar uma máquina com dados e deixar que ela descubra o padrão que deve ser descoberto.