Пример #1
0
        /// <summary>
        /// 1D convolution layer (e.g. temporal convolution). This layer creates a convolution kernel that is convolved with the layer input over a single spatial (or temporal) dimension to produce a tensor of outputs. If use_bias is True, a bias vector is created and added to the outputs. Finally, if activation is not None, it is applied to the outputs as well.
        /// </summary>
        /// <param name="layer">The output of the last layer.</param>
        /// <param name="channels">Integer, the dimensionality of the output space</param>
        /// <param name="kernalSize">An integer specifying the length of the 1D convolution window.</param>
        /// <param name="strides">An integer specifying the stride length of the convolution.</param>
        /// <param name="padding">Boolean, if true results in padding the input such that the output has the same length as the original input.</param>
        /// <param name="dialation">An integer specifying the dilation rate to use for dilated convolution. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any strides value != 1.</param>
        /// <param name="activation">Activation function to use. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x). <see cref="SiaNet.Common.OptActivations"/></param>
        /// <param name="useBias">Boolean, whether the layer uses a bias vector.</param>
        /// <param name="weightInitializer">Initializer for the kernel weights matrix. <see cref="SiaNet.Common.OptInitializers"/></param>
        /// <param name="biasInitializer">Initializer for the bias vector. <see cref="SiaNet.Common.OptInitializers"/></param>
        /// <returns></returns>
        public static Function Conv1D(Variable layer, int channels, int kernalSize, int strides=1, bool padding=true, int dialation=1, string activation = OptActivations.None, bool useBias = false, string weightInitializer = OptInitializers.Xavier, string biasInitializer = OptInitializers.Zeros)
        {
            Parameter convParams = null;
            Function conv = null;
            if (layer.Shape.Rank > 1)
            {
                int numInputChannels = layer.Shape[layer.Shape.Rank - 1];
                convParams = new Parameter(new int[] { kernalSize, numInputChannels, channels }, DataType.Float, Initializers.Get(weightInitializer), GlobalParameters.Device);
                conv = CNTKLib.Convolution(convParams, layer, new int[] { strides }, new BoolVector(new bool[] { true }), new BoolVector(new bool[] { padding, false, false }), new int[] { dialation });
            }
            else
            {
                convParams = new Parameter(new int[] { kernalSize, channels }, DataType.Float, Initializers.Get(weightInitializer), GlobalParameters.Device);
                conv = CNTKLib.Convolution(convParams, layer, new int[] { strides }, new BoolVector(new bool[] { true }), new BoolVector(new bool[] { padding }), new int[] { dialation });
            }

            Parameter bias = null;
            if (useBias)
            {
                bias = new Parameter(conv.Output.Shape, DataType.Float, Initializers.Get(biasInitializer), GlobalParameters.Device);
                conv = CNTKLib.Plus(bias, conv);
            }
            
            return Basic.Activation(conv, activation);
        }
Пример #2
0
        /// <summary>
        /// 2D convolution layer (e.g. spatial convolution over images). This layer creates a convolution kernel that is convolved with the layer input to produce a tensor of outputs. If  use_bias is True, a bias vector is created and added to the outputs. Finally, if activation is not None, it is applied to the outputs as well.
        /// </summary>
        /// <param name="layer">The output of the last layer.</param>
        /// <param name="channels">Integer, the dimensionality of the output space.</param>
        /// <param name="kernalSize">A tuple of 2 integers, specifying the width and height of the 2D convolution window. Can be a single integer to specify the same value for all spatial dimensions.</param>
        /// <param name="strides">A tuple of 2 integers, specifying the strides of the convolution along the width and height. Can be a single integer to specify the same value for all spatial dimensions. Specifying any stride value != 1 is incompatible with specifying any dilation_rate value != 1.</param>
        /// <param name="padding">Boolean, if true results in padding the input such that the output has the same length as the original input.</param>
        /// <param name="dialation">A tuple of 2 integers, specifying the dilation rate to use for dilated convolution. Can be a single integer to specify the same value for all spatial dimensions. Currently, specifying any dilation_rate value != 1 is incompatible with specifying any stride value != 1.</param>
        /// <param name="activation">Activation function to use. If you don't specify anything, no activation is applied (ie. "linear" activation: a(x) = x). <see cref="SiaNet.Common.OptActivations"/></param>
        /// <param name="useBias">Boolean, whether the layer uses a bias vector.</param>
        /// <param name="weightInitializer">Initializer for the kernel weights matrix. <see cref="SiaNet.Common.OptInitializers"/></param>
        /// <param name="biasInitializer">Initializer for the bias vector. <see cref="SiaNet.Common.OptInitializers"/></param>
        /// <returns></returns>
        public static Function Conv2D(Variable layer, int channels, Tuple<int, int> kernalSize, Tuple<int, int> strides = null, bool padding = true, Tuple<int, int> dialation = null, string activation = OptActivations.None, bool useBias = false, string weightInitializer = OptInitializers.Xavier, string biasInitializer = OptInitializers.Zeros)
        {
            int numInputChannels = layer.Shape[layer.Shape.Rank - 1];
            var convParams = new Parameter(new int[] { kernalSize.Item1, kernalSize.Item2, numInputChannels, channels }, DataType.Float, Initializers.Get(weightInitializer), GlobalParameters.Device);
            if (dialation == null)
            {
                dialation = new Tuple<int, int>(1, 1);
            }

            int[] stridesParams = null;
            if(strides!=null)
            {
                stridesParams = new int[] { strides.Item1, strides.Item2 };
            }

            var conv = CNTKLib.Convolution(convParams, layer, stridesParams, new BoolVector(new bool[] { true, true }), new BoolVector(new bool[] { padding, padding, false }), new int[] { dialation.Item1, dialation.Item2 });

            Parameter bias = null;
            if (useBias)
            {
                bias = new Parameter(conv.Output.Shape, DataType.Float, Initializers.Get(biasInitializer), GlobalParameters.Device);
                conv = CNTKLib.Plus(bias, conv);
            }

            return Basic.Activation(conv, activation);
        }
Пример #3
0
        /// <summary>
        /// Builds the RNN.
        /// </summary>
        /// <param name="inputDim">The input dim.</param>
        /// <param name="hiddenSize">Size of the hidden.</param>
        /// <param name="numLayers">The number layers.</param>
        /// <param name="bidirectional">if set to <c>true</c> [bidirectional].</param>
        /// <param name="weightInitializer">The weight initializer.</param>
        /// <param name="rnnName">Name of the RNN.</param>
        /// <returns></returns>
        private static Function BuildRNN(int inputDim, uint hiddenSize, uint numLayers, bool bidirectional = false, string weightInitializer = OptInitializers.Xavier, string rnnName = "")
        {
            int[] s       = { inputDim };
            var   weights = new Parameter(s, DataType.Float, Initializers.Get(weightInitializer), GlobalParameters.Device);

            return(CNTKLib.OptimizedRNNStack(Variable.InputVariable(new int[] { inputDim }, DataType.Float), weights, hiddenSize, numLayers, bidirectional, rnnName));
        }
Пример #4
0
        /// <summary>
        /// Builds the RNN.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="hiddenSize">Size of the hidden.</param>
        /// <param name="numLayers">The number layers.</param>
        /// <param name="bidirectional">if set to <c>true</c> [bidirectional].</param>
        /// <param name="weightInitializer">The weight initializer.</param>
        /// <param name="rnnName">Name of the RNN.</param>
        /// <returns></returns>
        private static Function BuildRNN(Variable input, int dim, uint hiddenSize, uint numLayers, bool bidirectional = false, string weightInitializer = OptInitializers.Xavier, string rnnName = "")
        {
            int[] s = input.Shape.Dimensions.ToArray();
            var weights = new Parameter(s, DataType.Float, Initializers.Get(weightInitializer), GlobalParameters.Device);

            return CNTKLib.OptimizedRNNStack(Variable.InputVariable(s, DataType.Float), weights, hiddenSize, numLayers, bidirectional, rnnName);
        }
Пример #5
0
        /// <summary>
        /// Builds the RNN.
        /// </summary>
        /// <param name="inputDim">The input dim.</param>
        /// <param name="hiddenSize">Size of the hidden.</param>
        /// <param name="numLayers">The number layers.</param>
        /// <param name="bidirectional">if set to <c>true</c> [bidirectional].</param>
        /// <param name="weightInitializer">The weight initializer.</param>
        /// <param name="rnnName">Name of the RNN.</param>
        /// <returns></returns>
        private static Function BuildRNN(int[] shape, int dim, uint hiddenSize, uint numLayers, bool bidirectional = false, string weightInitializer = OptInitializers.Xavier, string rnnName = "")
        {
            List<int> s = new List<int>();
            s.AddRange(shape);
            s.Add(dim);

            var weights = new Parameter(s.ToArray(), DataType.Float, Initializers.Get(weightInitializer), GlobalParameters.Device);
            
            return CNTKLib.OptimizedRNNStack(Variable.InputVariable(s.ToArray(), DataType.Float), weights, hiddenSize, numLayers, bidirectional, rnnName);
        }
Пример #6
0
        /// <summary>
        /// Fully connected layer.
        /// </summary>
        /// <param name="input">The input.</param>
        /// <param name="outputDim">The output dim.</param>
        /// <param name="useBias">if set to <c>true</c> [use bias].</param>
        /// <param name="weightInitializer">The weight initializer.</param>
        /// <param name="biasInitializer">The bias initializer.</param>
        /// <returns></returns>
        private static Function FullyConnected(Variable input, int outputDim, bool useBias, string weightInitializer, string biasInitializer)
        {
            int inputDim = input.Shape[0];

            int[] s       = { outputDim, inputDim };
            var   weights = new Parameter(s, DataType.Float, Initializers.Get(weightInitializer), GlobalParameters.Device);

            Parameter bias = null;

            if (useBias)
            {
                int[] s2 = { outputDim };
                bias = new Parameter(s2, DataType.Float, Initializers.Get(biasInitializer), GlobalParameters.Device);
            }
            else
            {
                int[] s2 = { outputDim };
                bias = new Parameter(s2, DataType.Float, 0.0f, GlobalParameters.Device);
            }

            return(CNTKLib.Plus(bias, CNTKLib.Times(weights, input)));
        }
Пример #7
0
        public static Function LSTM(Variable layer, int dim, int?cellDim = null, string activation = OptActivations.Tanh, string recurrentActivation = OptActivations.Sigmoid, string weightInitializer = OptInitializers.GlorotUniform, string recurrentInitializer = OptInitializers.GlorotUniform, bool useBias = true, string biasInitializer = OptInitializers.Zeros, bool returnSequence = false)
        {
            cellDim = cellDim.HasValue ? cellDim : dim;
            Variable prevOutput    = Variable.PlaceholderVariable(new int[] { dim }, layer.DynamicAxes);
            Variable prevCellState = cellDim.HasValue ? Variable.PlaceholderVariable(new int[] { cellDim.Value }, layer.DynamicAxes) : null;

            Func <int, Parameter> createBiasParam = (d) => new Parameter(new int[] { d }, DataType.Float, Initializers.Get(biasInitializer), GlobalParameters.Device);

            Func <int, Parameter> createProjectionParam = (oDim) => new Parameter(new int[] { oDim, NDShape.InferredDimension },
                                                                                  DataType.Float, Initializers.Get(weightInitializer), GlobalParameters.Device);

            Func <int, Parameter> createDiagWeightParam = (d) =>
                                                          new Parameter(new int[] { d }, DataType.Float, Initializers.Get(recurrentInitializer), GlobalParameters.Device);

            Function stabilizedPrevOutput    = Stabilize <float>(prevOutput, GlobalParameters.Device);
            Function stabilizedPrevCellState = prevCellState != null?Stabilize <float>(prevCellState, GlobalParameters.Device) : null;

            Func <Variable> projectInput = null;

            if (cellDim.HasValue)
            {
                projectInput = () => createBiasParam(cellDim.Value) + (createProjectionParam(cellDim.Value) * layer);
            }
            else
            {
                projectInput = () => layer;
            }

            //Input gate
            Function it = null;

            if (cellDim.HasValue)
            {
                it = Basic.Activation((Variable)(projectInput() + (createProjectionParam(cellDim.Value) * stabilizedPrevOutput)) + CNTKLib.ElementTimes(createDiagWeightParam(cellDim.Value), stabilizedPrevCellState), recurrentActivation);
            }
            else
            {
                it = Basic.Activation((Variable)(projectInput()), recurrentActivation);
            }

            Function bit = null;

            if (cellDim.HasValue)
            {
                bit = CNTKLib.ElementTimes(it, Basic.Activation(projectInput() + (createProjectionParam(cellDim.Value) * stabilizedPrevOutput), activation));
            }
            else
            {
                bit = CNTKLib.ElementTimes(it, Basic.Activation(projectInput(), activation));
            }

            // Forget-me-not gate
            Function ft = null;

            if (cellDim.HasValue)
            {
                ft = Basic.Activation((Variable)(projectInput() + (createProjectionParam(cellDim.Value) * stabilizedPrevOutput)) + CNTKLib.ElementTimes(createDiagWeightParam(cellDim.Value), stabilizedPrevCellState), recurrentActivation);
            }
            else
            {
                ft = Basic.Activation(projectInput(), recurrentActivation);
            }

            Function bft = prevCellState != null?CNTKLib.ElementTimes(ft, prevCellState) : ft;

            Function ct = (Variable)bft + bit;

            //Output gate
            Function ot = null;

            if (cellDim.HasValue)
            {
                ot = Basic.Activation((Variable)(projectInput() + (createProjectionParam(cellDim.Value) * stabilizedPrevOutput)) + CNTKLib.ElementTimes(createDiagWeightParam(cellDim.Value), Stabilize <float>(ct, GlobalParameters.Device)), recurrentActivation);
            }
            else
            {
                ot = Basic.Activation((Variable)(projectInput()) + Stabilize <float>(ct, GlobalParameters.Device), recurrentActivation);
            }

            Function ht = CNTKLib.ElementTimes(ot, CNTKLib.Tanh(ct));
            Function c  = ct;
            Function h  = (dim != cellDim) ? (createProjectionParam(dim) * Stabilize <float>(ht, GlobalParameters.Device)) : ht;

            Func <Variable, Function> recurrenceHookH = (x) => CNTKLib.PastValue(x);
            Func <Variable, Function> recurrenceHookC = (x) => CNTKLib.PastValue(x);

            var actualDh = recurrenceHookH(h);
            var actualDc = recurrenceHookC(c);

            if (prevCellState != null)
            {
                h.ReplacePlaceholders(new Dictionary <Variable, Variable> {
                    { prevOutput, actualDh }, { prevCellState, actualDc }
                });
            }
            else
            {
                h.ReplacePlaceholders(new Dictionary <Variable, Variable> {
                    { prevOutput, actualDh }
                });
            }

            if (returnSequence)
            {
                return(h);
            }

            return(CNTKLib.SequenceLast(h));
        }
Пример #8
0
        /// <summary>
        /// Batches the norm.
        /// </summary>
        /// <param name="shape">The input shape for batch norm layer.</param>
        /// <param name="epsilon">Small float added to variance to avoid dividing by zero.</param>
        /// <param name="betaInitializer">Initializer for the beta weight.</param>
        /// <param name="gammaInitializers">Initializer for the gamma weight.</param>
        /// <param name="runningMeanInitializer">Initializer for the running mean weight.</param>
        /// <param name="runningStdInvInitializer">Initializer for the running standard inv weight.</param>
        /// <param name="spatial">Boolean, if yes the input data is spatial (2D). If not, then sets to 1D</param>
        /// <param name="normalizationTimeConstant">The time constant in samples of the first-order low-pass filter that is used to compute mean/variance statistics for use in inference</param>
        /// <param name="blendTimeConst">The blend time constant in samples.</param>
        /// <returns></returns>
        public static Function BatchNorm(int shape, float epsilon        = 0.001f, string betaInitializer = OptInitializers.Zeros, string gammaInitializers = OptInitializers.Ones,
                                         string runningMeanInitializer   = OptInitializers.Zeros, string runningStdInvInitializer = OptInitializers.Ones, bool spatial = true,
                                         float normalizationTimeConstant = 4096f, float blendTimeConst = 0.0f)
        {
            var  input         = CNTKLib.InputVariable(new int[] { shape }, DataType.Float);
            var  biasParams    = new Parameter(new int[] { NDShape.InferredDimension }, DataType.Float, Initializers.Get(betaInitializer), GlobalParameters.Device, "");
            var  scaleParams   = new Parameter(new int[] { NDShape.InferredDimension }, DataType.Float, Initializers.Get(gammaInitializers), GlobalParameters.Device, "");
            var  runningMean   = new Parameter(new int[] { NDShape.InferredDimension }, DataType.Float, Initializers.Get(runningMeanInitializer), GlobalParameters.Device, "");
            var  runningInvStd = new Constant(new int[] { NDShape.InferredDimension }, 0.0f, GlobalParameters.Device);
            var  runningCount  = Constant.Scalar(0.0f, GlobalParameters.Device);
            bool useCudnn      = false;

            if (GlobalParameters.Device.Type == DeviceKind.GPU)
            {
                useCudnn = true;
            }

            return(CNTKLib.BatchNormalization(input, scaleParams, biasParams, runningMean, runningInvStd, runningCount, spatial, normalizationTimeConstant, blendTimeConst, epsilon, useCudnn));
        }
 List <IConstructor> ICodingStyle.GetInitializers(IType type) => Initializers.Get(type);
Пример #10
0
        /// <summary>
        /// Embeddings the specified layer.
        /// </summary>
        /// <param name="layer">The layer.</param>
        /// <param name="embeddingDim">The embedding dim.</param>
        /// <param name="initializers">The initializers.</param>
        /// <returns></returns>
        public static Function Embedding(Variable layer, int embeddingDim, string initializers = OptInitializers.GlorotUniform)
        {
            var embeddingParameters = new Parameter(new int[] { embeddingDim, layer.Shape[0] }, DataType.Float, Initializers.Get(initializers), GlobalParameters.Device);

            return(CNTKLib.Times(embeddingParameters, layer));
        }
Пример #11
0
        /// <summary>
        /// Embeddings layer
        /// </summary>
        /// <param name="shape">The shape.</param>
        /// <param name="embeddingDim">The dim.</param>
        /// <returns></returns>
        public static Function Embedding(int shape, int embeddingDim, string initializers = OptInitializers.GlorotUniform)
        {
            var input = CNTKLib.InputVariable(new int[] { shape }, true, DataType.Float);
            var embeddingParameters = new Parameter(new int[] { embeddingDim, shape }, DataType.Float, Initializers.Get(initializers), GlobalParameters.Device);

            return(CNTKLib.Times(embeddingParameters, input));
        }