系列文章
前言
學習率的調整對模型的收斂較爲重要,當學習率較大時,模型有可能會產生震盪甚至還會發生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)