如何為Halide后端安排網(wǎng)絡(luò)

2018-10-18 10:26 更新

介紹

Halide代碼對于我們使用的每個設(shè)備都是一樣的。但是為了達(dá)到滿意的效率,我們應(yīng)該正確地安排計算。在本教程中,我們將介紹如何使用OpenCV深度學(xué)習(xí)模塊中的Halide后端來安排網(wǎng)絡(luò)。

為了更好地了解Halide計劃,您可能需要閱讀教程@ http://halide-lang.org/tutorials

如果這是您在OpenCV中與Halide的第一次學(xué)習(xí),我們建議從如何啟用Halide后端以提高效率

配置文件

您可以通過編寫文本配置文件來計劃Halide管道的計算。這意味著您可以輕松地矢量化,并行和管理層計算的循環(huán)順序。cv::dnn::Net::setHalideScheduler在第一次cv::dnn::Net::forward調(diào)用之前,將特定設(shè)備的調(diào)度指令傳遞到文件路徑。

調(diào)度表示為YAML文件的配置文件,其中每個節(jié)點(diǎn)是計劃功能或調(diào)度指令。

relu1:
  reorder: [x, c, y]
  split: { y: 2, c: 8 }
  parallel: [yo, co]
  unroll: yi
  vectorize: { x: 4 }
conv1_constant_exterior:
  compute_at: { relu1: yi }

考慮使用n批量維度,c渠道,y行和x列的變量。對于變量分裂后都具有相同前綴使用的名稱,但o和i后綴對應(yīng)的外部和內(nèi)部的變量。例如,對于變量x范圍[0, 10)指令split: { x: 2 },xo在范圍[0, 5)和xi范圍內(nèi)給出了新的范圍指令[0, 2)。變量名稱x在同一調(diào)度節(jié)點(diǎn)中不再可用。

您可以在opencv_extra / testdata / dnn上找到調(diào)度示例,并使用它來安排您的網(wǎng)絡(luò)。

圖層融合

由于圖層融合,我們只能安排融合集頂層。因?yàn)閷τ诿總€輸出值,我們使用融合公式。例如,如果您有三層卷積+ Scale + ReLU一個一個。

conv(x, y, c, n) = sum(...) + bias(c);
scale(x, y, c, n) = conv(x, y, c, n) * weights(c);
relu(x, y, c, n) = max(scale(x, y, c, n), 0);

融合功能就是這樣

relu(x, y, c, n) = max((sum(...) + bias(c)) * weights(c), 0);

所以只有函數(shù)調(diào)用relu需要調(diào)度。

計劃模式

有時,使用阻塞結(jié)構(gòu)構(gòu)建的網(wǎng)絡(luò)意味著某些層是相同或非常相似的。如果要對不同的層應(yīng)用相同的調(diào)度,精確到平鋪或矢量化因子,請在patterns調(diào)度文件開頭部分中定義調(diào)度模式。此外,您的模式可能會使用一些參數(shù)變量。

# At the beginning of the file
patterns:
  fully_connected:
    split: { c: c_split }
    fuse: { src: [x, y, co], dst: block }
    parallel: block
    vectorize: { ci: c_split }
# Somewhere below
fc8:
  pattern: fully_connected
  params: { c_split: 8 }

自動調(diào)度

您可以讓DNN自動安排圖層。只是跳過電話cv::dnn::Net::setHalideScheduler。有時它可能比手動調(diào)度更有效率。但是,如果需要手動調(diào)度特定層次,則可以混合手動和自動調(diào)度方式。編寫計劃文件并跳過要自動計劃的圖層。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號