Tensorflow中Tensor類型解析

Tensorflow官方API文檔Python版本、Java版本、C++版本和Go版本,以下介紹Python版本

一般爲了編程方便,在引入依賴時,使用tf代替tensorflow,如下,下文內容中用TF代替Tensorflow

import tensorflow as tf

在TF程序中,主要操作的對象是tf.Tensor,即在TF框架中,數據都以tf.Tensor類型進行組織和存儲,熟悉面向對象編程的話應該很容易理解(下文“Tensor對象”和“Tensor變量”的含義相同),可以看到該類定義在

>>> tf.Tensor
<class 'tensorflow.python.framework.ops.Tensor'>
每個Tensor對象包括數據類型(data type)和形狀(shape)兩個基本屬性,每個對象的數據類型是唯一的,由於python本身是一種弱類型的語言,因此創建Tensor變量時可以不指定數據類型,而是通過運行時判別。Tensor在數學上的名稱是張量,張量會有階數,零階張量是標量,一階張量是向量,二階張量是矩陣,階數可以更多,例如三階張量、四階張量等,如下表(源自https://www.tensorflow.org/programmers_guide/tensors)

Rank Math entity
0 Scalar (magnitude only)
1 Vector (magnitude and direction)
2 Matrix (table of numbers)
3 3-Tensor (cube of numbers)
n n-Tensor (you get the idea)

TF提供了以下函數可以初始化Tensor對象。

1) placeholder函數

x = tf.placeholder(tf.float32, [None, 1024])

初始化Tensor變量並賦值給x,類型爲tf.float32,[None, 1024]表示行數不確定,列數爲1024。使用print輸出,可看到如下結果

Tensor("Placeholder:0", shape=(?, 1024), dtype=float32)

*注意字母p小寫,在r1.4版本中大寫無效

佔位變量的意義在於,定義模塊時,例如線性模型  "y = x * W + b"(TF中定義如下),其中 W 和 b 是模型參數,可以直接進行隨機初始化,而 x 是我們的訓練樣本,只在在訓練時輸入訓練數據後纔有實際的值,因此,只能先聲明佔位變量,使得模型可以用代碼表示出來,筆者認爲這其實也是爲什麼 tensor變量需要用 eval() 方法或者通過 session.run() 之後才能看到具體的值,否則只能看到類型定義(下文舉例說明)

y = tf.matmul(x, W) + b

2)Variable函數(示例源自https://www.tensorflow.org/programmers_guide/tensors)

一階張量初始化如下,

mystr = tf.Variable(["Hello"], tf.string)
cool_numbers  = tf.Variable([3.14159, 2.71828], tf.float32)
first_primes = tf.Variable([2, 3, 5, 7, 11], tf.int32)
its_very_complicated = tf.Variable([(12.3, -4.85), (7.5, -6.23)], tf.complex64)
二階張量初始化,結構爲1024行、10列,如下

W = tf.Variable(tf.zeros([1024, 10]))

*注意字母V大寫

零階張量初始化如下

mammal = tf.Variable("Elephant", tf.string)
ignition = tf.Variable(451, tf.int16)
floating = tf.Variable(3.14159265359, tf.float64)
its_complicated = tf.Variable((12.3, -4.85), tf.complex64)
高階張量初始化如下
mystr = tf.Variable(["Hello"], tf.string)
cool_numbers  = tf.Variable([3.14159, 2.71828], tf.float32)
first_primes = tf.Variable([2, 3, 5, 7, 11], tf.int32)
its_very_complicated = tf.Variable([(12.3, -4.85), (7.5, -6.23)], tf.complex64)
對於張量來說,使用  eval() 方法可以查看張量的具體數值,該方法返回 一個numpy數組,例如

>>> x=tf.zeros(10)
>>> x.eval()
array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.], dtype=float32)

使用tf.rank()函數可以獲取一個張量的階數,例如

>>> rk=tf.rank(x)
>>> rk.eval()
1
但是,一般需要輸出一個Tensor對象的值 時,要通過session來輸出,例如

>>> sess=tf.InteractiveSession()
>>> norm = tf.random_normal([2, 3], mean=-1, stddev=4)
>>> print(sess.run(norm))
[[-6.23512602  0.08872831 -4.23519659]
 [-0.37180948  0.1739198  -3.45424032]]
因爲在TF框架中,對於Tensor對象所指定的運算是動態執行的,例如,初始化一個正態隨機的一階張量tn,和一個全1的一階張量t,再將他們相加,每次的結果會不同,如下

>>> tn = tf.random_normal([1,10], mean=-1, stddev=4)
>>> t = tf.ones(10)
>>> tmp = tn + t
>>> tmp.eval()
array([[-9.58623028,  0.70157331,  7.56238651,  0.12382185,  1.78133655,
        -2.60228705,  2.09345794,  0.78153497,  4.40496349,  0.13798881]], dtype=float32)
>>> tmp.eval()
array([[-7.71660995,  6.11020565, -0.91900563,  1.48415923, -2.51670742,
         0.39632952,  1.62038779, -1.51520824, -1.37992334,  2.52663517]], dtype=float32)
>>> tmp.eval()
array([[-1.53174448,  4.66375542,  0.84976286, -0.25260258, -4.49670076,
        -1.02720261,  2.21190119, -1.00379395,  4.77040529,  5.89726973]], dtype=float32)
所以使用eval()方法的前提是,當前運行時已經創建了默認的session,例如創建交互式session,sess = tf.InteractiveSession(),否則會出現 如下錯誤 ,找不到缺省sesson

raise ValueError("Cannot evaluate tensor using `eval()`: No default "
ValueError: Cannot evaluate tensor using `eval()`: No default session is registered. Use `with sess.as_default()` or pass an explicit session to `eval(session=sess)`
而且使用 sess = tf.Session() 時,同樣會出現如上問題。因此顧名思義,TF的交互式session就是在使用python交互式命令時使用的。

文檔中指出,創建Tensor變量的最佳實踐是通過 get_variable() 函數來實現,最簡單的方式只需要指定名稱和形狀,如下

my_variable = tf.get_variable("my_variable", [1, 2, 3])
my_int_variable = tf.get_variable("my_int_variable", [1, 2, 3], dtype=tf.int32, initializer=tf.zeros_initializer)
other_variable = tf.get_variable("other_variable", dtype=tf.int32, initializer=tf.constant([23, 42]))

3)constant

*注意字母c小寫

4)SparseTensor

*注意字母S大寫

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