예제 #1
0
        public static (double[] scale, double bias) QuantizeWeights(bool isConv2d, Tensor <float> weights, K210ConvLayerConfig config, int weightsBits)
        {
#if CHANNEL_WISE
            var kernels     = weights.ToDenseTensor().Buffer.Span;
            var channels    = weights.Dimensions[isConv2d ? 0 : 1];
            var channelSize = weights.Dimensions.GetSize() / channels;

            var totalRange = Quantizer.GetRange(kernels);
            var scales     = new double[channels];

            for (int i = 0; i < channels; i++)
            {
                double s;
                var    buffer = kernels.Slice(i * channelSize, channelSize);
                var    range  = Quantizer.GetRange(buffer);

                var s1 = totalRange.Max / range.Max;
                var s2 = totalRange.Min / range.Min;
                s = (s1 < 0 || s2 < 0) ? Math.Max(s1, s2) : Math.Min(s1, s2);

                Debug.Assert(s > 0);
                for (int j = 0; j < buffer.Length; j++)
                {
                    buffer[j] = (float)(buffer[j] * s);
                }
                scales[i] = s;
            }

            (var scale, var bias) = Quantizer.GetRange(kernels).GetScaleBias(weightsBits);

            (var mul, var shift) = Quantizer.ExtractValueAndShift(bias, 24, 15);
            config.Weights       = Quantizer.Quantize(kernels, scale, bias, weightsBits);
            config.ArgX          = (int)Math.Round(mul);
            config.ShiftX        = shift;

            for (int i = 0; i < scales.Length; i++)
            {
                scales[i] *= scale;
            }
            return(scales, bias);
#else
            var buffer = weights.ToDenseTensor().Buffer.Span;
            (var scale, var bias) = GetRange(buffer).GetScaleBias();

            (var mul, var shift) = ExtractValueAndShift(bias, 24, 15);
            config.Weights       = Quantize(buffer, scale, bias);
            config.ArgX          = (int)Math.Round(mul);
            config.ShiftX        = shift;
            return(Enumerable.Repeat(scale, weights.Dimensions[0]).ToArray(), bias);
#endif
        }