本系列筆記記錄了學習TensorFlow2的過程,主要依據git
https://github.com/dragen1860/Deep-Learning-with-TensorFlow-bookgithub
進行學習算法
首先須要明確TensorFlow 是一個面向於深度學習算法的科學計算庫,內部數據保存在張量(Tensor)對象上,全部的運算操做(Operation, OP)也都是基於張量對象進行。數組
數據類型網絡
Tensorflow中的基本數據類型有三種,包括數值型、字符串型和布爾型。框架
【數值型】又包括:(在 TensorFlow 中間,爲了表達方便,通常把標量、向量、矩陣也統稱爲張量,不做區分,須要根據張量的維度數和形狀自行判斷。 )dom
1.Scalar(標量)函數
維度數(Dimension,也叫秩)爲 0,shape 爲[] 工具
a = tf.constant(1.2) # 建立標量 學習
2.Vector(向量)
維度數爲 1,長度不定,shape 爲[𝑛]
x = tf.constant([1,2.,3.3])
3.Matrix(矩陣)
維度數爲 2,每一個維度上的長度不定,shape 爲[𝑛,𝑚] (n 行 m 列)
b = tf.constant([[1,2],[3,4]])
4.Tensor(張量)
維度數dim > 2的數組統稱爲張量。
c = tf.constant([[[1,2],[3,4]],[[5,6],[7,8]]]) (三維張量定義)
【字符串】類型:
a = tf.constant('Hello, Deep Learning.')
在 tf.strings 模塊中,提供了常見的字符串型的工具函數,如拼接 join(),長度 length(),切分 split()等等,如:tf.strings.lower(a)
【布爾】類型:
a = tf.constant(True)
數值精度
經常使用的精度類型有 tf.int16, tf.int32, tf.int64, tf.float16, tf.float32, tf.float64,其中 tf.float64 即爲 tf.double
對於大部分深度學習算法,通常使用 tf.int32, tf.float32 可知足運算精度要求,部分對精度要求較高的算法,如強化學習,能夠選擇使用 tf.int64, tf.float64 精度保存張量。
經過訪問張量的 dtype 成員屬性能夠判斷張量的保存精度: a = tf.constant(np.pi, dtype=tf.float16) ,print(a.dtype)
轉換精度 :a = tf.cast(a,tf.float32)
布爾型與整形之間相互轉換也是合法的,是比較常見的操做,通常默認 0 表示 False,1 表示 True,在 TensorFlow 中,將非 0 數字都視爲 True
待優化張量
爲了區分須要計算梯度信息的張量與不須要計算梯度信息的張量,TensorFlow 增長了 一種專門的數據類型來支持梯度信息的記錄:tf.Variable。tf.Variable 類型在普通的張量類 型基礎上添加了 name,trainable 等屬性來支持計算圖的構建。因爲梯度運算會消耗大量的 計算資源,並且會自動更新相關參數,對於不須要的優化的張量,如神經網絡的輸入 X, 不須要經過 tf.Variable 封裝;相反,對於須要計算梯度並優化的張量,如神經網絡層的W 和𝒃,須要經過 tf.Variable 包裹以便 TensorFlow 跟蹤相關梯度信息。 經過 tf.Variable()函數能夠將普通張量轉換爲待優化張量。
a = tf.constant([-1, 0, 1, 2])
aa = tf.Variable(a)
aa.name, aa.trainable
'''''''''''''''''''''''''''''''
Out[20]:
('Variable:0', True)
'''''''''''''''''''''''''''''''
建立 Variable 對象是默認啓用優化標誌,能夠設置 trainable=False 來設置張量不須要優化。
除了經過普通張量方式建立 Variable,也能夠直接建立: a = tf.Variable([[1,2],[3,4]])
待優化張量可看作普通張量的特殊類型,普通張量也能夠經過 GradientTape.watch()方法臨 時加入跟蹤梯度信息的列表。
建立張量
1.從 Numpy, List 對象建立
經過 tf.convert_to_tensor 能夠建立新 Tensor,並將保存在 Python List 對象或者 Numpy Array 對象中的數據導入到新 Tensor 中: tf.convert_to_tensor([1,2.]) | tf.convert_to_tensor(np.array([[1,2.],[3,4]]))
須要注意的是,Numpy 中浮點數數組默認使用 64-Bit 精度保存數據,轉換到 Tensor 類型時 精度爲 tf.float64,能夠在須要的時候轉換爲 tf.float32 類型。
tf.constant()和 tf.convert_to_tensor()都可以自動的把 Numpy 數組或者 Python List 數據類型轉化爲 Tensor 類型
2. 建立全 0,全 1 張量
考慮線性變換 𝒚 = 𝑊𝒙 +𝒃,將權值矩陣 W 初始化爲全 1 矩陣,偏置 b 初始化爲全 0 向量,此時線性變 化層輸出𝒚 = 𝒙,是一種比較好的層初始化狀態。經過 tf.zeros()和 tf.ones()便可建立任意形 狀全 0 或全 1 的張量。例如,建立爲 0 和爲 1 的標量張量:
tf.zeros([2,2]) | tf.ones([3,2])
經過 tf.zeros_like, tf.ones_like 能夠方便地新建與某個張量 shape 一致,內容全 0 或全 1 的張量 : tf.zeros_like(a)
tf.*_like 是一個便捷函數,能夠經過 tf.zeros(a.shape)等方式實現
3.建立自定義數值張量
tf.fill([2,2], 99)
4.建立已知分佈的張量
正態分佈(Normal Distribution,或 Gaussian Distribution)和均勻分佈(Uniform Distribution)是最多見的分佈之一,建立採樣自這 2 種分佈的張量很是有用,好比在卷積神經網絡中,卷積核張量 W 初始化爲正態分佈有利於網絡的訓練;在對抗生成網絡中,隱藏變量 z 通常採樣自均勻分佈。
經過 tf.random.normal(shape, mean=0.0, stddev=1.0)能夠建立形狀爲 shape,均值爲 mean,標準差爲 stddev 的正態分佈𝒩(𝑚𝑒𝑎𝑛,𝑠𝑡𝑑𝑑𝑒𝑣2)。
經過 tf.random.uniform(shape, minval=0, maxval=None, dtype=tf.float32)能夠建立採樣自 [𝑚𝑖𝑛𝑣𝑎𝑙,𝑚𝑎𝑥𝑣𝑎𝑙]區間的均勻分佈的張量。
5. 建立序列
tf.range(start, limit, delta=1)能夠建立[𝑠𝑡𝑎𝑟𝑡,𝑙𝑖𝑚𝑖𝑡),步長爲 delta 的序列,不包含 limit 自己:tf.range(1,10,delta=2)
張量的典型應用
1.標量
在 TensorFlow 中,標量最容易理解,它就是一個簡單的數字,維度數爲 0,shape 爲 []。標量的典型用途之一是偏差值的表示、各類測量指標的表示,好比準確度(Accuracy, acc),精度(Precision)和召回率(Recall)等。
out = tf.random.uniform([4,10]) #隨機模擬網絡輸出
y = tf.constant([2,3,2,0]) # 隨機構造樣本真實標籤
y = tf.one_hot(y, depth=10) # one-hot 編碼
loss = tf.keras.losses.mse(y, out) # 計算每一個樣本的 MSE
loss = tf.reduce_mean(loss) # 平均 MSE
print(loss)
2.向量
向量是一種很是常見的數據載體,如在全鏈接層和卷積神經網絡層中,偏置張量𝒃就 使用向量來表示。如圖 所示,每一個全鏈接層的輸出節點都添加了一個偏置值,把全部 輸出節點的偏置表示成向量形式:𝒃 = [𝑏1,𝑏2]𝑇。
# z=wx,模擬得到激活函數的輸入 z
z = tf.random.normal([4,2])
b = tf.zeros([2]) # 模擬偏置向量
z = z + b # 累加偏置(到這裏 shape 爲[4,2]的𝒛和 shape 爲[2]的𝒃張量能夠直接相加,這是爲何呢?讓咱們在 Broadcasting 一節爲你們揭祕)
經過高層接口類 Dense()方式建立的網絡層,張量 W 和𝒃存儲在類的內部,由類自動創 建並管理。能夠經過全鏈接層的 bias 成員變量查看偏置變量𝒃
fc = tf.keras.layers.Dense(3)# 建立一層 Wx+b,輸出節點爲 3 (原書表述爲:fc = layers.Dense(3) # 建立一層 Wx+b,輸出節點爲 3,此處前提是:)
fc.build(input_shape=(2,4))# 經過 build 函數建立 W,b 張量,輸入節點爲 4
fc.bias # 查看偏置
3.矩陣
矩陣也是很是常見的張量類型,好比全鏈接層的批量輸入𝑋 = [𝑏,𝑑𝑖𝑛],其中𝑏表示輸入樣本的個數,即 batch size,𝑑𝑖𝑛表示輸入特徵的長度。好比特徵長度爲 4,一共包含 2 個樣本的輸入能夠表示爲矩陣: x = tf.random.normal([2,4])
能夠經過全鏈接層的 kernel 成員名查看其權值矩陣 W:
fc = layers.Dense(3) # 定義全鏈接層的輸出節點爲 3
fc.build(input_shape=(2,4)) # 定義全鏈接層的輸入節點爲 4
fc.kernel
4.三維張量
三維的張量一個典型應用是表示序列信號,它的格式是 𝑋 = [𝑏,𝑠𝑒𝑞𝑢𝑒𝑛𝑐𝑒 𝑙𝑒𝑛,𝑓𝑒𝑎𝑡𝑢𝑟𝑒 𝑙𝑒𝑛] 其中𝑏表示序列信號的數量,sequence len 表示序列信號在時間維度上的採樣點數,feature len 表示每一個點的特徵長度。
爲了可以方便字符串被神經網絡處理,通常將單詞經過嵌入層(Embedding Layer)編碼爲固定長度的向量,好比「a」編碼爲某個長度 3 的向量,那麼 2 個 等長(單詞數爲 5)的句子序列能夠表示爲 shape 爲[2,5,3]的 3 維張量,其中 2 表示句子個數,5 表示單詞數量,3 表示單詞向量的長度。
5.四維張量
咱們這裏只討論 3/4 維張量,大於 4 維的張量通常應用的比較少,如在元學習(meta learning)中會採用 5 維的張量表示方法,理解方法與 3/4 維張量相似。
4 維張量在卷積神經網絡中應用的很是普遍,它用於保存特徵圖(Feature maps)數據, 格式通常定義爲
[𝑏,ℎ,w,𝑐]
其中𝑏表示輸入的數量,h/w分佈表示特徵圖的高寬,𝑐表示特徵圖的通道數,部分深度學習框架也會使用[𝑏,𝑐,ℎ, ]格式的特徵圖張量,例如 PyTorch。圖片數據是特徵圖的一種, 對於含有 RGB 3 個通道的彩色圖片,每張圖片包含了 h 行 w 列像素點,每一個點須要 3 個數 值表示 RGB 通道的顏色強度,所以一張圖片能夠表示爲[h,w,3]。