2.16 关于 Python Numpy 的说明-深度学习-Stanford吴恩达教授
| 2.15 Python 中的廣播 | 回到目錄 | 2.17 Jupyter/iPython 筆記本的快速指南 |
關于 Python Numpy 的說明 (A Note on Python/Numpy Vectors)
本節主要講Python中的numpy一維數組的特性,以及與行向量或列向量的區別。并介紹了老師在實際應用中的一些小技巧,去避免在coding中由于這些特性而導致的bug。
Python的特性允許你使用廣播(broadcasting)功能,這是Python的numpy程序語言庫中最靈活的地方。而我認為這是程序語言的優點,也是缺點。優點的原因在于它們創造出語言的表達性,Python語言巨大的靈活性使得你僅僅通過一行代碼就能做很多事情。但是這也是缺點,由于廣播巨大的靈活性,有時候你對于廣播的特點以及廣播的工作原理這些細節不熟悉的話,你可能會產生很細微或者看起來很奇怪的bug。例如,如果你將一個列向量添加到一個行向量中,你會以為它報出維度不匹配或類型錯誤之類的錯誤,但是實際上你會得到一個行向量和列向量的求和。
在Python的這些奇怪的影響之中,其實是有一個內在的邏輯關系的。但是如果對Python不熟悉的話,我就曾經見過的一些學生非常生硬、非常艱難地去尋找bug。所以我在這里想做的就是分享給你們一些技巧,這些技巧對我非常有用,它們能消除或者簡化我的代碼中所有看起來很奇怪的bug。同時我也希望通過這些技巧,你也能更容易地寫沒有bug的Python和numpy代碼。
為了演示Python-numpy的一個容易被忽略的效果,特別是怎樣在Python-numpy中構造向量,讓我來做一個快速示范。首先設置 a=np.random.randn(5) ,這樣會生成存儲在數組 aaa 中的5個高斯隨機數變量。之后輸出 aaa ,從屏幕上可以得知,此時 aaa 的shape(形狀)是一個 (5,)(5,)(5,) 的結構。這在Python中被稱作一個一維數組。它既不是一個行向量也不是一個列向量,這也導致它有一些不是很直觀的效果。舉個例子,如果我輸出一個轉置陣,最終結果它會和 aaa 看起來一樣,所以 aaa 和 aaa 的轉置陣最終結果看起來一樣。而如果我輸出 aaa 和 aaa 的轉置陣的內積,你可能會想: aaa 乘以 aaa 的轉置返回給你的可能會是一個矩陣。但是如果我這樣做,你只會得到一個數。
所以我建議當你編寫神經網絡時,不要在它的shape是 (5,)(5,)(5,) 還是 (n,)(n,)(n,) 或者一維數組時使用數據結構。相反,如果你設置 aaa 為 (5,1)(5,1)(5,1) ,那么這就將置于5行1列向量中。在先前的操作里 aaa 和 aaa 的轉置看起來一樣,而現在這樣的 aaa 變成一個新的 aaa 的轉置,并且它是一個行向量。請注意一個細微的差別,在這種數據結構中,當我們輸出 aaa 的轉置時有兩對方括號,而之前只有一對方括號,所以這就是1行5列的矩陣和一維數組的差別。
如果你輸出 aaa 和 aaa 的轉置的乘積,然后會返回給你一個向量的外積,是吧?所以這兩個向量的外積返回給你的是一個矩陣。
就我們剛才看到的,再進一步說明。首先我們剛剛運行的命令是這個 (a=np.random.randn(5)) ,而且它生成了一個數據結構 (a.shape)(a.shape)(a.shape) , a.shapea.shapea.shape 是 (5,)(5,)(5,) ,一個有趣的東西。這被稱作 aaa 的一維數組,同時這也是一個非常有趣的數據結構。它不像行向量和列向量那樣表現的很一致,這也讓它的一些影響不那么明顯。所以我建議,當你在編程練習或者在執行邏輯回歸和神經網絡時,你不需要使用這些一維數組。
相反,如果你每次創建一個數組,你都得讓它成為一個列向量,產生一個 (5,1)(5,1)(5,1) 向量或者你讓它成為一個行向量,那么你的向量的行為可能會更容易被理解。所以在這種情況下, a.shapea.shapea.shape 等同于 (5,1)(5,1)(5,1) 。這種表現很像 aaa ,但是實際上卻是一個列向量。同時這也是為什么當它是一個列向量的時候,你能認為這是矩陣 (5,1)(5,1)(5,1) ;同時這里 a.shapea.shapea.shape 將要變成 (1,5)(1,5)(1,5) ,這就像行向量一樣。所以當你需要一個向量時,我會說用這個或那個(column vector or row vector),但絕不會是一維數組。
我寫代碼時還有一件經常做的事,那就是如果我不完全確定一個向量的維度(dimension),我經常會扔進一個斷言語句(assertion statement)。像這樣,去確保在這種情況下是一個 (5,1)(5,1)(5,1) 向量,或者說是一個列向量。這些斷言語句實際上是要去執行的,并且它們也會有助于為你的代碼提供信息。所以不論你要做什么,不要猶豫直接插入斷言語句。如果你不小心以一維數組來執行,你也能夠重新改變數組維數 a=reshapea=reshapea=reshape ,表明一個 (5,1)(5,1)(5,1) 數組或者一個 (1,5)(1,5)(1,5) 數組,以致于它表現更像列向量或行向量。
我有時候看見學生因為一維數組不直觀的影響,難以定位bug而告終。通過在原先的代碼里清除一維數組,我的代碼變得更加簡潔。而且實際上就我在代碼中表現的事情而言,我從來不使用一維數組。因此,要去簡化你的代碼,而且不要使用一維數組。總是使用 n?1n*1n?1 維矩陣(基本上是列向量),或者 1?n1*n1?n 維矩陣(基本上是行向量),這樣你可以減少很多assert語句來節省核矩陣和數組的維數的時間。另外,為了確保你的矩陣或向量所需要的維數時,不要羞于 reshape 操作。
總之,我希望這些建議能幫助你解決一個Python中的bug,從而使你更容易地完成練習。
課程PPT
| 2.15 Python 中的廣播 | 回到目錄 | 2.17 Jupyter/iPython 筆記本的快速指南 |
總結
以上是生活随笔為你收集整理的2.16 关于 Python Numpy 的说明-深度学习-Stanford吴恩达教授的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2.15 Python 中的广播-深度学
- 下一篇: 2.17 Jupyter/ipython