前言CNTK作为微软在机器学习领域的重点项目,已经成功的应用于各种产品之中,CNTK可以快速且方便的训练神经网络并使用神经网络。其中CNTK的一大亮点就是CNTK的速度,在机器学习领域,训练速度以及计算决定了工具是否好用。 但是一些情况下,也许我们只需要使用CNTK对于网络训练的速度,之后导出训练的结果用于其他第三方软件使用,也许是绘图,也许是进行实际的生产计算。 通过
|
键 | 值 |
---|---|
modelPath | 指定网络模型的文件。一般这个参数再配置文件中应该已经在上级给出了指定。 |
nodeName | (可选)指定用于导出的网络节点名称。如果不指定或者指定的是一个不存在的名称则导出所有的节点。 |
nodeNameRegex | (可选)可以通过正则表达式的方式指定网络节点名称,导出相匹配的节点。如果指定了这个参数的话,nodeName 将值会被忽视。 |
outputFile | (可选)指定导出文件的位置,如果不指定的情况下,默认会被设置为通网络模型文件同路径下的一个文本文件。在网络模型的文件名后面加上.{nodename}.txt 。 |
printValues | (可选)是否导出网络节点的值,默认值为true 。 |
printMetadata | (可选)是否导出元数据信息,包括节点名称、维度等,默认值为true 。 |
我们以Simple2D
(位于CNTK的~\CNTK\Examples\Other\Simple2d\
目录)为例,
我们只需要在配置文件末尾的位置添加如下内容,不需要设置modelPath
是因为modelPath
已经在上面指定了,
########################################
# DUMP NODE INFORMATION #
########################################
Simple_Demo_DumpNode=[
action = "dumpnode"
]
之后我们在配置文件的command
中指定新设置的Simple_Demo_DumpNode
即可,
command = Simple_Demo_Train:Simple_Demo_Test:Simple_Demo_Output:Simple_Demo_DumpNode
之后从新运行后,运行的结果如下,并在其中会多出有关dumpnode的相关内容,
(注,那个Action "dumpnode" complete.
是笔者后期标黄的,不是默认输出就是黄色的。)
此时,我们可以去往model
所在目录(~\CNTK\Examples\Other\Simple2d\Output\Models
)打开导出的文件,
默认情况下,是导出的网络节点是包括参数以及元数据的,所以数据信息比较多。
CNTK可以通过dumpnode命令给出的文本格式的导出文件,如果是用来看的则没什么大问题,但是如果希望实现自动化的某些操作,则需要解析这个文件后输入下游程序中,解析过程也许会十分的繁琐,
我们也可以通过探究CNTK的源码来找出节点数据存储的位置,直接使用CNTK的文件即可,
这种情况,只需要我们在我们的程序中加载CNTK中的EvalDLL
读取网络模型文件后,直接使用其参数,后者根据需要导出成我们所期望的形式。
CNTK中核心的一个类是ComputationNetwork
,一个网络模型对应着一个ComputationNetwork
的实例。
如果我们只是为了读取网络模型,那么我们可以通过如下代码打开一个CNTK的网络模型文件。
ComputationNetwork net(-1); // -1 means we only need to use CPU
net.Load<ElemType>(modelPath); // ElemType should be a float type (float or double)
这样我们就可以将模型文件加载到net中,进而我们可以通过net的方法去获取我们所需要的内容,
class ComputationNetwork : ...
{
...
public:
ComputationNetwork();
ComputationNetwork(DEVICEID_TYPE deviceId);
virtual ~ComputationNetwork();
template <class ElemType>
void Load(const std::wstring& fileName);
ComputationNodeBasePtr GetNodeFromName(const std::wstring& name) const;
// GetNodesFromName - Get all the nodes from a name that may match a wildcard '*' pattern
// only patterns with a single '*' at the beginning, in the middle, or at the end are accepted
// name - node name (with possible wildcard)
// returns: vector of nodes that match the pattern, may return an empty vector for no match
std::vector<ComputationNodeBasePtr> GetNodesFromName(const std::wstring& name) const;
// these are specified as such by the user
const std::vector<ComputationNodeBasePtr>& FeatureNodes();
const std::vector<ComputationNodeBasePtr>& LabelNodes();
const std::vector<ComputationNodeBasePtr>& FinalCriterionNodes();
const std::vector<ComputationNodeBasePtr>& EvaluationNodes();
const std::vector<ComputationNodeBasePtr>& OutputNodes();
...
private:
// main node holder
std::map<const std::wstring, ComputationNodeBasePtr, nocase_compare> m_nameToNodeMap; // [name] -> node; this is the main container that holds this networks' nodes
// node groups
// These are specified by the user by means of tags or explicitly listing the node groups.
// TODO: Are these meant to be disjoint?
std::vector<ComputationNodeBasePtr> m_featureNodes; // tag="feature"
std::vector<ComputationNodeBasePtr> m_labelNodes; // tag="label"
std::vector<ComputationNodeBasePtr> m_criterionNodes; // tag="criterion"
std::vector<ComputationNodeBasePtr> m_evaluationNodes; // tag="evaluation"
std::vector<ComputationNodeBasePtr> m_outputNodes; // tag="output"
...
};
在Net中,我们能够获取每个节点的ComputationNodeBasePtr, 我们进而可以通过这个指针来进行其节点中数据或者参数的访问。
class ComputationNodeBase : ...
{
...
public:
// -----------------------------------------------------------------------
// accessors for value and gradient
// -----------------------------------------------------------------------
const Matrix<ElemType>& Value() const { return *m_value; }
Matrix<ElemType>& Value() { return *m_value; }
MatrixBasePtr ValuePtr() const override final { return m_value; } // readers want this as a shared_ptr straight
// Note: We cannot return a const& since returning m_value as a MatrixBasePtr is a type cast that generates a temporary. Interesting.
const Matrix<ElemType>& Gradient() const { return *m_gradient; }
Matrix<ElemType>& Gradient() { return *m_gradient; }
MatrixBasePtr GradientPtr() const { return m_gradient; }
...
};
这样我们就可以通过Value来获取来获取内部的计算矩阵以应用于实际的项目中。
本文主要是描述了CNTK中网络节点训练结果的导出方法,首先将CNTK当做工具使用情况下的导出方法,之后接受的是将CNTK看做一个开源项目的前提下,通过研究源码的方式针对其内部数据结果进行探究。希望能够对大家使用或者学习CNTK有所帮助,如本文中有任何错误或者读者有任何意见或者建议,请在评论区给出,谢谢。
|