1.視頻網站:mooc慕課https://mooc.study.163.com/university/deeplearning_ai#/c
2.詳細筆記網站(中文):http://www.ai-start.com/dl2017/
3.github課件+作業+答案:https://github.com/stormstone/deeplearning.ai
2.16 關於 python / numpy 向量的說明 A note on p ython/numpy vectors
本節會介紹一些技巧,用於排除,簡化代碼中各種奇奇怪怪的bug,更容易寫出無bug的numpy代碼。包含:
- 注意數組的shape
- 使用assert確保向量
- reshape的使用
numpy允許你使用廣播(broadcasting)功能,這是它最靈活的地方。
numpy的優勢在於它讓語言表達能力更強,更靈活,用一行代碼完成很多運算。
但是這也是有弱點的,因爲廣播的巨大靈活性,有時候會引入非常細微的錯誤。如果你不熟悉廣播的運作方式,會寫出很奇怪,非常難調試的bug。例如,如果你將一個列向量添加到一個行向量中,你會以爲它報出維度不匹配或類型錯誤之類的錯誤,但是實際上你會得到一個行向量和列向量求和後的矩陣。
爲了演示numpy的一個容易被忽略的效果,特別是怎樣在numpy中構造向量,讓我來做一個快速示範。
首先生成存儲在數組 a 中的5個高斯隨機數變量
import numpy as np #導入numpy庫
a=np.random.randn(5)
print ("a=",a)
print (a.shape)
運行效果
a= [-1.30954715 -1.25722051 -0.31537174 -0.04121987 0.1119526 ]
(5,)
shape打印結果是一個(5,)的結構,這在Python中被稱作秩爲1的數組(rank 1 arra)。它既不是一個行向量也不是一個列向量,這也導致它有一些略微不直觀的效果。
如果打印a的轉置
import numpy as np #導入numpy庫
a=np.random.randn(5)
print ("a=",a)
print (a.shape)
print (a.T)
運行結果
a= [-0.93094324 -1.9257376 -1.13399415 -1.644786 -0.16162342]
(5,)
[-0.93094324 -1.9257376 -1.13399415 -1.644786 -0.16162342]
你會發現,a的轉置和a看上去一樣。
如果打印a和a的轉置的乘積
print (np.dot(a,a.T))
結果
4.71615439939
你會發現,結果不是矩陣,而是一個實數。
所以,建議當你編寫神經網絡時,不要使用shape是(5,)或者(n,)的這種秩爲1的數據結構。
如果你設置a爲(5,1)
import numpy as np #導入numpy庫
a=np.random.randn(5,1) #修改後代碼
print ("a=",a)
print (a.shape)
運行結果如下
a= [[ 1.66552728]
[ 0.97158225]
[ 2.32880578]
[-0.41018567]
[-0.46105292]]
(5, 1)
a變成了一個5x1的列向量。
現在打印a的轉置
print (a.T)
結果變成了行向量
[[ 1.66552728 0.97158225 2.32880578 -0.41018567 -0.46105292]]
這個數據結構中,有2個方括號。而上面例子中a的轉置打印只有1個方括號。
區別是,這裏是1x5的矩陣,不是秩爲1的數組。
再打印a和a的轉置的乘積
print (np.dot(a,a.T))
結果是一個矩陣
[[ 2.77398112 1.61819674 3.87868956 -0.68317543 -0.76789621]
[ 1.61819674 0.94397207 2.26262636 -0.39852912 -0.44795083]
[ 3.87868956 2.26262636 5.42333637 -0.95524277 -1.0737027 ]
[-0.68317543 -0.39852912 -0.95524277 0.16825229 0.1891173 ]
[-0.76789621 -0.44795083 -1.0737027 0.1891173 0.21256979]]
再次強調一下,(5,)這種秩爲1的數組,它的行爲和行向量或者列向量並不一樣。在編程時候建議不要使用。
相反,每次定義創建數組時候,要把它定義爲(5,1)列向量
a=np.random.randn(5,1)
或者(1,5)行向量
a=np.random.randn(1,5)
另外,如果代碼中做了很多操作,導致不完全確定一個向量具體的維度,可以使用斷言語句(assertion statement),確保這是一個向量。
例如,以下代碼確保a是一個列向量
assert=(a.shape==(5,1))
assert執行起來很快。
最後,如果代碼中得到了一個秩爲1的數組,可以使用reshape轉換爲列向量或者行向量。
例如
a=a.reshape((5,1))
這樣它的行爲會更好預測,因爲變成了列向量或者行向量的行爲。