TensorFlow2.0(9):TensorBoard可視化

 

注:本系列全部博客將持續更新併發布在github上,您能夠經過github下載本系列全部文章筆記文件。javascript

 

1 神器級的TensorBoard

 

TensorBoard是TensorFlow中的又一神器級工具,想用戶提供了模型可視化的功能。咱們都知道,在構建神經網絡模型時,只要模型開始訓練,不少細節對外界來講都是不可見的,參數如何變化,準確率怎麼樣了,loss還在減少嗎,這些問題都很難弄明白。可是,TensorBoard經過結合web應用爲咱們提供了這一功能,它將模型訓練過程的細節以圖表的形式經過瀏覽器可視化得展示在咱們眼前,經過這種方式咱們能夠清晰感知weight、bias、accuracy的變化,把握訓練的趨勢。css

 

本文介紹兩種使用TensorBoard的方式。不過,不管使用那種方式,請先啓動TensorBoard的web應用,這個web應用讀取模型訓練時的日誌數據,每隔30秒更新到網頁端。在TensorFlow2.0中,TensorBoard是默認安裝好的,因此,能夠直接根據如下命令啓動:html

 

tensorboard --logdir "/home/chb/jupyter/logs"html5

 

logdir指的是日誌目錄,每次訓練模型時,TensorBoard會在日誌目錄中建立一個子目錄,在其中寫入日誌,TensorBoard的web應用正是經過日誌來感知模型的訓練狀態,而後更新到網頁端。java

若是命令成功運行,能夠經過本地的6006端口打開網頁,可是,此時打開的頁面時下面這個樣子,由於尚未開始訓練模型,更沒有將日誌寫入到指定的目錄。node

 

image

 

要將訓練數據寫入指定目錄就必須將TensorBoard嵌入模型的訓練過程,TensorFlow介紹了兩種方式。下面,咱們經過mnist數據集訓練過程來介紹着兩種方式。python

 

2 在Model.fit()中使用TensorBoard

In [1]:
import tensorflow as tf
import tensorboard
import datetime
In [20]:
mnist = tf.keras.datasets.mnist

(x_train, y_train),(x_test, y_test) = mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0

def create_model():
  return tf.keras.models.Sequential([
    tf.keras.layers.Flatten(input_shape=(28, 28)),
    tf.keras.layers.Dense(512, activation='relu'),
    tf.keras.layers.Dropout(0.2),
    tf.keras.layers.Dense(10, activation='softmax')
  ])
In [21]:
model = create_model()
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])

# 定義日誌目錄,必須是啓動web應用時指定目錄的子目錄,建議使用日期時間做爲子目錄名
log_dir="/home/chb/jupyter/logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, histogram_freq=1)  # 定義TensorBoard對象

model.fit(x=x_train, 
          y=y_train, 
          epochs=5, 
          validation_data=(x_test, y_test), 
          callbacks=[tensorboard_callback])  # 將定義好的TensorBoard對象做爲回調傳給fit方法,這樣就將TensorBoard嵌入了模型訓練過程
 
Train on 60000 samples, validate on 10000 samples
Epoch 1/5
60000/60000 [==============================] - 4s 71us/sample - loss: 0.2186 - accuracy: 0.9349 - val_loss: 0.1180 - val_accuracy: 0.9640
Epoch 2/5
60000/60000 [==============================] - 4s 66us/sample - loss: 0.0972 - accuracy: 0.9706 - val_loss: 0.0754 - val_accuracy: 0.9764
Epoch 3/5
60000/60000 [==============================] - 4s 66us/sample - loss: 0.0685 - accuracy: 0.9781 - val_loss: 0.0696 - val_accuracy: 0.9781
Epoch 4/5
60000/60000 [==============================] - 4s 66us/sample - loss: 0.0527 - accuracy: 0.9831 - val_loss: 0.0608 - val_accuracy: 0.9808
Epoch 5/5
60000/60000 [==============================] - 4s 66us/sample - loss: 0.0444 - accuracy: 0.9859 - val_loss: 0.0637 - val_accuracy: 0.9803
Out[21]:
<tensorflow.python.keras.callbacks.History at 0x7f9b690893d0>
 

image

 

經過TensorBoard提供的圖標,咱們能夠清楚的知道訓練模型時loss和accuracy在每個epoch中是怎麼變化的,甚至,在網頁菜單欄咱們能夠看到,TensorBoard提供了查看其餘內容的功能:jquery

  • 在 scalars 下能夠看到 accuracy,cross entropy,dropout,bias,weights 等的趨勢。linux

  • 在 images 和 audio 下能夠看到輸入的數據。android

  • 在 graphs 中能夠看到模型的結構。

  • 在 histogram 能夠看到 activations,gradients 或者 weights 等變量的每一步的分佈,越靠前面就是越新的步數的結果。

  • distribution 和 histogram 是兩種不一樣的形式,能夠看到總體的情況。

  • 在 embedding 中能夠看到用 PCA 主成分分析方法將高維數據投影到 3D 空間後的數據的關係。

 

這就是TensorBoard提供的功能,不可爲不強大。這裏,咱們在介紹一下TensorBoard構造方法中的參數: 工具在Tensorflow中是很是經常使用的其參數解釋以下:

  • log_dir:保存TensorBoard要解析的日誌文件的目錄的路徑。
  • histogram_freq:頻率(在epoch中),計算模型層的激活和權重直方圖。若是設置爲0,則不會計算直方圖。必須爲直方圖可視化指定驗證數據(或拆分)。
  • write_graph:是否在TensorBoard中可視化圖像。當write_graph設置爲True時,日誌文件可能會變得很是大。
  • write_grads:是否在TensorBoard中可視化漸變直方圖。 histogram_freq必須大於0。
  • batch_size:用以直方圖計算的傳入神經元網絡輸入批的大小。
  • write_images:是否在TensorBoard中編寫模型權重以顯示爲圖像。
  • embeddings_freq:將保存所選嵌入層的頻率(在epoch中)。若是設置爲0,則不會計算嵌入。要在TensorBoard的嵌入選項卡中顯示的數據必須做爲embeddings_data傳遞。
  • embeddings_layer_names:要關注的層名稱列表。若是爲None或空列表,則將監測全部嵌入層。
  • embeddings_metadata:將層名稱映射到文件名的字典,其中保存了此嵌入層的元數據。若是相同的元數據文件用於全部嵌入層,則能夠傳遞字符串。
  • embeddings_data:要嵌入在embeddings_layer_names指定的層的數據。Numpy數組(若是模型有單個輸入)或Numpy數組列表(若是模型有多個輸入)。
  • update_freq:‘batch’或’epoch’或整數。使用’batch’時,在每一個batch後將損失和指標寫入TensorBoard。這一樣適用’epoch’。若是使用整數,比方說1000,回調將會在每1000個樣本後將指標和損失寫入TensorBoard。請注意,過於頻繁地寫入TensorBoard會下降您的訓練速度。 還有可能引起的異常:
  • ValueError:若是設置了histogram_freq且未提供驗證數據。
 

3 在其餘功能函數中嵌入TensorBoard

 

在訓練模型時,咱們能夠在 tf.GradientTape()等等功能函數中個性化得經過tf.summary()方法指定須要TensorBoard展現的參數。

 

一樣適用fashion_mnist數據集創建一個模型:

In [15]:
import datetime
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import datasets, layers, optimizers, Sequential ,metrics
In [16]:
def preprocess(x, y):
    x = tf.cast(x, dtype=tf.float32) / 255.
    y = tf.cast(y, dtype=tf.int32)
    return x, y
In [17]:
(x, y), (x_test, y_test) = datasets.fashion_mnist.load_data()
db = tf.data.Dataset.from_tensor_slices((x, y))
db = db.map(preprocess).shuffle(10000).batch(128)
db_test = tf.data.Dataset.from_tensor_slices((x_test, y_test))
db_test = db_test.map(preprocess).batch(128)
In [18]:
model = Sequential([
    layers.Dense(256, activation=tf.nn.relu),  #  [b, 784]  --> [b, 256]
    layers.Dense(128, activation=tf.nn.relu),  #  [b, 256]  --> [b, 128]
    layers.Dense(64, activation=tf.nn.relu),  #  [b, 128]  --> [b, 64]
    layers.Dense(32, activation=tf.nn.relu),  #  [b, 64]  --> [b, 32]
    layers.Dense(10)  #  [b, 32]  --> [b, 10]
    ]
)
model.build(input_shape=[None,28*28])
model.summary()
optimizer = optimizers.Adam(lr=1e-3)#1e-3
# 指定日誌目錄
log_dir="/home/chb/jupyter/logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
summary_writer = tf.summary.create_file_writer(log_dir)  # 建立日誌文件句柄
 
Model: "sequential_3"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_15 (Dense)             multiple                  200960    
_________________________________________________________________
dense_16 (Dense)             multiple                  32896     
_________________________________________________________________
dense_17 (Dense)             multiple                  8256      
_________________________________________________________________
dense_18 (Dense)             multiple                  2080      
_________________________________________________________________
dense_19 (Dense)             multiple                  330       
=================================================================
Total params: 244,522
Trainable params: 244,522
Non-trainable params: 0
_________________________________________________________________
In [19]:
db_iter = iter(db)
images = next(db_iter)
# 必須進行reshape,第一個緯度是圖片數量或者說簇大小,28*28是圖片大小,1是chanel,由於只灰度圖片因此是1
images = tf.reshape(x, (-1, 28, 28, 1))  
with summary_writer.as_default():  # 將第一個簇的圖片寫入TensorBoard
    tf.summary.image('Training data', images, max_outputs=5, step=0)   # max_outputs設置最大顯示圖片數量
In [20]:
tf.summary.trace_on(graph=True, profiler=True)
for epoch in range(30):
    train_loss = 0
    train_num = 0
    for step, (x, y) in enumerate(db):

        x = tf.reshape(x, [-1, 28*28])

        with tf.GradientTape() as tape: 
            logits = model(x)
            y_onehot = tf.one_hot(y,depth=10)

            loss_mse = tf.reduce_mean(tf.losses.MSE(y_onehot, logits))
            loss_ce = tf.losses.categorical_crossentropy(y_onehot, logits, from_logits=True)
            
            loss_ce = tf.reduce_mean(loss_ce)  # 計算整個簇的平均loss
        grads = tape.gradient(loss_ce, model.trainable_variables)  # 計算梯度
        optimizer.apply_gradients(zip(grads, model.trainable_variables)) # 更新梯度

        train_loss += float(loss_ce)
        train_num += x.shape[0]
        
    loss = train_loss / train_num  # 計算每一次迭代的平均loss
    with summary_writer.as_default():  # 將loss寫入TensorBoard
        tf.summary.scalar('train_loss', train_loss, step=epoch)

    total_correct = 0
    total_num = 0
    for x,y in db_test:  # 用測試集驗證每一次迭代後的準確率
        x = tf.reshape(x, [-1, 28*28])
        logits = model(x)
        prob = tf.nn.softmax(logits, axis=1)
        pred = tf.argmax(prob, axis=1)
        pred = tf.cast(pred, dtype=tf.int32)
        correct = tf.equal(pred, y)
        correct = tf.reduce_sum(tf.cast(correct, dtype=tf.int32))

        total_correct += int(correct)
        total_num += x.shape[0]
    acc = total_correct / total_num  # 平均準確率
    with summary_writer.as_default():  # 將acc寫入TensorBoard
        tf.summary.scalar('test_acc', acc, step=epoch)
    print(epoch, 'train_loss:',loss,'test_acc:', acc)
 
0 train_loss: 0.004282377735277017 test_acc: 0.8435
1 train_loss: 0.0029437638364732265 test_acc: 0.8635
2 train_loss: 0.0025979293311635654 test_acc: 0.858
3 train_loss: 0.0024499946276346843 test_acc: 0.8698
4 train_loss: 0.0022926158788303536 test_acc: 0.8777
5 train_loss: 0.002190616005907456 test_acc: 0.8703
6 train_loss: 0.0020421392366290095 test_acc: 0.8672
7 train_loss: 0.001972314653545618 test_acc: 0.8815
8 train_loss: 0.0018821696805457274 test_acc: 0.882
9 train_loss: 0.0018143038821717104 test_acc: 0.8874
10 train_loss: 0.0017742110469688972 test_acc: 0.8776
11 train_loss: 0.0017088291154553493 test_acc: 0.8867
12 train_loss: 0.0016564140267670154 test_acc: 0.8883
13 train_loss: 0.001609446036318938 test_acc: 0.8853
14 train_loss: 0.0015313156222303709 test_acc: 0.8939
15 train_loss: 0.0014887714397162199 test_acc: 0.8793
16 train_loss: 0.001450310030952096 test_acc: 0.8853
17 train_loss: 0.001389076333368818 test_acc: 0.892
18 train_loss: 0.0013547154798482855 test_acc: 0.892
19 train_loss: 0.0013331565233568351 test_acc: 0.8879
20 train_loss: 0.001276270254018406 test_acc: 0.8919
21 train_loss: 0.001228199392867585 test_acc: 0.8911
22 train_loss: 0.0012089030482495824 test_acc: 0.8848
23 train_loss: 0.0011713500657429298 test_acc: 0.8822
24 train_loss: 0.0011197352315609655 test_acc: 0.8898
25 train_loss: 0.0011078068762707214 test_acc: 0.8925
26 train_loss: 0.0010750674727062384 test_acc: 0.8874
27 train_loss: 0.0010422117731223503 test_acc: 0.8917
28 train_loss: 0.0010244071063275138 test_acc: 0.8851
29 train_loss: 0.0009715937084207933 test_acc: 0.8929
 

TensorBoard中web界面以下:

 

image

 

image

 

除了上述示例中使用過的scalar、image以外,summary模塊還提供了替他數據嵌入TensorBoard方法:

 

image

 

參考

相關文章
相關標籤/搜索