TensorFlow : Guide : TensorBoard: ヒストグラム・ダッシュボード (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 07/15/2018
* TensorFlow 1.9 でドキュメント構成が変わりましたので調整しました。
* 本ページは、TensorFlow の本家サイト Guide – TensorBoard – Histogram Dashboard を翻訳した上で
適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- Windows PC のブラウザからご参加が可能です。スマートデバイスもご利用可能です。
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ |
Facebook: https://www.facebook.com/ClassCatJP/ |
TensorBoard ヒストグラム・ダッシュボードは貴方の TensorFlow グラフのある Tensor の分布が時間とともにどのように変化するかを示します。異なるポイントで tensor の多くのヒストグラムの可視化を揃えて見せることによりこれを遂行します。
基本サンプル
単純なケースから始めましょう: 正規分布に従う変数、ここで平均 (= mean) は時間と共にシフトします。TensorFlow は op tf.random_normal を持ち、これはこの目的のために完璧です。TensorBoard では通常のことですが、summary op を使用してデータを取り込みます、この場合には、‘tf.summary.histogram’ です。
ここにコード・スニペットがあります、これは時間につれて分布の平均が増加するような正規分布に従うデータを含む何某かのヒストグラム要約を生成します。
import tensorflow as tf k = tf.placeholder(tf.float32) # Make a normal distribution, with a shifting mean mean_moving_normal = tf.random_normal(shape=[1000], mean=(5*k), stddev=1) # Record that distribution into a histogram summary tf.summary.histogram("normal/moving_mean", mean_moving_normal) # Setup a session and summary writer sess = tf.Session() writer = tf.summary.FileWriter("/tmp/histogram_example") summaries = tf.summary.merge_all() # Setup a loop and write the summaries to disk N = 400 for step in range(N): k_val = step/float(N) summ = sess.run(summaries, feed_dict={k: k_val}) writer.add_summary(summ, global_step=step)
コードを実行すれば、コマンド行を通してデータを TensorBoard にロードすることができます :
tensorboard --logdir=/tmp/histogram_example
TensorBoard が動作していれば、それを Chrome か Firefox へロードしてヒストグラム・ダッシュボードにナビゲートします。それから正規分布に従うヒストグラム可視化を見ることができます。
tf.summary.histogram は任意のサイズと shape の Tensor を取り、それを幅とカウントを持つ多くのビンから成るヒストグラム・データ構造に圧縮 (= compress) します。例えば、数字 [0.5, 1.1, 1.3, 2.2, 2.9, 2.99] をビンに構造化することを望むとします。3つのビンを作れるでしょう :
- 0 から 1 の総てを含むビン (それは 1 要素, 0.5 を含むでしょう)、
- 1 から 2 の総てを含むビン (それは 2 要素, 1.1 と 1.3 を含むでしょう)、
- 2 から 3 の総てを含むビン (それは 3 要素: 2.2, 2.9 と 2.99 を含むでしょう)。
TensorFlow はビンを作成するために同様のアプローチを使用しますが、この例とは違って、それは整数値ビンを作成しません。巨大な、疎なデータセットに対して、それは数千のビンという結果になるかもしれません。代わりに、ビンは指数関数的に分布して、多くのビンは 0 に近くそして非常に巨大な数のための比較的少ないビンがあります。けれども、指数関数的に分布したビンの可視化はトリッキーです ; もし高さがカウントをエンコードするために使用される場合、より広いビンは更にスペースを取ります、それらが同じ要素数を持つ場合でさえも。逆に、領域でカウントをエンコードすると高さの比較が不可能になります。代わりに、ヒストグラムは一様なビンに データをリサンプリング します。これはある場合には不幸な人工物に繋がるかもしれません。
ヒストグラム・ビジュアライザで各スライスはシングル・ヒストグラムを示します。スライスはステップで構成されます ; より古いスライス (e.g. ステップ 0) は更に “後ろ (= back)” でより暗く、一方でより新しいスライス (e.g. step 400) は最前面に近く、色の点でより明るいです。右側の y-軸はステップ数を示します。
より詳細な情報を持つツールチップを見るにはヒストグラム上でマウスカーソルを移動することができます。例えば、次の画像ではタイムステップ 176 のヒストグラムは 177 要素を持ち 2.25 を中心とするビンを持つことを見て取れます。
また、ヒストグラム・スライスはステップカウントや時間で常に等分に分けられるわけではないことに注意してください。これは TensorBoard は (メモリをセーブするため) 総てのヒストグラムのサブセットを保持するのに reservoir (貯水池) サンプリング を使用するからです。reservoir サンプリングは総てのサンプルが (含まれるために) 等しい尤度を持つことを保証しますが、それはランダム化されたアルゴリズムですから、選択されるサンプルは一定のステップでは発生しません。
オーバーレイ・モード
ダッシュボードの左側に histogram mode を “offset” から “overlay” へのトグルを可能にするコントロールがあります :
“offset” モードでは、ビジュアリゼーションは 45 度回転して、個々のヒストグラム・スライスは時間で広がるのではなく、代わりに総ては同じ y-軸上にプロットされます。
今では、各スライスはチャート上で分離したラインで、y-軸は各バケット内の項目カウントを示します。より暗い線はより古く、より早いステップで、より明るい線はより最近で、後のステップです。再度、何某かの追加情報を見るためにチャート上でマウスカーソルを移動できます。
一般的に、overlay ビジュアリゼーションは異なるヒストグラムのカウントを直接比較することを望む場合に有用です。
マルチモーダル分布
ヒストグラム・ダッシュボードはマルチモーダル分布の可視化について素晴らしいです。2 つの異なる正規分布からの出力を結合して単純なバイモーダル (二峰性) 分布を構築してみましょう。コードはこのようなものです :
import tensorflow as tf k = tf.placeholder(tf.float32) # Make a normal distribution, with a shifting mean mean_moving_normal = tf.random_normal(shape=[1000], mean=(5*k), stddev=1) # Record that distribution into a histogram summary tf.summary.histogram("normal/moving_mean", mean_moving_normal) # Make a normal distribution with shrinking variance variance_shrinking_normal = tf.random_normal(shape=[1000], mean=0, stddev=1-(k)) # Record that distribution too tf.summary.histogram("normal/shrinking_variance", variance_shrinking_normal) # Let's combine both of those distributions into one dataset normal_combined = tf.concat([mean_moving_normal, variance_shrinking_normal], 0) # We add another histogram summary to record the combined distribution tf.summary.histogram("normal/bimodal", normal_combined) summaries = tf.summary.merge_all() # Setup a session and summary writer sess = tf.Session() writer = tf.summary.FileWriter("/tmp/histogram_example") # Setup a loop and write the summaries to disk N = 400 for step in range(N): k_val = step/float(N) summ = sess.run(summaries, feed_dict={k: k_val}) writer.add_summary(summ, global_step=step)
貴方は既に上の例から “移動平均” 正規分布を覚えているでしょう。今 “shrinking variance (分散)” 分布もまた持ちます。それらは並んで、このように見えます :
それらを結合するとき、分岐する、バイモーダル構造を明瞭に示すチャートを得ます :
更に幾つかの分布
楽しみのために、更に幾つかの分布を生成して可視化し、そしてそれら総てを一つのチャートに結合してみましょう。ここに使用するコードがあります :
import tensorflow as tf k = tf.placeholder(tf.float32) # Make a normal distribution, with a shifting mean mean_moving_normal = tf.random_normal(shape=[1000], mean=(5*k), stddev=1) # Record that distribution into a histogram summary tf.summary.histogram("normal/moving_mean", mean_moving_normal) # Make a normal distribution with shrinking variance variance_shrinking_normal = tf.random_normal(shape=[1000], mean=0, stddev=1-(k)) # Record that distribution too tf.summary.histogram("normal/shrinking_variance", variance_shrinking_normal) # Let's combine both of those distributions into one dataset normal_combined = tf.concat([mean_moving_normal, variance_shrinking_normal], 0) # We add another histogram summary to record the combined distribution tf.summary.histogram("normal/bimodal", normal_combined) # Add a gamma distribution gamma = tf.random_gamma(shape=[1000], alpha=k) tf.summary.histogram("gamma", gamma) # And a poisson distribution poisson = tf.random_poisson(shape=[1000], lam=k) tf.summary.histogram("poisson", poisson) # And a uniform distribution uniform = tf.random_uniform(shape=[1000], maxval=k*10) tf.summary.histogram("uniform", uniform) # Finally, combine everything together! all_distributions = [mean_moving_normal, variance_shrinking_normal, gamma, poisson, uniform] all_combined = tf.concat(all_distributions, 0) tf.summary.histogram("all_combined", all_combined) summaries = tf.summary.merge_all() # Setup a session and summary writer sess = tf.Session() writer = tf.summary.FileWriter("/tmp/histogram_example") # Setup a loop and write the summaries to disk N = 400 for step in range(N): k_val = step/float(N) summ = sess.run(summaries, feed_dict={k: k_val}) writer.add_summary(summ, global_step=step)
ガンマ分布
一様分布
ポアソン分布
ポアソン分布は整数に渡り定義されます。そのため、生成される総ての値は完全な整数です。ヒストグラム圧縮はデータを浮動小数点ビンに移動し、ビジュアリゼーションは完全なスパイク (尖った波形) ではなく整数値に渡って小さいバンプ (凹凸) を示すことになります。
All Together Now
最後に、データ総てを一つの奇妙に見える (= funny-looking) カーブに結合することができます。
以上