為什麼要用 Numpy?
只用Python不好嗎?
前言
這是我學習 Deep Learning Specialization 系列課程的心得筆記,其他相關的心得我會陸續整理在 學習深度學習的課堂筆記 底下
正文
在開始學習Machine Learning 之前我就是一個Python的重度使用者,開始學習ML之後我才接觸到Jupyter notebook跟Numpy這兩項工具。一開始有些不習慣,但久了之後覺得這個組合實在是非常方便。不過有一個問題一直令我非常不理解…
為什麼做資料分析的人都不喜歡寫 for loop?
Numpy在做數學(向量,矩陣)運算上提供了非常多方便的語法,例如向量的內積,如果要自己用for loop來做會很麻煩:
VEC_LENGTH = 100000
w = np.random.rand(VEC_LENGTH)
x = np.random.rand(VEC_LENGTH)# for loop
c = 0
for i in range(VEC_LENGTH):
c += w[i] * x[i]# numpy
import numpy as np
c = np.dot(w, x)
numpy版本是不是簡單又清楚呢?除了向量內積以外,許多常用的運算也有很好的支援,例如矩陣乘法
A = np.array([
[1, 2, 3],
[2, 3, 4],
])B = np.array([
[2],
[0],
])A * B
# array([[2 4 6], [0 0 0]])
或是對矩陣內的每一個項目進行操作
A = np.array([1, 2, 3])
A ** 2
# array([1, 4, 9])
但除了這些 API簡單好用之外,使用Numpy跟自己寫的for loop有一個最關鍵的差別,那就是執行的效能!!我在Jupyter notebook上面做了簡單的實驗,結果如下:
VEC_LENGTH = 100000
w = np.random.rand(VEC_LENGTH)
x = np.random.rand(VEC_LENGTH)
tic = time.time()
c = 0
for i in range(VEC_LENGTH):
c += w[i] * x[i]
toc = time.time()
print('For loop took: %s ms' % str(1000 * (toc - tic)))# >> For loop took: 124.56703186 mstic = time.time()
c = np.dot(w, x)
toc = time.time()
print('Vectorized dot took: %s ms' % str(1000 * (toc - tic)))# >> Vectorized dot took: 0.262975692749 ms
124.5670 ms vs 0.2529ms !!快要五百倍的速度提升,五百倍!!這樣的速度提升在其他Numpy API 也都有類似的情形(可以參考這個Notebook)。
這揪~竟~是為什麼呢??
原來Numpy除了幫我們把結果正確算出來之外,會透過硬體裝置(GPU or CPU)來進行加速運算。因此當我們把原本要交給同一個CPU的運算改成透過GPU上面好多個運算單元來同時進行就可以達到這樣的效果了 💪 💪
另外值得一提的是就算電腦沒有安裝GPU,Numpy 還是可以透過SIMD (Single Instruction, Multiple Data) 這種CPU內建的機制來達成加速,因此不論如何使用Numpy就是比自己寫 for loop快上許多。
結論
對於認真想把是資料處理當飯吃的人來說,五百倍的加速是跑一小時得到結果跟一個月的差別… 如果沒有特別注意很容易就不小心在程式碼裡面寫了低效能的Code而不自知 🙁 所以要非常小心。
最簡單無腦的原則就是:
除非萬不得已,不然不要用 for loop來做資料處理。
以上就是這部分的心得。謝謝您閱讀到最後。想看更多我上課的心得可以參考我學習深度學習的課堂筆記