# 8-bit Unet Verification 目前還沒完工,但快了,還有一些小 bug 要解,以及 M 要用 fixed-point 運算的問題 - inference_Unet_v1_8bit(ver1) ```python= # -*- coding: utf-8 -*- """ Created on Mon Sep 18 04:02:01 2023 @author: Jay """ from os import listdir import cv2 as cv import os import CONV from CONV import GEMMConv3D from CONV import Conv3D from CONV import Maxpool_3D from CONV import De_Conv2x2 #from CONV import De_Conv2x2_fast import math from skimage.measure import block_reduce as maxpooling import matplotlib.pyplot as plt import numpy as np layer = ['conv'+str(i) for i in range(1, 24)] current_path = os.getcwd() all_file_name = os.listdir(current_path) print(all_file_name) parameter = {} floatingVar = {} Load_parameter = 0 if Load_parameter == 1: parameter = np.load('./parameter/parameter.npy',allow_pickle='TRUE').item() floatingVar = np.load('./parameter/floatingVar.npy',allow_pickle='TRUE').item() else: for item in all_file_name: if item in layer: file_name = os.listdir(current_path+'/'+item) print(file_name) for item_in in file_name: parameter[item+'_'+item_in[:-4]] = np.load(current_path+'/'+item+'/'+item_in) elif item.endswith("npy"): print('npy:', item) floatingVar[item[:-4]] = np.load(current_path+'/'+item) # resize the output activations for i in range(1, 32): floatingVar['out'+str(i)] = np.reshape(floatingVar['out'+str(i)], (floatingVar['out'+str(i)].shape[1],floatingVar['out'+str(i)].shape[2],floatingVar['out'+str(i)].shape[3])) floatingVar['out'+str(i)+'_quantFloating'] = np.reshape(floatingVar['out'+str(i)+'_quantFloating'], (floatingVar['out'+str(i)+'_quantFloating'].shape[1],floatingVar['out'+str(i)+'_quantFloating'].shape[2],floatingVar['out'+str(i)+'_quantFloating'].shape[3])) # Initialize the input_scale of each layer for idx in range(2, 24): parameter['conv' + str(idx) + '_input_scale'] = parameter['conv' + str(idx-1) + '_output_scale'].copy() parameter['conv'+str(idx)+'_input_zero_point'] = parameter['conv'+str(idx-1)+'_output_zero'] use_shift_instead_of_divide = 2 print(" ==================== Unet inference (Int8 model) ====================") Unet = {} debug = {} input_data = floatingVar['input_np'][0,] out_num = 0 Unet['q_out'+str(out_num)] = np.round( (input_data / parameter['conv1_input_scale']) + parameter['conv1_input_zero_point']) print("max = ", np.max(Unet['q_out'+str(out_num)])) print("min = ", np.min(Unet['q_out'+str(out_num)])) out_num += 1 weight_num = 1 bit = 32 # =========================================== Encoder =========================================== for times in range(5): print("\n-------- out{} --------".format(out_num)) # Conv + Relu Unet['q_out'+str(out_num)] = GEMMConv3D( (Unet['q_out'+str(out_num-1)] - parameter['conv'+str(weight_num)+'_input_zero_point'] ) , parameter['conv'+str(weight_num)+'_weight_int']) # calculate left shift bit ratio = ( parameter['conv' + str(weight_num) + '_input_scale'] * parameter['conv' + str(weight_num) + '_weight_scale'] / parameter['conv' + str(weight_num) + '_output_scale'] ) shift_bit = math.log(ratio, 2) shift_bit = abs( math.ceil(shift_bit) ) M = ratio / 2**(-shift_bit) M_fixed = round(M * 2**bit) Unet['shift_bit'+str(out_num)] = shift_bit Unet['M'+str(out_num)] = M Unet['M_fixed'+str(out_num)] = M_fixed # Relu Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] < 0.0 ] = 0.0 print('ratio = {}, shift_bit = {}'.format(ratio, shift_bit)) if use_shift_instead_of_divide == 1 : Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] // (2**(bit+Unet['shift_bit'+str(out_num)])) elif use_shift_instead_of_divide == 2 : one = np.ones(Unet['q_out'+str(out_num)].shape) tmp = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] float_int_err = ( tmp / (2**(bit+Unet['shift_bit'+str(out_num)])) ) - ( tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) ) outTmp = tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) tag = float_int_err > 0.5 Unet['q_out'+str(out_num)] = outTmp.copy() Unet['q_out'+str(out_num)][tag] = outTmp[tag] + one[tag] else: Unet['q_out'+str(out_num)] = np.round( Unet['q_out'+str(out_num)] * ratio ) Unet['q_out'+str(out_num)] += parameter['conv' + str(weight_num) + '_output_zero'] Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] > 255.0 ] = 255.0 print("max = ", np.max(Unet['q_out'+str(out_num)])) print("min = ", np.min(Unet['q_out'+str(out_num)])) Unet['ratio'+str(out_num)] = ratio Unet['q_out_floating'+str(out_num)] = parameter['conv' + str(weight_num) + '_output_scale'] * (Unet['q_out'+str(out_num)] - parameter['conv'+str(weight_num)+'_output_zero'] ) debug['out'+str(out_num)+'_quantFloating_quant'] = np.round( (floatingVar['out'+str(out_num)+'_quantFloating'] / parameter['conv' + str(weight_num) + '_output_scale']) + parameter['conv'+str(weight_num)+'_output_zero']) out_num += 1 weight_num += 1 #-------------------------------------------------------------------------------------------------------- print("\n-------- out{} --------".format(out_num)) # Conv + Relu Unet['q_out'+str(out_num)] = GEMMConv3D( (Unet['q_out'+str(out_num-1)] - parameter['conv'+str(weight_num)+'_input_zero_point'] ) , parameter['conv'+str(weight_num)+'_weight_int']) # calculate left shift bit ratio = ( parameter['conv' + str(weight_num) + '_input_scale'] * parameter['conv' + str(weight_num) + '_weight_scale'] / parameter['conv' + str(weight_num) + '_output_scale'] ) shift_bit = math.log(ratio, 2) shift_bit = abs( math.ceil(shift_bit) ) M = ratio / 2**(-shift_bit) M_fixed = round(M * 2**bit) Unet['shift_bit'+str(out_num)] = shift_bit Unet['M'+str(out_num)] = M Unet['M_fixed'+str(out_num)] = M_fixed # Relu Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] < 0.0 ] = 0.0 print('ratio = {}, shift_bit = {}'.format(ratio, shift_bit)) if use_shift_instead_of_divide == 1 : Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] // (2**(bit+Unet['shift_bit'+str(out_num)])) elif use_shift_instead_of_divide == 2 : one = np.ones(Unet['q_out'+str(out_num)].shape) tmp = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] float_int_err = ( tmp / (2**(bit+Unet['shift_bit'+str(out_num)])) ) - ( tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) ) outTmp = tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) tag = float_int_err > 0.5 Unet['q_out'+str(out_num)] = outTmp.copy() Unet['q_out'+str(out_num)][tag] = outTmp[tag] + one[tag] else: Unet['q_out'+str(out_num)] = np.round( Unet['q_out'+str(out_num)] * ratio ) Unet['q_out'+str(out_num)] += parameter['conv' + str(weight_num) + '_output_zero'] Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] > 255.0 ] = 255.0 print("max = ", np.max(Unet['q_out'+str(out_num)])) print("min = ", np.min(Unet['q_out'+str(out_num)])) Unet['ratio'+str(out_num)] = ratio Unet['q_out_floating'+str(out_num)] = parameter['conv' + str(weight_num) + '_output_scale'] * (Unet['q_out'+str(out_num)] - parameter['conv'+str(weight_num)+'_output_zero'] ) debug['out'+str(out_num)+'_quantFloating_quant'] = np.round( (floatingVar['out'+str(out_num)+'_quantFloating'] / parameter['conv' + str(weight_num) + '_output_scale']) + parameter['conv'+str(weight_num)+'_output_zero']) out_num += 1 weight_num += 1 if(times < 4): print("\n-------- out{} --------".format(out_num)) # Pooling Unet['q_out'+str(out_num)] = Maxpool_3D(Unet['q_out'+str(out_num-1)]) out_num += 1 ''' print(" ===================== check with Ans (each layer) ===================== ") checkList = [1, 2] for i in range(len(checkList)): print('---------check out{}------------'.format(checkList[i])) temp1 = Unet['q_out'+str(checkList[i])] temp2 = debug['out'+str(checkList[i])+'_quantFloating_quant'] err = temp1 - temp2 print("max err = ", np.max(err)) print("min err = ", np.min(err)) ''' print("====================================================================================================") print('------check input------') input_int = floatingVar['input_int'] my_input_int = Unet['q_out'+str(0)] err_input = input_int - my_input_int print("max err = ", np.max(err_input)) print("min err = ", np.min(err_input)) if((input_int == my_input_int).all()): print("same") else: print('different') print('------check weight1------') weight1_int = parameter['conv'+str(1)+'_weight_int'] weight1_int_fromFloat = np.round ( (floatingVar['conv1_weight'] / parameter['conv1_weight_scale'] + parameter['conv1_weight_zero'] ) ) err_weight1 = weight1_int - weight1_int_fromFloat print("max err = ", np.max(err_weight1)) print("min err = ", np.min(err_weight1)) if((weight1_int == weight1_int_fromFloat).all()): print("same") else: print('different') print("====================================================================================================") #print(out_num) #print(weight_num) # =========================================== Decoder =========================================== catNum = 11 for times in range(4): #-------------------------------------------------------------------------------------------------------- print("\n-------- out{} --------".format(out_num)) # de-Conv Unet['q_out'+str(out_num)] = De_Conv2x2((Unet['q_out'+str(out_num-1)] - parameter['conv'+str(weight_num)+'_input_zero_point'] ) , parameter['conv'+str(weight_num)+'_weight_int']) # calculate left shift bit ratio = ( parameter['conv' + str(weight_num) + '_input_scale'] * parameter['conv' + str(weight_num) + '_weight_scale'] / parameter['conv' + str(weight_num) + '_output_scale'] ) shift_bit = math.log(ratio, 2) shift_bit = abs( math.ceil(shift_bit) ) M = ratio / 2**(-shift_bit) M_fixed = round(M * 2**bit) Unet['shift_bit'+str(out_num)] = shift_bit Unet['M'+str(out_num)] = M Unet['M_fixed'+str(out_num)] = M_fixed print('ratio = {}, shift_bit = {}'.format(ratio, shift_bit)) if use_shift_instead_of_divide == 1 : Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] // (2**(bit+Unet['shift_bit'+str(out_num)])) elif use_shift_instead_of_divide == 2 : one = np.ones(Unet['q_out'+str(out_num)].shape) tmp = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] float_int_err = ( tmp / (2**(bit+Unet['shift_bit'+str(out_num)])) ) - ( tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) ) outTmp = tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) tag = float_int_err > 0.5 Unet['q_out'+str(out_num)] = outTmp.copy() Unet['q_out'+str(out_num)][tag] = outTmp[tag] + one[tag] else: Unet['q_out'+str(out_num)] = np.round( Unet['q_out'+str(out_num)] * ratio ) Unet['q_out'+str(out_num)] += parameter['conv' + str(weight_num) + '_output_zero'] Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] > 255.0 ] = 255.0 Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] < 0.0 ] = 0.0 #Unet['q_out'+str(out_num)] += abs( np.min(Unet['q_out'+str(out_num)]) ) print("max = ", np.max(Unet['q_out'+str(out_num)])) print("min = ", np.min(Unet['q_out'+str(out_num)])) Unet['ratio'+str(out_num)] = ratio Unet['q_out_floating'+str(out_num)] = parameter['conv' + str(weight_num) + '_output_scale'] * (Unet['q_out'+str(out_num)] - parameter['conv'+str(weight_num)+'_output_zero'] ) debug['out'+str(out_num)+'_quantFloating_quant'] = np.round( (floatingVar['out'+str(out_num)+'_quantFloating'] / parameter['conv' + str(weight_num) + '_output_scale']) + parameter['conv'+str(weight_num)+'_output_zero']) out_num += 1 weight_num += 1 #-------------------------------------------------------------------------------------------------------- print("\n-------- out{} --------".format(out_num)) # concatenate Unet['q_out'+str(out_num)] = np.concatenate([Unet['q_out'+str(out_num-1)], Unet['q_out'+str(catNum)]], axis=0) out_num += 1 #-------------------------------------------------------------------------------------------------------- print("\n-------- out{} --------".format(out_num)) # Conv + Relu Unet['q_out'+str(out_num)] = GEMMConv3D( (Unet['q_out'+str(out_num-1)] - parameter['conv'+str(weight_num)+'_input_zero_point'] ) , parameter['conv'+str(weight_num)+'_weight_int']) # calculate left shift bit ratio = ( parameter['conv' + str(weight_num) + '_input_scale'] * parameter['conv' + str(weight_num) + '_weight_scale'] / parameter['conv' + str(weight_num) + '_output_scale'] ) shift_bit = math.log(ratio, 2) shift_bit = abs( math.ceil(shift_bit) ) M = ratio / 2**(-shift_bit) M_fixed = round(M * 2**bit) Unet['shift_bit'+str(out_num)] = shift_bit Unet['M'+str(out_num)] = M Unet['M_fixed'+str(out_num)] = M_fixed # Relu Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] < 0.0 ] = 0.0 print('ratio = {}, shift_bit = {}'.format(ratio, shift_bit)) if use_shift_instead_of_divide == 1 : Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] // (2**(bit+Unet['shift_bit'+str(out_num)])) elif use_shift_instead_of_divide == 2 : one = np.ones(Unet['q_out'+str(out_num)].shape) tmp = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] float_int_err = ( tmp / (2**(bit+Unet['shift_bit'+str(out_num)])) ) - ( tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) ) outTmp = tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) tag = float_int_err > 0.5 Unet['q_out'+str(out_num)] = outTmp.copy() Unet['q_out'+str(out_num)][tag] = outTmp[tag] + one[tag] else: Unet['q_out'+str(out_num)] = np.round( Unet['q_out'+str(out_num)] * ratio ) Unet['q_out'+str(out_num)] += parameter['conv' + str(weight_num) + '_output_zero'] Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] > 255.0 ] = 255.0 print("max = ", np.max(Unet['q_out'+str(out_num)])) print("min = ", np.min(Unet['q_out'+str(out_num)])) Unet['ratio'+str(out_num)] = ratio Unet['q_out_floating'+str(out_num)] = parameter['conv' + str(weight_num) + '_output_scale'] * (Unet['q_out'+str(out_num)] - parameter['conv'+str(weight_num)+'_output_zero'] ) debug['out'+str(out_num)+'_quantFloating_quant'] = np.round( (floatingVar['out'+str(out_num)+'_quantFloating'] / parameter['conv' + str(weight_num) + '_output_scale']) + parameter['conv'+str(weight_num)+'_output_zero']) out_num += 1 weight_num += 1 #-------------------------------------------------------------------------------------------------------- print("\n-------- out{} --------".format(out_num)) # Conv + Relu Unet['q_out'+str(out_num)] = GEMMConv3D( (Unet['q_out'+str(out_num-1)] - parameter['conv'+str(weight_num)+'_input_zero_point'] ) , parameter['conv'+str(weight_num)+'_weight_int']) # calculate left shift bit ratio = ( parameter['conv' + str(weight_num) + '_input_scale'] * parameter['conv' + str(weight_num) + '_weight_scale'] / parameter['conv' + str(weight_num) + '_output_scale'] ) shift_bit = math.log(ratio, 2) shift_bit = abs( math.ceil(shift_bit) ) M = ratio / 2**(-shift_bit) M_fixed = round(M * 2**bit) Unet['shift_bit'+str(out_num)] = shift_bit Unet['M'+str(out_num)] = M Unet['M_fixed'+str(out_num)] = M_fixed # Relu Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] < 0.0 ] = 0.0 print('ratio = {}, shift_bit = {}'.format(ratio, shift_bit)) if use_shift_instead_of_divide == 1 : Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] // (2**(bit+Unet['shift_bit'+str(out_num)])) elif use_shift_instead_of_divide == 2 : one = np.ones(Unet['q_out'+str(out_num)].shape) tmp = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] float_int_err = ( tmp / (2**(bit+Unet['shift_bit'+str(out_num)])) ) - ( tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) ) outTmp = tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) tag = float_int_err > 0.5 Unet['q_out'+str(out_num)] = outTmp.copy() Unet['q_out'+str(out_num)][tag] = outTmp[tag] + one[tag] else: Unet['q_out'+str(out_num)] = np.round( Unet['q_out'+str(out_num)] * ratio ) Unet['q_out'+str(out_num)] += parameter['conv' + str(weight_num) + '_output_zero'] Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] > 255.0 ] = 255.0 print("max = ", np.max(Unet['q_out'+str(out_num)])) print("min = ", np.min(Unet['q_out'+str(out_num)])) Unet['ratio'+str(out_num)] = ratio Unet['q_out_floating'+str(out_num)] = parameter['conv' + str(weight_num) + '_output_scale'] * (Unet['q_out'+str(out_num)] - parameter['conv'+str(weight_num)+'_output_zero'] ) debug['out'+str(out_num)+'_quantFloating_quant'] = np.round( (floatingVar['out'+str(out_num)+'_quantFloating'] / parameter['conv' + str(weight_num) + '_output_scale']) + parameter['conv'+str(weight_num)+'_output_zero']) out_num += 1 weight_num += 1 catNum -= 3 print("\n-------- out{} --------".format(out_num)) # =========================================== Output Layer =========================================== output_channel = floatingVar['conv'+str(weight_num)+'_weight'].shape[0] input_channel = floatingVar['conv'+str(weight_num)+'_weight'].shape[1] floatingVar['conv'+str(weight_num)+'_weight'] = np.reshape(floatingVar['conv'+str(weight_num)+'_weight'], (-1, floatingVar['conv'+str(weight_num)+'_weight'].shape[1])) parameter['conv'+str(weight_num)+'_weight_int'] = np.reshape( parameter['conv'+str(weight_num)+'_weight_int'], (-1, parameter['conv'+str(weight_num)+'_weight_int'].shape[1])) Unet['q_out'+str(out_num)] = np.zeros([output_channel, Unet['q_out'+str(out_num-1)].shape[1], Unet['q_out'+str(out_num-1)].shape[2]]) outTmp = np.zeros([output_channel, Unet['q_out'+str(out_num-1)].shape[1], Unet['q_out'+str(out_num-1)].shape[2]]) Unet['q_out'+str(out_num-1)] -= parameter['conv'+str(weight_num)+'_input_zero_point'] for oc in range(output_channel): for ic in range(input_channel): for y in range(Unet['q_out'+str(out_num-1)].shape[1]): for x in range(Unet['q_out'+str(out_num-1)].shape[2]): Unet['q_out'+str(out_num)][oc, y, x] += Unet['q_out'+str(out_num-1)][ic, y, x] * parameter['conv'+str(weight_num)+'_weight_int'][0, ic] # calculate left shift bit ratio = ( parameter['conv' + str(weight_num) + '_input_scale'] * parameter['conv' + str(weight_num) + '_weight_scale'] / parameter['conv' + str(weight_num) + '_output_scale'] ) shift_bit = math.log(ratio, 2) shift_bit = abs( math.ceil(shift_bit) ) M = ratio / 2**(-shift_bit) M_fixed = round(M * 2**bit) Unet['shift_bit'+str(out_num)] = shift_bit Unet['M'+str(out_num)] = M Unet['M_fixed'+str(out_num)] = M_fixed print('ratio = {}, shift_bit = {}'.format(ratio, shift_bit)) if use_shift_instead_of_divide == 1 : Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] Unet['q_out'+str(out_num)] = Unet['q_out'+str(out_num)] // (2**(bit+Unet['shift_bit'+str(out_num)])) elif use_shift_instead_of_divide == 2 : one = np.ones(Unet['q_out'+str(out_num)].shape) tmp = Unet['q_out'+str(out_num)] * Unet['M_fixed'+str(out_num)] float_int_err = ( tmp / (2**(bit+Unet['shift_bit'+str(out_num)])) ) - ( tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) ) outTmp = tmp // (2**(bit+Unet['shift_bit'+str(out_num)])) tag = float_int_err > 0.5 Unet['q_out'+str(out_num)] = outTmp.copy() Unet['q_out'+str(out_num)][tag] = outTmp[tag] + one[tag] else: Unet['q_out'+str(out_num)] = np.round( Unet['q_out'+str(out_num)] * ratio ) Unet['q_out'+str(out_num)] += parameter['conv' + str(weight_num) + '_output_zero'] Unet['q_out'+str(out_num)] [ Unet['q_out'+str(out_num)] > 255.0 ] = 255.0 print("max = ", np.max(Unet['q_out'+str(out_num)])) print("min = ", np.min(Unet['q_out'+str(out_num)])) Unet['ratio'+str(out_num)] = ratio Unet['q_out_floating'+str(out_num)] = parameter['conv' + str(weight_num) + '_output_scale'] * (Unet['q_out'+str(out_num)] - parameter['conv'+str(weight_num)+'_output_zero'] ) debug['out'+str(out_num)+'_quantFloating_quant'] = np.round( (floatingVar['out'+str(out_num)+'_quantFloating'] / parameter['conv' + str(weight_num) + '_output_scale']) + parameter['conv'+str(weight_num)+'_output_zero']) print(" ===================== check with Ans (each layer) ===================== ") checkList = [1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 31] for i in range(len(checkList)): print('---------check out{}------------'.format(checkList[i])) temp1 = Unet['q_out'+str(checkList[i])] temp2 = debug['out'+str(checkList[i])+'_quantFloating_quant'] err = temp1 - temp2 print("max err = ", np.max(err)) print("min err = ", np.min(err)) print(" ===================== check with out31 (floating point) ===================== ") out31_floating = parameter['conv' + str(weight_num) + '_output_scale'] * ( Unet['q_out'+str(out_num)] - parameter['conv'+str(weight_num)+'_output_zero'] ) out31_floating_ans = floatingVar['out'+str(out_num)+'_quantFloating'] err = out31_floating - out31_floating_ans print("max err = ", np.max(err)) print("min err = ", np.min(err)) # =========================================== Sigmoid =========================================== myOutput = out31_floating one = np.ones([1, 224, 224]) mySigmoidOutput = one / (one + np.exp(-myOutput)) ans = floatingVar['output_np'][0] print(" ===================== check with Sigmoid output (floating point) ===================== ") err = mySigmoidOutput - ans print("max err = ", np.max(err)) print("min err = ", np.min(err)) inputImage = (input_data[0] * 255).astype("uint8") label = (floatingVar['label_np'][0, 0] * 255).astype("uint8") imageAns = (ans[0] * 255).astype("uint8") imageMy = (mySigmoidOutput[0] * 255).astype("uint8") print(" ===================== check with Ans (uint8 of image) ===================== ") err = imageAns.astype("int32") - imageMy.astype("int32") print("max err = ", np.max(err)) print("min err = ", np.min(err)) def IOU_calculate(arr1_one_tag, arr2_one_tag): intersect = np.sum(arr1_one_tag * arr2_one_tag) union = np.sum(arr1_one_tag) + np.sum(arr2_one_tag) - intersect iou = round(intersect/union, 5) return iou label_tag = label >= 250 floating_tag = imageAns >= 250 uint8_floating_tag = floatingVar['Image_output'] >= 250 uint8_tag = imageMy >= 250 print("-------------------- IOU --------------------") print("IOU of floating = ", IOU_calculate(label_tag, floating_tag)) print("IOU of uint8 floating = ", IOU_calculate(label_tag, uint8_floating_tag)) print("IOU of uint8 = ", IOU_calculate(label_tag, uint8_tag)) # =========================================== visualization =========================================== fig, axes = plt.subplots(ncols=4, figsize=(10, 3), sharex=True, sharey=True) ax = axes.ravel() ax[0].imshow(inputImage, cmap=plt.cm.gray) ax[0].set_title('input data') ax[1].imshow(label, cmap=plt.cm.gray) ax[1].set_title('label') ax[2].imshow(imageAns, cmap=plt.cm.gray) ax[2].set_title('floating Unet(IOU=' + str( IOU_calculate(label_tag, uint8_floating_tag) ) + ')') ax[3].imshow(imageMy, cmap=plt.cm.gray) ax[3].set_title('8-bit Unet(IOU=' + str( IOU_calculate(label_tag, uint8_tag) ) + ')') #fig.show() fig.tight_layout() #plt.subplots_adjust(wspace=0, hspace=0) fig.savefig('8-bit Unet result.png') ``` ```python= # -*- coding: utf-8 -*- """ Created on Mon Sep 18 21:58:04 2023 @author: leots """ import os import numpy as np import torch from CONV import GEMMConv3D from CONV import Maxpool_3D from CONV import De_Conv2x2 #====================================Read Files=========================================# current_path = os.getcwd() all_file_name = os.listdir(current_path) # it prints out all file names in this directory #print("all_file_name",all_file_name) layer = ['conv'+str(i) for i in range(1, 24)] parameter = {} floatingVar = {} quantizedOutAct = {} Load_parameter = 1 if Load_parameter == 1: parameter = np.load('parameter.npy',allow_pickle='TRUE').item() floatingVar = np.load('floatingVar.npy',allow_pickle='TRUE').item() else: for item in all_file_name: if item in layer: file_name = os.listdir(current_path+'/'+item) ''' if item == 'conv1': print(item) print(file_name) ''' for item_in in file_name: #if item == 'conv1': #print(item_in[:-4]) # excludes .npy -> clever!!! parameter[item+'_'+item_in[:-4]] = np.load(current_path+'/'+item+'/'+item_in) elif item.endswith("npy"): #print('npy:', item) floatingVar[item[:-4]] = np.load(current_path+'/'+item) #============================Load Quantized act. output=======================================# for item in all_file_name: if item == 'quantized_act_out': file_name = os.listdir(current_path+'/'+item) for in_item in file_name: #print(in_item) quantizedOutAct[in_item[:-4]] = np.load(current_path+'/'+item+'/'+in_item) # CONV1 first #///////////////////////////////Computation starts!!!//////////////////////////////////////# #convi_wight is 4D, except conv23_weigth, which is 1x1 conv #==============================Converts input_np into quantized tensor==================================# input_tensor = torch.tensor(floatingVar['input_np']) #torch.quantize_per_tensor(input, scale, zero_point, dtype) → Tensor, using .int_rep() shows integer representation input_scale = torch.tensor(parameter['conv1_input_scale']) input_zero_point = torch.tensor(parameter['conv1_input_zero_point']) quantized_input = torch.round(input_tensor/input_scale+ input_zero_point) quantized_input = torch.tensor(quantized_input, dtype=torch.uint8) quantized_input = quantized_input.numpy() #transforms tensor into np for GEMM # before calling GEMM3D the operands need to be formated into 3D array quantized_input = quantized_input.reshape(quantized_input.shape[1], quantized_input.shape[2], quantized_input.shape[3]) output = GEMMConv3D(quantized_input, parameter['conv1_weight_int']) #GEMM output = torch.tensor(output, dtype=torch.float32) # the same #print(np.max(quantized_conv1_output_np), np.min(quantized_conv1_output_np)) #max: 46355, min: 0 # verify dequantized output and the real output # Note: dequantize() seems not to be working output_scale = torch.tensor(parameter['conv1_output_scale']) output_zero_point = torch.tensor(parameter['conv1_output_zero']) weight_scale = parameter['conv1_weight_scale'] ''' output_torch = torch.quantize_per_tensor(output, output_scale, output_zero_point, torch.quint8).int_repr() # quantize the GEMM output output_torch = output_torch.numpy() ''' output_my = output*input_scale*weight_scale/output_scale+output_zero_point #output_my_round = np.round(output_my) #output_my_round = output_my_round.numpy() output_my = np.round(output_my.numpy()) output_my[output_my < 0.0] = 0.0 #ReLU #output_my_round[output_my_round < 0.0] = 0.0 # quantize the golden data to compare with my quantized output golden_output = torch.tensor(floatingVar['out1']) #golden_output = torch.quantize_per_tensor(golden_output, output_scale, output_zero_point, torch.quint8).int_repr() golden_output = torch.round(golden_output/output_scale+output_zero_point) golden_output = golden_output.numpy() # error between floating and quantized output still exists -> 0.9799 ''' ans = golden_output error = np.abs(quantizedOutAct['qout1'] - floatingVar['out1']) print('max of error = ', np.max(error)) if (np.max(error) < 1e-5): print("pass!!") else: print("failed.....") ''' ans = golden_output error = np.abs(output_my - ans) print('max of error = ', np.max(error)) print('max error index = ', np.where(error == np.max(error))) if (np.max(error) < 3): print("pass!!") else: print("failed.....") ```