TensorFlow1.x入門(8)——手動調整學習率與TensorBoard

系列文章

1. 計算圖的創建與啓動

2. 變量的定義及其操作

3. Feed與Fetch

4. 線性迴歸

5. 構建非線性迴歸模型

6. 簡單分類問題

7. Dropout與優化器

手動調整學習率與TensorBoard

前言

學習率的調整對模型的收斂較爲重要,當學習率較大時,模型有可能會產生震盪甚至還會發生Loss跑飛的情況。所以隨着迭代的進行,學習率的下降會有利於模型收斂到較好的水平。

TensorBoard是TensorFlow自帶的畫圖工具,能夠記錄變量的變化情況。常常用來記錄模型的Loss以及準確率的變化,同時也可以記錄其他的模型參數以及變量的變化,需要手動添加所需記錄的變量。

知識點

tf.name_scope()定義一個命名空間,不同命名空間中的參數的name可以一樣,避免了命名混亂以及相互之間的污染。同時在TensorBoard中也可以更加直觀的看到相關的曲線與圖像,同時命名空間可以進行嵌套。

tf.sqrt()函數代表了開根號的操作。
tf.summary.scalar()傳入兩個參數,分別是name和相關的值。name代表圖像在TensorBoard中的名稱,值爲圖像上的點。這個函數可以依據迭代的進行二生成對應值的趨勢圖。
tf.summary.histogram()代表繪製直方圖。

要繪製計算圖中的變量及其變化,必須在計算途中將所有的變量融合到一起,做統一的記錄,而不是分開做多次。所以採用如下的代碼在計算圖中進行融合。

	merged = tf.summary.merge_all()

同時TensorBoard可以記錄計算圖,在Session中寫如下語句就可以實現,這樣就會將計算圖保存,並且也會保存要存的變量。

writer = tf.summary.FileWriter('logs/', sess.graph)

在迭代每個epoch時,需要將summary在sess中run一下,將其寫入到上述的文件中。

summary, _ = sess.run([merged, train_step], feed_dict = {x:batch_x, y:batch_y, keep_prob:0.5})
writer.add_summary(summary, epoch * n_batchs + batch)

示例

#%% md
# 手動調整學習率並在TensorBoard中顯示
#%%
import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data
#%% md
載入數據
#%%
mnist = input_data.read_data_sets("MNIST", one_hot=True)
#%%
mnist
#%%
batch_size = 100
n_batchs = mnist.train.num_examples // batch_size
#%% md
## 構建參數的概要函數
#%% md
針對模型的參數進行的統計
#%%
def variable_info(var):
    with tf.name_scope('summaries'):
        mean_value = tf.reduce_mean(var)
        tf.summary.scalar('mean', mean_value)
        with tf.name_scope('stddev'):
            stddev_value = tf.sqrt(tf.reduce_mean(tf.square(var - mean_value)))
        tf.summary.scalar('stddev', stddev_value)
        tf.summary.scalar('max', tf.reduce_max(var))
        tf.summary.scalar('min', tf.reduce_min(var))
        tf.summary.histogram('histogram',var)
#%% md
## 定義輸入層
#%%
with tf.name_scope("input_layer"):
    x = tf.placeholder(tf.float32, [None, 784])
    y = tf.placeholder(tf.float32, [None, 10])
    keep_prob = tf.placeholder(tf.float32)
    lr = tf.Variable(0.01,tf.float32)
    tf.summary.scalar('learning_rate',lr)
#%% md
## 定義網絡結構
#%%
with tf.name_scope('network'):
    with tf.name_scope("weights"):
        w = tf.Variable(tf.truncated_normal([784,10], stddev=0.1), name='w')
        variable_info(w)
    with tf.name_scope('baises'):
        b = tf.Variable(tf.zeros([10]) + 0.1, name="b")
        variable_info(b)
    with tf.name_scope('xw_plus_b'):
        a = tf.matmul(x,w) + b
    with tf.name_scope('softmax'):
        out = tf.nn.softmax(a)
#%% md
## 定義交叉熵損失函數與優化器
#%%
with tf.name_scope("loss_train"):
    loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=out, labels=y))
    train_step = tf.train.AdamOptimizer(lr).minimize(loss)
    tf.summary.scalar("loss", loss)
    
#%% md
##  定義評價模塊
#%%
with tf.name_scope("eval"):
    with tf.name_scope("correct"):
        correct = tf.equal(tf.argmax(out, 1), tf.argmax(y, 1))
    with tf.name_scope("accuracy"):
        accuracy = tf.reduce_mean(tf.cast(correct, tf.float32))
        tf.summary.scalar('accuracy',accuracy)
#%% md
## 初始化變量和summary
#%%
init = tf.global_variables_initializer()
merged = tf.summary.merge_all()
#%% md
## 訓練
#%%
with tf.Session() as sess:
    sess.run(init)
    writer = tf.summary.FileWriter('logs/', sess.graph)
    for epoch in range(200):
        sess.run(tf.assign(lr, 0.001 * (0.95 ** epoch)))
        for batch in range(n_batchs):
            batch_x, batch_y = mnist.train.next_batch(batch_size)
            summary, _ = sess.run([merged, train_step], feed_dict = {x:batch_x, y:batch_y, keep_prob:0.5})
            writer.add_summary(summary, epoch * n_batchs + batch)
        loss_value, acc, lr_value = sess.run([loss, accuracy, lr], feed_dict = {x:mnist.test.images, y:mnist.test.labels, keep_prob:1.0})
        print("Iter: ", epoch, "Loss: ", loss_value, "Acc: ", acc, "lr: ", lr_value)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章