12 juil. 2021

[Dynamo+=Python] Deep Learning avec TensorFlow


artificial-neural-network-3501528_1280



Totalement débutant dans ce domaine, pouvoir faire des prédictions à l'aide d'un réseau neuronal artificielle a fini par attiser ma curiosité...

if this article is not in your language, use the Google Translate widget (bottom of page for Mobile version)

 1. Définition : 

Le deep learning (ou apprentissage profond) est un type d'intelligence artificielle dérivé du machine learning (apprentissage automatique) où la machine est capable d'apprendre par elle-même, contrairement à la programmation où elle se contente d'exécuter à la lettre des règles prédéterminées.


912px-Carto_IA_deepLearning


Pour cet article, nous utiliserons la bibliothèque développée par Google Brain "TensorFlow" (version 2.2.0) avec le modèle Keras (qui est désormais intégré à TensorFlow). 

Cet article n'a pas pour but de former à TensorFlow (vous trouverez beaucoup de tuto sur ce sujet, dont ceux de Google). Nous allons plutôt de découvrir comment nous pouvons utiliser cette librairie au sein de Dynamo avec Python et un exemple très simple.


    2. Installation

TensorFlow ayant des dépendances de libraires écrit en C et nécessitant à minima Python 3.5, il sera utilisé le moteur CPython3/PythonNet (tests réalisés sous Dynamo SandBox 2.10)

Il est important de noter que TensorFlow n'est compatible qu'avec Python 64bits

L'installation du package se fait en suivant ce tutoriel
https://github.com/DynamoDS/Dynamo/wiki/Customizing-Dynamo's-Python-3-installation


pip install tensorflow   

ou  

pip install tensorflow==2.2.0 si l'on souhaite spécifier une version (ici 2.2.0)

install%2Btensorflow

Si vous avez une erreur sur l'installation du package termcolor, il faudra préalablement installer manuellement la librairie

error%2Btermcolor

Télécharger l'archive 

termcolor avec le lien ci-dessous, puis extrayez le contenu dans le répertoire "site-packages" 
https://pypi.org/project/termcolor/#files
fix%2Btermcolor

installation manuelle de termcolor

puis refaite un  pip install tensorflow==2.2.0

Note il possible également que vous ayez à désinstaller - réinstaller NumPy vous avez plusieurs versions de ce dernier 


    2. Le Data Set

Pour cet exemple, le data set pour entraîner notre  réseau de neurones est constitué de 2 listes :

  • une liste de points (ou l'on récupère seulement les coordonnées X et Y)

  • une liste de booléens qui est associée a la liste de points.

            si la valeur est True le point du même index de la liste de points est dans le cercle 

            si la valeur est False  le point du même index de la liste de points est hors du cercle 

dataSet%2Band%2Bsphere%2Bfor%2B%2Bprediction


Enfin, on génère une dernière liste qui est constituée de sphères géométriques. Elle servira à réaliser des prédictions. Le but est de prédire (à partir du réseau de neurones entrainé) pour chaque sphère si celle-ci se situe dans le cercle


Note :
Bien évidement on pourrait déterminer si les sphères sont dans le cercle à partir d'une simple opération mathématique, mais ce n'est pas le but ici.


    3. Le Code 

Dans l'exemple ci-dessous, nous créons un réseau de neurones avec Keras (qui facilite grandement les opérations) qui a les caractéristiques suivantes :

  • une couche d'entrée constituée de 2 nœuds, chaque nœud recevra respectivement les coordonnés et un entier (0 ou 1, suivant si le point est dans le cercle ou non)
  • 2 couches cachées (hidden layers) composées de 5 nœuds
  • une couche de sortie avec 2 nœuds également


Une fois le modèle créé, on l’entraîne avec la méthode fit(), et enfin on effectue des prédictions avec predict()

Le choix et les caractéristiques des fonctions d'activation, de la fonction d'erreur et d'optimiseur ne sont pas abordées ici


import sys
import clr
import System

clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
clr.AddReference('GeometryColor')
from Modifiers import GeometryColor
clr.AddReference('DSCoreNodes')
from DSCore import Color

clr.AddReference('System.Windows.Forms')
import System.Windows.Forms
from System.Windows.Forms import MessageBox, MessageBoxButtons

dirAppLoc = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData) 
sys.path.append(dirAppLoc + r'\python-3.8.3-embed-amd64\Lib\site-packages')
datacsv = dirAppLoc + "\\dataTensorFlow.csv"

# force to reload module
if "tensorflow" in sys.modules:
    del sys.modules["tensorflow"]

import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
from tensorflow.python.client import device_lib

from io import StringIO    

sys.stdout = StringIO()
print("Num GPUs Available: ", len(tf.config.list_physical_devices('GPU')))
print(device_lib.list_local_devices())

LEARNING_RATE = 0.01 
EPOCH_COUNT = 2000 
max_accuracy = 80
# get X and Y from randoms points
x = np.array([[pt.X, pt.Y] for pt in IN[0]], dtype=np.float32) 
# convert bool to integer
y = np.array([int(x) for x in IN[1]], dtype=np.float32) 
# get X and Y from Test points for prediction
lstSpheres = IN[2]
testPoints = np.array([[sphere.CenterPoint.X, sphere.CenterPoint.Y] for sphere in lstSpheres], dtype=np.float32)
outGeometry = []

### Different activation ###
# softmax , tanh , relu , sigmoid
#
### Different loss ###
# binary_crossentropy , mean_squared_error , squared_hinge , categorical_crossentropy , sparse_categorical_crossentropy
#
model = keras.Sequential()
model.add(keras.layers.Dense(units=5,  input_shape=x.shape, activation='relu'))
model.add(keras.layers.Dense(units=5, activation='relu'))
model.add(keras.layers.Dense(units=2, activation='sigmoid')) 

#optimizer = tf.keras.optimizers.SGD(learning_rate = LEARNING_RATE)
optimizer = tf.keras.optimizers.Adam(learning_rate = LEARNING_RATE)

model.compile(optimizer=optimizer,
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
 
# train the model  
i = 0
final_accuracy = 0
while i < 3 and final_accuracy <= max_accuracy * 0.01:

    model.fit(x, y, epochs=EPOCH_COUNT)
    # get the final accuracy
    final_accuracy = round(model.history.history['accuracy'][-1], 2)
    i += 1

model.summary()
print(f"final_accuracy : {final_accuracy}")
# test Prediction
result1 = model.predict(testPoints)
# color the result
for idx, (sph, (out1, out2)) in enumerate(zip(lstSpheres, result1)):
    factor = 1 if out2 > 0.001 else 0
    print("probability shpere at index {} is inside circle : {}%".format(idx, round((1 - out1) * factor,  2) * 100))
    if out1  < 0.1 and out2 > 0.001:
        geocolor = GeometryColor.ByGeometryColor(sph, Color.ByARGB(255,0,255,0))
        outGeometry.append(geocolor)
    else:
        geocolor = GeometryColor.ByGeometryColor(sph, Color.ByARGB(255,255,0,0))
        outGeometry.append(geocolor)    


sys.stdout.seek(0)
readerstdout =  sys.stdout.read()
OUT = readerstdout, result1, outGeometry


Note :
Le taux d'apprentissage, le nombre epochs et les diverses fonctions doivent être ajustés de manière appropriée.

    4. Démonstration en Vidéo

    5. Ressources  






Notes
À noter qu'il existe aussi un package intégrant du Machine Learning
https://provingground.io/2017/10/03/lunchboxml-for-dynamo/
un exemple :
https://bitbucket.org/archinate/lunchboxml/pull-requests/1/dynamo-neural-network-sample/diff
https://forum.dynamobim.com/t/lunchbox-machine-learning/37663/9





















4 commentaires:

  1. Bonjour! Votre article est génial. C'est peut-être la seule chose que j'ai trouvée sur Internet concernant l'utilisation de l'intelligence artificielle dans Revit. J'aimerais beaucoup une introduction plus détaillée à AI + Revit. C'est possible? Je suis nouveau sur ce sujet. Toutes mes excuses pour mon français (j'ai écrit ce post avec le traducteur google).
    Cordialement, Anton.

    RépondreSupprimer
    Réponses
    1. Bonjour Anton, à ce jour je n'ai pas prévu une introduction plus détaillée, car il y a déjà beaucoup de tuto sur les bibliothèques TensorFlow + Keras.
      À noter qu'il existe aussi un package intégrant du Machine Learning
      https://provingground.io/2017/10/03/lunchboxml-for-dynamo/
      https://bitbucket.org/archinate/lunchboxml/pull-requests/1/dynamo-neural-network-sample/diff
      https://forum.dynamobim.com/t/lunchbox-machine-learning/37663/9

      Supprimer
  2. I was always looking for a way to connect Dynamopython and Tensorflow. Your article really helps a lot. Thank you.

    RépondreSupprimer
    Réponses
    1. I'll try to do another more detailed article (including sklearn module)

      Supprimer