public override List <Tensor> Call(List <Array> inputs) { var feed_dict = new Dictionary <Variable, Array>(); foreach (var(tensor, value) in Enumerable.Zip(this.placeholders, inputs, (a, b) => (a, b))) { Type t = value.GetInnerMostType(); Array v = value; // cntk only support calculate on float, do auto cast here if (t != typeof(float) && t != typeof(double)) { v = MatrixEx.Convert <double>(value); } feed_dict[tensor] = v; } var updated = new List <Tensor>(); if (this.trainer != null) { var input_dict = new UnorderedMapVariableValuePtr(); foreach (Variable argument in this.loss.Arguments) { if (feed_dict.ContainsKey(argument)) { input_dict[argument] = new Value(CNTKBackend.In(feed_dict[argument])); } else { throw new Exception($"CNTK backend: argument {argument.Name} is not found in inputs. Please double check the model and inputs in 'train_function'."); } } var result = this.trainer.TrainMinibatch(input_dict, this.trainer_output); foreach (Variable o in this.trainer_output.Keys) { updated.Add(c.Out(this.trainer_output[o])); } } if (this.metrics_func != null) { var input_dict = new Dictionary <Variable, Value>(); foreach (Variable argument in this.metrics_func.Arguments) { if (feed_dict.ContainsKey(argument)) { input_dict[argument] = new Value(CNTKBackend.In(feed_dict[argument])); } else { throw new Exception($"CNTK backend: metrics argument {argument.Name} is not found in inputs. Please double check the model and inputs."); } } var output_values = new Dictionary <Variable, Value>(); foreach (Variable variable in this.metrics_outputs) { output_values[variable] = null; } this.metrics_func.Evaluate(input_dict, output_values, DeviceDescriptor.CPUDevice); foreach (Variable o in this.metrics_outputs) { Value value = output_values[o]; var v = c.Out(value); updated.Add(v); } } if (this.unrelated_updates != null) { var input_dict = new Dictionary <Variable, Value>(); foreach (Variable argument in this.unrelated_updates.Arguments) { if (feed_dict.ContainsKey(argument)) { input_dict[argument] = new Value(CNTKBackend.In(feed_dict[argument])); } else { throw new Exception($"CNTK backend: assign ops argument {argument.Name} is not found in inputs. Please double check the model and inputs."); } } var output_values = new Dictionary <Variable, Value>(); this.unrelated_updates.Evaluate(input_dict, output_values, DeviceDescriptor.CPUDevice); } return(updated); }