[PYTHON] Utiliser tensorboard avec Chainer

Le tensorboard est assez pratique à utiliser. Des graphiques, des histogrammes, des images, etc. peuvent être dessinés, et l'interface est également bonne. J'utilise beaucoup chainer ces jours-ci, mais je voulais utiliser ce tensorboard pratique comme outil de visualisation, alors j'ai créé un package qui utilise tensorboard avec chainer.

https://github.com/neka-nat/tensorboard-chainer

Il y avait une personne qui fait la même chose avec pytorch, donc je le fais sur cette base.

Comment utiliser

En gros, vous pouvez voir à quoi il ressemble en exécutant demp.py ou demo_graph.py. Il prend en charge le dessin de graphiques, d'histogrammes, d'images, etc.

python demo.py
tensorboard --logdir runs

** SCARA ** scalar.png

** histogramme **

histogram.png

image

image.png

À propos de la mise en œuvre

J'étais un peu ennuyé par la génération de graphes. Fondamentalement, le computational_graph du chainer est utilisé pour calculer les nœuds et les arêtes, et le type de protobuf utilisé dans le journal du tensorboard est changé. Pour le moment, comme le graphe de chaînage est adopté tel quel, le "VariableNode" entre les fonctions qui ne sont pas affichées dans tensorflow est également dessiné.

name_scope Le reste est de savoir comment nommer les nœuds, mais nous avons préparé une version chainer de name_scope utilisée dans tensorflow pour rendre le graphique plus facile à voir. Il peut être utilisé sous les formes suivantes.

import chainer
import chainer.functions as F
import chainer.links as L
from tb_chainer import name_scope

class MLP(chainer.Chain):
    def __init__(self, n_units, n_out):
        super(MLP, self).__init__()
        with self.init_scope():
            self.l1 = L.Linear(None, n_units)  # n_in -> n_units
            self.l2 = L.Linear(None, n_units)  # n_units -> n_units
            self.l3 = L.Linear(None, n_out)  # n_units -> n_out

    def __call__(self, x):
        with name_scope('linear1', self.l1.params()):
            h1 = F.relu(self.l1(x))
        with name_scope('linear2', self.l2.params()):
            h2 = F.relu(self.l2(h1))
        with name_scope('linear3', self.l3.params()):
            o = self.l3(h2)
        return o

L'endroit où with name_scope ... définit l'espace de noms. Dans ce cas, si vous ne définissez pas l'espace de noms, tous les nœuds seront dessinés comme indiqué ci-dessous, mais si vous définissez l'espace de noms, ils seront dessinés comme indiqué ci-dessous.

** Pas d'espace de noms ** graph_no_name_scope.png

** Avec espace de noms ** graph_with_name_scope.png

Bien sûr, il peut être développé dans l'espace de noms.

open_scope.png

Comment implémenter name_scope

C'est une méthode assez agressive, mais c'est fait avec syntaxe + patch monkey. Je réécris le constructeur de VariableNode et Function pour le changer en constructeur qui peut contenir la pile d'espaces de noms.

from chainer import function
from chainer import variable
import functools
from types import MethodType

def copy_method(c):
    g = MethodType(c.__init__, None, c)
    return g

def _init_with_name_scope(self, *args, **kargs):
    self.name_scope = kargs['name_scope']
    org_init = kargs['org_init']
    del kargs['name_scope']
    del kargs['org_init']
    org_init(self, *args, **kargs)

#Augmentez la classe de fonctions selon vos besoins.
_org_classes = [function.Function,
                variable.VariableNode]
_copy_org_inits = [copy_method(c) for c in _org_classes]

class name_scope(object):
    stack = []
    def __init__(self, name, values=[]):
        self.stack.append(name)
        self._org_inits = []
        for v in values:
            v.node.name_scope = '/'.join(self.stack)

    def __enter__(self):
        for idx, c in enumerate(_org_classes):
            self._org_inits.append(c.__init__)
            c.__init__ = MethodType(functools.partial(_init_with_name_scope,
                                                      name_scope='/'.join(self.stack),
                                                      org_init=_copy_org_inits[idx]),
                                    None, c)
        return self

    def __exit__(self, exec_type, exec_value, traceback):
        for idx, c in enumerate(_org_classes):
            c.__init__ = self._org_inits[idx]
        self.stack.pop(-1)

Le _init_with_name_scope ci-dessus appelle normalement le constructeur et préserve l'espace de noms, et ne bascule vers ce constructeur que dans la syntaxe with.

Fonctionnalités que vous souhaitez ajouter

Notation de taille Tensol sur le bord

Il semble que la taille du tenseur puisse être indiquée sur le bord lors du dessin du réseau sur le tensorboard, mais je ne peux pas le faire car je ne sais pas comment le faire. Vous devrez peut-être regarder le contenu de la source tensorflow pour savoir ...

référence

Magie noire avec Python Metaprogramming Python

Recommended Posts

Utiliser tensorboard avec Chainer
Utiliser tensorboard avec NNabla
Utilisation du chainer avec Jetson TK1
Seq2Seq (1) avec chainer
Utilisez mecab-ipadic-neologd avec igo-python
Utilisez RTX 3090 avec PyTorch
Utiliser ansible avec cygwin
Utiliser pipdeptree avec virtualenv
[Python] Utiliser JSON avec Python
Utilisez Mock avec pytest
Utiliser l'indicateur avec pd.merge
Utiliser Gentelella avec Django
Utiliser mecab avec Python 3
Utiliser DynamoDB avec Python
Utiliser pip avec MSYS2
Utilisez Python 3.8 avec Anaconda
Utiliser les droits d'auteur avec Spacemacs
Histoire d'essayer d'utiliser Tensorboard avec Pytorch
Utiliser python avec docker
Utiliser TypeScript avec django-compresseur
Utilisez LESS avec Django
Utiliser MySQL avec Django
Utiliser Enum avec SQLAlchemy
Utiliser le GPS avec Edison
Utilisez nim avec Jupyter
Utilisez l'ensemble de données d'entraînement scikit-learn avec chainer (pour l'entraînement / la prédiction)
Autoencoder dans Chainer (Remarques sur l'utilisation de + trainer)
Utiliser l'API Trello avec python
Utiliser la mémoire partagée avec une bibliothèque partagée
Utiliser des balises personnalisées avec PyYAML
Utiliser des graphiques directionnels avec networkx
Utiliser TensorFlow avec Intellij IDEA
Essayez d'implémenter RBM avec chainer.
Utiliser DATE_FORMAT avec le filtre SQLAlchemy
Utiliser TUN / TAP avec Python
Utilisez sqlite3 avec NAO (Pepper)
Apprenez les orbites elliptiques avec Chainer
Utilisez les load_extensions de sqlite avec Pyramid
Seq2Seq (3) ~ Edition CopyNet ~ avec chainer
Utiliser les polices Windows 10 avec WSL
Utiliser SSL avec Celery + Redis
Utiliser Cython avec Jupyter Notebook
Réseau de neurones commençant par Chainer
Utilisez Maxout + CNN avec Pylearn2
Implémentation du GAN conditionnel avec chainer
Génération de légende d'image avec Chainer
Utilisez WDC-433SU2M2 avec Manjaro Linux
Utilisez OpenBLAS avec numpy, scipy
Utiliser l'API subsonique avec python3
Implémentation de SmoothGrad avec Chainer v2
Utilisation de Sonicwall NetExtener avec Systemd
Clustering embarqué profond avec Chainer 2.0
Un peu coincé dans le chainer
Utilisez prefetch_related commodément avec Django
Utiliser l'interpréteur AWS avec Pycharm
Utilisation de Bokeh avec IPython Notebook
Utiliser une plage de type Python avec Rust
Utiliser MLflow avec Databricks ④ --Call model -
Utiliser pyright avec CentOS7, emacs lsp-mode
Python: comment utiliser async avec