Computational Network Toolkit (CNTK) 是微軟出品的開源深度學習工具包。本文介紹CNTK的基本內容,如何寫CNTK的網絡定義語言,以及跑通一個簡單的例子。html
根據微軟開發者的描述,CNTK的性能比Caffe,Theano, TensoFlow等主流工具都要強。它支持CPU和GPU模式,因此沒有GPU,或者神經網絡比較小的實驗,直接用CPU版的CNTK跑就好了。 其開源主頁在 https://github.com/Microsoft/CNTK 它把神經網絡描述成一個有向圖的結構,葉子節點表明輸入或者網絡參數,其餘節點計算步驟。 它支持卷積神經網絡和遞歸神經網絡。 因爲CNTK剛推出不久,大衆教程估計很少,並且bug估計也很多。我學習的時候,主要參考三個資料:node
1 官方入門教程 https://github.com/Microsoft/CNTK/wiki/Tutorial 本文也主要以這裏的教程爲例git
2 官方論壇 https://github.com/Microsoft/CNTK/issuesgithub
3 官方論文 http://research.microsoft.com/pubs/226641/CNTKBook-20160217..pdf 這個有150頁,我是看成字典來用,遇到問題的時候就在裏面搜算法
安裝CNTK: https://github.com/Microsoft/CNTK/wiki/CNTK-Binary-Download-and-Configuration 去這個頁面找符合本身系統的版本。 我是Windows用戶,CNTK有編譯好的CPU和GPU版本。因爲本人的顯卡不是英偉達的,因此無奈只能用CPU版湊合用用。已經編譯好的包最方便了,解壓,而後把目錄(相似%...%、CNTK-2016-02-08-Windows-64bit-CPU-Only\cntk\cntk)添加到PATH變量中就好了。 有條件的人也能夠本身編譯源代碼,稍微麻煩一些,各類依賴關係,好處是源碼更新的比較快,CNTK一大特色就是目前各類小bug比較多,好比我如今用的編譯好的包仍是兩個月前發佈的,已經本身填了好多坑了。網絡
安裝好CNTK以後,運行一個程序,就是一個簡單的命令行: CNTK configFile=your_config_file , 其中,your_config_file 是網絡的定義文件,大概長這樣:app
command=Train:Test Train=[
]action="train" NDLNetworkBuilder = [ ... ] SGD = [ ... ] reader = [ ...
]
Test=[ ... ]
運行的入口就是command命令,command後面接須要依次運行的模塊,用冒號分開。 每一個模塊裏面須要定義的事情比較相似,主要是定義輸入的格式,網絡結構,學習算法(目前只有SGD)和參數。 在定義網絡結構的時候,會指明哪些節點是優化目標,哪些是評價指標,以及哪些是輸出的點。框架
衆所周知,把神經網絡的隱藏層去掉以後,輸入直接連到輸出層,這樣就行成了一個logistics regression分類器。因此https://github.com/Microsoft/CNTK/wiki/Tutorial 這個教程就指導你們如何構建一個LR。 我這裏稍微變一下,學習一下如何構建帶有一層隱藏層的neural network,以下圖:dom
定義網絡結構函數
CNTK用網絡描述語言(network description language, NDL)描述一個神經網絡。 簡單的說,咱們要描述輸入的feature,輸入的label,一些參數,參數和輸入之間的計算關係,以及目標節點是什麼。
NDLNetworkBuilder=[ run=ndlLR ndlLR=[ # sample and label dimensions SDim=$dimension$ LDim=1 features=Input(SDim, 1) labels=Input(LDim, 1) # parameters to learn B0 = Parameter(4) W0 = Parameter(4, SDim) B = Parameter(LDim) W = Parameter(LDim, 4) # operations t0 = Times(W0, features) z0 = Plus(t0, B0) s0 = Sigmoid(z0) t = Times(W, s0) z = Plus(t, B) s = Sigmoid(z) LR = Logistic(labels, s) EP = SquareError(labels, s) # root nodes FeatureNodes=(features) LabelNodes=(labels) CriteriaNodes=(LR) EvalNodes=(EP) OutputNodes=(s,t,z,s0,W0) ] ]
features=Input(SDim, 1) labels=Input(LDim, 1) 和 B0 = Parameter(4) 等能夠想象成是在定義變量。 輸入是列向量,CNTK裏面的運算全是矩陣運算,因此就把輸入當作只有一列的矩陣。 t0 = Times(W0, features) 是作矩陣乘法,t0把輸入和權重相乘,z0 是在t0上面加了一個bias,
s0表示通過一個激活函數。 B0,W0,t0,z0,s0構成了隱層的操做,這裏定義的隱層有4個節點。 t,z,s是輸出層的操做,s就是輸出節點的值。 框架定義好以後,還須要指定一些根節點,用來指定特殊的任務,例如 FeatureNodes=(features) 和LabelNodes=(labels)分別規定了輸入和輸出節點,CriteriaNodes 是訓練的
時候優化的目標,EvalNodes 是在作評測的時候輸出的參考值。OutputNodes 指定了須要輸出到文件的節點。
設置訓練算法
SGD = [ epochSize=0 # 每輪迭代使用的樣例數, =0 表示使用整個訓練集 minibatchSize=25 # 訓練25個樣本就更新一次參數 learningRatesPerMB=0.1 # learning rates per MB maxEpochs=50 #迭代50次 ]
目前只有SGD(以及在SGD上的各類變種),能夠在裏面設置各類參數。
設置輸入格式
reader = [ #customDelimiter = " " readerType = "UCIFastReader" file = "Train.txt" miniBatchMode = "partial" verbosity = 1 randomize = "none" features=[ dim = $dimension$ start = 0 ] labels=[ start = $dimension$ # skip $dimension$ elements before reading the label (i.e. the first two dimensions so we have "x1 x2 y" basically) dim = 1 # label has 1 dimension labelType=regression labelMappingFile = "SimpleMapping.txt" ] ]
這也是CNTK的一個特色(吐槽點), 指定用什麼方式讀取數據文件。 readerType = "UCIFastReader" 指定用普通的扁平化表格的格式(一行一個樣例,同一行內用空格隔開不一樣的數值),還有別的格式類型,例如圖像格式,文本語料格式等。
UCIFastReader 是將被棄用的,並且在目前最新的binary包中是有bug的 (因此說,有條件的同窗儘可能本身編譯最新的源碼)。 用官方教程裏的設置直接跑回出bug,以上是我修改過的代碼。 輸入格式主要描述了feature是哪幾列,維度是多少,label是哪幾列, label的類型等等。
綜上,Train這個模塊就是定義了這幾件事情:輸入格式,網絡內容,訓練模式。 運行的時候也是這個步驟: 讀取數據-> SGD 訓練.
其餘
除了Train以外的模塊的流程比較相似,它們不須要再定義網絡結構和訓練模式,可是輸入格式仍是要指定的。 例如Test模塊的流程是: 讀取數據->計算網絡->獲得預測值->評估. 評估針對的是在網絡結構中被定義爲EvalNodes
的節點。 SquareError 只是其中的一種評估指標。若是想用別的偏差函數,能夠去查字典http://research.microsoft.com/pubs/226641/CNTKBook-20160217..pdf
Test=[ action="test" reader=[ readerType="UCIFastReader" file="Test.txt" features=[ dim=2 start=0 ] labels=[ start=$dimension$ dim=1 labelDim=2 ] ] ]
Output模塊和Test的流程基本同樣,只不過最後一個不是評估,而是把屬於OutputNodes的值給輸出到文件。 Output模塊會指定一個輸出目錄 outputPath = "LR.txt" , 輸出的文件以「LR.txt」爲前綴,再加上變量命做爲文件名。例如"LR.txt.W0"。
# output the results Output=[ action="write" reader=[ readerType="UCIFastReader" file="Test.txt" features=[ dim=$dimension$ start=0 ] labels=[ start=2 dim=1 labelType=regression ] ] outputPath = "LR.txt" # dump the output as text ]
dumpNodeInfo
用來輸出參數的值。這在調試中頗有用,例如去看看網絡的參數是如何變化的:
dumpNodeInfo=[ action=dumpnode printValues=true ]
#################################################################### B=LearnableParameter [1,1] NeedGradient=true -6.67130613 #################################################################### EP=SquareError ( labels , s ) features=InputValue [ 2 x 1 {1,2} ] labels=InputValue [ 1 x 1 {1,1} ] LR=Logistic ( labels , s ) s=Sigmoid ( z ) t=Times ( W , features ) W=LearnableParameter [1,2] NeedGradient=true 1.23924482 1.59913719 #################################################################### z=Plus ( t , B )
所有的代碼以下。 train文件 https://github.com/Microsoft/CNTK/wiki/Tutorial/Train-3Classes.txt test 文件 https://github.com/Microsoft/CNTK/wiki/Tutorial/Test-3Classes.txt。 數據是2維的:
# Copyright (c) Microsoft. All rights reserved. # Licensed under the MIT license. See LICENSE file in the project root for full license information. # logistic regression cntk script -- Network Description Language # which commands to run command=Train:Output:dumpNodeInfo:Test #required... modelPath="Models/LR_reg.dnn" # where to write the model to deviceId=-1 # CPU dimension=2 # input data dimensions # training config Train=[ action="train" traceLevel = 1 NDLNetworkBuilder=[ run=ndlLR ndlLR=[ # sample and label dimensions SDim=$dimension$ LDim=1 features=Input(SDim, 1) labels=Input(LDim, 1) # parameters to learn B0 = Parameter(4) W0 = Parameter(4, SDim) B = Parameter(LDim) W = Parameter(LDim, 4) # operations t0 = Times(W0, features) z0 = Plus(t0, B0) s0 = Sigmoid(z0) t = Times(W, s0) z = Plus(t, B) s = Sigmoid(z) LR = Logistic(labels, s) EP = SquareError(labels, s) # root nodes FeatureNodes=(features) LabelNodes=(labels) CriteriaNodes=(LR) EvalNodes=(EP) OutputNodes=(s,t,z,s0,W0) ] ] SGD = [ epochSize=0 # =0 means size of the training set minibatchSize=25 learningRatesPerMB=0.1 # learning rates per MB maxEpochs=50 ] # parameter values for the reader reader = [ #customDelimiter = " " readerType = "UCIFastReader" file = "Train.txt" miniBatchMode = "partial" verbosity = 1 randomize = "none" features=[ dim = $dimension$ start = 0 ] labels=[ start = $dimension$ # skip $dimension$ elements before reading the label (i.e. the first two dimensions so we have "x1 x2 y" basically) dim = 1 # label has 1 dimension labelType=regression labelMappingFile = "SimpleMapping.txt" ] ] ] # test Test=[ action="test" reader=[ readerType="UCIFastReader" randomize = "none" file="Test.txt" features=[ dim=$dimension$ start=0 ] labels=[ start = $dimension$ # skip $dimension$ elements before reading the label (i.e. the first two dimensions so we have "x1 x2 y" basically) dim = 1 # label has 1 dimension labelType=regression labelMappingFile = "SimpleMapping.txt" ] ] ] # output the results Output=[ action="write" reader=[ readerType="UCIFastReader" file="Test.txt" randomize = "none" features=[ dim=$dimension$ start=0 ] labels=[ start = $dimension$ # skip $dimension$ elements before reading the label (i.e. the first two dimensions so we have "x1 x2 y" basically) dim = 1 # label has 1 dimension labelType=regression labelMappingFile = "SimpleMapping.txt" ] ] outputPath = "LR.txt" # dump the output as text ] dumpNodeInfo=[ action=dumpnode printValues=false ]
後一篇:
http://www.cnblogs.com/sylvanas2012/p/5419477.html
原創博客,未經容許,請勿轉載。