Tensorflow簡單實踐系列(二):張量


上一節中,我們安裝 TensorFlow 並運行了最簡單的應用,這節我們熟悉 TensorFlow 中的張量。

張量是 TensorFlow 的核心數據類型。數學里面也有張量的概念,但是 TensorFlow 的張量其實不一樣,更像是一個 n 維數組。

不能在常規 Python 例程中訪問張量,因此 TensorFlow API 提供了很多張量的操作函數。

張量的創建

張量是一個 n 維數組。當 $n=0$ 時它就是標量;當 $n=1$ 時它就是向量;當 $n=2$ 時它就是矩陣。

所有的張量都是 Tensor 類的實例。

張量可以包含數字、字符串和布爾類型。但是一個張量包含的的元素必須是相同類型的。

創建常數

constant 函數簽名:

constant(value, dtype=None, shape=None, name='Const', verify_shape=False)

代碼示例:

 1 # 創建常數
 2 t1 = tf.constant('hello world')
 3 t2 = tf.constant([1, 2, 3])
 4 t3 = tf.constant([[1, 2], [3, 4]])
 5 t4 = tf.constant([6, 66, 666], tf.int16, [3], 'very_6', True)
 6 
 7 # 發起一個會話
 8 with tf.Session() as sess:
 9     print(sess.run(t1))
10     print(sess.run(t2))
11     print(sess.run(t3))
12     print(sess.run(t4))
b'hello world'
[1 2 3]
[[1 2]
 [3 4]]
[  6  66 666]

zeros/ones/fill

zeros 函數簽名:

zeros(shape, dtype=tf.float32, name=None)

ones 函數簽名:

ones(shape, dtype=tf.float32, name=None)

fill 函數簽名:

fill(dims, value, name=None)

代碼示例:

 1 # 創建零值張量
 2 t1 = tf.zeros([2])
 3 # 創建一值張量
 4 t2 = tf.ones([2, 3])
 5 # 填值
 6 t3 = tf.fill([3, 2], 666)
 7 
 8 # 發起一個會話
 9 with tf.Session() as sess:
10     print(sess.run(t1))
11     print(sess.run(t2))
12     print(sess.run(t3))
[0. 0.]
[[1. 1. 1.]
 [1. 1. 1.]]
[[666 666]
 [666 666]
 [666 666]]

創建序列

linspance 函數簽名:

linspace(start, stop, num,  name=None)

range 函數簽名:

range(start, limit, delta=1, dtype=None, name='range')
range(limit, delta=1, dtype=None, name='range')

代碼示例:

 1 # 創建序列
 2 t1 = tf.linspace(0., 1., 10)
 3 t2 = tf.range(-1., 1., delta=0.1)
 4 t3 = tf.range(-2., delta=-0.5)
 5 
 6 # 發起一個會話
 7 with tf.Session() as sess:
 8     print(sess.run(t1))
 9     print(sess.run(t2))
10     print(sess.run(t3))
[0.         0.11111111 0.22222222 0.33333334 0.44444445 0.5555556
 0.6666667  0.7777778  0.8888889  1.        ]
[-1.00000000e+00 -8.99999976e-01 -7.99999952e-01 -6.99999928e-01
 -5.99999905e-01 -4.99999911e-01 -3.99999917e-01 -2.99999923e-01
 -1.99999928e-01 -9.99999270e-02  7.45058060e-08  1.00000076e-01
  2.00000077e-01  3.00000072e-01  4.00000066e-01  5.00000060e-01
  6.00000083e-01  7.00000107e-01  8.00000131e-01  9.00000155e-01]
[ 0.  -0.5 -1.  -1.5]

創建隨機值:正態分布

很多時候機器學習需要創建隨機值。正態分布有兩種:random_normal 和 truncated_normal。對於一般意義的正態分布,大約 95.4% 的概率會落在 2 倍標准方差的范圍之內。

random_normal 是一般意義的正態分布,有可能有小概率會選擇 2 倍標准方差的范圍之外。而 truncated_normal 會有截斷,保證所有值都落在 2 倍標准方差的范圍之內。

函數簽名:

 random_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None) 

 truncated_normal(shape, mean=0.0, stddev=1.0, dtype=tf.float32, seed=None, name=None) 

代碼示例:

 1 # 創建隨機值:正態分布
 2 t1 = tf.random_normal([10], dtype=tf.float64)
 3 t2 = tf.random_normal([20], 0, 2, dtype=tf.float64, seed=60)
 4 t3 = tf.truncated_normal([20], 0, 2, dtype=tf.float32, seed=60)
 5 
 6 # 發起一個會話
 7 with tf.Session() as sess:
 8     print(sess.run(t1))
 9     print(sess.run(t2))
10     print(sess.run(t3))
[-0.30217352 -0.01353907  0.11583214  0.7693184  -2.03386255  0.74505956
 -1.57310053  1.16255292  1.87307555  1.1607303 ]
[ 0.43070572  1.78930951  1.90006543 -0.08042026 -2.3744852   1.88272049
  1.56724792  1.37002113 -0.12527277  4.5297854  -0.82256769  0.87545214
  0.85278266 -0.14404349  0.93608167 -2.59733351 -0.33442825  1.19330448
  4.15318877 -3.12805352]
[ 0.74157673 -0.9606577   0.46180212 -3.2753797   0.16152781 -2.189441
 -0.09013904 -2.1726682  -1.2061952   0.5147551  -3.3902223   1.843447
 -0.83136135 -2.4879968   3.2793632   2.9981675  -3.217487   -0.13496129
  1.7222887  -3.1599777 ]

觀察第 2 個輸出中的 4.15318877,已經超過了 2 倍標准方差(標准方差為 2),這有將近 4.6% 的概率發生。

而對於 truncated_normal 函數,不管輸出多少數,也不可能有這樣的輸出。

創建隨機值:均勻分布

random_uniform 創建最大值和最小值之間的均勻分布。

函數簽名:

 random_uniform(shape, minval=0, maxval=None, dtype=tf.float32, seed=None, name=None) 

代碼示例:

1 # 創建隨機值:均勻分布
2 t1 = tf.random_uniform([20], 0, 10, dtype=tf.int32, seed=66)
3 
4 # 發起一個會話
5 with tf.Session() as sess:
6     print(sess.run(t1))
[0 7 5 3 2 7 7 5 1 7 9 9 0 3 0 1 4 7 3 4]

隨機打亂某張量

random_shuffle 可以對張量沿着一維方向,隨機打亂順序。

函數簽名:

random_shuffle(tensor, seed=None, name=None)

代碼示例:

1 # 隨機打亂張量(沿第一維方向)
2 t1 = tf.constant([[1, 2], [3, 4], [5, 6], [7, 8], [9, 10]])
3 t2 = tf.random_shuffle(t1, seed=66)
4 
5 # 發起一個會話
6 with tf.Session() as sess:
7     print(sess.run(t1))
8     print(sess.run(t2))
[[ 1  2]
 [ 3  4]
 [ 5  6]
 [ 7  8]
 [ 9 10]]
[[ 1  2]
 [ 5  6]
 [ 3  4]
 [ 9 10]
 [ 7  8]]

設置隨機種子

前面的隨機函數都有一個 seed 參數,我們其實可以直接設置,讓所有隨機函數都會用同一個隨機種子。

set_random_seed(seed)

代碼示例:

1 # 隨機種子
2 tf.set_random_seed(66)

創建張量的運算

基本的數學運算

代碼示例:

 1 # 基本的數學運算
 2 x1 = tf.constant([2, 2, 2])
 3 x2 = tf.constant([4, 4, 4])
 4 my_sum1 = tf.add(x1, x2)
 5 my_diff1 = tf.subtract(x1, x2)
 6 my_prod1 = tf.multiply(x1, x2)
 7 my_quot1 = tf.divide(x1, x2)
 8 # 發起一個會話
 9 with tf.Session() as sess:
10     print(sess.run(my_sum1))
11     print(sess.run(my_diff1))
12     print(sess.run(my_prod1))
13     print(sess.run(my_quot1))
14 print('-' * 20)
15 # 還可以使用 Python 運算符
16 my_sum2 = x1 + x2
17 my_diff2 = x1 - x2
18 my_prod2 = x1 * x2
19 my_quot2 = x1 / x2
20 # 發起一個會話
21 with tf.Session() as sess:
22     print(sess.run(my_sum2))
23     print(sess.run(my_diff2))
24     print(sess.run(my_prod2))
25     print(sess.run(my_quot2))
26 print('-' * 20)
27 # 除和整除
28 my_quot3 = x1 / x2
29 my_quot4 = x1 // x2
30 my_quot5 = tf.divide(x1, x2)
31 my_quot6 = tf.div(x1, x2)
32 # 發起一個會話
33 with tf.Session() as sess:
34     print(sess.run(my_quot3))
35     print(sess.run(my_quot4))
36     print(sess.run(my_quot5))
37     print(sess.run(my_quot6))
[6 6 6]
[-2 -2 -2]
[8 8 8]
[0.5 0.5 0.5]
--------------------
[6 6 6]
[-2 -2 -2]
[8 8 8]
[0.5 0.5 0.5]
--------------------
[0.5 0.5 0.5]
[0 0 0]
[0.5 0.5 0.5]
[0 0 0]

湊整和比較運算

代碼示例:

 1 # 湊整和比較運算
 2 # 湊整
 3 t = tf.constant([-1.5, -1.4, 1.4, 1.5])
 4 r1 = tf.round(t)
 5 r2 = tf.rint(t)
 6 r3 = tf.ceil(t)
 7 r4 = tf.floor(t)
 8 # 發起一個會話
 9 with tf.Session() as sess:
10     print(sess.run(r1))
11     print(sess.run(r2))
12     print(sess.run(r3))
13     print(sess.run(r4))
14 print('-' * 20)
15 # 比較
16 t1 = tf.constant([1., 2.])
17 t2 = tf.constant([1.5, 3.])
18 my_max = tf.maximum(t1, t2)
19 my_min = tf.minimum(t1, t2)
20 t3 = tf.constant([[6., 2.], [4., -6.]])
21 min_index = tf.argmin(t3) 
22 max_index = tf.argmax(t3) 
23 # 發起一個會話
24 with tf.Session() as sess:
25     print(sess.run(my_max))
26     print(sess.run(my_min))
27     print(sess.run(min_index))
28     print(sess.run(max_index))
[-2. -1.  1.  2.]
[-2. -1.  1.  2.]
[-1. -1.  2.  2.]
[-2. -2.  1.  1.]
--------------------
[1.5 3. ]
[1. 2.]
[1 1]
[0 0]

指數和對數

機器學習經常要用到指數和對數來計算概率。

 1 # 指數和對數
 2 x = tf.constant([0., 1., 2.])
 3 y = tf.constant([-1., -1., -1.])
 4 t1 = tf.square(x)
 5 t2 = tf.squared_difference(x, y)
 6 t3 = tf.sqrt(x)
 7 t4 = tf.rsqrt(x)  # tf.sqrt(x)的倒數
 8 t5 = tf.pow(x, 3)
 9 t6 = tf.exp(x)
10 t7 = tf.expm1(x)  # exp(x)-1
11 t8 = tf.log(x)  # ln(x)
12 t9 = tf.log1p(x)  # log(x+1)
13 t10 = tf.erf(x)  # 誤差函數
14 t11 = tf.erfc(x)  # 互補誤差函數
15 
16 # 發起一個會話
17 with tf.Session() as sess:
18     print(sess.run(t1))
19     print(sess.run(t2))
20     print(sess.run(t3))
21     print(sess.run(t4))
22     print(sess.run(t5))
23     print(sess.run(t6))
24     print(sess.run(t7))
25     print(sess.run(t8))
26     print(sess.run(t9))
27     print(sess.run(t10))
28     print(sess.run(t11))
[0. 1. 4.]
[1. 4. 9.]
[0.        1.        1.4142135]
[       inf 1.         0.70710677]
[0. 1. 8.]
[1.        2.7182817 7.389056 ]
[0.        1.7182819 6.389056 ]
[     -inf 0.        0.6931472]
[0.        0.6931472 1.0986123]
[0.        0.8427008 0.9953223]
[1.         0.1572992  0.00467773]

向量和矩陣運算

機器學習中有很多向量(一維張量)和矩陣(二維張量)的運算。

代碼示例:

 1 # 向量和矩陣運算
 2 # 點乘
 3 t1 = tf.constant([0., 1., 2.])
 4 t2 = tf.constant([1., 2., 3.])
 5 dot0 = tf.tensordot(t1, t2, axes=0)
 6 dot1 = tf.tensordot(t1, t2, axes=1)
 7 # 發起一個會話
 8 with tf.Session() as sess:
 9     print(sess.run(dot0))
10     print(sess.run(dot1))
11 print('-' * 20)
12 # 矩陣乘法
13 t3 = tf.constant([[0., 1., 2.]])
14 t4 = tf.constant([[1., 2., 3.]])
15 dot3 = tf.matmul(t3, tf.transpose(t4))
16 # 交叉內積
17 cross = tf.cross(t3, t4)
18 # 對角矩陣
19 t5 = tf.diag([1, 2, 3])
20 #
21 trace = tf.trace(t5)
22 # 單位矩陣
23 eye = tf.eye(4)
24 # 范數
25 t6 = tf.constant([[1., 2.], [3., 4.]])
26 norm = tf.norm(t6)
27 # 求解Ax = b
28 A = tf.constant([[1., 1.], [2., 3.]])
29 b = tf.constant([[10.], [23.]])
30 x = tf.matrix_solve(A, b)
31 # 特征向量
32 t7 = tf.constant([[1., 2.], [3., 4.]])
33 qr = tf.qr(t7)
34 # 矩陣分解
35 svd = tf.svd(t7)
36 # 發起一個會話
37 with tf.Session() as sess:
38     print(sess.run(dot3))
39     print(sess.run(cross))
40     print(sess.run(t5))
41     print(sess.run(trace))
42     print(sess.run(eye))
43     print(sess.run(norm))
44     print(sess.run(x))
45     print(sess.run(qr))
46     print(sess.run(svd))
47 print('-' * 20)
48 # 自定義運算
49 m1 = tf.constant([[1, 2], [3, 4]])
50 m2 = tf.constant([[5, 6], [7, 8]])
51 e1 = tf.einsum('ij->ji', m1)
52 e2 = tf.einsum('ij,jk->ik', m1, m2)
53 # 發起一個會話
54 with tf.Session() as sess:
55     print(sess.run(e1))
56     print(sess.run(e2))
[[0. 0. 0.]
 [1. 2. 3.]
 [2. 4. 6.]]
8.0
--------------------
[[8.]]
[[-1.  2. -1.]]
[[1 0 0]
 [0 2 0]
 [0 0 3]]
6
[[1. 0. 0. 0.]
 [0. 1. 0. 0.]
 [0. 0. 1. 0.]
 [0. 0. 0. 1.]]
5.477226
[[7.]
 [3.]]
Qr(q=array([[-0.3162278 , -0.9486833 ],
       [-0.9486833 ,  0.31622773]], dtype=float32), r=array([[-3.1622777 , -4.4271884 ],
       [ 0.        , -0.63245535]], dtype=float32))
(array([5.4649854 , 0.36596614], dtype=float32), array([[ 0.4045535, -0.9145143],
       [ 0.9145143,  0.4045535]], dtype=float32), array([[ 0.5760484,  0.8174156],
       [ 0.8174156, -0.5760484]], dtype=float32))
--------------------
[[1 3]
 [2 4]]
[[19 22]
 [43 50]]

總結

張量是 TensorFlow 中核心的數據類型。本文揭開了 TensorFlow 中張量的神秘面紗,包括張量的創建和張量的運算。

張量類似於 N 維數組。0 維張量就是標量,1 維張量就是向量,2 維張量就是矩陣。

我們只是熟悉了張量基本的創建和運算(很多 API 和我們熟悉的 Numpy 很類似),更多的技巧知識還需要不斷在實踐中總結和提升。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM