コード例 #1
0
        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);
        }