Votre première application Machine Learning avec Tensorflowjs et React

Commencez l'aventure ‘machine learning’ avec Tensorflowjs et React, tutoriel avec démo et sources

Objectifs

  • Intégrer Tensorflowjs dans React
  • Créer et entrainer un modèle simple de machine learning
  • Prédire une valeur à partir de données linéraires

Une démo de l’application et les sources sont disponibles sur github.

Contexte

Préparation de l’environnement

L’application est développée grâce à la librairie React, nous allons utiliser Create React App pour générer le projet rapidement avec une configuration de base.

Création du Projet React

npx create-react-app tensorflowjs-app && cd tensorflowjs-app

Les fichiers non nécessaires sont supprimés, l’application se présente ainsi :

Ajout de Tensorflowjs au projet :

npm i @tensorflow/tfjs

Développement de l’application

  • Visualiser les données d’entrainement du modèle
  • Saisir les paramètres pour créer et entrainer le modèle
  • Saisir une valeur d’entrée qui servira au modèle pour calculer la valeur de sortie

Génération des données

On part avec les données suivantes :

Pas besoin de machine learning pour prédire une valeur inconnue à partir de ces données.

Si on veut déterminer la valeur de y pour x = 100 on obtient y = 100 * 2 + 5 = 205

L’exemple est volontairement simple ce n’est pas le résultat qui compte mais comment on va entrainer notre modèle pour prédire ce résultat. Notre application ignore le lien entre x et y, c’est ce lien que l’on va recréer en utilisant le machine learning.

Le fichier tensorflow.js contiendra les fonctions liées à la logique de notre application.

La première fonction nous retourne nos valeurs de départ sous forme de tensors. Les tensors sont des éléments utilisés par Tensorflow pour travailler sur les données.

// tensorflow.js
export function generateData() {
// data may come from an external resource : CSV file, API, database...
const input = tf.tensor([0, 2, 4, 7, 10, 20, 50], [7, 1]);
const label = tf.tensor([5, 9, 13, 19, 25, 45, 105], [7, 1]);
return [input, label];
}

On créé deux tensors, un pour les données “x” que l’on nomme input par convention, et l’autre pour les données “y” nommées label.

Du côté de l’interface, on créé un composant React TensorflowApp.js, qui sera directement rendu par notre index.js.

// TensorflowApp.js
function TensorflowApp() {
return (
<div>
<h1>Tensorflowjs in React</h1>
</div>
);
}

On récupère les tensors générés.

// TensorflowApp.js
const [input, label] = generateData();

Tensorflowjs nous met à disposition des fonctions pour accéder aux données contenues dans les tensor. On utilise tensor.arraySync() pour transformer les données en tableaux javascript. On affiche les valeurs qu’ils contiennent sous forme de tableau html.

Création du modèle

// tensorflow.js
export function createModel({
units = 1,
learningRate = 0.01,
optimizer = "adam",
}) {
const selectOptimizer = (optimizer) => {
return OPTIMIZERS[optimizer].fn(learningRate);
};

const model = tf.sequential();
model.add(tf.layers.dense({ units, inputShape: [1] }));
model.compile({
optimizer: selectOptimizer(optimizer),
loss: "meanSquaredError",
});
return model;
}

Un des paramètres important est l’ optimizer qui est l’algorithme qui permettra au modèle de s’affiner pendant son entrainement. Ce paramètre est une chaine de caractères, qui retourne une fonction mise à disposition par Tensorflowjs.

Il nous faut une structure contenant les fonctions d’optimisation fournies par Tensorflowjs, nous allons créer un objet qui aura ce rôle, dans un fichier séparé pour permettre de le réutiliser éventuellement plus tard :

// optimizers.js
export const OPTIMIZERS = {
sgd: { libelle: "sgd", fn: (lr) => tf.train.sgd(lr) },
adam: { libelle: "adam", fn: (lr) => tf.train.adam(lr) },
adagrad: { libelle: "adagrad", fn: (lr) => tf.train.adagrad(lr) },
adadelta: { libelle: "adadelta", fn: (lr) => tf.train.adadelta(lr) },
momentum: { libelle: "momentum", fn: (lr) => tf.train.momentum(lr, 1) },
rmsprop: { libelle: "rmsprop", fn: (lr) => tf.train.rmsprop(lr) },
};

Nous allons ensuite mettre en place la gestion du modèle et ses paramètres. Pour cela nous utilisons le hook useReducer fourni par React.

// TensorflowApp.js
const initialModelOptions = {
optimizer: "adam",
learningRate: 0.01,
epochs: 50,
};

function modelReducer(state, action) {
switch (action.type) {
case "SET_OPTIMIZER":
return { ...state, optimizer: action.value };
case "SET_LEARNINGRATE":
return { ...state, learningRate: parseFloat(action.value) };
case "SET_EPOCHS":
return { ...state, epochs: parseInt(action.value) };
default:
return state;
}
}

Tous les paramètres seront facilement mis à jour grâce à une seule fonction qui s’occupe d’update le state avec la nouvelle valeur. Cela évite d’avoir autant de fonction “handleChange()” que l’on a de paramètres.

// TensorflowApp.js
const handleChangeModelOptions = (action) => (e) => {
dispatch({ type: action, value: e.target.value });
};

Il ne reste plus qu’à coder les champs correspondants aux paramètres (la fonction d’optimisation et le learning rate).

Entrainement du modèle

Les epochs sont le nombre de cycles pendant lesquels le modèle va être entrainé. Plus ce nombre est important, plus le modèle est censé être affiné et ses prévisions exactes.

// tensorflow.js
export async function trainModel(model, input, label, epochs = 150) {
await model.fit(input, label, { epochs });
}

Le modèle est créé, il faut à présent l’entrainer sur les données. La fonction suivante va entrainer le modèle, c’est une opération qui peut prendre un certain temps et doit donc être réalisée de façon asynchrone. Une fois le modèle créé on met à jour le state du composant avec un booléen qui gère le statut de notre modèle.

// TensorflowApp.js
const handleTrain = () => {
setModelReady(false);
trainModel(model, input, label, modelOptions.epochs).then(() =>
setModelReady(true)
);
};

Il nous reste à permettre à l’utilisateur de régler le nombre de cycles d’apprentissage, les epochs.

Utilisation pour prédire une valeur

Résultats et perspectives

Pour compléter l’application, on pourrait afficher les valeurs fournies par Tensorflowjs sur la précision du modèle, ou bien ajouter la visualisation des données grâce à la librairie d3js.

Vous pouvez tester la démo de l’application, et voir les sources.

Originally published at https://romainamichaud.com.

French independant developer.