Python神經網路-常見的科學計算庫中的易錯點和技巧
文章說明:本文主要內容來自吳恩達老師的神經網路課程的課後練習,結合何寬的部落格,希望能為大家更加通俗清晰地理解和解決一些在使用Python實現神經網路中可能遇到的一些問題。
文章目錄
常見的科學計算庫中的易錯點和技巧
矩陣相加
看一下下面的這兩個隨機陣列“a”和“b”:
a = np.random.randn(2, 3) # a.shape = (2, 3)
b = np.random.randn( 2, 1) # b.shape = (2, 1)
c = a + b
問陣列c的維度是多少?
答: 因為B的列維數為1,所以先為B的列向量複製3次,使得A與B的行維數與列維數都相等,然後進行每項元素的相加,得:c.shape = (2, 3)
這個其實就是Python語法中的廣播機制。
另一種情況是A、B矩陣元素相乘,即A * B
,只有當A與B的矩陣之間維數相等時,A、B才能相乘,若A矩陣的列數不等於B矩陣的列數,或A矩陣的行數不等於B矩陣的行數,則不能將兩個矩陣相乘,程式會報錯,如下:
a = np.random.randn(4, 3) # a.shape = (4, 3)
b = np.random.randn(3, 2) # b.shape = (3, 2)
c = a * b
# ValueError: operands could not be broadcast together with shapes (4,3) (3,2)
然而,當a,b矩陣的行數或列數中有一個相等時,乘法是可以成立的,如下:
# a,b矩陣的行數相等,列數不相等
a = np.random.randn(3, 3)
b = np.random.randn(3, 1)
c = a * b
"""
[[ 0.30044552 0.32163572 0.83089828]
[-0.41384331 0.140933 0.20342014]
[ 0.15084242 -0.24968459 0.06532467]]
"""
在這種情況下,將會使用廣播機制,b會被複制三次,就會變成(3,3),再使用元素乘法。所以有:
c.shape = (3, 3)
.
矩陣乘法
np.dot(a,b
在a和b上執行矩陣乘法,而a * b
執行元素方式的乘法。
例如下面的兩個隨機陣列a
和b
:
a = np.random.randn(4, 3) # a.shape = (4, 3
b = np.random.randn(3, 2) # b.shape = (3, 2)
c = np.dot(a, b)
問c的維度是多少?
答: 兩個矩陣相乘,獲得的矩陣行數等於前一個矩陣的行數,列數等於後一個矩陣的列數c.shape = (4, 2)
。
廣播機制的缺點
當使用numpy進行科學計算的時候,可能對產生一個秩為1的矩陣,例如:
import numpy as np
a = np.random.randn(5)
a.shape
# (5,)
此時,如果將a矩陣與a矩陣的轉置相乘,你猜結果會如果
print(np.dot(a,a.T))
# 3.948322708713407
結果竟然得到一個數,而不是矩陣。
在來看看另一個例子:
A = np.random.randn(4,3)
B = np.sum(A, axis = 0)
B.shape
來猜測一些結果如何
答案是:(3,)
。這是因為對A矩陣進行行縱向相加後,返回了一個秩為1的矩陣。
那麼為了確保A.shape
是(4,1)
而不是(4,)
,則需要在sum
函式中新增引數keepdims = True
,這使我們的程式碼更加地嚴謹。
小結:
在寫神經網路時,不推薦使用類似的秩為1的矩陣,可能會造成一些誤差。
但是可以將a轉變為一個數組:
a = np.random.randn(5,1)
a.shape
# (5,1)
這個時候,就不會發生剛才的狀況了。
小技巧:
當自己不確定矩陣a的形狀是否正確,則可以使用assert(a.shape==(m,n)
來斷言a的形狀,此時如果a的形狀錯誤,則程式會丟擲異常,這樣就不怕出錯了。
未完待續~~~