【tensorflow】tensorflow相關基礎概念

參考極客時間 彭靖田老師:TensorFlow快速入門與實戰

課程鏈接

0 數據流圖

TensorFlow 是一個編程系統, 使用圖來表示計算任務。圖中每個節點稱作operation。
通過一個可執行隊列,藉助拓撲排序的方式,把所有入度爲0的節點放入執行隊列中,每執行一個節點,就會更新它的入度和所連接的節點,然後執行下一層次入度爲0的執行隊列,可以進行並行運算。

0.1 有向邊:數據流向

  • 張量(Tensor):使用高維數組表示數據。

  • 稀疏張量(SparseTensor):有意義的數值存下來索引和值。然後存下來矩陣形狀,不用把所有的值都存下來。

0.2 節點:

  • 計算節點(Operation):計算操作,邏輯操作等
  • 存儲節點(Variable):變量,訓練對象等,存儲迭代更新的數據
  • 數據節點(Placeholder):描述額外輸入的數據

1 基本結構

1.1 張量(Tensor)

就是標量,向量,數組,多維數組的通用表示說法。

張量的描述有兩個重要屬性:

  • 數據類型(內部數據類型要一樣)
  • 數組形狀
Tensor("Const:0", shape=(1,), dtype=float32)

在這裏插入圖片描述
常見的張量操作:

  • tf.constant() 常量,不可變
  • tf.Variable() 變量,運行中一直在內存中
  • tf.placeholder() 先佔位,高維數據殼
animal = tf.Variable("dog", tf.string)
num = tf.Variable(451, tf.int32)

類型:tf.float,tf.string,tf.int,tf.complex,tf.bool

聲明張量的時候要給定數據和類型。也可以指定在tensorflow裏的名字name=’’,不是變量名

張量的階和維度

注意看 shape=()裏面的部分,裏面有幾個數就是幾階,然後看數的內容判斷數據維度和每維的結構。

0階和1階

# 0 階 數學標量 shape爲空
pai = tf.Variable(3.14159265359, tf.float64)
<tf.Variable 'Variable_1:0' shape=() dtype=float32_ref>

# 1階 數學向量,shape裏一個數,數5表示5個元素
first_primes = tf.Variable([2, 3, 5, 7, 11],tf.int32)
<tf.Variable 'Variable_2:0' shape=(5,) dtype=int32_ref>

2 階和 3 階

# 2 階數組,shape裏兩個數,表示第1維2個元素,下一維每維1個數
m = tf.Variable([[6],[12]], tf.int32)
<tf.Variable 'Variable_3:0' shape=(2, 1) dtype=int32_ref>

# 3 階,shape裏3個數,3維,數表示每個維度對應的元素個數
aaa = tf.Variable([[[1,2],[3,4]],[[1,2],[3,4]]],tf.int32,name='aaa')
<tf.Variable 'aaa_6:0' shape=(2, 2, 2) dtype=int32_ref>

1.2 變量(Variable)

普通的張量(Tensor)在計算結束後內存就會被釋放,變量會被保存在內存之中,每一步訓練的時候進行迭代更新。

  • 創建

    w = tf.Variable(value,type,name)
    
    W = tf.Variable(tf.random_normal(shape=(1, 4), mean=100, stddev=0.5), name="W")
    b = tf.Variable(tf.zeros([4]), name="b")
    
    [<tf.Variable 'W_4:0' shape=(1, 4) dtype=float32_ref>,
     <tf.Variable 'b_4:0' shape=(4,) dtype=float32_ref>]
    
  • 重新賦值

    w.assign(1.0)
    w.assign_add(2.4)
    

變量的使用圖:
在這裏插入圖片描述

變量保存與使用(Saver):

  • 創建

    saver = tf.train.Saver({'W': W, 'b': b})
    saver = tf.train.Saver([v1, v2])
    saver = tf.train.Saver({v.op.name: v for v in [v1, v2]})
    
  • 保存變量

    saver.save(sess, 'MODEL_SAVE_PATH', global_step=global_step)
    
  • 複用變量

    saver.restore(sess, ckpt.model_checkpoint_path)
    

變量創建後啓動sess會話後必須經過初始化(init_op):

init_op = tf.initialize_all_variables()

恢復數據流圖的圖結構:tf.train.import_meta_graph,還有索引index等恢復方法。

1.3 操作(operation)

數據流圖中的節點對應一個具體的操作,是模型訓練運行的實際載體。包含存儲、計算和數據節點。

  • 存儲:放模型參數,存儲有狀態的變量
  • 數據:佔位描述輸入數據屬性,之後喂數據
  • 計算:運算控制操作,負責邏輯表達流程控制

在數據流圖裏,操作的輸入和輸出都是張量,所以在圖內需要使用TF的指定函數來查看某一個變量的值。數據流圖輸入的訓練和測試數據需要用佔位操作符提前聲明。

name = tf.placeholder(dtype, shape, name)
x = tf.placeholder(tf.int32, shape=(), name="x")

在內部用字典的形式填充數據(Feed)後需要run執行才能更新值:

with tf.Session() as sess:
    print(sess.run(add, feed_dict={x: 10, y: 5}))

常用的操作:
在這裏插入圖片描述

1.4 會話(Operation)

就是一個運行環境,分配資源去真正執行運算操作,之前只是聲明瞭規則和值,並沒有真的把值賦給變量。

  • 創建會話:

    sess = tf.Session()
    with tf.Session() as sess:
    
  • 初始化全局變量

    init = tf.initialize_all_variables()
    sess.run(init)
    #或 sess.run(tf.global_variables_initializer())
    
  • 更新運算

    for step in stepsepoch:
    	sess.run(train_op計算式、節點、變量)
    
  • 關閉會話

    sess.close()
    

先更新值,更新了之後要sess.run()才能取出來值。

sess.run(tf.assign_add(b, [1, 1, 1, 1]))
sess.run(b)
array([1., 1., 1., 1.], dtype=float32)

如果之前數據是使用佔位符placeholder定義的變量,在會話裏run的時候要真正喂入feed_dict數據。

feed_dict = {
    images_placeholder: images_feed,
    labels_placeholder: labels_feed,
}  #佔位的字典,用來作爲每輪batch喂入的數據
with tf.Session() as sess:
    print(sess.run(mul, feed_dict={x: 2, y: 3}))

也可以使用估算張量Tensor.eval()和Operation.run()的形式執行,他們最終都是調用的底層:Sess.run()

tf.global_variables_initializer().run() # Operation.run
fetch = y.eval(feed_dict={x: 3.0})      # Tensor.eval
print(fetch)                            # fetch = w * x + b

可以指定某個執行模塊是用GPU\CPU哪個執行的:

#存儲用CPU
with tf.device("/cpu:0"):
	v=tf.Variable(...)

# 大規模運算用GPU
with tf.device("/gpu:0"):
	z=tf.matmul(x,y)

1.5 優化器(Optimizer)

模型的優化目標:降低損失函數loss。

cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits,
                                                 onehot_labels,name='xentropy')
#比較前向推理計算輸出和one-hot化標籤的距離

loss = tf.reduce_mean(cross_entropy, name='xentropy_mean')

一般使用迭代求解,設定一個初始解,然後基於特定函數模型計算可行解,直到找到最優解或者達到預設收斂條件。

不同優化算法的迭代策略不同:常見牛頓法、梯度下降法、Adam等。

optimizer = tf.train.GradientDescentOptimizer(FLAGS.learning_rate)
global_step = tf.Variable(0, name='global_step', trainable=False)
# 保存全局訓練步數
train_op = optimizer.minimize(loss, global_step=global_step)

優化器的使用步驟:計算梯度》處理梯度()》應用梯度。

在這裏插入圖片描述

常用優化器:
在這裏插入圖片描述

1.6 評估函數

傳入的logits和標籤參數要與loss函數的一致。

eval_correct = mnist.evaluation(logits, labels_placeholder)

在K個最有可能的預測中可以發現真的標籤,那麼這個操作就會將模型輸出標記爲正確。

eval_correct = tf.nn.in_top_k(logits, labels, 1)

準確率:

true_count += sess.run(eval_correct, feed_dict=feed_dict)
precision = float(true_count) / float(num_examples)

2 TensorBoard 可視化工具

數據處理過程中可視化工具,幫助理解算法提升工作效率。

  • 查看數據集分佈
  • 數據流圖是否正確實現
  • 模型參數和超參數變化趨勢
  • 查看評估指標

使用

使用時需要從會話(session)中加載,然後使用FileWriter實例寫入事件文件,最後加載到Tensorboard獲取實例文件中的序列化數據進行展示。
在這裏插入圖片描述

2.1 典型應用形式:

1)首先創建數據流圖:

可以使用tf.name_scope()抽象層節點。
展示的時候可以將一些節點進行抽象,使輸出TF圖像看起來層次關係更明確,之後可以再將抽象層的細節展開顯示。

#只需要定義的時候將參數變量聲明放置在指定的抽象節點之下。
With tf.name_scope('name'):
	定義變量。。。。。
    w = tf。。。。。。。。。

2)然後創建FileWriter實例

創建filewriter實例,加載到當前數據流圖(graph):

tf.reset_default_graph()
writer = tf.summary.FileWriter(savepath,sess.graph)

在數據流圖會話(sess)中加載的實例寫入到eventfile之中,寫完需要關閉FileWriter的輸出流:

writer.close()

3)啓動tensorboard

將eventfile所在的目錄傳給tensorboard,能夠獲取相關的參數可視化展示。需要制定文件位置和打開的host。

tensorboard --logdir ./ --host localhost

默認本地位置,打開瀏覽器複製進去地址就可以。

可能出現的問題

windows10 打開tensorboard 遇到的問題,在瀏覽器打開提示沒有圖(不能用360,用Chrome)。No scalar data was found.

找到文件保存的位置:

writer = tf.summary.FileWriter(r'D:\project\UCIPre\summary\lr2', sess.graph)

進入cmd,cd到最後一級文件夾上一級,轉到文件夾下後直接用logdir=最後name名。

cd D:\project\UCIPre\summary\
summary>tensorboard --logdir=lr2

剛開始用的anaconda prompt 一直提示打不開,用cmd就可以了。
奇葩的是時好時壞。

2.2 官方文檔推薦形式

1)創建事件文件

所有的即時數據都要在圖表構建階段合併至一個操作(op)中。

summary_op = tf.merge_all_summaries()

2) 實例化FileWriter

在創建好會話(session)之後,可以實例化一個tf.train.SummaryWriter,用於寫入包含了圖表本身和即時數據具體值的事件文件。

summary_writer = tf.train.SummaryWriter(FLAGS.train_dir,
                                        graph_def=sess.graph_def)

3)寫入最新的數據

每次運行summary_op時,都會往事件文件中寫入最新的即時數據,函數的輸出會傳入事件文件讀寫器(writer)的add_summary()函數。

summary_str = sess.run(summary_op, feed_dict=feed_dict)
summary_writer.add_summary(summary_str, step)

參考:中文手冊

動手實現一個簡單的全連接神經網:
只看 Fullnet.py 部分即可。 girhub文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章