def eval(node, clean_up=True): """ It evaluates a node that has taken a numpy array as input. Note that sequences are not supported yet by this method Examples: Plus with two matrices >>> print (cntk.eval(cntk.ops.plus([[-30.,40.], [1.,2.]], [[-30.,40.], [1.,2.]]))) # [array([[[-60., 80.], [2., 4.]]])] Times with broadcast of a scalar over a matrix >>> print (cntk.eval(cntk.ops.element_times([[-30.,40.], [1.,2.]], 5))) # [array([[[-150., 200.], [5., 10.]]])] Args: node (:class:`cntk.graph.ComputationNode`): the node to evaluate clean_up (bool): whether the temporary directory should be removed when the context is left Returns: NumPy array containing the result """ from cntk.context import get_new_context from cntk.ops import input_numpy, constant from cntk.graph import ComputationNode, _InputComputationNodeBase import numpy as np # call a helper method to get a context with get_new_context() as ctx: ctx.clean_up = clean_up first = True # The params are passed as arryas, e.g. plus([1,2], [3,4]), and we need to # wrap them with input and parameter nodes. if node.params: for p in node.params: if p in node.inputs: val = getattr(node, p) if not isinstance(val, ComputationNode): # One param needs to be an Input() node. This will be fixed in # CNTK soon, so that we can remove this workaround and evaluate a # network with no inputs. if first: ir = input_numpy([val], alias=p, name=p) setattr(node, p, ir) first = False else: setattr(node, p, constant(getattr(node, p), name=p)) else: if isinstance(val, _InputComputationNodeBase) and first: first = False return ctx.eval(node)
def eval(node): """ It evaluates a node that has taken a numpy array as input. Note that sequences are not supported yet by this method Examples: Plus with two matrices >>> print (cntk.eval(cntk.ops.plus([[-30.,40.], [1.,2.]], [[-30.,40.], [1.,2.]]))) # [array([[[-60., 80.], [2., 4.]]])] Times with broadcast of a scalar over a matrix >>> print (cntk.eval(cntk.ops.element_times([[-30.,40.], [1.,2.]], 5))) # [array([[[-150., 200.], [5., 10.]]])] Args: node (:class:`cntk.graph.ComputationNode`): the node to evaluate Returns: NumPy array containing the result """ from cntk.context import get_context from cntk.ops import input_numpy, constant from cntk.graph import ComputationNode # call a helper method to get a context ctx = get_context() first = True # The params are passed as arryas, e.g. plus([1,2], [3,4]), and we need to # wrap them with input and parameter nodes. if node.params: for p in node.params: if p in node.inputs: val = getattr(node, p) if not isinstance(val, ComputationNode): # One param needs to be an Input() node. This will being fixed in # CNTK soon, so that we can remove this workaround and evaluate a # network with no inputs. if first: if not isinstance(val, list): # inputs have the outmost dimension for sequences val = [val] ir = input_numpy([val], alias=p, name=p) setattr(node, p, ir) first = False else: setattr(node, p, constant(getattr(node, p), name=p)) else: if val.op_name == 'CNTK2.Input' and first: first = False return ctx.eval(node)
def _generate_eval_config(self, root_nodes, input_map=None, node_unit_test=False, action_name=None): ''' Generates the configuration file for write action. Args: root_nodes (:class:`cntk.graph.ComputationNode` or list thereof): node(s) to start the graph generation from (most likely evaluation and criterion nodes) node (:class:`cntk.graph.ComputationNode`): the node to evaluate input_map (:class:`cntk.reader.InputMap`): describes how to map inputs to the data in a data file using a reader node_unit_test (bool): set to `True` if you want to output the gradient of a node (backward pass) action_name (str): the name of the action in cntk configuration file Returns: configuration string ''' if input_map is None: input_map = InputMap() description, inputs = self._generate_config(root_nodes, input_map) if len(inputs) == 0: # add dummy input to keep CNTK happy # TODO relieve this requirement on CNTK side #import ipdb;ipdb.set_trace() from cntk.ops import input_numpy dummy_input = input_numpy([[[1]]]) dummy_input.name = '_dummy_input' input_map._add_unmapped(dummy_input) desc, _inputs = dummy_input._to_config_description(input_map) description += '\n\n' + desc g_params = self._generate_global_params(DevideId=self.device_id, Precision='"{0}"'.format( self.precision)) tmpl = open(CNTK_EVAL_TEMPLATE_PATH, "r").read() tmpl_dict = { 'ActionName': action_name, 'NodeUnitTest': node_unit_test, 'OutputFile': self.output_filename_base, 'ModelDescription': description, 'Reader': input_map._to_config_description(self.directory), } return "{0}\n{1}".format(g_params, tmpl % tmpl_dict)
def _generate_eval_config(self, root_nodes, input_map=None, node_unit_test=False, action_name=None): ''' Generates the configuration file for write action. Args: root_nodes (:class:`cntk.graph.ComputationNode` or list thereof): node(s) to start the graph generation from (most likely evaluation and criterion nodes) node (:class:`cntk.graph.ComputationNode`): the node to evaluate input_map (:class:`cntk.reader.InputMap`): describes how to map inputs to the data in a data file using a reader node_unit_test (bool): set to `True` if you want to output the gradient of a node (backward pass) action_name (str): the name of the action in cntk configuration file Returns: configuration string ''' if input_map is None: input_map = InputMap() description, inputs = self._generate_config(root_nodes, input_map) if len(inputs) == 0: # add dummy input to keep CNTK happy # TODO relieve this requirement on CNTK side #import ipdb;ipdb.set_trace() from cntk.ops import input_numpy dummy_input = input_numpy([[[1]]]) dummy_input.name='_dummy_input' input_map._add_unmapped(dummy_input) desc, _inputs = dummy_input._to_config_description(input_map) description += '\n\n' + desc g_params = self._generate_global_params(DevideId=self.device_id, Precision='"{0}"'.format(self.precision)) tmpl = open(CNTK_EVAL_TEMPLATE_PATH, "r").read() tmpl_dict = { 'ActionName': action_name, 'NodeUnitTest': node_unit_test, 'OutputFile': self.output_filename_base, 'ModelDescription': description, 'Reader': input_map._to_config_description(self.directory), } return "{0}\n{1}".format(g_params, tmpl % tmpl_dict)
def _generate_eval_config(self, root_nodes, input_map=None, node_unit_test=False, action_name=None): """ Generates the configuration file for write action. Args: root_nodes (list): the list of root nodes of the model node (:class:`cntk.graph.ComputationNode`): the node to evaluate input_map (:class:`cntk.reader.InputMap`): describes how to map inputs to the data in a data file using a reader node_unit_test (bool): set to True if you want to output the gradient of a node (backward pass) action_name (str): the name of the action in cntk configuration file Returns: configuration string """ if input_map is None: input_map = InputMap() description, inputs = self._generate_config(root_nodes, input_map) if len(inputs) == 0: # add dummy input to keep CNTK happy # TODO relieve this requirement on CNTK side # import ipdb;ipdb.set_trace() from cntk.ops import input_numpy dummy_input = input_numpy([[[1]]]) dummy_input.name = "_dummy_input" input_map._add_unmapped(dummy_input) desc, _inputs = dummy_input._to_config_description(input_map) description += "\n\n" + desc tmpl = open(CNTK_EVAL_TEMPLATE_PATH, "r").read() tmpl_dict = { "ActionName": action_name, "DevideId": self.device_id, "Precision": self.precision, "NodeUnitTest": node_unit_test, "OutputFile": self.output_filename_base, "ModelDescription": description, "Reader": input_map._to_config_description(), } return tmpl % tmpl_dict