基於ARM在cpu上做神經網路加速

2021-07-30 02:34:42 字數 4016 閱讀 2388

本文將嘗試回答乙個簡單的問題:什麼庫/工具包/框架可以幫助我們優化訓練模型的推理時間?本文只討論已為arm架構晶元提供c / c ++介面的工具包和庫(由於嵌入式裝置上使用 ,我們很少lua 或 python),限於文章篇幅,不闡述另外一種加速神經網路推理的方法,即修改網路架構,從sqeezenet架構可看出,修改網路架構是乙個可行的方案。基於上述原因,本文涉及的實驗只涉及使用caffe,

tensorflow

和mxnet這3個開源的

深度學習框架。

加速神經網路模型在硬體平台計算速度,兩個主要有大的策略:

1)修改神經網路的模型;

2)加快框架執行速度。

當然,將這兩個策略結合起來使用,也是一種不錯的思路。

修改神經網路模型有兩種方法,一是通過降低權重精度實現,即降低特徵量化的精度,二是通過權重剪枝來實現,權重剪枝的背後的思想是降低系統引數的冗餘。降低權重低精度通常採用(用定點數或動態定點數表示浮點數的方法,支援這種做法的原理是:推理過程並不需要高精度,因為在運算過程中,計算的線性性質和非線性的動態範圍壓縮,使得量化誤差僅在子線性地(sub-linearly)範圍內傳遞,從而不會引起數值的劇烈變動。更進一步,我們可以使用低精度乘法來訓練神經網路模型。結合 simd 指令集,比如 sse3,可以使特徵量化過程可以更為高效,從而加速訓練過程。然而,目前我們還很難找到同時使用了這兩者的解決方案。比如使用ristretto框架可以執行有限精度的自動量化,但它卻並沒有降低計算負載。tensorflow 也可以執行量化,但其推理時間實際上卻增加了 5 到 20 倍,因為tensorflow還引入了輔助量化/去量化的計算節點。因此在實際操作中,我們只把量化作為壓縮網路權重的方法,當儲存空間有限時可以這樣操作,至少這已經是當前最先進的技術。

從另外乙個角度看,我們可採用加快框架的執行時間的方法,這種方法不會影響到模型的引數。這種策略主要上採用優化矩陣之間的乘法(gemm)類的通用計算技巧,從而同時影響卷積層(其計算通常是 im2col + gemm)和全連線層。除此之外,可以使用神經網路的加速包nnpack,就個人理解,nnpack的核心思路是使用快速傅利葉變換將時間域中的卷積運算轉換成了頻域中的乘法運算。

加快框架執行速度另一種方法是將網路模型和權重配置轉換成針對目標平台**,並對**進行優化,而不是讓它們直接在某乙個框架內執行。這種方法的典型案例是 tensorrt。還有 caffepresso, 可以將 caffe中prototxt型別的檔案定製成適用於各種不同硬體平台的低規格版本。然而,tensorrt 的執行需要cuda,而且只能在 nvidia的 gpu中才能使用,而 caffepresso 也需要某種硬體加速器(dsp、fpga 或 noc)

上述內容仔細地評估現有的解決辦法後,我發現以下幾種方法能夠加速當前流行的可用模型的推理:

基於以上3種方法,我概括出以下調測配置:

1. 使用以 openblas為後端的caffe 主分支(caffe-openblas);

2. 使用以 openblas為後端openblas 且為深度學習優化過的caffe分支版本(caffe-openblas-dl);

3. 編譯tensorflow時,使用優化編譯標誌 optflags="-os" (tf-vanilla)

4. 編譯tensorflow時,使用優化編譯標誌 optflags="-os -mfpu=neon-vfpv4 -funsafe-math-optimizations -ftree-vectorize" (tf-neon-vfpv4)

5. 使用以openblas實現基礎線性代數程式集的vanilla mxnet

6. 使用帶有 openblas 、且為深度學習優化過mxnet 分支版本(mxnet-openblas-dl)。

你可能會疑惑:配置中怎麼沒有 nnpack?這確實有點複雜,由 ajtulloch 建立的 caffe 分支提供了最直接的使用 nnpack方法。然而自從它被整合進去以後,nnpack 的api介面 就已經改變了,並且目前我無法編譯它。caffe2 對 nnpack 有原生支援,但我不會考慮 caffe2,因為它處於實驗性階段並且幾乎對 caffe 進行了尚未文件化的重構。另外乙個選項就是使用 maratyszcza的caffe-nnpack分支,但該分支比較老舊且已經停止維護。

另外乙個問題就是出於nnpack本身。它只提供了android/arm平台的交叉編譯配置,並不提供在 linux/arm 平台上的交叉編譯配置。結合mxnet,我嘗試編譯目標平台**,但結果無法在目標平台上正常執行。我只能在台式電腦上執行它,但是我並沒有看到比 openblas 會有更好的效能。由於我的目標是評估已經可用的解決方法,所以我只能推遲nnpack 的實驗了。

以上所有的這些方法都是在四核 1.3 ghz cpu 和 1 gb ram 的樹莓派 3 上執行。作業系統是 32 位的 raspbian,所以檢測到的 cpu 不是 armv8 架構,而是 armv7 架構。硬體規格如下:

為了評估上述每個測試配置的效能,我制定的測試方案如下:使用相同的神經網路。也就是乙個有 3 個卷積層和2個全連線層且在頂層帶有softmax的小型卷積神經網路:

conv1: 16@7x7

relu1pool1: max pool 2x2conv2: 48@6x6

relu2pool2: max pool 3x3conv3: 96@5x5

relu3fc1: 128 unitsfc2: 848 units

softmax

該卷積神經網路有 1039744 個引數。雖然非常小,但它已經足夠強大了,可以用來處理許多計算機視覺演算法。該網路使用 caffe 進行訓練人臉識別任務,並將其轉換為 tensorflow 和 mxnet 格式,從而使用這些框架進行評估。批量執行次數對效能有很大的影響,為了測量前向通過時間(forward pass time),我們將批量執行的次數設定為 1 到 256。在不同次數的批量執行中,我們每次執行 100 次前向通過,並計算了每一張影象的平均處理時間。

在下面的**中,列出了平均前向通過的時間。其中,a 是 caffe-openblas, b 是 caffe-openblas-dl, c 代表 tf-vanilla, d 是 tf-neon-vfpv4, e 是 mxnet-openblas, f 是 mxnet-openblas-dl。

表1 不同測試配置在不同的批處理次數下的效能表現

圖1 線性尺度下不同配置的前向通過時間比較

在對數尺度尺度上我們再來看一下:

圖2 對數尺度下不同配置的前向通過時間比較

測試結果讓我大吃一驚。首先,我沒有預料到在 cpu 上執行 mxnet的效能會這麼差。但這看起來已經是乙個眾所周知的問題。此外,受限於儲存空間,它無法執行 256 張的批處理。第二個驚奇是優化過的 tensorflow 竟有如此好的效能。它甚至比 caffe 的表現還好(批處理次數超過2時),光從原始框架上看是很難預料這個結果的。需要注意的是,上述測試配置中的優化標誌並不是在任意 arm 晶元上都可以使用的。

caffe 因速度非常快和思路獨到而知名。如果你需要連續地處理,可以選擇使用優化過的 openblas 的 caffe,可得到最好的處理效能。如果想提公升10ms 的效能,你所要做的就只是簡單的輸入以下指令:

cd openblas

git checkout optimized_for_deeplearning

為了將我的研究轉變成正式的東西,我仍需要做大量的工作:評估更多的模型,最終整合 nnpack,以及研究更多結合了blas 後端的框架。雷鋒網希望本文能幫助你了解目前最流行的解決方案的推理速度。

via how to run deep neural networks on weak hardware

BP神經網路(基於MATLAB)

clc clear all 匯入資料 load s data.mat s含量所用資料 n 12 n 是自變數的個數 m 1 m 是因變數的個數 讀取訓練資料 train num 1600 訓練樣本數 train data s data 1 train num,特徵值歸一化 train input,m...

2 1 優化神經網路(上)

3 其他的一些解決過擬合的方法 3.1 data augmentation 資料增加 3.2 early stopping 4 加快訓練速度的方法 4.1 early stopping 4.2 歸一化輸入 5 梯度消失和梯度 及其解決 6 梯度檢驗 都遍歷神經網路的每一層,並設定消除神將網路中節點的...

基於BP神經網路的分類

使用的是乙個簡單的資料集fisheriris,該資料集資料類別分為3類,setosa,versicolor,virginica。每類植物有50個樣本,共150個樣本代表150朵花瓣。每個樣本有4個屬性,分別為花萼長,花萼寬,花瓣長,花瓣寬。其中meas是150 4的矩陣代表著有150個樣本每個樣本有...