Exemplo n.º 1
0
 public Tensor call(TensorShape shape, TF_DataType dtype = TF_DataType.DtInvalid)
 {
     throw new NotImplementedException();
 }
        Dictionary <Layer.Type, Action <Layer, ModelBuilder> > InstantiateRewriterNHWCToNHWC()
        {
            var rewritersNHWC = new Dictionary <Layer.Type, Action <Layer, ModelBuilder> >();

            // TODO, upsample is sometimes in NHWC mode
            rewritersNHWC.Add(Layer.Type.Reshape, (layer, net) =>
            {
                if (layer.inputs.Length == 1)
                {
                    var size = layer.pool;

                    // Don't use Tensorshape as this can remove a wild card
                    const int _ = 1;
                    if (size.Length == 1)
                    {
                        layer.pool = new[] { _, _, size[0], _, _, 1, 1, 1 }
                    }
                    ;                                                        // [1,1,N,1,1,1,1,1]
                    else if (size.Length == 2)
                    {
                        layer.pool = new[] { _, _, size[0], _, _, 1, 1, size[1] }
                    }
                    ;                                                              // [1, 1, N, 1, 1, 1, 1, C]
                    else if (size.Length == 3)
                    {
                        layer.pool = new[] { _, _, size[0], _, _, _, size[1], size[2] }
                    }
                    ;                                                                    // [1,1,N,1,1,1,W,C]
                    else if (size.Length == 4)
                    {
                        layer.pool = new[] { _, _, size[0], _, _, size[1], size[2], size[3] }
                    }
                    ;                                                                          // [1,1,N,1,1,H,W,C]
                    else if (size.Length == 5)
                    {
                        layer.pool = new[] { _, _, size[0], _, size[1], size[2], size[3], size[4] }
                    }
                    ;                                                                                // [1,1,N,1,D,H,W,C]
                    else if (size.Length == 6)
                    {
                        layer.pool = new[] { _, _, size[0], size[1], size[2], size[3], size[4], size[5] }
                    }
                    ;                                                                                      // [1,1,N,T,D,H,W,C]
                    else
                    {
                        layer.pool = new[] { size[0], size[1], size[2], size[3], size[4], size[5], size[6], size[7] }
                    };                                                                                                 // [S,R,N,T,D,H,W,C]
                }
            });
            rewritersNHWC.Add(Layer.Type.Concat, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.ReduceMax, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.ReduceMean, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.ReduceMin, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.ReduceProd, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.ReduceSum, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.ArgMax, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.ArgMin, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.Activation, ConvertAxisNHWC);
            rewritersNHWC.Add(Layer.Type.StridedSlice, (layer, net) =>
            {
                int rank = 4;
                if (m_RanksByName.ContainsKey(layer.name) && m_RanksByName[layer.name] != null)
                {
                    rank = m_RanksByName[layer.name].Value;
                }

                var name = layer.name;

                var starts = layer.pad;
                var ends   = layer.pool;
                var steps  = layer.stride;
                var axes   = layer.axes;

                var onnxStarts = Enumerable.Repeat(0, rank).ToArray();
                var onnxEnds   = Enumerable.Repeat(int.MaxValue, rank).ToArray(); // by default copy the whole axis till the end
                var onnxSteps  = Enumerable.Repeat(1, rank).ToArray();

                // NOTE: begin=0, end=0, stride=1  <=  full range from existing axis
                //       begin=0, end=inf,stride=1 <=  full range from existing axis
                //       begin=0, end=X, stride=1  <=  full range from existing axis, if X==last element on this axis
                //       begin=0, end=0, stride=0  <=  new axis OR shrink axis to single 1st element
                //       begin=N, end=N, stride=0  <=              shrink axis to single Nth element
                // These notes are copied from TensorExtensions.ApplyStridedSlice(...)

                for (int i = 0; i < axes.Length; ++i)
                {
                    var axis = axes[i];
                    if (axis < 0)
                    {
                        axis += rank;
                    }
                    axis = Math.Min(Math.Max(axis, 0), rank);

                    onnxStarts[axis] = starts[i];
                    onnxEnds[axis]   = ends[i];
                    onnxSteps[axis]  = steps[i];
                }

                switch (rank)
                {
                case 1:
                    layer.pad    = new[] { 0, 0, onnxStarts[0], 0, 0, 0, 0, 0 };
                    layer.pool   = new[] { int.MaxValue, int.MaxValue, onnxEnds[0], int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue };
                    layer.stride = new[] { 1, 1, onnxSteps[0], 1, 1, 1, 1, 1 };
                    break;

                case 2:
                    layer.pad    = new[] { 0, 0, onnxStarts[0], 0, 0, 0, 0, onnxStarts[1] };
                    layer.pool   = new[] { int.MaxValue, int.MaxValue, onnxEnds[0], int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, onnxEnds[1] };
                    layer.stride = new[] { 1, 1, onnxSteps[0], 1, 1, 1, 1, onnxSteps[1] };
                    break;

                case 3:
                    layer.pad    = new[] { 0, 0, onnxStarts[0], 0, 0, 0, onnxStarts[1], onnxStarts[2] };
                    layer.pool   = new[] { int.MaxValue, int.MaxValue, onnxEnds[0], int.MaxValue, int.MaxValue, int.MaxValue, onnxEnds[1], onnxEnds[2] };
                    layer.stride = new[] { 1, 1, onnxSteps[0], 1, 1, 1, onnxSteps[1], onnxSteps[2] };
                    break;

                case 4:
                    layer.pad    = new[] { 0, 0, onnxStarts[0], 0, 0, onnxStarts[1], onnxStarts[2], onnxStarts[3] };
                    layer.pool   = new[] { int.MaxValue, int.MaxValue, onnxEnds[0], int.MaxValue, int.MaxValue, onnxEnds[1], onnxEnds[2], onnxEnds[3] };
                    layer.stride = new[] { 1, 1, onnxSteps[0], 1, 1, onnxSteps[1], onnxSteps[2], onnxSteps[3] };
                    break;

                case 5:
                    layer.pad    = new[] { 0, 0, onnxStarts[0], 0, onnxStarts[1], onnxStarts[2], onnxStarts[3], onnxStarts[4] };
                    layer.pool   = new[] { int.MaxValue, int.MaxValue, onnxEnds[0], int.MaxValue, onnxEnds[1], onnxEnds[2], onnxEnds[3], onnxEnds[4] };
                    layer.stride = new[] { 1, 1, onnxSteps[0], 1, onnxSteps[1], onnxSteps[2], onnxSteps[3], onnxSteps[4] };
                    break;

                default:
                    throw new ArgumentException($"Unsupported tensor rank {rank} for StridedSlice");
                }
            });
            rewritersNHWC.Add(Layer.Type.Flatten, (layer, net) =>
            {
                layer.type = Layer.Type.Nop;
            });
            rewritersNHWC.Add(Layer.Type.Load, (layer, net) =>
            {
                int rank = layer.axis;
                if (rank != 2 && rank != 3)
                {
                    return;
                }

                var constX = layer.DataSetToTensor(0);

                var shape = constX.shape;
                switch (rank)
                {
                case 2:
                    // _,_,N,_,_,C,_,_ => _,_,N,_,_,_,_,C
                    shape = new TensorShape(shape.batch, shape.height);
                    break;

                case 3:
                    // _,_,N,_,_,W,C,_ => _,_,N,_,_,_,W,C
                    shape = new TensorShape(shape.batch, shape.height, shape.width);
                    break;
                }

                var reshapedX = m_Ops.Reshape(constX, shape);
                layer.ApplyTensorToDataSet(reshapedX, 0);
                reshapedX.Dispose();
                constX.Dispose();
            });


            return(rewritersNHWC);
        }
Exemplo n.º 3
0
 /// <summary>
 /// Outputs random values from a normal distribution.
 /// </summary>
 /// <param name="shape"></param>
 /// <param name="mean"></param>
 /// <param name="stddev"></param>
 /// <param name="dtype"></param>
 /// <param name="seed"></param>
 /// <param name="name"></param>
 /// <returns></returns>
 public Tensor random_normal(TensorShape shape,
                             float mean        = 0.0f,
                             float stddev      = 1.0f,
                             TF_DataType dtype = TF_DataType.TF_FLOAT,
                             int?seed          = null,
                             string name       = null) => random_ops.random_normal(shape, mean, stddev, dtype, seed, name);
Exemplo n.º 4
0
 public static Dimension dimension_at_index(TensorShape shape, int index)
 {
     return(shape.rank < 0 ?
            new Dimension(-1) :
            new Dimension(shape.dims[index]));
 }
Exemplo n.º 5
0
        public _GraphTensorArray(TF_DataType dtype, Tensor size, bool?dynamic_size = null,
                                 bool?clear_after_read = null, string tensor_array_name  = null, Tensor handle = null, Tensor flow = null,
                                 bool infer_shape      = true, TensorShape element_shape = null,
                                 bool colocate_with_first_write_call = true, string name = null)
        {
            clear_after_read = clear_after_read ?? true;
            dynamic_size     = dynamic_size ?? false;
            _dynamic_size    = dynamic_size.Value;
            _dtype           = dtype;

            _colocate_with_first_write_call = colocate_with_first_write_call;
            if (colocate_with_first_write_call)
            {
                _colocate_with = new List <Tensor>();
            }

            // Record the current static shape for the array elements. The element
            // shape is defined either by `element_shape` or the shape of the tensor
            // of the first write. If `infer_shape` is true, all writes checks for
            // shape equality.
            if (element_shape == null)
            {
                _infer_shape   = infer_shape;
                _element_shape = new List <TensorShape> {
                };
            }
            else
            {
                _infer_shape   = true;
                _element_shape = new List <TensorShape> {
                    element_shape
                };
            }

            tf_with(ops.name_scope(name, "TensorArray", new { handle, size, flow }), scope =>
            {
                if (handle != null)
                {
                    _handle = handle;
                    _flow   = flow;
                }
                else
                {
                    Func <(Tensor, Tensor)> create = () => gen_data_flow_ops.tensor_array_v3(size,
                                                                                             dtype: dtype,
                                                                                             element_shape: element_shape,
                                                                                             identical_element_shapes: infer_shape,
                                                                                             dynamic_size: dynamic_size.Value,
                                                                                             clear_after_read: clear_after_read.Value,
                                                                                             tensor_array_name: tensor_array_name,
                                                                                             name: scope);

                    // Construct the TensorArray with an empty device.  The first
                    // write into the TensorArray from a Tensor with a set device
                    // will retroactively set the device value of this op.
                    if (colocate_with_first_write_call)
                    {
                        ops.colocate_with(ignore_existing: true);
                        (_handle, _flow) = create();
                    }
                    else
                    {
                        (_handle, _flow) = create();
                    }
                }
            });
        }
Exemplo n.º 6
0
        protected override void build(Tensors inputs)
        {
            TensorShape input_shape = inputs.shape;
            var         ndims       = input_shape.ndim;

            foreach (var(idx, x) in enumerate(axis))
            {
                if (x < 0)
                {
                    axis[idx] = ndims + x;
                }
            }

            fused = ndims == 4;

            if (fused)
            {
                if (Enumerable.SequenceEqual(axis, new int[] { 1 }))
                {
                    _data_format = "NCHW";
                }
                else if (Enumerable.SequenceEqual(axis, new int[] { 3 }))
                {
                    _data_format = "NHWC";
                }
                else
                {
                    throw new ValueError($"Unsupported axis, fused batch norm only supports axis == [1] or axis == [3]");
                }
            }

            var axis_to_dim = new Dictionary <int, int>();

            foreach (var x in axis)
            {
                axis_to_dim[x] = input_shape[x];
            }

            inputSpec = new InputSpec(ndim: ndims, axes: axis_to_dim);
            var param_dtype = DType == TF_DataType.DtInvalid ? TF_DataType.TF_FLOAT : DType;
            var param_shape = inputSpec.AllAxisDim;

            if (scale)
            {
                gamma = add_weight("gamma",
                                   param_shape,
                                   dtype: param_dtype,
                                   initializer: gamma_initializer,
                                   trainable: true);
            }
            else
            {
                throw new NotImplementedException("add_weight gamma");
            }

            if (center)
            {
                beta = add_weight("beta",
                                  param_shape,
                                  dtype: param_dtype,
                                  initializer: beta_initializer,
                                  trainable: true);
            }
            else
            {
                throw new NotImplementedException("add_weight beta");
            }

            moving_mean = add_weight("moving_mean",
                                     param_shape,
                                     dtype: param_dtype,
                                     initializer: moving_mean_initializer,
                                     synchronization: VariableSynchronization.OnRead,
                                     aggregation: VariableAggregation.Mean,
                                     trainable: false);

            moving_variance = add_weight("moving_variance",
                                         shape: param_shape,
                                         dtype: param_dtype,
                                         initializer: moving_variance_initializer,
                                         synchronization: VariableSynchronization.OnRead,
                                         aggregation: VariableAggregation.Mean,
                                         trainable: false);

            if (renorm)
            {
                throw new NotImplementedException("build when renorm is true");
            }

            built = true;
        }
Exemplo n.º 7
0
 private void _build(TensorShape shape) => throw new NotImplementedException();
Exemplo n.º 8
0
        public void Case7()
        {
            TensorShape shape = new TensorShape();

            Assert.AreEqual(shape.rank, -1);
        }
Exemplo n.º 9
0
 public Tensor reduce_sum(Tensor input, TensorShape axis, int?reduction_indices = null,
                          bool keepdims = false, string name = null)
 => math_ops.reduce_sum(input, axis, keepdims: keepdims, name: name);
Exemplo n.º 10
0
        internal static Tensor CastDataAndReturnAsTensor <T>(T[] data, TensorShape tfShape)
        {
            var dims = tfShape.dims.Select(x => (long)x).ToArray();

            if (typeof(T) == typeof(sbyte))
            {
                return(new Tensor((sbyte[])(object)data, dims, TF_DataType.TF_INT8));
            }
            else if (typeof(T) == typeof(long))
            {
                return(new Tensor((long[])(object)data, dims, TF_DataType.TF_INT64));
            }
            else if (typeof(T) == typeof(Int32))
            {
                return(new Tensor((Int32[])(object)data, dims, TF_DataType.TF_INT32));
            }
            else if (typeof(T) == typeof(Int16))
            {
                return(new Tensor((Int16[])(object)data, dims, TF_DataType.TF_INT16));
            }
            else if (typeof(T) == typeof(byte))
            {
                return(new Tensor((byte[])(object)data, dims, TF_DataType.TF_UINT8));
            }
            else if (typeof(T) == typeof(ulong))
            {
                return(new Tensor((ulong[])(object)data, dims, TF_DataType.TF_UINT64));
            }
            else if (typeof(T) == typeof(UInt32))
            {
                return(new Tensor((UInt32[])(object)data, dims, TF_DataType.TF_UINT32));
            }
            else if (typeof(T) == typeof(UInt16))
            {
                return(new Tensor((UInt16[])(object)data, dims, TF_DataType.TF_UINT16));
            }
            else if (typeof(T) == typeof(bool))
            {
                return(new Tensor((bool[])(object)data, dims, TF_DataType.TF_BOOL));
            }
            else if (typeof(T) == typeof(float))
            {
                return(new Tensor((float[])(object)data, dims, TF_DataType.TF_FLOAT));
            }
            else if (typeof(T) == typeof(double))
            {
                return(new Tensor((double[])(object)data, dims, TF_DataType.TF_DOUBLE));
            }
            else if (typeof(T) == typeof(ReadOnlyMemory <char>))
            {
                string[] strings = new string[data.Length];
                for (int i = 0; i < strings.Length; i++)
                {
                    strings[i] = data[i].ToString();
                }

                return(new Tensor(strings));
            }

            return(new Tensor(new NDArray(data, tfShape)));
        }
Exemplo n.º 11
0
        public override TensorShape compute_output_shape(TensorShape input_shape)
        {
            var outputShape = input_shape.as_list();

            outputShape[^ 1] = this.innerLayers[^ 1].units;
Exemplo n.º 12
0
 public Tensor ones(TensorShape shape, TF_DataType dtype = TF_DataType.TF_FLOAT, string name = null)
 => array_ops.ones(shape, dtype, name);
Exemplo n.º 13
0
 protected virtual void build(TensorShape input_shape)
 {
     built = true;
 }
Exemplo n.º 14
0
        public void Case5()
        {
            TensorShape shape = (1, Unknown, 3);

            shape.GetPrivate <Shape>("shape").Should().BeShaped(1, -1, 3);
        }
Exemplo n.º 15
0
 public Tensor reshape(Tensor tensor,
                       TensorShape shape,
                       string name = null) => gen_array_ops.reshape(tensor, shape, name);
Exemplo n.º 16
0
        public void Case6()
        {
            TensorShape shape = (Unknown, 1, 2, 3, Unknown);

            shape.GetPrivate <Shape>("shape").Should().BeShaped(-1, 1, 2, 3, -1);
        }
Exemplo n.º 17
0
 public virtual TensorShape ComputeOutputShape(TensorShape input_shape)
 => throw new NotImplementedException("");
Exemplo n.º 18
0
 public void _merge_element_shape(TensorShape shape)
 {
     _element_shape.Add(shape);
 }
        public void Run(ref Model model)
        {
            // MatMul (rank3) + known input -> Add/Sub => Dense3
            var constLayers = new Dictionary <string, Layer>();

            foreach (var l in model.layers)
            {
                if (l.type == Layer.Type.Load)
                {
                    constLayers[l.name] = l;
                }
            }
            var preserve = new HashSet <string>(
                model.memories.Select(mem => mem.input).Concat(
                    model.memories.Select(mem => mem.output)).Concat(
                    model.outputs));


            var removeLayers = new HashSet <string>();
            var remap        = new Dictionary <string, string>();

            for (int l = 0; l < model.layers.Count - 1; ++l)
            {
                Layer layer = model.layers[l];

                List <Layer> downStreamLayers = GetDownStreamLayers(model, layer.name);

                if (!IsLayerDense3(layer, downStreamLayers, constLayers))
                {
                    continue;
                }

                if (preserve.Contains(layer.name) || preserve.Contains(downStreamLayers[0].name))
                {
                    continue;
                }

                string weights      = (layer.inputs.Where(x => constLayers.ContainsKey(x)).ToList())[0];
                Layer  constWeights = constLayers[weights];
                var    weightArray  = constWeights.weights;
                var    weightShape  = constWeights.datasets[0].shape;

                Layer       downStreamLayer = downStreamLayers[0];
                string      bias            = (downStreamLayer.inputs.Where(x => x != layer.name).ToList())[0];
                Layer       constBias       = constLayers[bias];
                TensorShape biasShape       = new TensorShape(1, 1, 1, Mathf.Max(weightShape.channels, constBias.datasets[0].shape.length));
                var         biasArray       = constBias.weights;

                var inputs = layer.inputs.Where(x => x != weights).ToArray();

                Layer mergedLayer = new Layer(layer.name, Layer.Type.Dense3);

                mergedLayer.inputs = inputs;

                mergedLayer.datasets                    = new Layer.DataSet[2];
                mergedLayer.datasets[0].name            = $"{mergedLayer.name}/W";
                mergedLayer.datasets[0].shape           = weightShape;
                mergedLayer.datasets[0].itemSizeInBytes = 4;
                mergedLayer.datasets[0].length          = weightShape.length;
                mergedLayer.datasets[0].offset          = 0;
                mergedLayer.datasets[1].name            = $"{mergedLayer.name}/B";
                mergedLayer.datasets[1].shape           = biasShape;
                mergedLayer.datasets[1].itemSizeInBytes = 4;
                mergedLayer.datasets[1].length          = biasShape.length;
                mergedLayer.datasets[1].offset          = weightShape.length;
                mergedLayer.weights = new float[weightShape.length + biasShape.length];

                weightArray.CopyTo(mergedLayer.weights, 0);
                if (constBias.datasets[0].shape.length == 1)
                {
                    for (int i = 0; i < biasShape.length; i++)
                    {
                        mergedLayer.weights[mergedLayer.datasets[1].offset + i] = biasArray[0];
                    }
                }
                else
                {
                    biasArray.CopyTo(mergedLayer.weights, mergedLayer.datasets[1].offset);
                }


                model.layers[l] = mergedLayer;

                if (!preserve.Contains(constWeights.name))
                {
                    removeLayers.Add(constWeights.name);
                }
                removeLayers.Add(downStreamLayer.name);
                if (!preserve.Contains(constBias.name))
                {
                    removeLayers.Add(constBias.name);
                }
                remap[downStreamLayer.name] = mergedLayer.name;
            }

            model.layers.RemoveAll(l => removeLayers.Contains(l.name));
            for (int l = 0; l < model.layers.Count; ++l)
            {
                Layer layer = model.layers[l];
                for (int i = 0; i < layer.inputs.Length; i++)
                {
                    var input = layer.inputs[i];
                    if (remap.ContainsKey(input))
                    {
                        model.layers[l].inputs[i] = remap[input];
                    }
                }
            }
        }
Exemplo n.º 20
0
 public override TensorShape ComputeOutputShape(TensorShape input_shape)
 {
     return(input_shape);
 }
Exemplo n.º 21
0
 public TapeTensor(long id, TF_DataType dtype, TensorShape shape)
 {
     this.id    = id;
     this.dtype = dtype;
     this.shape = shape;
 }
Exemplo n.º 22
0
        protected virtual IVariableV1 add_weight(string name,
                                                 TensorShape shape,
                                                 TF_DataType dtype        = TF_DataType.TF_FLOAT,
                                                 IInitializer initializer = null,
                                                 IRegularizer regularizer = null,
                                                 VariableSynchronization synchronization = VariableSynchronization.Auto,
                                                 VariableAggregation aggregation         = VariableAggregation.None,
                                                 bool trainable = true,
                                                 Func <VariableArgs, IVariableV1> getter = null)
        {
            // Initialize variable when no initializer provided
            if (initializer == null)
            {
                // If dtype is DT_FLOAT, provide a uniform unit scaling initializer
                if (dtype.is_floating())
                {
                    initializer = tf.glorot_uniform_initializer;
                }
                else if (dtype.is_integer())
                {
                    initializer = tf.zeros_initializer;
                }
                else
                {
                    throw new ValueError($"An initializer for variable {name} of type {dtype.as_base_dtype()} is required for layer {name}");
                }
            }

            if (synchronization == VariableSynchronization.OnRead)
            {
                trainable = false;
            }

            var args = new VariableArgs
            {
                Name            = name,
                Shape           = shape,
                DType           = dtype,
                Getter          = getter ?? base_layer_utils.make_variable,
                Overwrite       = true,
                Initializer     = initializer,
                Synchronization = synchronization,
                Aggregation     = aggregation,
                Trainable       = trainable
            };
            var variable = _add_variable_with_custom_getter(args);

            if (regularizer != null)
            {
                var name_in_scope = variable.Name.Split(':')[0];
                _handle_weight_regularization(name_in_scope, variable, regularizer);
            }

            //backend.track_variable(variable);
            if (trainable == true)
            {
                trainableWeights.Add(variable);
            }
            else
            {
                nonTrainableWeights.Add(variable);
            }

            return(variable);
        }
Exemplo n.º 23
0
 public static Model NASNetLarge(TensorShape input_shape = null, bool include_top = true, string weights = "imagenet",
                                 Tensor input_tensor     = null, string pooling   = null, int classes    = 1000) => throw new NotImplementedException();
Exemplo n.º 24
0
 public Tensor random_uniform(TensorShape shape,
                              float minval      = 0,
                              float maxval      = 1,
                              TF_DataType dtype = TF_DataType.TF_FLOAT,
                              int?seed          = null,
                              string name       = null) => random_ops.random_uniform(shape, minval, maxval, dtype, seed, name);
Exemplo n.º 25
0
 public static Model NASNet(TensorShape input_shape = null, int penultimate_filters = 4032, int num_blocks = 6, int stem_block_filters = 96,
                            bool skip_reduction     = true, int filter_multiplier   = 2, bool include_top  = true, string weights      = null,
                            Tensor input_tensor     = null, string pooling = null, int classes = 1000, int?default_size = null) => throw new NotImplementedException();
Exemplo n.º 26
0
        protected override void build(TensorShape input_shape)
        {
            var ndims = input_shape.NDim;

            foreach (var(idx, x) in Python.enumerate(axis))
            {
                if (x < 0)
                {
                    axis[idx] = ndims + x;
                }
            }

            if (fused)
            {
                if (Enumerable.SequenceEqual(axis, new int[] { 3 }))
                {
                    _data_format = "NHWC";
                }
            }

            var param_dtype = _dtype == TF_DataType.DtInvalid ? TF_DataType.TF_FLOAT : _dtype;
            var param_shape = new int[] { input_shape.Dimensions[axis[0]] };

            if (scale)
            {
                gamma = add_weight("gamma",
                                   param_shape,
                                   dtype: param_dtype,
                                   initializer: gamma_initializer,
                                   trainable: true);
            }
            else
            {
                throw new NotImplementedException("add_weight gamma");
            }

            if (center)
            {
                beta = add_weight("beta",
                                  param_shape,
                                  dtype: param_dtype,
                                  initializer: beta_initializer,
                                  trainable: true);
            }
            else
            {
                throw new NotImplementedException("add_weight beta");
            }

            if (_scope != null)
            {
            }

            moving_mean = add_weight("moving_mean",
                                     param_shape,
                                     dtype: param_dtype,
                                     initializer: moving_mean_initializer,
                                     synchronization: VariableSynchronization.OnRead,
                                     trainable: false,
                                     aggregation: VariableAggregation.Mean);

            moving_variance = add_weight("moving_variance",
                                         shape: param_shape,
                                         dtype: param_dtype,
                                         initializer: moving_variance_initializer,
                                         synchronization: VariableSynchronization.OnRead,
                                         trainable: false,
                                         aggregation: VariableAggregation.Mean);

            if (renorm)
            {
                throw new NotImplementedException("build when renorm is true");
            }

            built = true;
        }
Exemplo n.º 27
0
        public void FuseInputsIntoLayer(ref Layer layer, Dictionary <string, Tensor> knownLayersValue, IDictionary <string, int?> ranksByName)
        {
            switch (layer.type)
            {
            case Layer.Type.Upsample2D:
            {
                if (layer.inputs.Length <= 1 || !IsLayerKnown(layer.inputs[1], knownLayersValue))
                {
                    return;
                }

                float[] scales = knownLayersValue[layer.inputs[1]].ToReadOnlyArray();

                if (scales[0] == 1 && scales[1] == 1 && scales[2] < 1.0f && scales[3] < 1.0f)
                {
                    scales     = new[] { scales[2], scales[3] };
                    layer.type = Layer.Type.AvgPool2D;
                    layer.pad  = new[] { 0, 0 };
                    var inverseScalesRoundedToInt = scales.Select(x => (int)Mathf.Round(1f / x)).ToArray();
                    layer.stride = new[] { 1, 1 };
                    layer.pool   = inverseScalesRoundedToInt;
                }
                else
                {
                    layer.inputs = new[] { layer.inputs[0] };
                    layer.pool   = Array.ConvertAll(scales, x => (int)x);
                }
                return;
            }

            case Layer.Type.Resample2D:
            {
                if (layer.inputs.Length <= 1 || !IsLayerKnown(layer.inputs[1], knownLayersValue))
                {
                    return;
                }

                int[] sizes = Array.ConvertAll(knownLayersValue[layer.inputs[1]].ToReadOnlyArray(), x => (int)x);

                layer.inputs = new[] { layer.inputs[0] };
                layer.pool   = sizes;
                return;
            }

            case Layer.Type.Expand:
            {
                if (layer.inputs.Length <= 1 || !IsLayerKnown(layer.inputs[1], knownLayersValue))
                {
                    return;
                }

                float[] shapeValue = knownLayersValue[layer.inputs[1]].ToReadOnlyArray();
                var     shape      = new int[shapeValue.Length];
                for (int i = 0; i < shapeValue.Length; i++)
                {
                    shape[i] = (int)shapeValue[i];
                }

                layer.pool   = shape;
                layer.inputs = new[] { layer.inputs[0] };
                return;
            }

            case Layer.Type.MatMul:
            {
                var input0 = layer.inputs[0]; var input1 = layer.inputs[1];
                if (!ranksByName.ContainsKey(input0) || !ranksByName[input0].HasValue)
                {
                    return;
                }
                if (!ranksByName.ContainsKey(input1) || !ranksByName[input1].HasValue)
                {
                    return;
                }
                int rank0 = ranksByName[input0].Value;
                int rank1 = ranksByName[input1].Value;

                if (rank0 > 2 || rank1 > 2)
                {
                    return;
                }

                if (!IsLayerKnown(input1, knownLayersValue))
                {
                    return;
                }

                layer.type = Layer.Type.Dense;

                var weight = knownLayersValue[input1];
                weight = weight.Reshape(new TensorShape(weight.batch, weight.height));
                var biasShape = new TensorShape(1, 1, 1, weight.shape.channels);

                layer.inputs                      = new [] { input0 };
                layer.datasets                    = new Layer.DataSet[2];
                layer.datasets[0].name            = $"{layer.name}/W";
                layer.datasets[0].shape           = weight.shape;
                layer.datasets[0].itemSizeInBytes = 4;
                layer.datasets[0].length          = weight.shape.length;
                layer.datasets[0].offset          = 0;
                layer.datasets[1].name            = $"{layer.name}/B";
                layer.datasets[1].shape           = biasShape;
                layer.datasets[1].itemSizeInBytes = 4;
                layer.datasets[1].length          = biasShape.length;
                layer.datasets[1].offset          = weight.shape.length;
                layer.weights                     = new float[weight.shape.length + biasShape.length];

                weight.ToReadOnlyArray().CopyTo(layer.weights, 0);
                return;
            }

            case Layer.Type.Tile:
            {
                if (layer.inputs.Length <= 1 || !IsLayerKnown(layer.inputs[1], knownLayersValue))
                {
                    return;
                }

                var shape = Array.ConvertAll(knownLayersValue[layer.inputs[1]].ToReadOnlyArray(), x => (int)x);
                layer.pool = shape;

                layer.inputs = new[] { layer.inputs[0] };
                return;
            }

            case Layer.Type.Reshape:
            {
                if (layer.inputs.Length <= 1 || !IsLayerKnown(layer.inputs[1], knownLayersValue))
                {
                    return;
                }

                float[] shapeValue = knownLayersValue[layer.inputs[1]].ToReadOnlyArray();
                var     shape      = new int[shapeValue.Length];
                for (int i = 0; i < shapeValue.Length; i++)
                {
                    shape[i] = (int)shapeValue[i];
                }

                layer.pool   = shape;
                layer.inputs = new[] { layer.inputs[0] };
                return;
            }

            case Layer.Type.ConstantOfShape:
            {
                if (layer.inputs.Length < 1 || !IsLayerKnown(layer.inputs[0], knownLayersValue))
                {
                    return;
                }

                Tensor input       = knownLayersValue[layer.inputs[0]];
                var    shape       = Array.ConvertAll(input.ToReadOnlyArray(), x => (int)x);
                var    tensorShape = IRShapeInferenceHelper.ShapeInference.OnnxLayoutToTensorShape(shape);


                layer.type = Layer.Type.Load;


                layer.axis                        = shape.Length;
                layer.datasets                    = new Layer.DataSet[1];
                layer.datasets[0].name            = layer.name;
                layer.datasets[0].shape           = tensorShape;
                layer.datasets[0].itemSizeInBytes = 4;
                layer.datasets[0].length          = tensorShape.length;
                layer.datasets[0].offset          = 0;
                layer.weights                     = new float[tensorShape.length];

                var tensor = new Tensor(tensorShape);
                tensor.Fill(layer.alpha);
                tensor.ToReadOnlyArray().CopyTo(layer.weights, 0);

                layer.inputs = new string[0];
                return;
            }

            case Layer.Type.LSTM:
            {
                if (layer.inputs.Length <= 3 || !knownLayersValue.TryGetValue(layer.inputs[1], out Tensor W) ||
                    !knownLayersValue.TryGetValue(layer.inputs[2], out Tensor R) ||
                    !knownLayersValue.TryGetValue(layer.inputs[3], out Tensor B))
                {
                    return;
                }

                var ops = new ReferenceCPUOps();
                using (var td = new TensorScope())
                {
                    TensorScope.F _ = td._;

                    W = _(ops.Transpose(W, new[] { 2, 0, 3, 1 }));
                    R = _(ops.Transpose(R, new[] { 2, 0, 3, 1 }));
                    B = _(ops.Transpose(B, new[] { 0, 2, 3, 1 }));

                    OpsUtils.BakeConstantWRBIntoLSTMLayer(layer, W, R, B);
                }

                layer.inputs = new[] { layer.inputs[0], layer.inputs[4], layer.inputs[5] };

                return;
            }

            case Layer.Type.Activation:
            {
                if (layer.activation == Layer.Activation.None)
                {
                    if (layer.inputs.Length < 1 || !IsLayerKnown(layer.inputs[0], knownLayersValue))
                    {
                        return;
                    }

                    Tensor input       = knownLayersValue[layer.inputs[0]];
                    var    tensorShape = input.shape;

                    layer.type = Layer.Type.Load;

                    layer.axis                        = input.dimensions; // TODO real rank
                    layer.datasets                    = new Layer.DataSet[1];
                    layer.datasets[0].name            = layer.name;
                    layer.datasets[0].shape           = tensorShape;
                    layer.datasets[0].itemSizeInBytes = 4;
                    layer.datasets[0].length          = tensorShape.length;
                    layer.datasets[0].offset          = 0;
                    layer.weights                     = new float[tensorShape.length];

                    input.ToReadOnlyArray().CopyTo(layer.weights, 0);

                    layer.inputs = new string[0];
                }

                return;
            }

            case Layer.Type.StridedSlice:
            {
                if (layer.inputs.Length <= 1 ||
                    !IsLayerKnown(layer.inputs[1], knownLayersValue) || !IsLayerKnown(layer.inputs[2], knownLayersValue) || !IsLayerKnown(layer.inputs[3], knownLayersValue) || !IsLayerKnown(layer.inputs[4], knownLayersValue))
                {
                    return;
                }

                var starts = Array.ConvertAll(knownLayersValue[layer.inputs[1]].ToReadOnlyArray(), x => x <= (float)int.MinValue ? int.MinValue : x >= (float)int.MaxValue ? int.MaxValue : (int)x);
                var ends   = Array.ConvertAll(knownLayersValue[layer.inputs[2]].ToReadOnlyArray(), x => x <= (float)int.MinValue ? int.MinValue : x >= (float)int.MaxValue ? int.MaxValue : (int)x);

                var strides = Enumerable.Repeat(1, starts.Length).Select(v => (int)v).ToArray();
                if (layer.inputs.Length >= 4)
                {
                    strides = Array.ConvertAll(knownLayersValue[layer.inputs[3]].ToReadOnlyArray(), x => (int)x);
                }
                var axes = Enumerable.Range(0, starts.Length).Select(v => (int)v).ToArray();
                if (layer.inputs.Length == 5)
                {
                    axes = Array.ConvertAll(knownLayersValue[layer.inputs[4]].ToReadOnlyArray(), x => (int)x);
                }

                layer.pad    = starts;
                layer.pool   = ends;
                layer.stride = strides;
                layer.axes   = axes;

                layer.inputs = new[] { layer.inputs[0] };

                return;
            }

            default:
                return;
            }
        }