標籤:

cs20si:tensorflow for research 學習筆記2

TensorBoard 可視化

tensorflow不僅僅是一個計算圖軟體,其還包含了tensorboard可視化工具,安裝tensorflow的時候會默認安裝,使用方法非常簡單,使用writer = tf.summary.FileWriter(./graph, sess.graph)就能夠創建一個文件寫入器,./graph是存儲目錄,sess.graph表示讀入的圖結構。

我們可以寫一個簡單的小程序

import tensorflow as tfa = tf.constant(2)b = tf.constant(3)x = tf.add(a, b)with tf.Session() as sess: writer = tf.summary.FileWriter(./graphs, sess.graph) print(sess.run(x))writer.close() # close the writer when you』re done using it

然後打開終端,運行程序,接著輸入`tensorboard --logdir="./graphs"`,然後打開網頁輸入 http://localhost:6006/,就能夠進入tensorboard,可以得到下面的結果。

常數類型(Constant types)

能夠通過下面這個方式創造一個常數

tf.constant(value, dtype=None, shape=None, name=Const, verify_shape=False)

比如建立一維向量和矩陣,然後將他們乘起來

a = tf.constant([2, 2], name=a)b = tf.constant([[0, 1], [2, 3]], name=b)x = tf.multiply(a, b, name=dot_production)with tf.Session() as sess: print(sess.run(x))>> [[0, 2] [4, 6]]

這跟numpy裡面的是差不多的,同時還有一些特殊值的常量創建。

tf.zeros(shape, dtype=tf.float32, name=None)tf.zeros_like(input_tensor, dtype=None, name=None, optimize=True)tf.ones(shape, dtype=tf.float32, name=None)tf.ones_like(input_tensor, dtype=None, name=None, optimize=True)tf.fill(dims, value, name=None)tf.fill([2, 3], 8)>> [[8, 8, 8], [8, 8, 8]]

也有和numpy類似的序列創建

tf.linspace(start, stop, num, name=None)tf.linspace(10.0, 13.0, 4)>> [10.0, 11.0, 12.0, 13.0]tf.range(start, limit=None, delta=1, dtype=None, name=range)tf.range(3, limit=18, delta=3)>> [3, 6, 9, 12, 15]

這和numpy最大的區別在於其不能迭代,即

for _ in tf.range(4): # TypeError

除此之外還可以產生一些隨機數

tf.random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None)tf.truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None,name=None)tf.random_uniform(shape, minval=0, maxval=None, dtype=tf.float32, seed=None,name=None)tf.random_shuffle(value, seed=None, name=None)tf.random_crop(value, size, seed=None, name=None)tf.multinomial(logits, num_samples, seed=None, name=None)tf.random_gamma(shape, alpha, beta=None, dtype=tf.float32, seed=None, name=None)

另外tensorflow和numpy的數據類型可以通用,也就是說

tf.ones([2, 2], np.float32)>> [[1.0, 1.0], [1.0, 1.0]]

最好不要使用python自帶的數據類型,同時在使用numpy數據類型的時候要小心,因為未來可能tensorflow的數據類型和numpy不再兼容。

變數(Variable)

使用常量會存在什麼問題呢?常量會存在計算圖的定義當中,如果常量過多,這會使得載入計算圖變得非常慢,同時常量的值不可改變,所以引入了變數。

a = tf.Variable(2, name=scalar)b = tf.Variable([2, 3], name=vector)c = tf.Variable([[0, 1], [2, 3]], name=matrix)w = tf.Variable(tf.zeros([784, 10]), name=weight)

變數有著下面幾個操作

x = tf.Variable()x.initializer # 初始化x.eval() # 讀取裡面的值x.assign() # 分配值給這個變數

注意一點,在使用變數之前必須對其進行初始化,初始化可以看作是一種變數的分配值操作。最簡單的初始化方式是一次性初始化所有的變數

init = tf.global_variables_initializer()with tf.Session() as sess: sess.run(init)

也可以對某一部分變數進行初始化

init_ab = tf.variable_initializer([a, b], name=init_ab)with tf.Session() as sess: sess.run(init_ab)

或者是對某一個變數進行初始化

w = tf.Variable(tf.zeros([784, 10]))with tf.Session() as sess: sess.run(w.initializer)

如果我們想取出變數的值,有兩種方法

w = tf.Variable(tf.truncated_normal([10, 10], name=normal))with tf.Session() as sess: sess.run(w.initializer) print(w.eval()) # 方法一 print(sess.run(w)) # 方法二

下面看看這個小程序

w = tf.Variable(10)w.assign(100)with tf.Session() as sess: sess.run(w.initializer) print(w.eval())>> 10

上面這個程度會得到10,這是因為我們雖然定義了assign操作,但是tensorflow是在session中執行操作,所以我們需要執行assign操作。

w = tf.Variable(10)assign_op = w.assign(100)with tf.Session() as sess: sess.run(w.initializer) sess.run(assign_op) print(w.eval())>> 100

另外tensorflow的每個session是相互獨立的,我們可以看看下面這個例子

W = tf.Variable(10)sess1 = tf.Session()sess2 = tf.Session()sess1.run(W.initializer)sess2.run(W.initializer)print(sess1.run(W.assign_add(10))) # >> 20print(sess2.run(W.assign_sub(2))) # >> 8print(sess1.run(W.assign_add(100))) # >> 120print(sess2.run(W.assign_sub(50))) # >> -42sess1.close()sess2.close()

你也可以根據一個變數來定義一個變數

w = tf.Variable(tf.truncated_normal([700, 10]))u = tf.Variable(w * 2)

佔位符(Placeholders)

tensorflow中一般有兩步,第一步是定義圖,第二步是在session中進行圖中的計算。對於圖中我們暫時不知道值的量,我們可以定義為佔位符,之後再用`feed_dict`去賦值。

定義佔位符的方式非常簡單

tf.placeholder(dtype, shape=None, name=None)

dtype是必須要指定的參數,shape如果是None,說明任何大小的tensor都能夠接受,使用shape=None很容易定義好圖,但是在debug的時候這將成為噩夢,所以最好是指定好shape。

我們可以給出下面的小例子。

a = tf.placeholder(tf.float32, shape=[3])b = tf.constant([5, 5, 5], tf.float32)c = a + bwith tf.Session() as sess: print(sess.run(c, feed_dict={a: [1, 2, 3]}))

除此之外,也可以給tensorflow中的運算進行feed操作,如下

a = tf.add(2, 3)b = tf.multiply(a, 3)with tf.Session() as sess: print(sess.run(b, feed_dict={a: 2}))>> 6

lazy loading

lazy loading是指你推遲變數的創建直到你必須要使用他的時候。下面我們看看一般的loading和lazy loading的區別。

# normal loadingx = tf.Variable(10, name=x)y = tf.Variable(20, name=y)z = tf.add(x, y)with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for _ in range(10): sess.run(z)# lazy loadingx = tf.Variable(10, name=x)y = tf.Variable(20, name=y)with tf.Session() as sess: sess.run(tf.global_variables_initializer()) for _ in range(10): sess.run(tf.add(x, y))

normal loading 會在圖中創建x和y變數,同時創建x+y的運算,而lazy loading只會創建x和y兩個變數。這不是一個bug,那麼問題在哪裡呢?

normal loading在session中不管做多少次x+y,只需要執行z定義的加法操作就可以了,而lazy loading在session中每進行一次x+y,就會在圖中創建一個加法操作,如果進行1000次x+y的運算,normal loading的計算圖沒有任何變化,而lazy loading的計算圖會多1000個節點,每個節點都表示x+y的操作。

看到了嗎,這就是lazy loading造成的問題,這會嚴重影響圖的讀入速度。

本文的內容和代碼都在該github上

歡迎訪問我的博客

歡迎查看我的知乎專欄深度煉丹


推薦閱讀:

深入淺出Tensorflow(一):深度學習及TensorFlow簡介
K-means聚類 的 Python 實現【圖文解釋】
評論上的情感分析:主題與情感詞抽取

TAG:TensorFlow |