日萌社
人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度學習實戰(不定時更新)
2.3 會話、張量、變量OP
學習目標
- 目標
- 應用sess.run或者eval運行圖程序並獲取張量值
- 應用feed_dict機制實現運行時填充數據
- 應用placeholder實現創建佔位符
- 知道常見的TensorFlow創建張量
- 知道常見的張量數學運算操作
- 說明numpy的數組和張量相同性
- 說明張量的兩種形狀改變特點
- 應用set_shape和tf.reshape實現張量形狀的修改
- 應用tf.matmul實現張量的矩陣運算修改
- 應用tf.cast實現張量的類型
- 說明變量op的特殊作用
- 說明變量op的trainable參數的作用
- 應用global_variables_initializer實現變量op的初始化
- 應用
- 無
- 內容預覽
2.3.1 會話
一個運行TensorFlow operation的類。會話包含以下兩種開啓方式
- tf.Session:用於完整的程序當中
- tf.InteractiveSession:用於交互式上下文中的TensorFlow ,例如shell
1 TensorFlow 使用 tf.Session 類來表示客戶端程序(通常爲 Python 程序,但也提供了使用其他語言的類似接口)與 C++ 運行時之間的連接
2 tf.Session 對象使用分佈式 TensorFlow 運行時提供對本地計算機中的設備和遠程設備的訪問權限。
2.3.1.1 __init__(target='', graph=None, config=None)
會話可能擁有的資源,如 tf.Variable,tf.QueueBase和tf.ReaderBase。當這些資源不再需要時,釋放這些資源非常重要。因此,需要調用tf.Session.close會話中的方法,或將會話用作上下文管理器。以下兩個例子作用是一樣的:
def session_demo():
"""
會話演示
:return:
"""
a_t = tf.constant(10)
b_t = tf.constant(20)
# 不提倡直接運用這種符號運算符進行計算
# 更常用tensorflow提供的函數進行計算
# c_t = a_t + b_t
c_t = tf.add(a_t, b_t)
print("tensorflow實現加法運算:\n", c_t)
# 開啓會話
# 傳統的會話定義
# sess = tf.Session()
# sum_t = sess.run(c_t)
# print("sum_t:\n", sum_t)
# sess.close()
# 開啓會話
with tf.Session() as sess:
# sum_t = sess.run(c_t)
# 想同時執行多個tensor
print(sess.run([a_t, b_t, c_t]))
# 方便獲取張量值的方法
# print("在sess當中的sum_t:\n", c_t.eval())
# 會話的圖屬性
print("會話的圖屬性:\n", sess.graph)
return None
- target:如果將此參數留空(默認設置),會話將僅使用本地計算機中的設備。可以指定 grpc:// 網址,以便指定 TensorFlow 服務器的地址,這使得會話可以訪問該服務器控制的計算機上的所有設備。
- graph:默認情況下,新的 tf.Session 將綁定到當前的默認圖。
- config:此參數允許您指定一個 tf.ConfigProto 以便控制會話的行爲。例如,ConfigProto協議用於打印設備使用信息
# 運行會話並打印設備信息
sess = tf.Session(config=tf.ConfigProto(allow_soft_placement=True,
log_device_placement=True))
會話可以分配不同的資源在不同的設備上運行。
/job:worker/replica:0/task:0/device:CPU:0
device_type:類型設備(例如CPU,GPU,TPU)
2.3.1.2 會話的run()
- run(fetches,feed_dict=None, options=None, run_metadata=None)
- 通過使用sess.run()來運行operation
- fetches:單一的operation,或者列表、元組(其它不屬於tensorflow的類型不行)
- feed_dict:參數允許調用者覆蓋圖中張量的值,運行時賦值
- 與tf.placeholder搭配使用,則會檢查值的形狀是否與佔位符兼容。
使用tf.operation.eval()也可運行operation,但需要在會話中運行
# 創建圖
a = tf.constant(5.0)
b = tf.constant(6.0)
c = a * b
# 創建會話
sess = tf.Session()
# 計算C的值
print(sess.run(c))
print(c.eval(session=sess))
2.3.1.3 feed操作
- placeholder提供佔位符,run時候通過feed_dict指定參數
def session_run_demo():
"""
會話的run方法
:return:
"""
# 定義佔位符
a = tf.placeholder(tf.float32)
b = tf.placeholder(tf.float32)
sum_ab = tf.add(a, b)
print("sum_ab:\n", sum_ab)
# 開啓會話
with tf.Session() as sess:
print("佔位符的結果:\n", sess.run(sum_ab, feed_dict={a: 3.0, b: 4.0}))
return None
請注意運行時候報的錯誤error:
RuntimeError:如果這Session是無效狀態(例如已關閉)。 TypeError:如果fetches或者feed_dict鍵的類型不合適。 ValueError:如果fetches或feed_dict鍵無效或引用 Tensor不存在的鍵。
在編寫 TensorFlow 程序時,程序傳遞和運算的主要目標是tf.Tensor
2.3.2 張量(Tensor)
TensorFlow 的張量就是一個 n 維數組, 類型爲tf.Tensor。Tensor具有以下兩個重要的屬性
- type:數據類型
- shape:形狀(階)
2.3.2.1 張量的類型
2.3.2.2 張量的階
形狀有0階、1階、2階….
tensor1 = tf.constant(4.0)
tensor2 = tf.constant([1, 2, 3, 4])
linear_squares = tf.constant([[4], [9], [16], [25]], dtype=tf.int32)
print(tensor1.shape)
# 0維:() 1維:(10, ) 2維:(3, 4) 3維:(3, 4, 5)
2.3.3 創建張量的指令
- 固定值張量
- 隨機值張量
- 其它特殊的創建張量的op
- tf.Variable
- tf.placeholder
2.3.4 張量的變換
2.3.4.1 類型改變
2.3.4.2 形狀改變
TensorFlow的張量具有兩種形狀變換,動態形狀和靜態形狀
- tf.reshape
- tf.set_shape
關於動態形狀和靜態形狀必須符合以下規則
- 靜態形狀
- 轉換靜態形狀的時候,1-D到1-D,2-D到2-D,不能跨階數改變形狀
- 對於已經固定的張量的靜態形狀的張量,不能再次設置靜態形狀
- 動態形狀
- tf.reshape()動態創建新張量時,張量的元素個數必須匹配
def tensor_demo():
"""
張量的介紹
:return:
"""
a = tf.constant(value=30.0, dtype=tf.float32, name="a")
b = tf.constant([[1, 2], [3, 4]], dtype=tf.int32, name="b")
a2 = tf.constant(value=30.0, dtype=tf.float32, name="a2")
c = tf.placeholder(dtype=tf.float32, shape=[2, 3, 4], name="c")
sum = tf.add(a, a2, name="my_add")
print(a, a2, b, c)
print(sum)
# 獲取張量屬性
print("a的圖屬性:\n", a.graph)
print("b的名字:\n", b.name)
print("a2的形狀:\n", a2.shape)
print("c的數據類型:\n", c.dtype)
print("sum的op:\n", sum.op)
# 獲取靜態形狀
print("b的靜態形狀:\n", b.get_shape())
# 定義佔位符
a_p = tf.placeholder(dtype=tf.float32, shape=[None, None])
b_p = tf.placeholder(dtype=tf.float32, shape=[None, 10])
c_p = tf.placeholder(dtype=tf.float32, shape=[3, 2])
# 獲取靜態形狀
print("a_p的靜態形狀爲:\n", a_p.get_shape())
print("b_p的靜態形狀爲:\n", b_p.get_shape())
print("c_p的靜態形狀爲:\n", c_p.get_shape())
# 形狀更新
# a_p.set_shape([2, 3])
# 靜態形狀已經固定部分就不能修改了
# b_p.set_shape([10, 3])
# c_p.set_shape([2, 3])
# 靜態形狀已經固定的部分包括它的階數,如果階數固定了,就不能跨階更新形狀
# 如果想要跨階改變形狀,就要用動態形狀
# a_p.set_shape([1, 2, 3])
# 獲取靜態形狀
print("a_p的靜態形狀爲:\n", a_p.get_shape())
print("b_p的靜態形狀爲:\n", b_p.get_shape())
print("c_p的靜態形狀爲:\n", c_p.get_shape())
# 動態形狀
# c_p_r = tf.reshape(c_p, [1, 2, 3])
c_p_r = tf.reshape(c_p, [2, 3])
# 動態形狀,改變的時候,不能改變元素的總個數
# c_p_r2 = tf.reshape(c_p, [3, 1])
print("動態形狀的結果:\n", c_p_r)
# print("動態形狀的結果2:\n", c_p_r2)
return None
2.3.5 張量的數學運算
- 算術運算符
- 基本數學函數
- 矩陣運算
- reduce操作
- 序列索引操作
詳細請參考: https://www.tensorflow.org/versions/r1.8/api_guides/python/math_ops
這些API使用,我們在使用的時候介紹,具體參考文檔
2.3.6 變量
TensorFlow變量是表示程序處理的共享持久狀態的最佳方法。變量通過 tf.Variable OP類進行操作。變量的特點:
- 存儲持久化
- 可修改值
- 可指定被訓練
2.3.6.1 創建變量
- tf.Variable(initial_value=None,trainable=True,collections=None,name=None)
- initial_value:初始化的值
- trainable:是否被訓練
- collections:新變量將添加到列出的圖的集合中collections,默認爲[GraphKeys.GLOBAL_VARIABLES],如果trainable是True變量也被添加到圖形集合 GraphKeys.TRAINABLE_VARIABLES
- 變量需要顯式初始化,才能運行值
def variable_demo():
"""
變量的演示
:return:
"""
# 定義變量
a = tf.Variable(initial_value=30)
b = tf.Variable(initial_value=40)
sum = tf.add(a, b)
# 初始化變量
init = tf.global_variables_initializer()
# 開啓會話
with tf.Session() as sess:
# 變量初始化
sess.run(init)
print("sum:\n", sess.run(sum))
return None
2.3.6.2 使用tf.variable_scope()修改變量的命名空間
會在OP的名字前面增加命名空間的指定名字
with tf.variable_scope("name"):
var = tf.Variable(name='var', initial_value=[4], dtype=tf.float32)
var_double = tf.Variable(name='var', initial_value=[4], dtype=tf.float32)
<tf.Variable 'name/var:0' shape=() dtype=float32_ref>
<tf.Variable 'name/var_1:0' shape=() dtype=float32_ref>