2020-5-3 吳恩達-NN&DL-w2 NN基礎(2.16 關於 python / numpy 向量的說明)

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))

這樣它的行爲會更好預測,因爲變成了列向量或者行向量的行爲。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章