The Beautiful Future

TF Quantize function 본문

DNN/Quantization

TF Quantize function

Small Octopus 2020. 8. 23. 14:52

 

@ tensorflow quantize

tf.quantization.quantize(
    input
, min_range, max_range, T, mode='MIN_COMBINED',
    round_mode
='HALF_AWAY_FROM_ZERO', name=None, narrow_range=False, axis=None,
    ensure_minimum_range
=0.01
)

- min_range = min( input_tensor ), max_range = max( input_tensor)

 

- MIN_COMBINED mode 인경우,

out[i] = (in[i] - min_range) * range(T) / (max_range - min_range)

if ( T == qint8 )
 out[i] -= (range(T) + 1) / 2.0

[0.0, 6.0]는 [0, 255]로 변환된다면, 모든 값들은 255/6 이곱해져서 quint8 범위를 갖게되어진다. 

범위가 qint8이라면 cast 전에 128을 빼준다. [-128, 127]

 

- MIN_FIRST mode 인경우,

num_discrete_values = 1 << 8                                             // == 256
range_adjust = num_discrete_values / (num_discrete_values - 1)  // 256/255 = 1.0039...
range = (range_max - range_min) * range_adjust                     // range_input*1.0039...
range_scale = num_discrete_values / range                            // 255*256/ (range_input*256/255*255)??
quantized = round( input * range_scale) - round(range_min * range_scale) + numeric_limits<T>::min()
quantized = max(quantized, numeric_limits<T>::min())
quantized = min(quantized, numeric_limits<T>::max())

range_min 이 rounded value가 빼지기 전에 rounded되는 점이 MIN_COMBINED와 다른 점이다. 

MIN_COMBINED 는 작은 바이어스가 발생되어서 퀀타이제이션이 반복될수록 에러가 커지는 문제점이 있다.

 

- SCALED mode 인경우, QuantizeAndDequantize{V2|V3} 에서 사용된다.

const int min_T = -128; // -127 if narrow_range is true.
const int max_T = 127;
const float max_float = std::numeric_limits<float>::max();

// 같은 부호인지 확인후 스케일 팩터구하기
const float scale_factor_min = (min_T*min_range > 0) ? min_T / min_range :  max_float;
const float scale_factor_max = (max_T*max_range > 0) ? max_T / max_range : max_float;

const float scale_factor = std::min(scale_factor_min, scale_factor_max);

T result = round(min(max_range, max(min_range, input)) * scale_factor)

-10 ~ 9 인경우 -128/-10 = 12.8 이고 127/9.0 = 14.11 이다. 작은 값을 택해야 더 넓은 범위로 포괄 할 수 있다. 그래서 scale factor는 12.8이 된다. min_range = -128/12.8 = -10, max_range = 127/12.8 = 9.92 이다.

 그러면 (-10, 9.921875) 는 (-128, 127)로  퀀타이즈 된다. 어느 한쪽에 맞춰진 min_range, max_range 는 리턴된다.

 

- narrow_range

True이면 [-128, 127] 대신에 [-127, 127]을 사용한다. 오직 SCALED mode에만 적용된다.

 

- axis

input tensor의 dimension index을 명시하면 slice 단위로 나눠져서 콴타이제이션 된다. 

만약 axis 명시되면 min_range와 max_range 사용되고, None이면 tensor 단위 콴타이제이션이 된다.

 

- ensure_minium_range

적어도 이값 보다 위다. 기본값 0.01이지만 새로운 사용을 위해 0으로 강하게 제안된다.

Args
input A Tensor of type float32
min_range A Tensor of type float32. The minimum value of the quantization range. This value may be adjusted by the op depending on other parameters. The adjusted value is written to output_min. If the axis attribue is specified, this must be a 1-D tensor whose size matches the axis dimension of the input and output tensors.
min_range output_max
T tf.qint8, tf.quint8, tf.qint32, tf.qint16, tf.quint16.
mode MIN_COMBINED, MIN_FIRST, SCALED
narrow_range  
axis  
ensure_minium_range  
name  

 

Returns  
A tuple of Tensor objects ( output, output_min, output_max)
output A Tensor of type T.
output_min A Tensor of type float32.
output_max A Tensor of type float32.

 

'DNN > Quantization' 카테고리의 다른 글

Quantization and Training of Neural Networks for EfficientInteger-Arithmetic-Only Inference  (0) 2020.08.25
gemmlowp  (0) 2020.08.24
Pytorch Quantization  (0) 2020.08.16
Comments