學(xué)習(xí)參考:
- 動手學(xué)深度學(xué)習(xí)2.0
- Deep-Learning-with-TensorFlow-book
- pytorchlightning
①如有冒犯、請聯(lián)系侵刪。
②已寫完的筆記文章會不定時一直修訂修改(刪、改、增),以達到集多方教程的精華于一文的目的。
③非常推薦上面(學(xué)習(xí)參考)的前兩個教程,在網(wǎng)上是開源免費的,寫的很棒,不管是開始學(xué)還是復(fù)習(xí)鞏固都很不錯的。
深度學(xué)習(xí)回顧,專欄內(nèi)容來源多個書籍筆記、在線筆記、以及自己的感想、想法,佛系更新。爭取內(nèi)容全面而不失重點。完結(jié)時間到了也會一直更新下去,已寫完的筆記文章會不定時一直修訂修改(刪、改、增),以達到集多方教程的精華于一文的目的。所有文章涉及的教程都會寫在開頭、一起學(xué)習(xí)一起進步。
一、數(shù)組與張量
雖然張量看起來是復(fù)雜的對象,但它們可以理解為向量和矩陣的集合。理解向量和矩陣對于理解張量至關(guān)重要。
- 向量是元素的一維列表,向量是一個有序的數(shù)列,可以表示為一維數(shù)組。通常用來表示空間中的方向和大小。
- 矩陣是向量的二維列表,陣是一個二維數(shù)組,由行和列組成。通常用來表示線性變換、數(shù)據(jù)集合等。
- 張量可以被視為多維矩陣列表,張量是一個多維數(shù)組,可以看作是向量和矩陣的推廣。在深度學(xué)習(xí)和機器學(xué)習(xí)中,張量是數(shù)據(jù)的基本表示形式。0階張量是標(biāo)量(Scalar)、1階張量是向量、2階張量是矩陣,以此類推。
TensorFlow中的Tensors是不可變的,也不能被賦值。 TensorFlow中的Variables是支持賦值的可變?nèi)萜鳌?請記住,TensorFlow中的梯度不會通過Variable反向傳播。
1.張量創(chuàng)建
張量表示一個由數(shù)值組成的數(shù)組,這個數(shù)組可能有多個維度]。 具有一個軸的張量對應(yīng)數(shù)學(xué)上的向量(vector); 具有兩個軸的張量對應(yīng)數(shù)學(xué)上的矩陣(matrix); 具有兩個軸以上的張量沒有特殊的數(shù)學(xué)名稱。
如何創(chuàng)建張量?
(1)range方法
import tensorflow as tf
x = tf.range(12)
#可以通過張量的shape屬性來訪問張量(沿每個軸的長度)的形狀
print(x.shape)
# 如果只想知道張量中元素的總數(shù),即形狀的所有元素乘積,可以檢查它的大?。╯ize)。
print(tf.size(x))
使用全0、全1、其他常量,或者從特定分布中隨機采樣的數(shù)字]來初始化張量。
print(tf.ones((2, 3, 4)))
tf.zeros((2, 3, 4))
(2)從某個概率分布中采樣創(chuàng)建
通過從某個特定的概率分布中隨機采樣來得到張量中每個元素的值。 例如,當(dāng)構(gòu)造數(shù)組來作為神經(jīng)網(wǎng)絡(luò)中的參數(shù)時,通常會隨機初始化參數(shù)的值。 以下代碼創(chuàng)建一個形狀為(3,4)的張量。 其中的每個元素都從均值為0、標(biāo)準(zhǔn)差為1的標(biāo)準(zhǔn)高斯分布(正態(tài)分布)中隨機采樣。
tf.random.normal(shape=[3, 4])
<tf.Tensor: shape=(3, 4), dtype=float32, numpy=
array([[ 0.77872986, -0.82767004, 1.489659 , 0.3403899 ],
[-0.07687712, -1.2800221 , 0.48299474, -0.5643912 ],
[-1.0667747 , 0.32837722, -0.02862396, -0.49701583]],
dtype=float32)>
(3)從其它數(shù)據(jù)結(jié)構(gòu)(如列表)創(chuàng)建
通過提供包含數(shù)值的Python列表(或嵌套列表),來為所需張量中的每個元素賦予確定值]
tf.constant([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
<tf.Tensor: shape=(3, 4), dtype=int32, numpy=
array([[2, 1, 4, 3],
[1, 2, 3, 4],
[4, 3, 2, 1]])>
2.改變維度
要想改變一個張量的形狀而不改變元素數(shù)量和元素值,可以調(diào)用reshape函數(shù)。
X = tf.reshape(x, (3, 4))
X
<tf.Tensor: shape=(3, 4), dtype=int32, numpy=
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])>
不需要通過手動指定每個維度來改變形狀。 也就是說,如果的目標(biāo)形狀是(高度,寬度), 那么在知道寬度后,高度會被自動計算得出,不必自己做除法。 在上面的例子中,為了獲得一個3行的矩陣,我們手動指定了它有3行和4列。 幸運的是,可以通過-1來調(diào)用此自動計算出維度的功能。 即可以用x.reshape(-1,4)或x.reshape(3,-1)來取代x.reshape(3,4)。
tf.reshape(x, (4, -1))
<tf.Tensor: shape=(4, 3), dtype=int32, numpy=
array([[ 0, 1, 2],
[ 3, 4, 5],
[ 6, 7, 8],
[ 9, 10, 11]])>
3.長度、維度和形狀
調(diào)用Python的內(nèi)置len()函數(shù)來訪問張量的長度
x = tf.range(4)
len(x),len(tf.constant([[1,2,3,5,6],[1,2,3,9,6]]))
形狀(shape)是一個元素組,列出了張量沿每個軸的長度(維數(shù))。
x.shape
二、按元素運算(運算符)
在數(shù)據(jù)上執(zhí)行數(shù)學(xué)運算,其中最簡單且最有用的操作是按元素(elementwise)運算。 它們將標(biāo)準(zhǔn)標(biāo)量運算符應(yīng)用于數(shù)組的每個元素。 對于將兩個數(shù)組作為輸入的函數(shù),按元素運算將二元運算符應(yīng)用于兩個數(shù)組中的每對位置對應(yīng)的元素。 可以基于任何從標(biāo)量到標(biāo)量的函數(shù)來創(chuàng)建按元素函數(shù)。
1. 基本運算(按元素位置)
對于任意具有相同形狀的張量, [常見的標(biāo)準(zhǔn)算術(shù)運算符(+、-、*、/和**)都可以被升級為按元素運算]。 可以在同一形狀的任意兩個張量上調(diào)用按元素操作。
x = tf.constant([1.0, 2, 4, 8])
y = tf.constant([2.0, 2, 2, 2])
x + y, x - y, x * y, x / y, x ** y # **運算符是求冪運算
(<tf.Tensor: shape=(4,), dtype=float32, numpy=array([ 3., 4., 6., 10.], dtype=float32)>,
<tf.Tensor: shape=(4,), dtype=float32, numpy=array([-1., 0., 2., 6.], dtype=float32)>,
<tf.Tensor: shape=(4,), dtype=float32, numpy=array([ 2., 4., 8., 16.], dtype=float32)>,
<tf.Tensor: shape=(4,), dtype=float32, numpy=array([0.5, 1. , 2. , 4. ], dtype=float32)>,
<tf.Tensor: shape=(4,), dtype=float32, numpy=array([ 1., 4., 16., 64.], dtype=float32)>)
#求冪運算也可以如下
tf.exp(x)
有時,想[通過邏輯運算符構(gòu)建二元張量]。 以X == Y為例: 對于每個位置,如果X和Y在該位置相等,則新張量中相應(yīng)項的值為1。 這意味著邏輯語句X == Y在該位置處為真,否則該位置為0。
X = tf.reshape(tf.range(12, dtype=tf.float32), (3, 4))
Y = tf.constant([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
X == Y
對張量中的所有元素進行求和,會產(chǎn)生一個單元素張量。
tf.reduce_sum(X)
2.張量連結(jié)(拼接)
把多個張量連結(jié)(concatenate)在一起], 把它們端對端地疊起來形成一個更大的張量。 只需要提供張量列表,并給出沿哪個軸連結(jié)。
X = tf.reshape(tf.range(12, dtype=tf.float32), (3, 4))
Y = tf.constant([[2.0, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])
print(X)
print(Y)
print("\n")
print(tf.concat([X, Y], axis=1))
tf.concat([X, Y], axis=0)
tf.Tensor(
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]], shape=(3, 4), dtype=float32)
tf.Tensor(
[[2. 1. 4. 3.]
[1. 2. 3. 4.]
[4. 3. 2. 1.]], shape=(3, 4), dtype=float32)
tf.Tensor(
[[ 0. 1. 2. 3. 2. 1. 4. 3.]
[ 4. 5. 6. 7. 1. 2. 3. 4.]
[ 8. 9. 10. 11. 4. 3. 2. 1.]], shape=(3, 8), dtype=float32)
<tf.Tensor: shape=(6, 4), dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[ 2., 1., 4., 3.],
[ 1., 2., 3., 4.],
[ 4., 3., 2., 1.]], dtype=float32)>
3.張量的廣播機制
在某些情況下,[即使形狀不同,仍然可以通過調(diào)用 廣播機制(broadcasting mechanism)來執(zhí)行按元素操作]。 這種機制的工作方式如下:
- 通過適當(dāng)復(fù)制元素來擴展一個或兩個數(shù)組,以便在轉(zhuǎn)換之后,兩個張量具有相同的形狀;
- 對生成的數(shù)組執(zhí)行按元素操作。
a和b分別是 3×1 和 1×2矩陣,如果讓它們相加,它們的形狀不匹配。 我們將兩個矩陣廣播為一個更大的 3×2矩陣,如下所示:矩陣a將復(fù)制列, 矩陣b將復(fù)制行,然后再按元素相加。
a = tf.reshape(tf.range(3), (3, 1))
b = tf.reshape(tf.range(2), (1, 2))
print(a, b)
a + b
返回:
(<tf.Tensor: shape=(3, 1), dtype=int32, numpy=
array([[0],
[1],
[2]])>,
<tf.Tensor: shape=(1, 2), dtype=int32, numpy=array([[0, 1]])>)
<tf.Tensor: shape=(3, 2), dtype=int32, numpy=
array([[0, 1],
[1, 2],
[2, 3]])>
三、張量的數(shù)據(jù)操作
1. 張量的訪問:索引和切片
張量中的元素可以通過索引訪問。 與任何Python數(shù)組一樣:第一個元素的索引是0,最后一個元素索引是-1; 可以指定范圍以包含第一個元素和最后一個之前的元素。
可以用[-1]選擇最后一個元素,可以用[1:3]選擇第二個和第三個元素:
X = tf.reshape(tf.range(12, dtype=tf.float32), (3, 4))
X[-1], X[1:3]
索引、切片可以用來訪問元素也可以用來更改和刪除元素,但僅在Variable類型的張量中可進行更改和刪除元素
X_var = tf.Variable(X)
print(X_var)
X_var[1, 2].assign(9)
X_var
<tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
<tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 9., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
為多個元素賦值相同的值,只需要索引所有元素,然后為它們賦值。] 例如,[0:2, :]訪問第1行和第2行,其中“:”代表沿軸1(列)的所有元素。
X_var = tf.Variable(X)
print(X_var)
X_var[0:2, :].assign(tf.ones(X_var[0:2,:].shape, dtype = tf.float32) * 12)
X_var
<tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.]], dtype=float32)>
<tf.Variable 'Variable:0' shape=(3, 4) dtype=float32, numpy=
array([[12., 12., 12., 12.],
[12., 12., 12., 12.],
[ 8., 9., 10., 11.]], dtype=float32)>
2.張量和其他python對象互相轉(zhuǎn)換
將深度學(xué)習(xí)框架定義的張量[轉(zhuǎn)換為NumPy張量(ndarray)]很容易,反之也同樣容易。 轉(zhuǎn)換后的結(jié)果不共享內(nèi)存。
(1)將張量和numpy數(shù)組互相轉(zhuǎn)換
print(type(X))
A = X.numpy()
B = tf.constant(A)
type(A), type(B)
<class 'tensorflow.python.framework.ops.EagerTensor'>
(numpy.ndarray, tensorflow.python.framework.ops.EagerTensor)
(2)將大小為1的張量轉(zhuǎn)換為Python標(biāo)量
a = tf.constant([3.5]).numpy()
a, a.item(), float(a), int(a)
(3)將pandas的df轉(zhuǎn)換為張量
首先讀取數(shù)據(jù)并預(yù)處理,這里不多說,很簡單,基操。
import os
os.makedirs(os.path.join('..', 'data'), exist_ok=True)
data_file = os.path.join('..', 'data', 'house_tiny.csv')
# 如果沒有安裝pandas,只需取消對以下行的注釋來安裝pandas
# !pip install pandas
import pandas as pd
data = pd.read_csv(data_file)
print(data)
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())
print(inputs)
inputs = pd.get_dummies(inputs, dummy_na=True)
print(inputs)
NumRooms Alley Price
0 NaN Pave 127500
1 2.0 NaN 106000
2 4.0 NaN 178100
3 NaN NaN 140000
NumRooms Alley
0 3.0 Pave
1 2.0 NaN
2 4.0 NaN
3 3.0 NaN
NumRooms Alley_Pave Alley_nan
0 3.0 1 0
1 2.0 0 1
2 4.0 0 1
3 3.0 0 1
print(inputs)
print(outputs)
NumRooms Alley_Pave Alley_nan
0 3.0 1 0
1 2.0 0 1
2 4.0 0 1
3 3.0 0 1
0 127500
1 106000
2 178100
3 140000
Name: Price, dtype: int64
現(xiàn)在inputs和outputs中的所有條目都是數(shù)值類型,它們可以轉(zhuǎn)換為張量格式。
import tensorflow as tf
X, y = tf.constant(inputs.values), tf.constant(outputs.values)
X, y
(<tf.Tensor: shape=(4, 3), dtype=float64, numpy=
array([[3., 1., 0.],
[2., 0., 1.],
[4., 0., 1.],
[3., 0., 1.]])>,
<tf.Tensor: shape=(4,), dtype=int64, numpy=array([127500, 106000, 178100, 140000], dtype=int64)>)
3.可變張量與不可變張量(深淺復(fù)制、涉及節(jié)省內(nèi)存和優(yōu)化程序必需)
TensorFlow中的Tensors是不可變的,也不能被賦值。 TensorFlow中的Variables是支持賦值的可變?nèi)萜鳌?請記住,TensorFlow中的梯度不會通過Variable反向傳播。
運行一些操作可能會導(dǎo)致為新結(jié)果分配內(nèi)存,這種情況下內(nèi)存會快速增長、從而導(dǎo)致程序崩潰的可能性,但是有時候又需要使用新的張量結(jié)果、有時候又需要使用舊的張量結(jié)果 例如,如果用Y = X + Y,將取消引用Y指向的原有張量,而是指向新分配的內(nèi)存處的張量。
before = id(Y)
Y = Y + X
id(Y) == before
返回
False
Variables是TensorFlow中的可變?nèi)萜鳎鼈兲峁┝艘环N存儲模型參數(shù)的方法。 如此一來,在機器學(xué)習(xí)中,可能有數(shù)百兆的參數(shù),并且在一秒內(nèi)多次更新所有參數(shù)。通常情況下,希望原地執(zhí)行這些更新,Variables張量就能做到此需求;
Z = tf.Variable(tf.zeros_like(Y))
print('id(Z):', id(Z))
Z.assign(X + Y)
print('id(Z):', id(Z))
id(Z): 139712800290752
id(Z): 139712800290752
即使你將狀態(tài)持久存儲在Variable中, 你也可能希望避免為不是模型參數(shù)的張量過度分配內(nèi)存,從而進一步減少內(nèi)存使用量。由于TensorFlow的Tensors是不可變的,而且梯度不會通過Variable流動, 因此TensorFlow沒有提供一種明確的方式來原地運行單個操作。
TensorFlow提供了tf.function修飾符, 將計算封裝在TensorFlow圖中,該圖在運行前經(jīng)過編譯和優(yōu)化。 這允許TensorFlow刪除未使用的值,并復(fù)用先前分配的且不再需要的值。 這樣可以最大限度地減少TensorFlow計算的內(nèi)存開銷。
@tf.function
def computation(X, Y):
Z = tf.zeros_like(Y) # 這個未使用的值將被刪除
A = X + Y # 當(dāng)不再需要時,分配將被復(fù)用
B = A + Y
C = B + Y
return C + Y
computation(X, Y)
<tf.Tensor: shape=(3, 4), dtype=float32, numpy=
array([[ 8., 9., 26., 27.],
[24., 33., 42., 51.],
[56., 57., 58., 59.]], dtype=float32)>
四、線性代數(shù)
除了按元素計算外,還可以執(zhí)行線性代數(shù)運算,包括向量點積和矩陣乘法。
1.標(biāo)量、向量、矩陣、張量
(1)標(biāo)量
嚴(yán)格來說,僅包含一個數(shù)值被稱為標(biāo)量(scalar),標(biāo)量由只有一個元素的張量表示。
import tensorflow as tf
x = tf.constant(3.0)
y = tf.constant(2.0)
x + y, x * y, x / y, x**y
(<tf.Tensor: shape=(), dtype=float32, numpy=5.0>,
<tf.Tensor: shape=(), dtype=float32, numpy=6.0>,
<tf.Tensor: shape=(), dtype=float32, numpy=1.5>,
<tf.Tensor: shape=(), dtype=float32, numpy=9.0>)
(2)向量
向量可以被視為標(biāo)量值組成的列表。 這些標(biāo)量值被稱為向量的元素(element)或分量(component)。 當(dāng)向量表示數(shù)據(jù)集中的樣本時,它們的值具有一定的現(xiàn)實意義。 例如,如果正在訓(xùn)練一個模型來預(yù)測貸款違約風(fēng)險,可能會將每個申請人與一個向量相關(guān)聯(lián), 其分量與其收入、工作年限、過往違約次數(shù)和其他因素相對應(yīng)。
通過一維張量表示向量。一般來說,張量可以具有任意長度,取決于機器的內(nèi)存限制。通過張量的索引來訪問任一元素。
x = tf.range(4)
x
x[3]
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([0, 1, 2, 3])>
<tf.Tensor: shape=(), dtype=int32, numpy=3>
使用下標(biāo)來引用向量的任一元素,例如可以通過 ????來引用第 ??個元素。 注意,元素 ????是一個標(biāo)量,所以在引用它時不會加粗。 大量文獻認(rèn)為列向量是向量的默認(rèn)方向:
(3)矩陣
矩陣:正如向量將標(biāo)量從零階推廣到一階,矩陣將向量從一階推廣到二階。 矩陣,我們通常用粗體、大寫字母來表示 (例如, ?? 、 ?? 和 ?? ), 在代碼中表示為具有兩個軸的張量。
?? 的形狀是( ?? , ?? )或 ??×?? 。 當(dāng)矩陣具有相同數(shù)量的行和列時,其形狀將變?yōu)檎叫危?因此,它被稱為方陣(square matrix)。當(dāng)調(diào)用函數(shù)來實例化張量時, 可以[通過指定兩個分量 ?? 和 ?? 來創(chuàng)建一個形狀為 ??×?? 的矩陣]。
A = tf.reshape(tf.range(20), (5, 4))
A
矩陣轉(zhuǎn)置:當(dāng)交換矩陣的行和列時,結(jié)果稱為矩陣的轉(zhuǎn)置(transpose)。
tf.transpose(A)
(4)張量
就像向量是標(biāo)量的推廣,矩陣是向量的推廣一樣,可以構(gòu)建具有更多軸的數(shù)據(jù)結(jié)構(gòu)。當(dāng)開始處理圖像時,張量將變得更加重要,圖像以 ?? 維數(shù)組形式出現(xiàn), 其中3個軸對應(yīng)于高度、寬度,以及一個通道(channel)軸, 用于表示顏色通道(紅色、綠色和藍色)。
X = tf.reshape(tf.range(24), (2, 3, 4))
X
<tf.Tensor: shape=(2, 3, 4), dtype=int32, numpy=
array([[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]],
[[12, 13, 14, 15],
[16, 17, 18, 19],
[20, 21, 22, 23]]])>
2.張量計算的基本性質(zhì)
任何按元素的一元運算都不會改變其操作數(shù)的形狀。 同樣,給定具有相同形狀的任意兩個張量,任何按元素二元運算的結(jié)果都將是相同形狀的張量。
(1)直接賦值舊變量到形變量、不會分配新內(nèi)存
A = tf.reshape(tf.range(20, dtype=tf.float32), (5, 4))
print(A)
B = A # 不能通過分配新內(nèi)存將A克隆到B
id(A)==id(B) # 兩個變量的內(nèi)存地址一樣,沒有產(chǎn)生新的內(nèi)存地址
tf.Tensor(
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]
[16. 17. 18. 19.]], shape=(5, 4), dtype=float32)
True
(2)兩個矩陣的Hadamard積(按元素乘法)
兩個矩陣的按元素乘法稱為Hadamard積(Hadamard product)(數(shù)學(xué)符號 ⊙):
(3)矩陣與標(biāo)量的運算
將張量乘以或加上一個標(biāo)量不會改變張量的形狀,其中張量的每個元素都將與標(biāo)量相加或相乘。加減乘除、次冪等皆不會改變張量的形狀。
a = 2
X = tf.reshape(tf.range(24), (2, 3, 4))
print(X)
a + X, (a * X).shape
tf.Tensor(
[[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
[[12 13 14 15]
[16 17 18 19]
[20 21 22 23]]], shape=(2, 3, 4), dtype=int32)
(<tf.Tensor: shape=(2, 3, 4), dtype=int32, numpy=
array([[[ 2, 3, 4, 5],
[ 6, 7, 8, 9],
[10, 11, 12, 13]],
[[14, 15, 16, 17],
[18, 19, 20, 21],
[22, 23, 24, 25]]])>,
TensorShape([2, 3, 4]))
X.shape,(a / X).shape,(a-X).shape
(TensorShape([2, 3, 4]), TensorShape([2, 3, 4]), TensorShape([2, 3, 4]))
(4)降維計算
以對任意張量進行的一個有用的操作是計算其元素的和。 數(shù)學(xué)表示法使用 ∑ 符號表示求和。
當(dāng)然,也可以計算均值等。
x = tf.range(4, dtype=tf.float32)
x, tf.reduce_sum(x)
(<tf.Tensor: shape=(4,), dtype=float32, numpy=array([0., 1., 2., 3.], dtype=float32)>,
<tf.Tensor: shape=(), dtype=float32, numpy=6.0>)
默認(rèn)情況下,調(diào)用求和函數(shù)會沿所有的軸降低張量的維度,使它變?yōu)橐粋€標(biāo)量。 還可以指定張量沿哪一個軸來通過求和降低維度。
print(A)
A_sum_axis0 = tf.reduce_sum(A, axis=0)
A_sum_axis0, A_sum_axis0.shape
#指定axis=1將通過匯總所有列的元素降維(軸1)。因此,輸入軸1的維數(shù)在輸出形狀中消失。
A_sum_axis1 = tf.reduce_sum(A, axis=1)
A_sum_axis1, A_sum_axis1.shape
tf.Tensor(
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]
[16. 17. 18. 19.]], shape=(5, 4), dtype=float32)
(<tf.Tensor: shape=(4,), dtype=float32, numpy=array([40., 45., 50., 55.], dtype=float32)>,
TensorShape([4]))
(<tf.Tensor: shape=(5,), dtype=float32, numpy=array([ 6., 22., 38., 54., 70.], dtype=float32)>,
TensorShape([5]))
tf.reduce_sum(A, axis=[0, 1]) # 結(jié)果和tf.reduce_sum(A)相同
<tf.Tensor: shape=(), dtype=float32, numpy=190.0>
同樣,計算平均值的函數(shù)也可以沿指定軸降低張量的維度。
tf.reduce_mean(A, axis=0), tf.reduce_sum(A, axis=0) / A.shape[0]
(<tf.Tensor: shape=(4,), dtype=float32, numpy=array([ 8., 9., 10., 11.], dtype=float32)>,
<tf.Tensor: shape=(4,), dtype=float32, numpy=array([ 8., 9., 10., 11.], dtype=float32)>)
(5)非降維求和
有時在調(diào)用函數(shù)來計算總和或均值時保持軸數(shù)不變會很有用。
print(A)
sum_A = tf.reduce_sum(A, axis=1, keepdims=True)
sum_A
tf.Tensor(
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]
[16. 17. 18. 19.]], shape=(5, 4), dtype=float32)
<tf.Tensor: shape=(5, 1), dtype=float32, numpy=
array([[ 6.],
[22.],
[38.],
[54.],
[70.]], dtype=float32)>
想沿某個軸計算A元素的累積總和, 比如axis=0(按行計算),可以調(diào)用cumsum函數(shù)。 此函數(shù)不會沿任何軸降低輸入張量的維度。
A,tf.cumsum(A, axis=0),tf.cumsum(A, axis=1)
(<tf.Tensor: shape=(5, 4), dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.],
[16., 17., 18., 19.]], dtype=float32)>,
<tf.Tensor: shape=(5, 4), dtype=float32, numpy=
array([[ 0., 1., 2., 3.],
[ 4., 6., 8., 10.],
[12., 15., 18., 21.],
[24., 28., 32., 36.],
[40., 45., 50., 55.]], dtype=float32)>,
<tf.Tensor: shape=(5, 4), dtype=float32, numpy=
array([[ 0., 1., 3., 6.],
[ 4., 9., 15., 22.],
[ 8., 17., 27., 38.],
[12., 25., 39., 54.],
[16., 33., 51., 70.]], dtype=float32)>)
(6)點積(Dot Product)
y = tf.ones(4, dtype=tf.float32)
print(x, y)
tf.tensordot(x, y, axes=1)#點積
tf.Tensor([0. 1. 2. 3.], shape=(4,), dtype=float32) tf.Tensor([1. 1. 1. 1.], shape=(4,), dtype=float32)
<tf.Tensor: shape=(), dtype=float32, numpy=6.0>
(7)矩陣-向量積
使用與點積相同的matvec函數(shù)。 當(dāng)為矩陣A和向量x調(diào)用tf.linalg.matvec(A, x)時,會執(zhí)行矩陣-向量積。 注意,A的列維數(shù)(沿軸1的長度)必須與x的維數(shù)(其長度)相同。
print(A.shape, x.shape)
print(A,x)
tf.linalg.matvec(A, x)
(5, 4) (4,)
tf.Tensor(
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]
[16. 17. 18. 19.]], shape=(5, 4), dtype=float32) tf.Tensor([0. 1. 2. 3.], shape=(4,), dtype=float32)
<tf.Tensor: shape=(5,), dtype=float32, numpy=array([ 14., 38., 62., 86., 110.], dtype=float32)>
(8)矩陣-矩陣乘積(矩陣乘法)
可以將矩陣-矩陣乘法 ???? 看作簡單地執(zhí)行 ??次矩陣-向量積,并將結(jié)果拼接在一起,形成一個 ??×??
矩陣。 在下面的代碼中,我們在A和B上執(zhí)行矩陣乘法。 這里的A是一個5行4列的矩陣,B是一個4行3列的矩陣。 兩者相乘后,我們得到了一個5行3列的矩陣。
B = tf.ones((4, 3), tf.float32)
print(A,B)
tf.matmul(A, B)
tf.Tensor(
[[ 0. 1. 2. 3.]
[ 4. 5. 6. 7.]
[ 8. 9. 10. 11.]
[12. 13. 14. 15.]
[16. 17. 18. 19.]], shape=(5, 4), dtype=float32) tf.Tensor(
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]], shape=(4, 3), dtype=float32)
<tf.Tensor: shape=(5, 3), dtype=float32, numpy=
array([[ 6., 6., 6.],
[22., 22., 22.],
[38., 38., 38.],
[54., 54., 54.],
[70., 70., 70.]], dtype=float32)>
(9)范數(shù)
線性代數(shù)中最有用的一些運算符是范數(shù)(norm)。 非正式地說,向量的范數(shù)是表示一個向量有多大。 這里考慮的大?。╯ize)概念不涉及維度,而是分量的大小。
范數(shù)聽起來很像距離的度量。 歐幾里得距離和畢達哥拉斯定理中的非負性概念和三角不等式可能會給出一些啟發(fā)。 事實上,歐幾里得距離是一個 ??2范數(shù)。度學(xué)習(xí)中更經(jīng)常地使用 ??2 范數(shù)的平方,也會經(jīng)常遇到 ??1 范數(shù),它表示為向量元素的絕對值之和。
計算L2范數(shù):
u = tf.constant([3.0, -4.0])
tf.norm(u)
<tf.Tensor: shape=(), dtype=float32, numpy=5.0>
計算L1范數(shù):文章來源:http://www.zghlxwxcb.cn/news/detail-838141.html
tf.reduce_sum(tf.abs(u))
<tf.Tensor: shape=(), dtype=float32, numpy=7.0>
文章來源地址http://www.zghlxwxcb.cn/news/detail-838141.html
到了這里,關(guān)于深度學(xué)習(xí) 精選筆記(1)數(shù)據(jù)基本操作與線性代數(shù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!