官术网_书友最值得收藏!

1.5 計算的高速化

神經網絡的學習和推理需要大量的計算。因此,如何高速地計算神經網絡是一個重要課題。本節將簡單介紹一下可以有效加速神經網絡的計算的位精度和GPU的相關內容。

相比計算的高速化,本書更加重視實現的易理解性。但是,從計算的高速化的角度出發,之后進行的實現將考慮數據的位精度。另外,在需要花費大量時間進行計算的地方,會將代碼設計為可在GPU上執行。

1.5.1 位精度

NumPy的浮點數默認使用64位的數據類型。不過,是否為64位還依賴于具體的環境,包括操作系統、Python和NumPy的版本等。我們可以使用下面的代碼來驗證是否使用了64位浮點數。

        >>> import numpy as np
        >>> a = np.random.randn(3)
        >>> a.dtype
        dtype('float64')

通過NumPy數組的實例變量dtype,可以查看數據類型。上面的結果是float64,表示64位的浮點數。

NumPy中默認使用64位浮點數。但是,我們已經知道使用32位浮點數也可以無損地(識別精度幾乎不下降)進行神經網絡的推理和學習。從內存的角度來看,因為32位只有64位的一半,所以通常首選32位。另外,在神經網絡的計算中,數據傳輸的總線帶寬有時會成為瓶頸。在這種情況下,毫無疑問數據類型也是越小越好。再者,就計算速度而言,32位浮點數也能更高速地進行計算(浮點數的計算速度依賴于CPU或GPU的架構)。

因此,本書優先使用32位浮點數。要在NumPy中使用32位浮點數,可以像下面這樣將數據類型指定為np.float32或者’f'。

        >>> b = np.random.randn(3).astype(np.float32)
        >>> b.dtype
        dtype('float32')

        >>> c = np.random.randn(3).astype('f')
        >>> c.dtype
        dtype('float32')

另外,我們已經知道,如果只是神經網絡的推理,則即使使用16位浮點數進行計算,精度也基本上不會下降[6]。不過,雖然NumPy中準備有16位浮點數,但是普通CPU或GPU中的運算是用32位執行的。因此,即便變換為16位浮點數,因為計算本身還是用32位浮點數執行的,所以處理速度方面并不能獲得什么好處。

但是,如果是要(在外部文件中)保存學習好的權重,則16位浮點數是有用的。具體地說,將權重數據用16位精度保存時,只需要32位時的一半容量。因此,本書僅在保存學習好的權重時,將其變換為16位浮點數。

隨著深度學習備受矚目,最近的GPU已經開始支持16位半精度浮點數的存儲與計算。另外,谷歌公司設計了一款名為TPU的專用芯片,可以支持8位計算[7]

1.5.2 GPU(CuPy)

深度學習的計算由大量的乘法累加運算組成。這些乘法累加運算的絕大部分可以并行計算,這是GPU比CPU擅長的地方。因此,一般的深度學習框架都被設計為既可以在CPU上運行,也可以在GPU上運行。

本書中可以選用Python庫CuPy[3]。CuPy是基于GPU進行并行計算的庫。要使用CuPy,需要使用安裝有NVIDIA的GPU的機器,并且需要安裝CUDA這個面向GPU的通用并行計算平臺。詳細的安裝方法請參考CuPy的官方安裝文檔[4]

使用Cupy,可以輕松地使用NVIDIA的GPU進行并行計算。更重要的是,CuPy和NumPy擁有共同的API。下面我們來看一個簡單的使用示例。

        >>> import cupy as cp
        >>> x = cp.arange(6).reshape(2 , 3).astype('f')
        >>> x
        array([[ 0.,  1.,  2.],
              [ 3.,  4.,  5.]], dtype=float32)
        >>> x.sum(axis=1)
        array([  3.,  12.], dtype=float32)

如上所示,CuPy的使用方法與NumPy基本相同。另外,它的內部使用GPU進行計算。這意味著使用NumPy寫的代碼可以輕松地改成“GPU版”,因為我們要做的(基本上)只是把numpy替換為cupy而已。

截至2018年6月,CuPy并沒有完全覆蓋NumPy的方法。雖然CuPy和NumPy并不完全兼容,但是它們有許多共同的API。

重申一下,本書為了使代碼實現易于理解,基本上都基于CPU進行實現。對于計算上要耗費大量時間的代碼,則提供使用了CuPy的實現(可選)。不過,即便在使用CuPy的情況下,也會盡量做到不讓讀者感到是在使用CuPy。

本書中可以在GPU上運行的代碼最先出現在第4章(ch04/train.py)。這個ch04/train.py從以下的import語句開始。

        import sys
        sys.path.append('..')
        import numpy as np
        from common import config
        # 在用GPU運行時,請打開下面的注釋(需要cupy)
        # ===============================================
        # config.GPU = True
        # ===============================================
        ...

用CPU執行上述代碼需要花費幾個小時,但是如果使用GPU,則只需要幾十分鐘。并且,只要修改上述源代碼中的一行,本書提供的代碼就可以在GPU模式下運行。具體而言,只需打開注釋# config.GPU = True,并用CuPy代替NumPy即可。如此,代碼就可以在GPU上運行,并高速地進行學習。請有GPU的讀者多多嘗試一下。

將NumPy切換為CuPy的機制非常簡單,感興趣的讀者請參考common/config.py 、common/np.py和common/layers.py的import語句。

主站蜘蛛池模板: 旅游| 清流县| 浪卡子县| 濮阳市| 邢台县| 沿河| 陈巴尔虎旗| 克山县| 武夷山市| 台山市| 武鸣县| 章丘市| 罗城| 丹江口市| 江源县| 天水市| 双牌县| 屏边| 始兴县| 伊金霍洛旗| 弥渡县| 剑阁县| 永嘉县| 石景山区| 当雄县| 大宁县| 漳平市| 吴旗县| 宁波市| 通渭县| 柯坪县| 德兴市| 卓尼县| 图们市| 和硕县| 崇礼县| 江北区| 化隆| 永福县| 夏河县| 苍梧县|