1. 程式人生 > 實用技巧 >tensorflow2.0——常用的函式(包括tf.Variable)

tensorflow2.0——常用的函式(包括tf.Variable)

一、常用函式

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。