1. 程式人生 > >TensorFlow框架簡單介紹

TensorFlow框架簡單介紹

前言:TensorFlow框架的安裝以及環境配置,這裡就省略了,網上可以找到許多用安裝包、pip方式安裝的方法,不再贅述。這裡通過對TensorFlow的計算模型、資料模型以及執行模型三個角度的介紹,希望大家能對TensorFlow的工作原理能有一個大致的瞭解。
—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-

“TensorFlow”這個名字是個雙拼的詞——“Tensor”+“Flow”

  • Tensor:張量。(張量這個概念是引用於數學或物理上的,而且在數學和物理上的解釋也不完全相同,當然我們不是來研究它具體是什麼的)。在TensorFlow中,張量可以被簡單理解為多維陣列(下面有詳細解釋)
  • Flow:流、飛。直接表達了張量之間通過計算相互轉化的過程

總結:“Tensor”表明了TensorFlow的資料結構,“Flow”體現了TensorFlow的計算模型。下面的分主題,就是依照這兩個角度分別講解。

一、TensorFlow的計算模型——計算圖

計算圖是TensorFlow中最基本的一個概念,TensorFlow中的所有計算都會被轉化為計算圖上的節點,依據節點中傳遞的值,進行數值的“Flow”。

1、計算圖的概念

TensorFlow是一個通過計算圖的形式來表述計算的程式設計系統——TensorFlow中的每一個計算都是計算圖上的一個節點,而節點之間的邊描述了計算之間的依賴關係。

簡單的說,在計算圖裡任意一個節點上,完成計算,得到輸入或輸出的結果;邊的連線,表明了資料的走向或計算的依賴。計算圖就是資料在“節點–邊–節點”這種週轉方式下抽象出來的圖形概念。下圖是通過TensorBoard畫出來的兩個向量相加樣例的計算圖
這裡寫圖片描述
很直觀的表明節點add依賴於向量a、b的輸入。所有TensorFlow的程式都可以通過上圖所示的計算圖的形式來表示,這也就是TensorFlow的基本計算模型。

2、計算圖的使用

TensorFlow程式一般可以分為兩個階段:第一階段預定義計算圖中所有的計算,不論是資料還是計算方法。第二階段就是指定具體數值,執行計算得到結果。

以下程式碼給出了計算定義階段的樣例

import tensorflow as tf
a = tf.constant([1.0,2.0],name = "a")
b = tf.constant([2.0,3.0],name = "b")
result = a + b

在這個過程中,TensorFlow會自動將定義的計算轉化為計算圖上的節點,可以通過tf.get_default_graph()函式獲取當前預設的計算圖,以下程式碼示意瞭如何獲取預設計算圖以及如何檢視一個運算所屬的計算圖:

print(a.graph is tf.get_default_graph())

二、TensorFlow資料模型——張量

1、張量的概念

張量是TensorFlow管理資料的形式。在TensorFlow中,所有的資料都是通過張量的形式來表示。從功能的角度上看,張量可以簡單理解為多維陣列。其中

  • 零階張量表示標量,也就是一個數
  • 一階張量表示向量,也就是一個一維陣列
  • N階張量可以理解為一個N維陣列

但是張量在TensorFlow中的實現並不是直接採用陣列的形式,它只是對TensorFlow中運算結果的引用;在張量中並沒有真正儲存數字,它儲存的是如何得到這些數字的計算過程。例如引用下面程式碼,當執行時並不會得到加法的結果,而是得到對結果的一個引用:

import tensorflow as tf
#tf.constant是一個計算,這個計算的結果為一個張量,儲存在變數中
a = tf.constant([1.0,2.0],name = "a")
b = tf.constant([2.0,3.0],name = "b")
result = tf.add(a,b,name = "add")
print(result)

""""
輸出如下:
Tensor("add:0", shape=(2,), dtype=float32)
""""

從上結果可以看出TensorFlow中的張量與NumPy中的陣列是不同的——TensorFlow計算的結果並不是一個具體的數字,而是一個張量結構,主要儲存張量的三個屬性:名字(name)、維度(shape)和型別(type)

  • 名字(name):不僅是一個張量的唯一識別符號,同樣也給出了這個張量是如何計算出來的——上面已經介紹了TensorFlow的計算都可以通過計算圖的模型來建立,計算圖中每個節點代表一個計算,計算的結果儲存在張量之中,所以張量與計算圖上節點所代表的計算結果相對應。這樣張量的命名就可以通過“node:scr_output”的形式給出,其中node為節點名稱,scr_output代表當前張量來自節點的第幾個輸出。例上“add:0”就說明result這個張量是節點“add”輸出的第一個結果。
  • 維度(shape):這個屬性描述了一個張量的維度資訊。比如上面樣例中shape=(2,)說明了張量result是一個一維陣列,陣列長度為2
  • 型別:每一個張量會有一個唯一的型別,TensorFlow會對參與運算的所有張量進行型別檢查,只有型別都匹配,才能輸出正確結果。TensorFlow支援14種不同的型別,這裡就不一一羅列了

2、張量的使用

張量的使用主要可以總結為兩大類:

  • 第一類:對中間計算結果的引用。當一個計算包含很多中間結果時,使用張量可以很大程度提高程式碼的可讀性
  • 第二類:當計算圖構造完成,用張量來獲得計算結果,也就是真實值。雖然張量本身沒有儲存具體的數字,但是可以通過下面介紹的會話(session)就可以得到這些具體的數字。

三、TensorFlow執行模型——會話

前面介紹了TensorFlow是如何組織資料和運算的,本節將介紹如何使用會話(session)來執行定義好的運算。

第一種,需要明確呼叫會話的生成函式和關閉函式,防止錯誤執行時候導致的資源洩露。
程式碼流程如下:

#建立一個會話
sess = tf.Session()
#呼叫需要執行的語句;例如sess.run(result)
sess.run(...)
#關閉會話
sess.close()

第二種,通過Python的上下文管理器來使用會話,不用擔心異常退出時資源釋放的問題。
程式碼流程如下:

#建立一個會話,用上下文管理器來管理會話
with tf.Session() as sess:
    sess.run(...)
#不需要呼叫Session.close()函式關閉會話

溫馨提示:

  • sess.run()函式是執行函式
  • 互動環境下要用tf.InteractiveSession()函式直接構建預設會話

—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-

重要提示:

在具體使用TensorFlow框架處理問題的程式中,下面這段語句要放在主程式的前面

sess = tf.InteractiveSession()
init = tf.global_variables_initializer()
sess.run(init)
  • 上面是在具體使用TensorFlow框架前,啟用TensorFlow框架,初始化變數的語句

四、舉例TensorFlow框架做直線擬合

# -*- coding:utf-8 -*-
# -*- author:zzZ_CMing
# -*- 2018/01/22;22:13
# -*- python3.5

import tensorflow as tf
import numpy as np
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

#初始化:隨機生成輸入資料X,得到對應真實值Y
X = np.random.rand(100).astype(np.float32)
Y = X*0.1+0.3

"""
### tensorflow框架——開始
"""
#用隨機數列生成的方式,得到結構是1維,範圍在[-1,1]的權重
W = tf.Variable(tf.random_uniform([1],-1.0,1.0))
#用隨機數列生成的方式,得到全0的偏置值
b = tf.Variable(tf.zeros([1]))
#預測值y
y = W*X+b

#計算預測值與真實值的誤差
loss = tf.reduce_mean(tf.square(y - Y))
#梯度下降法:選擇GradientDescentOptimizer優化器,學習率為0.5
train = tf.train.GradientDescentOptimizer(0.5).minimize(loss)

#tf框架:初始化變數
init = tf.global_variables_initializer()
"""
### tensorflow框架——結束
"""

# 啟用init
sess = tf.Session()
sess.run(init)

for i in range(201):
    sess.run(train)
    if i%20 == 0:
        print(i,sess.run(W),sess.run(b))

主要看TensorFlow框架如何定義、初始化;sess.run()函式如何執行
結果展示:
這裡寫圖片描述

—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
結束語:後續還有TensorFlow各種變數的初始化、TensorBoard視覺化、以及用TensorFlow完成應用的相關部落格,請大家關注。

—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-
—-—-—-—-—-—-—-—-—-—-—-—–—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-—-

TensorFlow框架具體運用展示推薦: