通俗易懂之Tensorflow summary類 & 初識tensorboard
前面學習的cifar10項目雖小,但卻五臟俱全。全面理解該項目非常有利於進一步的學習和提高,也是走向更大型項目的必由之路。因此,summary依然要從cifar10項目說起,通俗易懂的理解並運用summary是本篇博客的關鍵。
先不管三七二十一,列出cifar10中定義模型和訓練模型中的summary的代碼:
# Display the training images in the visualizer. tf.summary.image(‘images‘, images)
def _activation_summary(x): """Helper to create summaries for activations. Creates a summary that provides a histogram of activations. Creates a summary that measure the sparsity of activations. Args: x: Tensor Returns: nothing""" # Remove ‘tower_[0-9]/‘ from the name in case this is a multi-GPU training # session. This helps the clarity of presentation on tensorboard. tensor_name = re.sub(‘%s_[0-9]*/‘ % TOWER_NAME, ‘‘, x.op.name) tf.summary.histogram(tensor_name + ‘/activations‘, x) tf.summary.scalar(tensor_name + ‘/sparsity‘, tf.nn.zero_fraction(x))
_activation_summary(conv1)
_activation_summary(conv2)
_activation_summary(local3)
_activation_summary(local4)
_activation_summary(softmax_linear)
def _add_loss_summaries(total_loss): """Add summaries for losses in CIFAR-10 model. Generates moving average for all losses and associated summaries for visualizing the performance of the network. Args: total_loss: Total loss from loss(). Returns: loss_averages_op: op for generating moving averages of losses.""" # Compute the moving average of all individual losses and the total loss. loss_averages = tf.train.ExponentialMovingAverage(0.9, name=‘avg‘) losses = tf.get_collection(‘losses‘) loss_averages_op = loss_averages.apply(losses + [total_loss]) # Attach a scalar summary to all individual losses and the total loss; do the # same for the averaged version of the losses. for l in losses + [total_loss]: # Name each loss as ‘(raw)‘ and name the moving average version of the loss # as the original loss name. tf.summary.scalar(l.op.name +‘ (raw)‘, l) tf.summary.scalar(l.op.name, loss_averages.average(l)) return loss_averages_op
tf.summary.scalar(‘learning_rate‘, lr) # Add histograms for trainable variables. for var in tf.trainable_variables(): tf.summary.histogram(var.op.name, var) # Add histograms for gradients. for grad, var in grads: if grad is not None: tf.summary.histogram(var.op.name + ‘/gradients‘, grad)
# Build the summary operation based on the TF collection of Summaries. summary_op = tf.summary.merge_all() summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph)
if step % 100 == 0: summary_str = sess.run(summary_op) summary_writer.add_summary(summary_str, step)
通過觀察,聰明的大家不禁發現以下問題:
- 函數_activation_summary可以為每一層激活值創建summary,而無任何返回值,既然沒有返回值,也就說明沒有數據的流動,也就是並非有意義的節點;
- summary類包含histogram和scalar兩種類型,而且似乎這兩種類型是有嚴格劃分的:為什麽這麽說呢?代碼中可以看到,學習率就是scalar類型,梯度值就是histogram類型;
- summary類在cifar10項目中普遍存在,包含學習率、梯度值、激活值、變量、loss等,而這些似乎都是在深度學習過程中,我們比較關心的量,這似乎讓人無限遐想。
帶著這些發現,我們又不禁產生下列疑問:
- summary如果都不是節點,那它在會話中起到什麽作用,又執行了什麽操作?
- summary類包含的數據類型有哪些,它們之間是如何劃分的?
- 我們可以為哪些量創建summary,除了上述函數,summary類中還包含哪些常見的函數?
帶著這些問題,打開官方的tutorial、API教程,這裏是中文版。純粹點說,summary和TensorBoard有關,也就是和tf的可視化有關。
上面列出的代碼實際上給我們列出了一個過程,就是使用summary或者可視化tensorboard的過程,具體來說:
- 為你需要可視化記錄的量創建summary,summary其實就相當於一個監測器,你讓它監測誰就監測誰,附加在你想監測的量上,如果沒有它,也就無從談起tensorboard可視化,根本不知道可視化什麽量;
- 收集匯總圖中所有創建的summary,如果不匯總,相互之間就沒有關聯,需要一個一個在會話中運行,麻煩費事;
- 把收集的數據寫入指定的文件,summary本身並不能可視化,保存數據則是為了tensorboard的可視化;
再從表面上來看,訓練cifar10模型,得到的文件問下:
歸納一下就是:
- checkpoint文件。打開該文件,內容如下:
model_checkpoint_path: "model.ckpt-1000" all_model_checkpoint_paths: "model.ckpt-0" all_model_checkpoint_paths: "model.ckpt-1000"
可見,該文件是記錄中間保存模型的位置的,第一行表明最新的模型,其他行是保存的其它模型,隨叠代次數從低到高排列。
- tfevents文件。該文件是保存的summary日誌文件,比如cifar10項目是每隔100次進行更新,代碼如下:
if step % 100 == 0: summary_str = sess.run(summary_op) summary_writer.add_summary(summary_str, step)
裏面就記錄著整個匯總summary監測的數據以及模型圖。這個文件是要在tensorboard可視化中要用到的。
- model data文件。該文件保存了所有訓練變量所在叠代次數時的值。比如上面的0和1000次。
- model index文件。該文件保存了所有訓練變量的名稱。
- model meta文件。該文件保存在模型圖的結構。
上述三個model文件data和index是結合在一起確定變量的,meta是模型網絡的結構,這和變量的加載聯系起來,就會發現,加載時data和index是必須的,因此可以只加載變量不加載圖結構,或者都加載,下面的例子是cifar10_eval.py中的例子,顯然這是屬於第一種,只加載了變量沒有加載圖結構而使用了默認圖。
tf.app.flags.DEFINE_string(‘checkpoint_dir‘, ‘cifar10_train/‘, """Directory where to read model checkpoints.""") def eval_once(saver, summary_writer, top_k_op, summary_op): """Run Eval once. Args: saver: Saver. summary_writer: Summary writer. top_k_op: Top K op. summary_op: Summary op. """ with tf.Session() as sess: ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir) if ckpt and ckpt.model_checkpoint_path: # Restores from checkpoint saver.restore(sess, ckpt.model_checkpoint_path) # Assuming model_checkpoint_path looks something like: # /my-favorite-path/cifar10_train/model.ckpt-0, # extract global_step from it. global_step = ckpt.model_checkpoint_path.split(‘/‘)[-1].split(‘-‘)[-1] else: print(‘No checkpoint file found‘) return
def evaluate(): """Eval CIFAR-10 for a number of steps.""" with tf.Graph().as_default():
也可以都加載,例如:
tf.app.flags.DEFINE_string(‘checkpoint_dir‘, ‘cifar10_train/‘, """Directory where to read model checkpoints.""") ckpt = tf.train.get_checkpoint_state(FLAGS.checkpoint_dir) saver = tf.train.import_meta_graph(ckpt.model_checkpoint_path +‘.meta‘) with tf.Session() as sess: saver.restore(sess,ckpt.model_checkpoint_path)
那如何用summary保存的訓練日誌啟動tensorboard呢?
只需要tensorboard --logdir=cifar10_train,註意cifar10_train是日誌所在的文件夾,同時請在cifar10_train所在目錄下執行該命令,可得:
請用IE瀏覽器,或者其它高級的瀏覽器(chrome、Firefox)打開圖片中出現的網址即可:http://DESKTOP-HMQ55PS:6006
到此為止,在表面上對summary類有了一定的認識,那接下來可以回答上述的三個疑問。
- summary如果都不是節點,那它在會話中起到什麽作用,又執行了什麽操作?
答:summary類是tensorboard可視化訓練過程和圖結構的基礎,它相當於一個監測器,在哪加就說明想要監測哪,summary類沒有執行任何實質性操作,tf就是這樣,如果不建立會話啟動的話,一切都是靜態的,當然,summary類只是監測動態性,因此無實質性操作,只能說不同的函數有不同的功能和目的,這將在第三問探討。
- summary類包含的數據類型有哪些,它們之間是如何劃分的?
答:從tensorboard可視化的截圖中可以發現,summary類包含的數據類型有:scalar、image、graph、histogram、audio。其中前四種在本項目中都出現了,只有audio類型沒有出現。那它們是如何劃分的呢?顯然是按照類型劃分的......scalar表示標量,image表示圖片,graph表示網絡節點模型圖,histogram表示變量的直方圖,audio表示音頻數據,具體內容參考上述代碼,也很容易明白,scalar通常表示單一的量,例如學習率、loss、AP等,而histogram表示的是統計信息,比如梯度、激活值等。graph通過summary_writer = tf.summary.FileWriter(FLAGS.train_dir, sess.graph)代碼中的sess.graph得到。註意除此之外,tensorboard還有兩個統計信息,一個是distributions,統計權值、偏置和梯度的分布,另一個是projector,包含T-SNE和PCA。
- 我們可以為哪些量創建summary,除了上述函數,summary類中還包含哪些常見的函數?
答:通常意義上只要符合上述5類的都可以創建summary,但是常用的有意義的量就上述常見的那些。summary類中常見的函數就上面那些,除此之外的很少遇到,詳見API。
人人都說,創作需要靈感,甚至需要一些情愫,感動的、真誠的、又或是善意的,這就是生活,如果我們能把工作和學習當作是創作一樣,又有什麽遺憾呢?
通俗易懂之Tensorflow summary類 & 初識tensorboard