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。

 

8、最大元素、最小元素的索引

  當我們對y進行One-hot編碼后,我們一般是認為最大值1所在的位置即為y的類別。同理,神經網絡輸出層用sofmax函數作為激活函數后,也取預測值y最大值的位置對應的類別作為預測的分類。這時候我們就需要知道最大值是對應的哪一個位置。

import tensorflow as tf

a=tf.constant([1,1,2,3,1])   
a_trans=tf.one_hot(a,3) # 轉換為獨熱編碼
a_pre=tf.argmax(a_trans,axis=1) # 最大值所在的位置

print(a)
print(a_trans)
print(a_pre)

輸出結果:

tf.Tensor([1 1 2 3 1], shape=(5,), dtype=int32)
tf.Tensor(
[[0. 1. 0.]
 [0. 1. 0.]
 [0. 0. 1.]
 [0. 0. 0.]
 [0. 1. 0.]], shape=(5, 3), dtype=float32)
tf.Tensor([1 1 2 0 1], shape=(5,), dtype=int64)

 

9、變量的自減

  在訓練模型時,權重w更新公式為w=w-grad*lr,grad為梯度,lr為學習率,如果我們是手動更新權重,那么這個時候用變量的自減就很方便。

import tensorflow as tf

x=tf.constant([[1],[2],[3],[4],[5]],dtype=tf.float32)
w=tf.Variable([[2]],dtype=tf.float32)  # 訓練的參數

with tf.GradientTape() as tape:
    tape.watch(x)
    y=tf.matmul(x,w)+0.5
w_grad=tape.gradient(y,w)   # 計算梯度
w.assign_sub(0.1*w_grad)    # 權重更新

print(w.value())

輸出結果:

tf.Tensor([[0.5]], shape=(1, 1), dtype=float32)

 


免責聲明!

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



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