Das Tensorboard ist sehr bequem zu bedienen. Grafiken, Histogramme, Bilder usw. können gezeichnet werden, und die Benutzeroberfläche ist auch gut. Ich habe in diesen Tagen viel Chainer verwendet, aber ich wollte dieses handliche Tensorboard als Visualisierungswerkzeug verwenden, deshalb habe ich ein Paket erstellt, das Tensorboard mit Chainer verwendet.
https://github.com/neka-nat/tensorboard-chainer
Es gab eine Person, die dasselbe mit Pytorch macht, also mache ich es basierend darauf.
Grundsätzlich können Sie sehen, wie es aussieht, indem Sie demp.py
oder demo_graph.py
ausführen. Es unterstützt das Zeichnen von Grafiken, Histogrammen, Bildern usw.
python demo.py
tensorboard --logdir runs
** SCARA **
Histogramm
Bild
Ich war ein wenig verärgert über die Graphgenerierung. Grundsätzlich wird der "Computational_graph" des Chainers verwendet, um die Knoten und Kanten zu berechnen, und der im Tensorboard-Protokoll verwendete Protobuf-Typ wird geändert. Da der Chainer-Graph unverändert übernommen wird, wird vorerst auch der "VariableNode" zwischen Funktionen gezeichnet, der nicht im Tensorflow angezeigt wird.
name_scope
Der Rest ist, wie man die Knoten benennt, aber wir haben eine Chainer-Version von name_scope
vorbereitet, die im Tensorflow verwendet wird, um das Diagramm besser sichtbar zu machen.
Es kann in den folgenden Formen verwendet werden.
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
Die Stelle, an der with name_scope ...
den Namespace festlegt.
Wenn Sie in diesem Fall den Namespace nicht festlegen, werden alle Knoten wie unten gezeigt gezeichnet. Wenn Sie jedoch den Namespace festlegen, werden sie wie unten gezeigt gezeichnet.
** Kein Namespace **
** Mit Namespace **
Natürlich kann es im Namespace erweitert werden.
Es ist eine ziemlich aggressive Methode, aber sie wird mit Syntax + Affen-Patch durchgeführt. Ich schreibe den Konstruktor von VariableNode und Function neu, um ihn in einen Konstruktor zu ändern, der den Stapel von Namespaces enthalten kann.
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)
#Erhöhen Sie die Funktionsklasse nach Bedarf.
_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)
Das obige _init_with_name_scope
ruft normalerweise den Konstruktor auf und behält den Namespace bei und wechselt nur in der with-Syntax zu diesem Konstruktor.
Es scheint, dass die Größe des Tensors beim Zeichnen des Netzwerks auf dem Tensorboard am Rand angegeben werden kann, aber ich kann es nicht tun, weil ich nicht weiß, wie es geht. Möglicherweise müssen Sie sich den Inhalt der Tensorflow-Quelle ansehen, um herauszufinden, ...
Schwarze Magie mit Python Metaprogramming Python
Recommended Posts