Esempio n. 1
0
        /// <summary>
        /// <para>
        /// Builds the layer by converting the abstract definition of the layer into
        /// a concrete set of instructions for Tensorflow and a layer configuration
        /// for use when training the model.
        /// </para>
        /// <para>This method should register any parameters and initializers with the compilation context.
        /// So that they can be used during the training phase. </para>
        /// <para>Additionally you are required to store the layer configuration in the
        /// <see cref="context"/> property. This information is required as metadata
        /// when the model is used.</para>
        /// </summary>
        /// <param name="context">Use this context to register trainable parameters
        /// and build the computational graph for the layer</param>
        public override TFOutput Compile(ModelCompilationContext context)
        {
            if (Configuration != null)
            {
                return(Configuration.Output);
            }

            var input          = _input.Compile(context);
            var inputDimension = _input.OutputShape[_input.OutputShape.Length - 1];

            using (var scope = context.Graph.WithScope(Name))
            {
                TFShape weightsShape = new TFShape(inputDimension, _units);
                TFShape biasShape    = new TFShape(_units);

                var weights = context.Graph.VariableV2(
                    weightsShape,
                    TFDataType.Double, operName: "Weights");

                var initializers = new List <TFOperation>
                {
                    context.Graph.Assign(weights, _weightsInitializer.Compile(context.Graph, weightsShape)).Operation
                };

                var parameters = new List <TFOutput>
                {
                    weights
                };

                context.AddParameters(weights);

                var output = context.Graph.MatMul(input, weights);

                if (_useBias)
                {
                    var bias = context.Graph.VariableV2(
                        biasShape,
                        TFDataType.Double, operName: "Bias");

                    initializers.Add(context.Graph.Assign(bias,
                                                          _biasInitializer.Compile(context.Graph, biasShape)).Operation);

                    parameters.Add(bias);

                    output = context.Graph.Add(output, bias);
                }

                output = _activation.Compile(context, output);

                Configuration = new LayerConfiguration(parameters, initializers, output);

                context.AddInitializers(initializers);

                return(output);
            }
        }
Esempio n. 2
0
        public void ReturnsGraphElement(Type functionType)
        {
            var activation = (ActivationFunction)Activator.CreateInstance(functionType);

            var context = new ModelCompilationContext(new TFGraph());
            var input   = context.Graph.Placeholder(TFDataType.Double, new TFShape(10, 10));
            var output  = activation.Compile(context, input);

            output.Should().NotBeNull();
        }
Esempio n. 3
0
        public void OutputShapeIsEqualToInputLayerShape()
        {
            var context = new ModelCompilationContext(new TFGraph());

            var input = new Input(new [] { 10L });
            var layer = new Dropout(0.2, input);

            layer.Compile(context);

            layer.OutputShape.Should().BeEquivalentTo(input.OutputShape);
        }
Esempio n. 4
0
        public void ReturnsLossFunction()
        {
            var graph   = new TFGraph();
            var context = new ModelCompilationContext(graph);

            var predictions = graph.Placeholder(TFDataType.Double, new TFShape(-1, 10));
            var actuals     = graph.Placeholder(TFDataType.Double, new TFShape(-1, 10));

            var loss = new MeanSquaredError().Compile(context, predictions, actuals);

            loss.Should().NotBeNull();
        }
        public void ShouldCompile()
        {
            var graph   = new TFGraph();
            var context = new ModelCompilationContext(graph);

            var predictions = graph.Placeholder(TFDataType.Double, new TFShape(-1, 10));
            var actuals     = graph.Placeholder(TFDataType.Double, new TFShape(-1, 10));

            var loss = new CategoricalCrossEntropy().Compile(context, predictions, actuals);

            loss.Should().NotBeNull();
        }
Esempio n. 6
0
        /// <summary>
        /// <para>
        /// Builds the layer by converting the abstract definition of the layer into
        /// a concrete set of instructions for Tensorflow and a layer configuration
        /// for use when training the model.
        /// </para>
        /// <para>This method should register any parameters and initializers with the compilation context.
        /// So that they can be used during the training phase. </para>
        /// <para>Additionally you are required to store the layer configuration in the
        /// <see cref="Layer.Configuration"/> property. This information is required as metadata
        /// when the model is used.</para>
        /// <param name="context">Use this context to register trainable parameters
        /// and build the computational graph for the layer</param>
        public override TFOutput Compile(ModelCompilationContext context)
        {
            var inputLayer = _input.Compile(context);
            var keepProb   = context.Graph.Const(_rate);

            var output = context.Graph.Dropout(inputLayer, keepProb,
                                               context.Graph.GetTensorShape(inputLayer), _seed);

            Configuration = new LayerConfiguration(new TFOutput[] { }, new TFOperation[] { }, output);

            return(output);
        }
Esempio n. 7
0
        /// <summary>
        /// Compiles the loss function
        /// </summary>
        /// <param name="context">Compilation context to use</param>
        /// <param name="predictions">The output of the graph producing predictions</param>
        /// <param name="targets">The output of the graph containing the targets</param>
        /// <returns>Returns the compiled loss function</returns>
        public override TFOutput Compile(ModelCompilationContext context, TFOutput predictions, TFOutput targets)
        {
            // Formula: loss = -sum(log(pred) * target)
            var graph = context.Graph;

            // Values should be clipped to be between epsilon and 1-epsilon
            // to prevent arithmic overflows into infinity.
            var clipped = graph.ClipByValue(predictions,
                                            graph.Const(_epsilon),
                                            graph.Const(1 - _epsilon));

            return(graph.Neg(graph.ReduceSum(graph.Mul(targets, graph.Log(clipped)))));
        }
Esempio n. 8
0
        public void CreatesLayerConfigurationDuringCompilation()
        {
            var context = new ModelCompilationContext(new TFGraph());

            var input = new Input(new [] { 10L });
            var layer = new Dropout(0.2, input);

            layer.Compile(context);

            layer.Configuration.Should().NotBeNull();
            layer.Configuration.Parameters.Count().Should().Be(0);
            layer.Configuration.Initializers.Count().Should().Be(0);
            layer.Configuration.Output.Should().NotBeNull();
        }
        public void ProducesHighLossForIncorrectCases()
        {
            var graph   = new TFGraph();
            var context = new ModelCompilationContext(graph);

            var output  = graph.Const(new[] { new[] { 0.0, 0.1 } });
            var targets = graph.Const(new[] { new[] { 1.0, 0.0 } });

            var loss = new NegativeLogLikelihood();

            var lossFunction = loss.Compile(context, output, targets);

            using (var session = new TFSession(graph))
            {
                var error = session.GetRunner().Run(lossFunction);
                Math.Round((double)error.GetValue(), 2).Should().Be(16.12);
            }
        }
Esempio n. 10
0
        public void ProducesOutput(Type functionType)
        {
            var activation = (ActivationFunction)Activator.CreateInstance(functionType);

            var graph   = new TFGraph();
            var context = new ModelCompilationContext(graph);
            var input   = context.Graph.Placeholder(TFDataType.Double, new TFShape(1));
            var output  = activation.Compile(context, input);

            using (var session = new TFSession(graph))
            {
                var runner = session.GetRunner();

                runner.AddInput(input, new TFTensor(new[] { new[] { 1.0 } }));
                var outputValue = runner.Run(output);

                outputValue.GetValue().Should().NotBe(new[] { new[] { 0.0 } });
            }
        }
Esempio n. 11
0
        /// <summary>
        /// <para>
        /// Builds the layer by converting the abstract definition of the layer into
        /// a concrete set of instructions for Tensorflow and a layer configuration
        /// for use when training the model.
        /// </para>
        /// <para>This method should register any parameters and initializers with the compilation context.
        /// So that they can be used during the training phase. </para>
        /// <para>Additionally you are required to store the layer configuration in the
        /// <see cref="Configuration"/> property. This information is required as metadata
        /// when the model is used.</para>
        /// <param name="context">Use this context to register trainable parameters
        /// and build the computational graph for the layer</param>
        public override TFOutput Compile(ModelCompilationContext context)
        {
            if (Configuration != null)
            {
                return(Configuration.Output);
            }

            if (_shape.Length == 0)
            {
                throw new ModelCompilationException("Shape must have at least one dimension");
            }

            var placeholder = context.Graph.Placeholder(TFDataType.Double,
                                                        new TFShape(OutputShape), operName: Name);

            Configuration = new LayerConfiguration(new TFOutput[] { }, new TFOperation[] {  }, placeholder);

            return(placeholder);
        }
        public void CanBeOptimized()
        {
            var graph   = new TFGraph();
            var context = new ModelCompilationContext(graph);

            var input  = new Input(new long[] { 10 }, name: "Input0");
            var output = new Dense(2, input, name: "Dense0");

            var compiledOutput = output.Compile(context);

            var loss = new NegativeLogLikelihood();

            var compiledLoss = loss.Compile(context, compiledOutput,
                                            context.Graph.Placeholder(TFDataType.Double, new TFShape(-1, 2)));

            var gradients = graph.AddGradients(
                new[] { compiledLoss },
                context.Parameters.ToArray());
        }
        public void ShouldBeOptimizable()
        {
            var graph   = new TFGraph();
            var context = new ModelCompilationContext(graph);

            var input  = new Input(new long[] { 10 }, name: "Input0");
            var output = new Dense(2, input, name: "Dense0");

            var compiledInput  = input.Compile(context);
            var compiledOutput = output.Compile(context);

            var loss = new CategoricalCrossEntropy();

            var compiledLoss = loss.Compile(context, compiledOutput,
                                            context.Graph.Placeholder(TFDataType.Double, new TFShape(-1, 2)));

            var gradients = graph.AddGradients(
                new [] { compiledLoss },
                context.Parameters.ToArray());
        }
Esempio n. 14
0
        /// <summary>
        /// Compiles the optimizer
        /// </summary>
        /// <param name="graph">Graph to use for compilation</param>
        /// <param name="loss">Loss function to use</param>
        /// <param name="parameters">Parameters to optimize</param>
        public override void Compile(ModelCompilationContext context, TFOutput loss, IEnumerable <TFOutput> parameters)
        {
            var graph      = context.Graph;
            var operations = new List <TFOperation>();
            var moments    = new List <TFOutput>();

            using (var optimizerScope = graph.WithScope("SGD"))
            {
                using (var momentScope = graph.WithScope("Moments"))
                {
                    foreach (var parameter in parameters)
                    {
                        var moment      = graph.VariableV2(graph.GetTensorShape(parameter), TFDataType.Double);
                        var initializer = graph.Assign(moment, graph.Zeros(graph.GetTensorShape(parameter))).Operation;

                        context.AddInitializers(initializer);

                        moments.Add(moment);
                    }
                }

                var momentum = graph.Const(_momentum, "Momentum");

                var learningRate = graph.Const(_learningRate);
                var gradients    = graph.AddGradients(new[] { loss }, parameters.ToArray());

                foreach (var(parameter, gradient, moment) in ZipLearningParameters(parameters, gradients, moments))
                {
                    // velocity = momentum * moment - learningRate * gradient
                    var velocity    = graph.Sub(graph.Mul(momentum, moment), graph.Mul(gradient, learningRate));
                    var newWeight   = graph.Add(parameter, velocity);
                    var newMomentum = graph.Add(moment, velocity);

                    operations.Add(graph.Assign(parameter, newWeight).Operation);
                    operations.Add(graph.Assign(moment, newMomentum).Operation);
                }
            }

            Operations = operations;
        }
Esempio n. 15
0
 /// <summary>
 /// Compiles the optimizer
 /// </summary>
 /// <param name="context">Context to use for compilation</param>
 /// <param name="loss">Loss function to use</param>
 /// <param name="parameters">Parameters to optimize</param>
 public abstract void Compile(ModelCompilationContext context, TFOutput loss, IEnumerable <TFOutput> parameters);
Esempio n. 16
0
 /// <summary>
 /// Compiles the loss function
 /// </summary>
 /// <param name="context">Compilation context to use</param>
 /// <param name="predictions">The output of the graph producing predictions</param>
 /// <param name="targets">The output of the graph containing the targets</param>
 /// <returns>Returns the compiled loss function</returns>
 public abstract TFOutput Compile(ModelCompilationContext context, TFOutput predictions, TFOutput targets);
        /// <summary>
        /// Compiles the categorical cross entropy function
        /// </summary>
        /// <param name="context">Compilation context to use</param>
        /// <param name="predictions">Output of the neural network</param>
        /// <param name="targets">Targets to optimize towards</param>
        /// <returns>Returns the compiled loss function</returns>
        public override TFOutput Compile(ModelCompilationContext context, TFOutput predictions, TFOutput targets)
        {
            var(loss, backprop) = context.Graph.SoftmaxCrossEntropyWithLogits(predictions, targets);

            return(loss);
        }
Esempio n. 18
0
 /// <summary>
 /// <para>
 /// Builds the layer by converting the abstract definition of the layer into
 /// a concrete set of instructions for Tensorflow and a layer configuration
 /// for use when training the model.
 /// </para>
 /// <para>This method should register any parameters and initializers with the compilation context.
 /// So that they can be used during the training phase. </para>
 /// <para>Additionally you are required to store the layer configuration in the
 /// <see cref="Configuration"/> property. This information is required as metadata
 /// when the model is used.</para>
 /// <param name="context">Use this context to register trainable parameters
 /// and build the computational graph for the layer</param>
 public abstract TFOutput Compile(ModelCompilationContext context);
Esempio n. 19
0
 /// <summary>
 /// Compiles the loss function
 /// </summary>
 /// <param name="context">Compilation context to use</param>
 /// <param name="predictions">The output of the graph producing predictions</param>
 /// <param name="targets">The output of the graph containing the targets</param>
 /// <returns>Returns the compiled loss function</returns>
 public override TFOutput Compile(ModelCompilationContext context, TFOutput predictions, TFOutput targets)
 {
     return(context.Graph.Mean(context.Graph.Square(context.Graph.Sub(predictions, targets)), context.Graph.Const(-1)));
 }
Esempio n. 20
0
 /// <summary>
 /// Compiles the activation function
 /// </summary>
 /// <param name="context">Use this context to register trainable parameters
 /// and build the computational graph for the layer</param>
 /// <param name="input">Input for the activation function</param>
 /// <returns>Returns the compiled activation function</returns>
 public override TFOutput Compile(ModelCompilationContext context, TFOutput input)
 {
     return(context.Graph.Relu(input));
 }