def process_group(G, group, threshold): total_precision = 0 cycles = 0 # Keep going until we converge while True: precisions = [] cycles += 1 if cycles > 50: raise QuantizationError("Weight scaling has failed to converge") for step in group: prec_0, prec_1 = calculate_precisions(G, step) precisions.append(np.sum(prec_0 * prec_1)) new_total_precision = sum(precisions) # end when the precision change drops below threshold if abs(new_total_precision - total_precision) < threshold: LOG.info("group has converged under %f after %d cycles", threshold, cycles) break total_precision = new_total_precision # note: traversing in reverse order. Not sure that it makes any difference. for step in reversed(group): nn_0 = step[0] nn_1 = step[1] # get the ranges of the output channels of layer 0 and input channels of layer 2 ranges_0, _ = Ranges.range_output(G, nn_0['node'], weights=nn_0['weights']) ranges_1, _ = Ranges.range_input(G, nn_1['node'], weights=nn_1['weights']) scale = calculate_s(ranges_0, ranges_1) # now apply the scale to the output and input channels nn_0['weights'], nn_0['biases'] =\ Scales.scale_output(G, nn_0['node'], scale, nn_0['weights'], nn_0['biases']) nn_1['weights'] = Scales.scale_input(G, nn_1['node'], scale, nn_1['weights'])
def calculate_precisions(G, step): nn_0 = step[0] nn_1 = step[1] ranges_0, max_0 = Ranges.range_output(G, nn_0['node'], weights=nn_0['weights']) ranges_1, max_1 = Ranges.range_input(G, nn_1['node'], weights=nn_1['weights']) prec_0 = ranges_0/max_0 prec_1 = ranges_1/max_1 return prec_0, prec_1
def process_group(group, threshold): total_precision = 0 cycles = 0 # Keep going until we converge while True: precisions = [] cycles += 1 if cycles > 50: raise QuantizationError("Weight scaling has failed to converge") for step in group: prec_0, prec_1 = calculate_precisions(step) precisions.append(np.sum(prec_0 * prec_1)) new_total_precision = sum(precisions) # end when the precision change drops below threshold if abs(new_total_precision - total_precision) < threshold: LOG.info("group has converged under %f after %d cycles", threshold, cycles) break total_precision = new_total_precision # note: traversing in reverse order. Not sure that it makes any difference. for step in reversed(group): nn_0 = step[0] nn_1 = step[1] # get the ranges of the output channels of layer 0 and input channels of layer 2 ranges_0, _ = Ranges.range_output(nn_0['node'], weights=nn_0['weights']) ranges_1, _ = Ranges.range_input(nn_1['node'], weights=nn_1['weights']) scale = calculate_s(ranges_0, ranges_1) if 'activation' in nn_0: if 'relun' not in nn_0: if nn_0['activation'].activation == "relu6": nn_0['relun'] = [6.0] * len(scale) elif nn_0['activation'].activation == "relun": if isinstance(nn_0['activation'].activation_params, list): nn_0['relun'] = copy( nn_0['activation'].activation_params) else: nn_0['relun'] = [ nn_0['activation'].activation_params ] * len(scale) nn_0['relun'] = [ relun / s for relun, s in zip(nn_0['relun'], scale) ] # now apply the scale to the output and input channels nn_0['weights'], nn_0['biases'] =\ Scales.scale_output(nn_0['node'], scale, nn_0['weights'], nn_0['biases']) nn_1['weights'] = Scales.scale_input(nn_1['node'], scale, nn_1['weights'])