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
原创博客,未经容许,请勿转载。