會話、張量、變量OP

日萌社

人工智能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>

 

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