在第一節中我們已經介紹了一些TensorFlow的編程技巧;第一節,TensorFlow基本用法,但是內容過於偏少,對於TensorFlow的講解並不多,這一節對之前的內容進行補充,並更加深入了解講解TensorFlow.
TesorFlow的命名來源於本身的運行原理。Tensor(張量)意味着N維數組,Flow(流)意味着基於數據流圖的計算。TensorFlow是張量從圖像的一端流動到另一端的計算過程,這也是TensorFlow的編程模型。
TensorFlow編程基礎上主要介紹session的創建,以及session與圖的交互機制,最后講解一下在session中指定GPU運算資源。
一 運行機制
TensorFlow的運行機制屬於"定義"與”運行“相分離。從操作層面可以抽象成兩種:構造模型和模型運行。
在講解構建模型之前,需要講解幾個概念。在一個叫做"圖"的容器中包括:
- 張量(tensor):TensorFlow程序使用tensor數據結構來代表所有的數據,計算圖中,操作間傳遞的數據都是tensor,你可以把TensorFlow tensor看做一個n維的數組或者列表。
- 變量(Variable):常用於定義模型中的參數,是通過不斷訓練得到的值。比如權重和偏置。
- 占位符(placeholder):輸入變量的載體。也可以理解成定義函數時的參數。
- 圖中的節點操作(op):一個op獲得0個或者多個Tensor,執行計算,產生0個或者多個Tensor。op是描述張量中的運算關系,是網絡中真正結構。
一個TensorFlow圖描述了計算的過程,為了進行計算,圖必須在會話里啟動,會話將圖的op分發到諸如CPU或者GPU的設備上,同時提供執行op的方法,這些方法執行后,將產生的tensor返回,在python語言中,返回的tensor是numpy array對象,在C或者C++語言中,返回的tensor是tensorflow:Tensor實例。
session與圖的交互過程中定義了以下兩種數據的流向機制。
- 注入機制(feed):通過占位符向模式中傳入數據。
- 取回機制(fetch):從模式中取得結果。
二 session的使用
1.session案例
第一個案例是通過session輸出一段字符串信息,通過這個案例,讓我們了解session如何創建。
import tensorflow as tf ''' TensorFlow 編程基礎 ''' ''' 1.編寫hello world程序掩飾session的使用 建立一個session,在session中輸出hello TensorFlow ''' #定義一個常量 hello = tf.constant('hello TensorFlow') #構造階段完成后,才能啟動圖,啟動圖的第一步是創建一個Session對象,如果無任何創建函數,會話構造器將啟動默認圖 sess = tf.Session() #通過session里面的run()函數來運行結果 print(sess.run(hello)) #或者 print(hello.eval(session=sess)) #任務完畢,關閉會話,Session對象在使用完畢后需要關閉以釋放資源,除了顯示調用close()外,也可以使用with代碼塊 sess.close() ''' 2. with session的使用 ''' a = tf.constant(3) b = tf.constant(4) with tf.Session() as sess: print(' a + b = {0}'.format(sess.run(a+b))) print(' a * b = {0}'.format(sess.run(a*b))) ''' 3.交互式session ''' #進入一個交互式TensorFlow會話 sess = tf.InteractiveSession() x = tf.Variable([1.0,2.0]) a = tf.constant([3.0,3.0]) #使用初始化器 initinalizer op的run()初始化x x.initializer.run() #增加一個減去sub op,從 x 減去 a,運行減去op,輸出結果 sub = tf.subtract(x,a) print(sub.eval()) #[-2. -1.]
上面使用了三種方法創建session,一個是是用了with代碼塊,一個是沒有使用with代碼塊。還有幾種交互式session方式。
為了方便使用諸如Jupter之類的Python交互環境,可以使用InteractiveSession替代Session類,使用Tensor.eval()和Operation.run()方法來代替Session.run(),這樣可以避免使用一個變量來持有會話。
2.session的注入機制
feed 使用一個 tensor 值臨時替換一個操作的輸出結果. 你可以提供 feed 數據作為 run()
調用的參數. feed 只在調用它的方法內有效, 方法結束,feed 就會消失. 最常見的用例是將某些特殊的操作指定為 "feed" 操作, 標記的方法是使用 tf.placeholder() 為這些操作創建占位符。下面將演示如何使用feed機制將上一個案例程序中的數值通過占位符傳入。
''' 4.注入機制 ''' a = tf.placeholder(dtype=tf.float32) b = tf.placeholder(dtype=tf.float32) add = a + b product = a*b with tf.Session() as sess: #啟動圖后,變量必須先經過'初始化' op sess.run(tf.global_variables_initializer()) print(' a + b = {0}'.format(sess.run(add,feed_dict={a:3,b:4}))) print(' a * b = {0}'.format(sess.run(product,feed_dict={a:3,b:4})))
#一次取出兩個節點值
print(' {0}'.format(sess.run([add,product],feed_dict={a:3,b:4})))
注意這個案例最后一個print一次取出來兩個節點的值。
3.指定GPU運算
在實現上, TensorFlow 將圖形定義轉換成分布式執行的操作, 以充分利用可用的計算資源(如 CPU 或 GPU).一般你不需要顯式指定使用 CPU 還是 GPU, TensorFlow 能自動檢測. 如果檢測到 GPU, TensorFlow 會盡可能地利用找到的第一個 GPU 來執行操作.如果機器上有超過一個可用的 GPU, 除第一個外的其它 GPU 默認是不參與計算的. 為了讓 TensorFlow 使用這些 GPU, 你必須將 op 明確指派給它們執行. with...Device 語句用來指派特定的 CPU 或 GPU 執行操作:
''' 5.指定GPU運算 ''' with tf.Session() as sess: with tf.device("/cpu:0"): print(sess.run(product,feed_dict={a:3,b:4}))
設備用字符串進行標識. 目前支持的設備包括: "/cpu:0": 機器的 CPU. "/gpu:0": 機器的第一個 GPU, 如果有的話. "/gpu:1": 機器的第二個 GPU, 以此類推.
類似的還有通過tf.ConfigProto來構建一個config,在config中指定相關的GPU,並且在session中傳入參數config='自己創建的config'來指定GPU操作
tf.ConfigProto參數如下:
- log_device_placement = True:是否打印設備分配日志
- allow_soft_placement = True:如果指定的設備不存在,允許TF自動分配設備
config=tf.ConfigProto(log_device_placement=True,allow_soft_placement=True)
session = tf.Session(config = config)
4.設置GPU使用資源
上面的tf.ConfigProto函數生成config之后,還可以設置其屬性來分配GPU的運算資源。如下代碼就是按需分配的意思。剛開始會分配少量的GPU容量,然后按需慢慢地增加,由於不會釋放內存,所以會導致碎片。
''' 6 設置GPU使用資源 ''' #按需分配GPU使用的資源 config.gpu_options.allow_growth = True
同樣,上述代碼也可以放在config創建時指定,如下:
#或者 gpu_options = tf.GPUOptions(allow_growth = True) config = tf.ConfigProto(gpu_options = gpu_options)
我們還可以給GPU分配固定大小得計算資源,如分配給tensorflow的GPU的顯存的大小為:GPU顯存x0.7
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction = 0.7)
完整代碼:

# -*- coding: utf-8 -*- """ Created on Tue Apr 17 19:47:48 2018 @author: zy """ import tensorflow as tf ''' TensorFlow 編程基礎上 這一節主要介紹session的創建,以及session與圖的交互機制,最后講解一下在session中指定GPU運算資源。 ''' ''' 1.編寫hello world程序掩飾session的使用 建立一個session,在session中輸出hello TensorFlow ''' #定義一個常量 hello = tf.constant('hello TensorFlow') #構造階段完成后,才能啟動圖,啟動圖的第一步是創建一個Session對象,如果無任何創建函數,會話構造器將啟動默認圖 sess = tf.Session() #通過session里面的run()函數來運行結果 print(sess.run(hello)) #或者 print(hello.eval(session=sess)) #任務完畢,關閉會話,Session對象在使用完畢后需要關閉以釋放資源,除了顯示調用close()外,也可以使用with代碼塊 sess.close() ''' 2. with session的使用 ''' a = tf.constant(3) b = tf.constant(4) with tf.Session() as sess: print(' a + b = {0}'.format(sess.run(a+b))) print(' a * b = {0}'.format(sess.run(a*b))) ''' 3.交互式session ''' #進入一個交互式TensorFlow會話 sess = tf.InteractiveSession() x = tf.Variable([1.0,2.0]) a = tf.constant([3.0,3.0]) #使用初始化器 initinalizer op的run()初始化x x.initializer.run() #增加一個減去sub op,從 x 減去 a,運行減去op,輸出結果 sub = tf.subtract(x,a) print(sub.eval()) #[-2. -1.] ''' 4.注入機制 ''' a = tf.placeholder(dtype=tf.float32) b = tf.placeholder(dtype=tf.float32) add = a + b product = a*b with tf.Session() as sess: #啟動圖后,變量必須先經過'初始化' op sess.run(tf.global_variables_initializer()) print(' a + b = {0}'.format(sess.run(add,feed_dict={a:3,b:4}))) print(' a * b = {0}'.format(sess.run(product,feed_dict={a:3,b:4}))) #一次取出兩個節點值 print(' {0}'.format(sess.run([add,product],feed_dict={a:3,b:4}))) ''' 5.指定GPU運算 ''' ''' 設備用字符串進行標識. 目前支持的設備包括: "/cpu:0": 機器的 CPU. "/gpu:0": 機器的第一個 GPU, 如果有的話. "/gpu:1": 機器的第二個 GPU, 以此類推. ''' with tf.Session() as sess: with tf.device("/cpu:0"): print(sess.run(product,feed_dict={a:3,b:4})) ''' 通過tf.ConfigProto來構建一個config,在config中指定相關的GPU,並且在session中傳入參數config='自己創建的config'來指定GPU操作 tf.ConfigProto參數如下 log_device_placement = True:是否打印設備分配日志 allow_soft_placement = True:如果指定的設備不存在,允許TF自動分配設備 ''' config = tf.ConfigProto(log_device_placement=True,allow_soft_placement=True) session = tf.Session(config = config) ''' 6 設置GPU使用資源 ''' #tf.ConfigProto生成之后,還可以按需分配GPU使用的資源 config.gpu_options.allow_growth = True #或者 gpu_options = tf.GPUOptions(allow_growth = True) config = tf.ConfigProto(gpu_options = gpu_options) #給GPU分配固定大小得計算資源,如分配給tensorflow的GPU的顯存的大小為:GPU顯存x0.7 gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction = 0.7)