源碼和運行結果
cuda:https://github.com/zhxfl/CUDA-CNN
C語言版本參考自:http://eric-yuan.me/
針對著名手寫數字識別的庫mnist,准確率是99.7%,在幾分鍾內,CNN的訓練就可以達到99.60%左右的准確率。
參數配置
網絡的配置使用Config.txt進行配置##之間是注釋,代碼會自動過濾掉,其他格式參考如下:
#Comment# #NON_LINEARITY CAN = NL_SIGMOID , NL_TANH , NL_RELU# ## ## ## ## IS_GRADIENT_CHECKING = false; BATCH_SIZE = 200; NON_LINEARITY = NL_RELU; [ LAYER = CONV; KERNEL_SIZE = 5; KERNEL_AMOUNT = 10; WEIGHT_DECAY = 1e-6; POOLING_DIM = 2; ] [ LAYER = CONV; KERNEL_SIZE = 5; KERNEL_AMOUNT = 20; WEIGHT_DECAY = 1e-6; POOLING_DIM = 2; ] [ LAYER = FC; NUM_HIDDEN_NEURONS = 256; WEIGHT_DECAY = 1e-6; DROPOUT_RATE = 0.5; ] [ LAYER = FC; NUM_HIDDEN_NEURONS = 256; WEIGHT_DECAY = 1e-6; DROPOUT_RATE = 0.5; ] [ LAYER = SOFTMAX; NUM_CLASSES = 10; WEIGHT_DECAY = 1e-6; ]
1)目前代碼支持多個卷積層,多個全鏈接層。
2)卷積層默認帶有池化層,池化算法目前只支持最大值池化。
3)卷積層的卷積核大小只支持奇數。
4)全鏈接層支持Dropconnect。(配置里面寫的是dropout,后面會糾正這個的)
5)weight_decay這個參數如果你不知道是做什么,也可以先不理會,先用這個值就行了。
編譯代碼
1)代碼目前依賴cuda-6.0以及opencv,如果你不想去裝opencv,可以將util.cu和util.h所有有關opencv的代碼都去掉,整個代碼只有這里使用到opencv,而且只是由於我在開發過程中需要顯示圖片來調試而已。
2)代碼直接可以導入nsight然后編譯運行。同時也可以再vs2010里面編譯運行。
代碼特性
1)我們對數據做了處理,每次進行訓練之前,都會隨機的進行旋轉、尺度變換、畸變和裁剪。下圖是兩個例子,實際上,這樣做非常有效,使得我們的准確能夠更高
2)整個代碼采用cuda進行加速,其中我們用到了cublas.lib和curand.lib兩個庫,一個是矩陣運算一個是隨機數的生成。我一次性申請了所有需要使用的內存,在程序開始運行之后,就不存在任何CPU和GPU之間的數據交換,事實證明這樣非常有效。程序的性能比原來作者C語言版本快了數十倍左右(如果網絡比較大,可以達到一百倍左右的加速比)。我們每個epos使用1600ms,處理了60000張圖片,也就是訓練一張圖片大概是0.0266ms。
3)實際上,如果訓練多個網絡,然后進行投票,准確率可以達到99.82%,這個結果是目前為止所有公開發表結果中最好(99.79%)的 。