《動手學深度學習》(TF2.0版)第二章
阿新 • • 發佈:2021-02-13
技術標籤:深度不學習
第二章
import tensorflow as tf
print(tf.__version__)
檢視TF的版本
2.2資料操作
2.2.1 建立tensor
- 建立tensor
x = tf.constant(range(12))#constant 代表是常量的tensor
print(x.shape)
x
print(x)
len(x)#可以用len函式獲取長度
(12,)
<tf.Tensor: id=0, shape=(12,), dtype=int32, numpy=array([ 0, 1, 2, 3, 4, 5, 6, 7, 8 , 9, 10, 11])>
12
- 使用reshape函式
使用reshape函式把行向量x的形狀改為(3, 4),也就是一個3行4列的矩陣,並記作X
X = tf.reshape(x,(3,4))#第一個引數為tensor,第二個引數為()元組
上面x.reshape((3, 4))也可寫成x.reshape((-1, 4))或x.reshape((3, -1))。由於x的元素個數是已知的,這裡的-1是能夠通過元素個數和其他維度的大小推斷出來的。
- 建立一個各元素為0,形狀為(2, 3, 4)的張量
tf.zeros((2,3,4))
- 建立各元素為1的張量
tf.ones((3,4 ))
- 通過Python的列表(list)指定需要建立的tensor中每個元素的值
Y = tf.constant([[2,1,4,3],[1,2,3,4],[4,3,2,1]])
Y
<tf.Tensor: id=9, shape=(3, 4), dtype=int32, numpy=
array([[2, 1, 4, 3],
[1, 2, 3, 4],
[4, 3, 2, 1]])>
- 我們需要隨機生成tensor中每個元素的值。下面我們建立一個形狀為(3, 4)的tensor。它的每個元素都隨機取樣於均值為0、標準差為1的正態分佈。
x=tf.random. normal(shape=[3,4], mean=0, stddev=1)
print(x)
tf.Tensor(
[[-1.153268 0.6116716 0.9703915 -2.7604232 ]
[ 0.48349026 -0.14327626 2.940394 0.98280823]
[ 0.11714476 -1.9485139 -0.46181852 -0.23992358]],
shape=(3, 4), dtype=float32)
2.2.2運算
- 乘除
X + Y #這裡的X,Y有相同的形狀,對應元素可以相加
X * Y#對應的元素相乘
X / Y
- 指數運算
Y = tf.cast(Y, tf.float32)#這裡先轉換tensor的型別
x=tf.reshape(tf.constant(range(12)),(3,4))
print(x)
x = tf.cast(x, tf.float32)
print(tf.exp(x))
tf.Tensor(
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]], shape=(3, 4), dtype=int32)
tf.Tensor(
[[1.0000000e+00 2.7182817e+00 7.3890562e+00 2.0085537e+01]
[5.4598152e+01 1.4841316e+02 4.0342880e+02 1.0966332e+03]
[2.9809580e+03 8.1030840e+03 2.2026467e+04 5.9874145e+04]], shape=(3, 4), dtype=float32)
這裡注意,這裡必須要cast 型別轉換
- 矩陣的乘法,matmul函式做矩陣乘法
Y = tf.cast(Y, tf.int32)
tf.matmul(X, tf.transpose(Y))
- 矩陣 的轉置
tf.transpose(Y)
- tensor 的拼接
tf.concat([X,Y],axis = 0)#行為axis=0,結果shape (6,4)
tf.concat([X,Y],axis = 1)#列為axis=1,結果shape (3,8)
- 判斷值相等,以X == Y為例,如果X和Y在相同位置的條件判斷為真(值相等),那麼新的tensor在相同位置的值為1;反之為0。
tf.equal(X,Y)
<tf.Tensor: id=31, shape=(3, 4), dtype=bool, numpy=
array([[False, True, False, True],
[False, False, False, False],
[False, False, False, False]])>
- 求和
tf.reduce_sum(X)
2.2.3廣播機制
對兩個形狀相同的tensor做按元素運算。當對兩個形狀不同的tensor按元素運算時,可能會觸發廣播(broadcasting)機制:先適當複製元素使這兩個tensor形狀相同後再按元素運算。
2.2.4索引
在tensor中,索引(index)代表了元素的位置。tensor的索引從0開始逐一遞增。例如,一個3行2列的矩陣的行索引分別為0、1和2,列索引分別為0和1。
X[1:3]
#X為3行4列,這句話等於X[1:3,:],依據左閉右開指定範圍的慣例,它截取了矩陣X中行索引為1和2的兩行。
<tf.Tensor: id=50, shape=(2, 4), dtype=float32, numpy=
array([[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
- 賦值
指定tensor中需要訪問的單個元素的位置,如矩陣中行和列的索引,併為該元素重新賦值。
X = tf.Variable(X)#從常量轉換為變數
X[1,2].assign(9)
<tf.Variable 'UnreadVariable' shape=(3, 4) dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 9., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
2.2.5 運算的記憶體開銷
tensor 和 NumPy 相互變換
import numpy as np
P = np.ones((2,3))
D = tf.constant(P)
下面為TF 的tensor
<tf.Tensor: id=115, shape=(2, 3), dtype=float64, numpy=
array([[1., 1., 1.],
[1., 1., 1.]])>
在轉換回來
下面為np的tensor
np.array(D)
2.3自動求梯度
對函式 求關於列向量 xx 的梯度。
x = tf.reshape(tf.Variable(range(4), dtype=tf.float32),(4,1))
with tf.GradientTape() as t:
t.watch(x)
y = 2 * tf.matmul(tf.transpose(x), x)
dy_dx = t.gradient(y, x)
dy_dx
<tf.Tensor: id=30, shape=(4, 1), dtype=float32, numpy=
array([[ 0.],
[ 4.],
[ 8.],
[12.]], dtype=float32)>
with tf.GradientTape(persistent=True) as g:
g.watch(x)
y = x * x
z = y * y
dz_dx = g.gradient(z, x) # 108.0 (4*x^3 at x = 3)
dy_dx = g.gradient(y, x) # 6.0
dz_dx,dy_dx
WARNING:tensorflow:Calling GradientTape.gradient on a persistent tape inside its context is significantly less efficient than calling it outside the context (it causes the gradient ops to be recorded on the tape, leading to increased CPU and memory usage). Only call GradientTape.gradient inside the context if you actually want to trace the gradient in order to compute higher order derivatives.
WARNING:tensorflow:Calling GradientTape.gradient on a persistent tape inside its context is significantly less efficient than calling it outside the context (it causes the gradient ops to be recorded on the tape, leading to increased CPU and memory usage). Only call GradientTape.gradient inside the context if you actually want to trace the gradient in order to compute higher order derivatives.
(<tf.Tensor: id=41, shape=(4, 1), dtype=float32, numpy=
array([[ 0.],
[ 4.],
[ 32.],
[108.]], dtype=float32)>,
<tf.Tensor: id=47, shape=(4, 1), dtype=float32, numpy=
array([[0.],
[2.],
[4.],
[6.]], dtype=float32)>)
with tf.GradientTape(persistent=True) as g:
g.watch(x)
y = x * x
z = y * y
dz_dx = g.gradient(z, x) # 108.0 (4*x^3 at x = 3)
dy_dx = g.gradient(y, x) # 6.0
dz_dx,dy_dx
WARNING:tensorflow:Calling GradientTape.gradient on a persistent tape inside its context is significantly less efficient than calling it outside the context (it causes the gradient ops to be recorded on the tape, leading to increased CPU and memory usage). Only call GradientTape.gradient inside the context if you actually want to trace the gradient in order to compute higher order derivatives.
WARNING:tensorflow:Calling GradientTape.gradient on a persistent tape inside its context is significantly less efficient than calling it outside the context (it causes the gradient ops to be recorded on the tape, leading to increased CPU and memory usage). Only call GradientTape.gradient inside the context if you actually want to trace the gradient in order to compute higher order derivatives.
(<tf.Tensor: id=41, shape=(4, 1), dtype=float32, numpy=
array([[ 0.],
[ 4.],
[ 32.],
[108.]], dtype=float32)>,
<tf.Tensor: id=47, shape=(4, 1), dtype=float32, numpy=
array([[0.],
[2.],
[4.],
[6.]], dtype=float32)>)
2.4
想了解某個函式或者類的具體用法時,可以使用help函式。讓我們以ones函式為例,查閱它的用法。更詳細的資訊,可以通過Tensorflow的API文件版本選擇頁,選擇與自己環境中的 tensorflow 版本一致的 API 版本進行查詢。
help(tf.ones)
當我們想知道一個模組裡面提供了哪些可以呼叫的函式和類的時候,可以使用dir函式。下面我們列印dtypes和random模組中所有的成員或屬性。
當我們想知道一個模組裡面提供了哪些可以呼叫的函式和類的時候,可以使用dir函式。下面我們列印dtypes和random模組中所有的成員或屬性。
dir(tf.dtypes)
['DType',
'QUANTIZED_DTYPES',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__path__',
'__spec__',
'_sys',
'as_dtype',
'bfloat16',
'bool',
'cast',
'complex',
'complex128',
'complex64',
'double',
'float16',
'float32',
'float64',
'half',
'int16',
'int32',
'int64',
'int8',
'qint16',
'qint32',
'qint8',
'quint16',
'quint8',
'resource',
'saturate_cast',
'string',
'uint16',
'uint32',
'uint64',
'uint8',
'variant']