??張量(Tensor)是TensorFlow的基本數據結構。張量即多維數組,Tensorflow的張量和Numpy中的ndarray對象很類似,用來定義一個 n 維數組對象,它是一個一系列相同類型元素組成的數組集合。從操作行為角度來看,TensorFlow中定義了兩種類型的張量:常量(constant)和變量(Variable)。其中常量的值在計算圖中不可以被重新賦值,而變量在計算圖中可以使用assign等算子進行重新賦值。一般在模型中需要被訓練的參數需要被設置成變量,而在整個訓練過程中保持不變的參數,則被設置程常量。下面用個簡單的實例來展示常量和變量的不同,代碼如下:
import tensorflow as tf
import numpy as np
#創建一個常量tensor
a_c = tf.constant([1,2,3], dtype = tf.int32)
#創建一個變量tensor
a_v = tf.Variable([1,2,3], dtype = tf.int32)
#打印兩個張量在內存中的id
print(id(a_c), id(a_v))
結果如下:
2979942624944 2979988437072
接下來我們分別對這兩個tensor進行操作,用他們加上另外一個tensor。代碼如下:
#分別修改常量和變量
a_c = a_c + tf.constant([1,1,1])
a_v.assign_add([1,1,1])
print("a_c:", a_c)
print("a_v:", a_v)
#打印兩個張量在內存中的id
print(id(a_c), id(a_v))
結果如下:
a_c: tf.Tensor([2 3 4], shape=(3,), dtype=int32)
a_v: <tf.Variable 'Variable:0' shape=(3,) dtype=int32, numpy=array([2, 3, 4])>
2979942625120 2979988437072
??通過對比我們發現,常量是不可修改的,每次對原常量的操作都會新建一個新的常量對象,而張量變量通過assign等操作在原內存空間中對值內容進行修改,并不創建新的對象。以上就是簡單的對TensorFlow中的Tensor數據結構的常量和變量的區別做了個簡單的展示,下面將詳細介紹張量上的結構操作和數學運算。其中結構操作包括:張量創建,索引切片,維度變換以及合并分割,數學運算包括:標量運算,向量運算,矩陣運算及廣播。
一,創建張量
??TensorFlow中張量的創建和Numpy中ndarray的創建很類似,而且很多方法的名稱和用法都基本一致,下面就幾種常見的張量常見方式進行演示,默認以Tensor常量的創建做為實例。
標量的創建,即0維張量的創建,代碼如下:
i = tf.constant(6) #創建一個數據類型默認為tf.int32的0維張量
l = tf.constant(6, dtype=tf.int64) #創建一個數據類型為tf.int64的0維張量
f = tf.constant(3.14) #創建一個數據類型默為tf.float32的0維張量
d = tf.constant(1.414, dtype=tf.double)#創建一個數據類型為tf.double的0維張量
s = tf.constant('Hello world~') #創建一個數據類型為tf.string的0維張量
b = tf.constant(False) #創建一個數據類型為tf.bool的0維張量
print(b)
print(tf.rank(b)) #打印張量b的維度
print(b.numpy().ndim) # tf.rank的作用和ndarray的ndim方法相同
結果如下:
tf.Tensor(False, shape=(), dtype=bool)
tf.Tensor(0, shape=(), dtype=int32)
0
向量的創建,即1維張量的創建,代碼如下:
a = tf.constant([1.0, 2.0, 3.0, 4.0, 5.0]) #使用1維數組創建1維張量
b = tf.range(1, 5, delta = 1) #使用range方法創建1維張量
c = tf.linspace(1, 5, 5) #使用linspace方法創建1維張量
tf.random.set_seed(1.0)
d = tf.random.uniform([5], minval=0, maxval = 10)#使用均勻分布隨機創建1維張量
tf.print(a)
print("a.rank:", tf.rank(a))
tf.print(b)
print("b.rank:", tf.rank(b))
tf.print(c)
print("c.rank:", tf.rank(c))
tf.print(d)
print("d.rank:", tf.rank(d))
結果如下:
[1 2 3 4 5]
a.rank: tf.Tensor(1, shape=(), dtype=int32)
[1 2 3 4]
b.rank: tf.Tensor(1, shape=(), dtype=int32)
[1 2 3 4 5]
c.rank: tf.Tensor(1, shape=(), dtype=int32)
[1.65130854 9.01481247 6.30974197 4.34546089 2.9193902]
d.rank: tf.Tensor(1, shape=(), dtype=int32)
??多維張量的創建基本上類似于Numpy中的多維數組ndarray,創建方式也是大同小異,結果中一般幾層中括號就代表創建的幾維的張量,示例代碼如下:
tensor2_array = tf.constant([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0]]) #利用二維數組創建矩陣
tensor3_array = tf.constant([[1.0, 2.0, 3.0],[4.0, 5.0, 6.0],[7.0, 8.0, 9.0]]) #利用三維數組,創建三維張量
tf.print("tensor2_array:\n", tensor2_array)
print("----------------------------------")
tf.print("\ntensor3_array:\n", tensor3_array)
print("----------------------------------")
tensor2_ones = tf.ones([2, 2]) #利用tf.ones創建默認值為1的二維張量
tensor3_ones = tf.ones([2, 2, 2]) #利用tf.ones創建默認值為1的三維張量
tf.print("\ntensor2_ones:\n", tensor2_ones)
print("----------------------------------")
tf.print("\ntensor3_ones:\n", tensor3_ones)
print("----------------------------------")
tensor2_fill = tf.fill([2, 2], 2) #利用tf.fill創建默認值為指定值的二維張量
tensor3_fill = tf.fill([2, 2, 2], 2) #利用tf.fill創建默認值為指定值的三維張量
tf.print("\ntensor2_fill:\n", tensor2_fill)
print("----------------------------------")
tf.print("\ntensor3_fill:\n", tensor3_fill)
print("----------------------------------")
tf.random.set_seed(1.0)
tensor2_rand_uniform = tf.random.uniform([2, 2], minval=0, maxval=10) #利用均勻分布隨機創建二維張量
tensor3_rand_uniform = tf.random.uniform([2, 2, 2], minval=0, maxval=10) #利用均勻分布隨機創建三維張量
tf.print("\ntensor2_rand_uniform:\n", tensor2_rand_uniform)
print("----------------------------------")
tf.print("\ntensor3_rand_uniform:\n", tensor3_rand_uniform)
print("----------------------------------")
tensor2_rand_norm = tf.random.normal([2, 2], mean=0.0, stddev=1.0)#利用正態分布隨機創建二維張量
tensor3_rand_norm = tf.random.normal([2, 2, 2], mean=0.0, stddev=1.0)#利用正態分布隨機創建三維張量
tf.print("\ntensor2_rand_norm:\n", tensor2_rand_norm)
print("----------------------------------")
tf.print("\ntensor3_rand_norm:\n", tensor3_rand_norm)
print("----------------------------------")
# 特殊二維張量
I = tf.eye(2,2) #單位矩陣
tf.print("\nI:\n", I)
print("----------------------------------")
diag = tf.linalg.diag([1,2,3]) #對角陣
tf.print("\ndiag:\n", diag)
print("----------------------------------")
結果如下:
tensor2_array:
[[1 2 3]
[4 5 6]]
----------------------------------
tensor3_array:
[[1 2 3]
[4 5 6]
[7 8 9]]
----------------------------------
tensor2_ones:
[[1 1]
[1 1]]
----------------------------------
tensor3_ones:
[[[1 1]
[1 1]]
[[1 1]
[1 1]]]
----------------------------------
tensor2_fill:
[[2 2]
[2 2]]
----------------------------------
tensor3_fill:
[[[2 2]
[2 2]]
[[2 2]
[2 2]]]
----------------------------------
tensor2_rand_uniform:
[[1.65130854 9.01481247]
[6.30974197 4.34546089]]
----------------------------------
tensor3_rand_uniform:
[[[5.1010704 4.43531752]
[4.08533096 9.92492294]]
[[6.8866396 3.45849633]
[4.36067 6.01060963]]]
----------------------------------
tensor2_rand_norm:
[[-0.457012236 -0.406867266]
[0.728577733 -0.892977774]]
----------------------------------
tensor3_rand_norm:
[[[1.6940167 0.119693168]
[-1.15846 0.172604024]]
[[-0.714496315 0.689600587]
[-1.0908159 -1.18651032]]]
----------------------------------
I:
[[1 0]
[0 1]]
----------------------------------
diag:
[[1 0 0]
[0 2 0]
[0 0 3]]
----------------------------------
??上面簡單介紹了一下幾種不同類型和維度的張量的創建方法,接下來我們將針對Tensor操作中的索引切片進行簡單的介紹。