投稿

4月, 2020の投稿を表示しています

TensorFlow2:TensorBoardのグラフがうまく表示されず困った件(余談)

前回の記事 のおまけ。 余談と言いつつ、重要そうなことも入っている気がする。 余談:モデルがmain graphに表示されない件 TensorBoardでは、グラフが複雑になるのを避けるため、入出力が多いノード(原文では"high-degree nodes")は、 Auxiliary Nodes 側に配置される。 "入出力が多いノードは、だいたい保存とかそんな感じのノードなので、外しても問題ないっしょ。メイングラフには〇も置いとくし"(超意訳)らしい。モデルなんだがなぁ…。 Reference: TensorBoard: Graph Visualization グラフを見ていると、レイヤ内の各weightの定義が、ただのVariableではなく、ReadVariableOpになっていることが原因のようだ。 しかしweightの定義はkeras内でやっているので、手が出せない。 調べてみると、issueが上がっていたが解決していない(放置されている?)。 [TF 2.0] Inconvenient graph visualization #29215 この件は、今のところ手動でmain graphに移動させることで回避。 余談:test側のグラフ出力がエラーになる 前回の変更2では @tf.function を付与する関数をtrainのみにして対処したが、testのみにした場合はうまく動かない。 この場合、最初と同じで Graph visualization failed. Error: Malformed GraphDef. が表示されてしまう。 TensorBoardのコンソールには以下のエラーが表示される。 ValueError: Cannot combine GraphDefs because nodes share a name but contents are different: images よく見てみると、今度は入力である images がエラーの原因となっている。 いやいやテスト中はループでぐるぐる回してるだけで、処理は変わってないし! とりあえず本筋でないから放置するか。。。 と思ってぼーっとコード見ていたら、なんとなくバッチが気になってきた。 結果、データ読み込みの部分を

TensorFlow2:TensorBoardのグラフがうまく表示されず困った件

イメージ
前回は、kerasのsummaryなどでグラフの可視化をしましたが、今回はTensorboardのグラフを使ってみます。 使用するモデルは、 TensorFlow2:MNISTやってみる(keras model class) で作成したものです。 1.xのときと違って、Summaryを保存するだけではグラフは出力されないようです。 ということで、変更を加えて出力してみたけど、うまく動かなかったり、いまいちきれいに出なかったという話。 Reference: Examining the TensorFlow Graph グラフ出力のための変更 紆余曲折が長いので、まずは最終的な形を記載します。 今回はsubclassedなモデルで、 model.fit() は使用していないので、 Graphs of tf.functions セクションで記載のある方法を試す。 計算開始時に tf.summary.trace_on(graph=True) を呼び、終了時に tf.summary.trace_export() を呼ぶ。 注意点としては、 trace_export() は、 writer.as_default() のブロック内で呼び出す必要がある。 必然的に、SummaryWriterのインスタンスが必要になる(Writerが書き出すファイル内にグラフが入るので、当たり前かもしれないが一応)。 以下の「# !!! ADD」コメント部分が追加した箇所。 def training(model, optimizer, epochs, ds_train, ds_test, logdir=None): # ...skip writer = tf.summary.create_noop_writer() if logdir: logdir.mkdir(parents=True, exist_ok=True) writer = tf.summary.create_file_writer(str(logdir)) global_step = 1 tf.summary.trace_on(graph=True) # !!! ADD for epoch in range(1, epochs

TensorFlow2:同一スクリプト内で複数回の学習を回す

パラメータを振った複数の学習を、一気に流したいときにどうするかという話。 エラー落ちする対策をやってみたが、最後に紹介するやり方が素直な気がする。 実行するモデル 今回使うモデルはこちら。weight decayをパラメータでとるようにしている。 import tensorflow as tf # asign aliases tfk = tf.keras tfkl = tf.keras.layers class MyModel2(tfk.Model): def __init__(self, wd=0.001): # add `weight decay` parameter. super(MyModel2, self).__init__() self.conv1 = tfkl.Conv2D(32, 3, padding="same", activation="relu", use_bias=True, kernel_regularizer=tfk.regularizers.l2(wd), name="conv1") self.pool1 = tfkl.MaxPool2D(name="pool1") self.conv2 = tfkl.Conv2D(64, 3, padding="same", activation="relu", use_bias=True, kernel_regularizer=tfk.regularizers.l2(wd), name="conv2") self.pool2 = tfkl.MaxPool2D(name="pool2") self.flatten = tfkl.Flatten() self.d

TensorFlow2:kerasの継承モデルのSummaryを表示する

イメージ
前回のMNISTモデル で summary() を呼び出してモデル構造を見ようと思ったエラーになったので調べた件。 (kerasは使ってなかったけど、パラメータ数とか出してくれるのは羨ましかったのよね) build() や call() を実行してモデルを構築すると出力されるようになる。 以下詳細。 エラーの内容 以下のようなコードを書くとエラーが出る。 class MyModel(tfk.Model): def __init__(self): super(MyModel, self).__init__() self.conv1 = tfkl.Conv2D(32, 3, padding="same", activation="relu", use_bias=True, name="conv1") # ... skip def call(self, inputs, training=False): x = self.conv1(inputs) # ... skip return self.d2(x) model = MyModel() model.summary() # this will error occored ValueError: This model has not yet been built. Build the model first by calling `build()` or calling `fit()` with some data, or specify an `input_shape` argument in the first layer(s) for automatic build.` 対策(1) エラーメッセージに素直に従って、 build() を呼び出してみる。 model = MyModel() model.build((None, 28, 28, 1)) # build with input shape. model.summary()

VSCode:エディタ間移動のkeybindings

コード編集中は、よく参照用などにエディタを分割して行ったり来たりする。 エディタ間の移動を、 Ctrl+w をプレフィックスにしたVim風キーバインドにしてみたのでメモ。 参考: デフォルトでは、Ctrl+[1-9]で1~9番目のエディタグループに移動できます。 設定 Ctrl+w c : 編集中のエディタを閉じる Ctrl+w s : エディタを縦に分割 Ctrl+w v : エディタを横に分割 Ctrl+w n/p : 次/前のエディタに移動 Ctrl+w h/l : 左/右のエディタに移動 Ctrl+w j/k : 下/上のエディタに移動 Ctrl+w </> : エディタサイズを縮小/拡大 最後のエディタサイズの拡縮は、左右分割&先頭グループ以外でやると、不等号の向きとウインドウの動きが一致しないのでちょっと気持ち悪い。先頭グループ以外で押すことは少ないので目をつぶる。 { // [ctrl+w -> c] close active editor. { "key" : "ctrl+w" , "command" : "-workbench.action.closeWindow" , } , { "key" : "ctrl+w" , "command" : "-workbench.action.closeActiveEditor" } , { "key" : "ctrl+w" , "command" : "-workbench.action.closeGroup" , } , { "key" : "ctrl+w c" , "command" : "workbench.action.clo

TensorFlow2:ログディレクトリ指定時のみSummaryを保存する

ちょっと動かすときはログを保存せず、学習時はログを保存する、みたいな切替をやりたくなる。 けど、summary記録箇所全部にif文入れるのはなぁというときの対処。 なにもしないnoop_writerが使える。 サンプルコード def run ( epochs , logdir = None ) : writer = tf . summary . create_noop_writer ( ) if logdir : writer = tf . summary . create_file_writer ( logdir ) for epoch in range ( epochs ) : loss = step_train ( ) with writer . as_default ( ) : # do nothing if writer is noop_writer. tf . summary . scalar ( "train_loss" , loss , epoch ) writer . close ( ) ちょっと記述が減って素敵。