CNTK Evaluate Hidden Layers
This page describes how to expose a trained model's hidden layer's values.
Overview
A CNTK model is built on interconnected layers. Some of these layers can be evaluated using the EvalDll
because they are tagged as being 'output' layers. In order to expose other layers through the EvalDll
, these layers must be tagged as output layers by adding them to the outputNodes
property.
For example, the 01_OneHidden_ndl_deprecated.cntk
configuration file refers to the 01_OneHidden.ndl
file for the network definition. In this network description file, we have two layers defined:
h1 = DNNSigmoidLayer (featDim, hiddenDim, featScaled, 1)
ol = DNNLayer (hiddenDim, labelDim, h1, 1)
But only one layer is marked as an output:
outputNodes = (ol)
Thus, the EvalDll
will only return values pertaining to the ol
layer during evaluation.
In order to be able to evaluate the h1
hidden layer, we need to expose it first as an output node. There are three possible ways:
1. Training model with hidden layers exposed
To output the h1
layer, just add it as an output in the network description (01_OneHidden.bs
file) when training it, and that layer would be available for reading during evaluation:
outputNodes = (h1:ol)
However this implies the model would need to be (re)trained with this configuration.
2. Modifying an already trained model
Models can be modified on the fly when being loaded using BrainScript expressions. This will be documented in a future update of this documentation.
3. Changing output-node set of an already trained model while loading it for evaluation using the EvalDll
/EvalDllWrapper
modules
If a trained will be evaluated using the EvalDll
/EvalDllWrapper
modules, you can add the outputNodeNames
property with a colon separated list of nodes to the network definition:
outputNodeNames = "h1.z:ol.z"
When loading the network, the Eval engine will recognize the outputNodeNames
property and replace the model's output nodes with the list of nodes specified in the outputNodeNames
property.
Looking at the code inside the CPPEvalClient
example project, shows the (uncommented) line specifying the outputNodeNames
property:
networkConfiguration += "outputNodeNames=\"h1.z:ol.z\"\n";
networkConfiguration += "modelPath=\"" + modelFilePath + "\"";
model->CreateNetwork(networkConfiguration);
Running the program shows the corresponding output for the h1.z
layer.