tensorflow2.0——常用的函式(包括tf.Variable)
阿新 • • 發佈:2020-11-17
一、常用函式
1、轉換tensor資料型別
import tensorflow as tf a=tf.constant(1.0) b=tf.cast(a,dtype='int32') print(a) print(b)
輸出:
tf.Tensor(1.0, shape=(), dtype=float32)
tf.Tensor(1, shape=(), dtype=int32)
2、tensor元素的最大值、最小值、求和與均值
import tensorflow as tf a=tf.constant([[1,1],[2,2]]) a_min=tf.reduce_min(a) #張量元素的最小值 a_max=tf.reduce_max(a) # 張量元素的最大值 a_mean=tf.reduce_mean(a) # 張量元素的均值 a_sum=tf.reduce_sum(a) # 張量元素的和 a_row_sum=tf.reduce_sum(a,axis=0) # 張量列(第1維度)元素的和 a_col_sum=tf.reduce_sum(a,axis=1) # 張量行(第2維度)元素的和 print('張量a:\n',a) print('行求和:\n',a_row_sum) print('列求和:\n',a_col_sum)
輸出:
張量a: tf.Tensor( [[1 1] [2 2]], shape=(2, 2), dtype=int32) 行求和: tf.Tensor([3 3], shape=(2,), dtype=int32) 列求和: tf.Tensor([2 4], shape=(2,), dtype=int32)
引數說明:axis可以定義操作的方向。在矩陣中axis=0表示跨行,對各個列進行求和操作。通常axis=0對應的是tensor.shape的第一個維度。示例圖如下:
3、變數的定義與建立
TensorFlow中,如果要對一個引數進行訓練,那麼這個引數必須是一個變數類tf.Variable,tf.Variable類會在反向傳播的時候進行梯度計算並儲存梯度資訊。
import tensorflow as tf bias = tf.Variable(initial_value=tf.constant(1.0)) # 定義一個邏輯迴歸的偏倚
4、tensor的數學運算
import tensorflow as tf a = tf.constant([[1.0, 2.0], [3.0, 4.0]]) b = tf.ones([2, 2]) a_add_b = tf.add(a, b) # 張量對應元素相加 # a_add_b = a + b # 張量對應元素相加 a_subtract_b = tf.subtract(a, b) # 張量對應元素相減 # a_subtract_b = a-b # 張量對應元素相減 a_multiply_b = tf.multiply(a, b) # 張量對應元素相乘 # a_subtract_b = a*b # 張量對應元素相減 a_divide_b = tf.divide(a, b) # 張量對應元素相除 # a_divide_b = a/b # 張量對應元素相除 a_square = tf.square(a) # 張量元素平方 a_pow = tf.pow(a, y=3) # 張量元素求3次方 # a_pow = a**3 # 張量元素求3次方 a_sqrt = tf.sqrt(a) # 張量元素開方 a_sqrt = tf.sqrt(a) # 張量元素開方 a_matmul_b = tf.matmul(a, b) # 矩陣乘法 print('a:\n',a) print('b:\n',b) print('對應元素乘:\n',a_multiply_b) print('矩陣乘法:\n',a_matmul_b)
輸出結果:
a: tf.Tensor( [[1. 2.] [3. 4.]], shape=(2, 2), dtype=float32) b: tf.Tensor( [[1. 1.] [1. 1.]], shape=(2, 2), dtype=float32) 對應元素乘: tf.Tensor( [[1. 2.] [3. 4.]], shape=(2, 2), dtype=float32) 矩陣乘法: tf.Tensor( [[3. 3.] [7. 7.]], shape=(2, 2), dtype=float32)
tips:只有當張量shape相同時才能做四則運算。
5、資料集的載入與處理
import tensorflow as tf import numpy as np # 構建資料集 x = np.array(np.arange(1, 7)).reshape(3, 2) y = np.array(list('ABC')).reshape([3, 1]) data = np.concatenate([x, y], axis=1) print('生成的資料集為:\n', data) dataset = tf.data.Dataset.from_tensor_slices((x, y)) # 對資料(x,y)進行切片,將每一個變數特徵與標籤組成一組 # 切片中的每個元素都是一組(特徵,標籤)對 print('切片的每一組的內容:') for element in dataset: print(element) # 定義一個對x、y進行操作的函式,用於dataset.map函式 def process(x, y): ''' :param x: dataset中的x :param y: dataset中的y :return: 返回值是x,y元祖 ''' print('process傳入的x:', x) print('process傳入的y:', y) return x, y dataset.shuffle(3) # 打亂資料 dataset.map(process) # 資料進行操作preprocess dataset.batch(3) # 定義資料集每批次大小
輸出結果為:
生成的資料集為: [['1' '2' 'A'] ['3' '4' 'B'] ['5' '6' 'C']] 切片的每一組的內容: (<tf.Tensor: shape=(2,), dtype=int32, numpy=array([1, 2])>, <tf.Tensor: shape=(1,), dtype=string, numpy=array([b'A'], dtype=object)>) (<tf.Tensor: shape=(2,), dtype=int32, numpy=array([3, 4])>, <tf.Tensor: shape=(1,), dtype=string, numpy=array([b'B'], dtype=object)>) (<tf.Tensor: shape=(2,), dtype=int32, numpy=array([5, 6])>, <tf.Tensor: shape=(1,), dtype=string, numpy=array([b'C'], dtype=object)>) process傳入的x: Tensor("args_0:0", shape=(2,), dtype=int32) process傳入的y: Tensor("args_1:0", shape=(1,), dtype=string)
總結:
-
tf.data.Dataset.from_tensor_slices((x, y)),用來對資料進行切片,形成x-y的特徵標籤對。
-
Dataset.shuffle(),用來打亂資料
-
dataset.map(func),用來處理dataset載入的資料,map裡面的函式func必須要有引數個數必須要和dataset的組成個數相同(這裡組成是x、y所以引數為2),因為map傳入func的引數個數等於組成個數。
-
dataset.batch(3),用來確定每個批次的大小,訓練神經網路時,資料經常是分批次訓練的。
6、梯度(導數)的計算
import tensorflow as tf x1 = tf.constant(1.0) x2 = tf.Variable(1.0) # 只使用一次tape計算梯度,計算y1在x1=1.0的一階導數 with tf.GradientTape(persistent=False) as tape: tape.watch(x1) # 對非tf.Variable類的資料需要加入監控才能夠訓練 y1 = x1 ** 2 # y需要在梯度帶上下文管理器上才可以被計算,如果不在梯度帶內無法被監控,計算結果為None dy1_dx1 = tape.gradient(target=y1, sources=x1) print('dy1_dx1一階導數:', dy1_dx1) # 使用多次tape計算梯度,計算兩個一階導數 with tf.GradientTape(persistent=True) as tape2: tape2.watch(x1) # 對非tf.Variable類的資料需要加入監控才能夠訓練 y1 = x1 ** 2 y2 = x2 ** 3 dy1_dx1 = tape2.gradient(target=y1, sources=x1) dy2_dx2 = tape2.gradient(target=y2, sources=x2) print('dy1_dx1一階導數:', dy1_dx1) print('dy2_dx2一階導數:', dy2_dx2) # 二階導數 with tf.GradientTape() as tape4: tape4.watch(x1) # 由於是二階導數,二階梯度帶需要先監控x1,不然二階求導tape4得不到一階求導tape3的結果,輸出為None with tf.GradientTape() as tape3: tape3.watch(x1) # 對非tf.Variable類的資料需要加入監控才能夠訓練 y1 = x1 ** 2 dy1_dx1_1 = tape3.gradient(y1, x1) dy1_dx1_2 = tape4.gradient(dy1_dx1_1, x1) print('dy3_dx1_2的二階導數為:',dy1_dx1_2)
輸出結果:
dy1_dx1一階導數: tf.Tensor(2.0, shape=(), dtype=float32) dy1_dx1一階導數: tf.Tensor(2.0, shape=(), dtype=float32) dy2_dx2一階導數: tf.Tensor(3.0, shape=(), dtype=float32) dy3_dx1_2的二階導數為: tf.Tensor(2.0, shape=(), dtype=float32)
注意事項:
-
with tf.GradientTape() as tape構建的是一個梯度帶上下文處理器,其中tf.GradientTape(persistent,watch_accessed_variables)的引數persistent表示是否可多次計算梯度,引數watch_accessed_variables表示自動監控tf.Variable類可訓練的變數。
- 對於非tf.Variable類張量計算梯度時,需要進行監控,如上述程式碼在梯度帶上下文處理器中新增tape.watch( x1)。
- 對於y變數,只有y變數的宣告在上下文管理器中才能進行梯度計算,否則無法計算。
7、One-hot編碼(獨熱編碼)
import tensorflow as tf y=tf.constant([1,2,3,1]) # y有三個類別 y_trans=tf.one_hot(y,depth=3) # 定義獨熱編碼的深度為3,即用3個位數表示類別 print(y_trans)
輸出結果:
tf.Tensor( [[0. 1. 0.] [0. 0. 1.] [0. 0. 0.] [0. 1. 0.]], shape=(4, 3), dtype=float32)
函式:
tf.one_hot(indices, depth, on_value=None, off_value=None, axis=None, dtype=None, name=None)
引數說明:
-
indices:表示輸入的多個數值,通常是矩陣形式。
-
depth:編碼的深度,即獨熱編碼的位數。
-
on_value:當y歸屬為這一類時,獨熱編碼在這個位置的表示值,預設為1。
-
off_value:當y不屬於這一類時,獨熱編碼在這個位置的表示值,預設為0。