天天看點

tensorflow(一):基礎

tensorflow簡要入門教程

一、張量

1、張量的概念

      在TensorFlow中,所有的資料都通過張量的形式來表示。從功能的角度,張量可以簡單了解為多元數組,零階張量表示标量(scalar),也就是一個數;一階張量為向量(vector),也就是一維數組;n階張量可以了解為一個n維數組。需要注意的是,張量并沒有真正儲存數字,它儲存的是計算過程。

2、張量的屬性

    以張量Tensor("Add:0", shape=(), dtype=float32) 為例:

(1)名字(Name)

    屬性的第一項就是名字,一般形式為“node:src_output”,node表示節點名稱,src_output 來自節點的第幾個輸出。

(2)形狀(Shape)

    屬性的第二項是次元,張量的次元可以用三個術語來描述:階(Rank)、形狀(Shape)、維數(Dimension Number)。一般表示形式如表1所示。

形狀 維數 例子
() 0-D 4
1 (D0) 1-D [2,3,5]
2 (D0,D1) 2-D [[2,3],[3,4]]
3 (D0,D1,D2) 3-D [[[7],[3]],[[2],[4]]]
N (D0,D1,…,Dn-1) N-D 形為(D0,D1,…,Dn-1)的張量

表3-1 張量的次元表示

(3)類型(Type)

    每一個張量會有一個唯一的類型,TensorFlow在進行運算的時候會對參與運算的所有張量進行類型的檢查,發現類型不比對時會報錯.

    TensorFlow支援14種不同的類型:

    實數 tf.float32, tf.float64

    整數 tf.int8, tf.int16, tf.int32, tf.int64, tf.uint8

    布爾 tf.bool

    複數 tf.complex64, tf.complex128

    預設類型:不帶小數點的數會被預設為int32,帶小數點的會被預設為float32。

二、常量與變量

1、常量 Constant

    常量指在運作過程中不會改變的值,在TensorFlow中無需進行初始化操作。

    建立語句:

    Constant_name = tf.constant(value)

    常量在TensorFlow中一般被用于設定訓練步數、訓練步長和訓練輪數等超參數,此類參數在程式執行過程中一般不需要被改變,是以一般被設定為常量。

2、變量 Variable

    變量是指在運作過程中會改變的值,在TensorFlow中需要進行初始化操作。

    建立語句:

    name_variable = tf.Variable(value, name)

    注意:V是大寫字母

    個别變量初始化:

    init_op = name_variable.initializer()

    使用TensorFlow編寫一個簡單的神經網絡一般會用到幾十個變量,若編寫大型的神經網絡,往往會使用到成千上萬個變量。若每個變量定義完都要初始化未免太過繁瑣,是以TensorFlow有提供所有變量初始化的語句。 所有變量初始化:

    init_op = tf.global_variables_initializer()

# 一個簡單計算圖
node1 = tf.constant(3.0,tf.float32,name="node1")
node2 = tf.constant(4.0,tf.float32,name="node2")
node3 = tf.add(node1, node2)
print(node3)
​
# 建立對話并顯示運作結果
sess = tf.Session()
​
print("運作sess.run(node1)的結果:", sess.run(node1))
# 更新變量并傳回計算結果
print("運作sess.run(node3)的結果:", sess.run(node3))
​
# 關閉session
sess.close()      

三、會話

# 定義計算圖
tens1 = tf.constant([1,2,3])
​
# 建立一個會話
sess = tf.Session()
try:
#使用這個建立好的會話來得到關心的運算的結果。比如可以調用 sess.run(result)
#來得到張量result的取值
    print(sess.run(tens1))
except:
    print("Exception!")
finally:
#關閉會話使得本次運作中使用到的資源可以被釋放
    sess.close()      
node1 = tf.constant(3.0,tf.float32,name="node1")
node2 = tf.constant(4.0,tf.float32,name="node2")
result = tf.add(node1, node2)
​
#建立一個會話,并通過Python中的上下文管理器來管理這個會話
with tf.Session() as sess:
    #使用這建立好的會話來計算關心的結果
    print(sess.run(result))
​
# 不需要再調用 Session.close() 函數來關閉會話
# 當上下文退出時會話關閉和資源釋放也自動完成了      

四、變量的指派

    與傳統的程式設計不同,在TensorFlow中變量定義和初始化後,一般無需人工進行指派,系統會根據算法模型,訓練優化過程中自動調整變量對應的數值。這部分的内容在後面我們使用TensorFlow實作機器學習的一些算法的時候會更加有體會。

    TensorFlow中的變量可以通過設定trainable參數來确定在訓練的時候是否更新其值,如前面提到訓練輪數一般設定為常量,但如果設定為變量,可以設定trainable=False,同樣可以達到程式執行過程中不改變其值的目的。前面提到的訓練輪數可以用以下語句進行變量指派:

    epoch = tf.Variable(0,name='epoch',trainable=False)。

    但是當TensorFlow中有特殊情況需要對變量進行人工更新,也是可以用變量的更新語句的,例如:

    update_op = tf.assign(variable_to_be_updated, new_value)。

import tensorflow as tf
​
value = tf.Variable(0, name="value")
one = tf.constant(1)
new_value = tf.add(value, one)
update_value = tf.assign(value, new_value)
​
init = tf.global_variables_initializer()
​
with tf.Session() as sess:
    sess.run(init)
    for _ in range(10):
        sess.run(update_value)
        print(sess.run(value))      

五、占位符

    前文提到,TensorFlow中的Variable變量類型,在定義時需要初始化,但有些變量定義時并不知道其數值,隻有當真正開始運作程式時,才由外部輸入,比如訓練資料,這時候需要用到占位符。

    占位符,是TensorFlow中特有的一種資料結構,類似動态變量,函數的參數、或者C語言或者Python語言中格式化輸出時的“%”占位符。

    TensorFlow中的占位符雖然定義完之後不需要對其值進行初始化,但是需要确定其資料的Type和Shape。占位符的函數接口如下:

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

    1、Feed送出資料

    在TensorFlow中如果建構了一個包含placeholder操作的計算圖,在程式執行當在session中調用run方法時,placeholder占用的變量必須通過feed_dict參數傳遞進去,否則報錯。圖12提供了一個Feed的樣例。

    注:多個操作可以通過一次Feed完成執行

    2、 Fetch提取資料

    會話運作完成之後,如果我們想檢視會話運作的結果,就需要使用fetch來實作,feed、fetch一般搭配起來使用

import tensorflow as tf
a = tf.placeholder(tf.float32, name='a')
b = tf.placeholder(tf.float32, name='b')
c = tf.multiply(a, b, name='c')

init = tf.global_variables_initializer()

with tf.Session() as sess:
#    sess.run(init)
    # 通過feed_dict的參數傳值,按字典格式
    result = sess.run(c, feed_dict={a:10.0, b:3.5})
    
print(result)      
import tensorflow as tf
a = tf.placeholder(tf.float32, name='a')
b = tf.placeholder(tf.float32, name='b')
c = tf.multiply(a, b, name='c')
d = tf.subtract(a, b, name='d')
with tf.Session() as sess:
    #傳回的兩個值分别賦給兩個變量
    rc,rd = sess.run([c,d], feed_dict={a:[8.0,2.0,3.5], b:[1.5,2.0,4.]})  
    print("value of c=",rc,"value of d=",rd)      

六、tensorboard可視化

1、 在TensorBoard中檢視圖結構

圖3-15 在TensorBoard中檢視圖結構

    上圖代碼中的Logdir指定的目錄為運作後産生日志檔案的目錄,如圖16所示我們可以打開檔案管理器進行檢視。

圖 3-16 日志目錄

2、啟動TensorBoard

    TensorBoard不需要額外安裝,在TensorFlow安裝時已自動完成,在Anaconda Prompt中先進入日志存放的目錄(注:非常重要),再運作TensorBoard,并将日志的位址指向程式日志輸出的位址。

    指令:tensorboard --logdir=/path/log (/path/log為産生日志檔案的目錄)

    啟動服務的端口預設為6006;使用 --port 參數可以改編啟動服務的端口。

    TensorBoard是一個在本地啟動的服務,啟動完成後在浏覽器網址:http://localhost:6006即可進行通路。

3、TensorBoard常用API

API 描述
tf.summary.FileWrite() 建立FileWriter和事件檔案,會在logdir中建立一個新的事件檔案
tf.summary.FileWriter.add_summary() 将摘要添加到事件檔案
tf.summary.FileWriter.add_event() 向事件檔案添加一個事件
tf.summary.FileWriter.add_graph() 向事件檔案添加一個圖
tf.summary.FileWriter.get_logdir() 擷取事件檔案的路徑
tf.summary.FileWriter.flush() 将所有事件都寫入磁盤
tf.summary.FileWriter.close() 将事件寫入磁盤,并關閉檔案操作符
tf.summary.scalar() 輸出包含單個标量值的摘要
tf.summary.histogram() 輸出包含直方圖的摘要
tf.summary.audio() 輸出包含音頻的摘要
tf.summary.image() 輸出包含圖檔的摘要
tf.summary.merge() 合并摘要,包含所有輸入摘要的值

表3-2 TensorBoard常用API

import tensorflow as tf
#清除default graph和不斷增加的節點
tf.reset_default_graph() 

# logdir改為自己機器上的合适路徑
logdir='D:/log'

#定義一個簡單的計算圖,實作向量加法的操作
input1 = tf.constant([1.0, 2.0, 3.0], name="input1")
input2 = tf.Variable(tf.random_uniform([3]), name="input2")
output = tf.add_n([input1, input2], name="add")

#生成一個寫日志的writer,并将目前的TensorFlow計算圖寫入日志。
writer = tf.summary.FileWriter(logdir,tf.get_default_graph())
writer.close()      

繼續閱讀