public void EMA(double alpha, ChannelwiseRange newRange) { Global = Global.EMA(alpha, newRange.Global); for (int i = 0; i < Channels.Length; i++) { Channels[i] = Channels[i].EMA(alpha, newRange.Channels[i]); } }
public void Union(ChannelwiseRange newRange) { Global = Global.Union(newRange.Global); for (int i = 0; i < Channels.Length; i++) { Channels[i] = Channels[i].Union(newRange.Channels[i]); } }
private static (double scale, double bias) QuantizeInput(QuantizationRange range, K210ConvLayerConfig config) { (var scale, var bias) = range.GetScaleBias(8); (var mul, var shift) = Quantizer.ExtractValueAndShift(bias, 24, 15); config.ArgW = (int)Math.Round(mul); config.ShiftW = shift; return(scale, bias); }
public ChannelwiseRange(QuantizationRange range, int channels) { Global = range; Channels = Enumerable.Repeat(range, channels).ToArray(); }
private static void QuantizeActivation(K210Conv2d layer, double postMul, QuantizationRange range, QuantizationRange beforeActRange, K210ConvLayerConfig config) { if (layer.NonTrivialActivation == null) { switch (layer.FusedActivationFunction) { case ActivationFunctionType.Linear: case ActivationFunctionType.Relu: case ActivationFunctionType.Relu6: break; default: throw new NotSupportedException($"Activation of {layer.FusedActivationFunction} is not supported."); } var starts = new ulong[] { 0x800000000, 0xf7d4cf4b8, 0xf8ed5a20c, 0xfa05e4f60, 0xfb2e05baa, 0xfc46908fe, 0xfd5f1b652, 0xfe77a63a6, 0xff9fc6ff0, 0xfffd4a9b7, 0, 0x7FFFFFFF0, 0x7FFFFFFF1, 0x7FFFFFFF2, 0x7FFFFFFF3, 0x7FFFFFFF4 }; for (int i = 0; i < starts.Length; i++) { var param = config.ActConfigs[i] = new K210LayerActConfig(); param.StartX = starts[i]; if (i == 10) { (var mul, var shift) = Quantizer.ExtractValueAndShift(1 / postMul, 16, 20); param.Mul = (int)Math.Round(mul); param.Shift = shift; } } } else if (layer.NonTrivialActivation is LeakyRelu leakyRelu) { (var scale, var bias) = range.GetScaleBias(8); var zero = (long)(Quantizer.Quantize(0, scale, bias) * postMul); var yTable = Generator.IntegerStep(0, (int)-bias, 15).Take(14).ToArray(); for (int i = 0; i < 16; i++) { var param = config.ActConfigs[i] = new K210LayerActConfig(); if (i == 0) { param.StartX = 0x800000000; } else if (i == 15) { (var mul, var shift) = Quantizer.ExtractValueAndShift(1 / postMul, 16, 20); param.StartX = (ulong)zero; param.Mul = (int)Math.Round(mul); param.Shift = shift; param.Add = (byte)(-bias); } else { // f(x) = (1 - slope) * zero + x * slope // f(x1) - f(x0) = (x1 - x0) * slope // x0 = zero - (zero - y0) / slope var add = (byte)yTable[i - 1]; var y0 = add * postMul; var x0 = zero - (zero - y0) / leakyRelu.Slope; (var mul, var shift) = Quantizer.ExtractValueAndShift(1 / postMul * leakyRelu.Slope, 16, 20); param.StartX = (ulong)(long)Math.Floor(x0); param.Mul = (int)Math.Round(mul); param.Shift = shift; param.Add = add; } } } else { throw new NotSupportedException($"Activation of {layer.NonTrivialActivation.GetType().Name} is not supported."); } }