在深度學(xué)習(xí)中,圖像數(shù)據(jù)通道格式有兩種:
-
NCHW锦溪,又稱:“channels_first”躏精,是nvidia cudnn庫原生支持的數(shù)據(jù)模式李丰;在GPU中惭蟋,使用NCHW格式計算卷積苗桂,比NHWC要快2.5倍左右(0:54 vs 2:14)
- NHWC, 又稱“channels_last”,是CPU指令比較適合的方式敞葛,SSE 或 AVX優(yōu)化誉察,沿著最后一維与涡,即C維計算惹谐,會更快。
-
NCHW排列驼卖,C在外層氨肌,所以每個通道內(nèi),像素緊挨在一起酌畜,即“RRRGGGBBB”怎囚;NHWC排列,C在最內(nèi)層桥胞,所以每個通道內(nèi)恳守,像素間隔挨在一起,即“RGBRGBRGB”贩虾,如下所示:
-
盡管存儲的數(shù)據(jù)實際上是一樣的催烘,但是不同的順序會導(dǎo)致數(shù)據(jù)的訪問特性不一致,因此即使進行同樣的運算缎罢,相應(yīng)的計算性能也會不一樣伊群。對于"NCHW" 而言,其同一個通道的像素值連續(xù)排布策精,更適合那些需要對每個通道單獨做運算的操作舰始,比如"MaxPooling"。對于"NHWC"而言咽袜,其不同通道中的同一位置元素順序存儲丸卷,因此更適合那些需要對不同通道的同一像素做某種運算的操作,比如“Conv1x1”
- 由于NCHW询刹,需要把所有通道的數(shù)據(jù)都讀取到谜嫉,才能運算抽莱,所以在計算時需要的存儲更多。這個特性適合GPU運算骄恶,正好利用了GPU內(nèi)存帶寬較大并且并行性強的特點食铐,其訪存與計算的控制邏輯相對簡單;而NHWC僧鲁,每讀取三個像素虐呻,都能獲得一個彩色像素的值,即可對該彩色像素進行計算寞秃,這更適合多核CPU運算斟叼,CPU的內(nèi)存帶寬相對較小,每個像素計算的時延較低春寿,臨時空間也很欣噬;若采取異步方式邊讀邊算來減小訪存時間绑改,計算控制會比較復(fù)雜谢床,這也比較適合CPU。
結(jié)論:在訓(xùn)練模型時厘线,使用GPU识腿,適合NCHW格式;在CPU中做推理時造壮,適合NHWC格式渡讼。采用什么格式排列,由計算硬件的特點決定耳璧。OpenCV在設(shè)計時是在CPU上運算的成箫,所以默認HWC格式。TensorFlow的默認格式是NHWC旨枯,也支持cuDNN的NCHW
import cv2
import matplotlib.pyplot as plt
import numpy as np
img = cv2.imread("data/images/bus.jpg")
img = cv2.resize(img, (5,4)) #(x, y) -> (W, H)
print(img.shape) # (H,W,C)
plt.figure()
plt.imshow(img)
plt.show()
line1 = img[1,...]
line1 = np.expand_dims(line1, axis=0)
print(line1.shape)
print(line1)
plt.figure()
plt.imshow(line1)
plt.show()
print("BGR->RGB")
rgb_line1 = cv2.cvtColor(line1, cv2.COLOR_BGR2RGB)
print(rgb_line1.shape)
print(rgb_line1)
print()
print("HWC->CHW")
CHW_line1 = np.transpose(line1, (2,0,1))
print(CHW_line1.shape)
print(CHW_line1)
運行結(jié)果如下: