def export(originpath="weights", newpath="jsonparamweights", load_name="512_512_ADAM_PRES_18", load_period=1, decode_number=-1, multiperclass=True, nms_thresh=0.45, nms_topk=200, except_class_thresh=0.01): try: _, test_dataset = testdataloader() except Exception: logging.info("The dataset does not exist") exit(0) prediction = Prediction( from_sigmoid=False, num_classes=test_dataset.num_class, decode_number=decode_number, nms_thresh=nms_thresh, nms_topk=nms_topk, except_class_thresh=except_class_thresh, multiperclass=multiperclass) origin_weight_path = os.path.join(originpath, load_name) sym_path = os.path.join(origin_weight_path, f'{load_name}-symbol.json') param_path = os.path.join(origin_weight_path, f'{load_name}-{load_period:04d}.params') temp = load_name.split("_") new_weight_path = os.path.join(newpath, load_name) if not os.path.exists(new_weight_path): os.makedirs(new_weight_path) if os.path.exists(sym_path) and os.path.exists(param_path): logging.info(f"loading {os.path.basename(param_path)} weights\n") net = gluon.SymbolBlock.imports(sym_path, ['data'], param_path) else: raise FileExistsError # prepost postnet = PostNet(net=net, auxnet=prediction) try: export_block_for_cplusplus(path=os.path.join(new_weight_path, f"{load_name}_prepost"), block=postnet, data_shape=tuple((int(temp[0]), int(temp[1]))) + tuple((3,)), epoch=load_period, preprocess=True, # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨 layout='HWC', remove_amp_cast=True) except Exception as E: logging.error(f"json, param model export 예외 발생 : {E}") else: logging.info("json, param model export 성공")
def export(input_frame_number=2, originpath="weights", newpath="jitweights", load_name="608_608_ADAM_PCENTER_RES18", load_period=1, topk=200, nms=False, except_class_thresh=0.01, nms_thresh=0.5): scale_factor = 4 # 고정 origin_weight_path = os.path.join(originpath, load_name) jit_path = os.path.join(origin_weight_path, f'{load_name}-{load_period:04d}.jit') new_weight_path = os.path.join(newpath, load_name) if not os.path.exists(new_weight_path): os.makedirs(new_weight_path) if os.path.exists(jit_path): logging.info(f"loading {os.path.basename(jit_path)}") net = torch.jit.load(jit_path) else: raise FileExistsError _, test_dataset = testdataloader() # prepost auxnet = Prediction(unique_ids=test_dataset.CLASSES, topk=topk, scale=scale_factor, nms=nms, except_class_thresh=except_class_thresh, nms_thresh=nms_thresh) prepostnet = PrePostNet( net=net, auxnet=auxnet, input_frame_number=input_frame_number) # 새로운 객체가 생성 try: script = torch.jit.script(prepostnet) script.save( os.path.join(new_weight_path, f'{load_name}-prepost-{load_period:04d}.jit')) except Exception as E: logging.error(f"jit export 예외 발생 : {E}") else: logging.info("jit export 성공")
def export(path="weights", newpath="exportweights", load_name="480_640_ADAM_PCENTER_RES18", load_period=1, target_size=(768, 768), dtype=np.float32): try: _, test_dataset = testdataloader() except Exception: logging.info("The dataset does not exist") exit(0) weight_path = os.path.join(path, load_name) if not os.path.exists(weight_path): raise FileExistsError temp = load_name.split("_") new_weight_path = os.path.join(newpath, load_name) if not os.path.exists(new_weight_path): os.makedirs(new_weight_path) newname = str(target_size[0]) + "_" + str( target_size[1]) + "_" + temp[2] + "_" + temp[3] + "_" + temp[4] sym = os.path.join(weight_path, f'{newname}_prepost-symbol.json') params = os.path.join(weight_path, f'{newname}_prepost-{load_period:04d}.params') onnx_pre_file_path = os.path.join(new_weight_path, f"{newname}_prepost.onnx") try: onnx_mxnet.export_model( sym=sym, params=params, input_shape=[tuple((1, )) + tuple(target_size) + tuple((3, ))], input_type=dtype, onnx_file_path=onnx_pre_file_path, verbose=False) except Exception as E: logging.error(f"ONNX model export 예외 발생 : {E}") else: logging.info(f"ONNX model export 성공") try: check_onnx(onnx_pre_file_path) logging.info(f"{os.path.basename(onnx_pre_file_path)} saved completed") except Exception as E: logging.error(f"ONNX model check 예외 발생 : {E}") else: logging.info("ONNX model check completed")
def run( image_list=True, # True일 때, 폴더에 있는 이미지(jpg)들 전부다 평가 / False일 때, 한장 평가 # image_path='Dataset/test/2. csm_meng_meng_baby_1_88cad0f74f.jpg', image_path='Dataset/test', weight_path="weights", load_name="480_640_ADAM_PCENTER_RES18", load_period=200, GPU_COUNT=0, topk=100, plot_class_thresh=0.5, image_save_path="result_image", image_show=False, image_save=True): if GPU_COUNT <= 0: ctx = mx.cpu(0) elif GPU_COUNT > 0: ctx = mx.gpu(0) # 운영체제 확인 if platform.system() == "Linux": logging.info(f"{platform.system()} OS") elif platform.system() == "Windows": logging.info(f"{platform.system()} OS") else: logging.info(f"{platform.system()} OS") if GPU_COUNT > 0: free_memory, total_memory = mx.context.gpu_memory_info(0) free_memory = round(free_memory / (1024 * 1024 * 1024), 2) total_memory = round(total_memory / (1024 * 1024 * 1024), 2) logging.info( f'Running on {ctx} / free memory : {free_memory}GB / total memory {total_memory}GB' ) else: logging.info(f'Running on {ctx}') logging.info(f"test {load_name}") scale_factor = 4 # 고정 logging.info(f"scale factor {scale_factor}") netheight = int(load_name.split("_")[0]) netwidth = int(load_name.split("_")[1]) if not isinstance(netheight, int) and not isinstance(netwidth, int): logging.info("height is not int") logging.info("width is not int") raise ValueError else: logging.info(f"network input size : {(netheight, netwidth)}") try: _, test_dataset = testdataloader() except Exception: logging.info("The dataset does not exist") exit(0) weight_path = os.path.join(weight_path, load_name) sym = os.path.join(weight_path, f'{load_name}-symbol.json') params = os.path.join(weight_path, f'{load_name}-{load_period:04d}.params') logging.info("symbol model test") if os.path.exists(sym) and os.path.exists(params): logging.info(f"loading {os.path.basename(params)} weights\n") net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx) else: raise FileExistsError try: net = export_block_for_cplusplus( block=net, data_shape=tuple((netheight, netwidth)) + tuple((3, )), preprocess=True, # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨 layout='HWC', ctx=ctx) except Exception as E: logging.error(f"adding preprocessing layer 실패 : {E}") else: logging.info(f"adding preprocessing layer 성공 ") net.hybridize(active=True, static_alloc=True, static_shape=True) prediction = Prediction(topk=topk, scale=scale_factor) if image_list: types = ('*.jpg', '*.png') images_path = [] for type in types: images_path.extend(glob.glob(os.path.join(image_path, type))) if images_path: for img_path in tqdm(images_path): name = os.path.splitext(os.path.basename(img_path))[0] image = cv2.imread(img_path, cv2.IMREAD_COLOR) height, width, _ = image.shape logging.info(f"real input size : {(height, width)}") origin_image = image.copy() image = cv2.resize(image, (netwidth, netheight), interpolation=3) image[:, :, (0, 1, 2)] = image[:, :, (2, 1, 0)] # BGR to RGB image = mx.nd.array(image, ctx=ctx) image = image.expand_dims(axis=0) heatmap_pred, offset_pred, wh_pred = net(image) ids, scores, bboxes = prediction(heatmap_pred, offset_pred, wh_pred) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) plot_bbox(origin_image, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes, image_show=image_show, image_save=image_save, image_save_path=image_save_path, image_name=name) else: raise FileNotFoundError else: name = os.path.splitext(os.path.basename(image_path))[0] image = cv2.imread(image_path, cv2.IMREAD_COLOR) height, width, _ = image.shape logging.info(f"real input size : {(height, width)}") origin_image = image.copy() image = cv2.resize(image, (netwidth, netheight), interpolation=3) image[:, :, (0, 1, 2)] = image[:, :, (2, 1, 0)] # BGR to RGB image = mx.nd.array(image, ctx=ctx) image = image.expand_dims(axis=0) heatmap_pred, offset_pred, wh_pred = net(image) ids, scores, bboxes = prediction(heatmap_pred, offset_pred, wh_pred) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) plot_bbox(origin_image, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes, image_show=image_show, image_save=image_save, image_save_path=image_save_path, image_name=name) cv2.destroyAllWindows()
def run(weight_path="weights", load_name="512_512_ADAM_PEFF_0", load_period=100, GPU_COUNT=0, decode_number=5000, multiperclass=True, nms_thresh=0.5, nms_topk=500, except_class_thresh=0.05, plot_class_thresh=0.5, video_name="webcam", video_save_path="result_video", video_show=True, video_save=True): if video_save: if not os.path.exists(video_save_path): os.makedirs(video_save_path) if GPU_COUNT <= 0: ctx = mx.cpu(0) elif GPU_COUNT > 0: ctx = mx.gpu(0) # 운영체제 확인 if platform.system() == "Linux": logging.info(f"{platform.system()} OS") elif platform.system() == "Windows": logging.info(f"{platform.system()} OS") else: logging.info(f"{platform.system()} OS") if GPU_COUNT > 0: free_memory, total_memory = mx.context.gpu_memory_info(0) free_memory = round(free_memory / (1024 * 1024 * 1024), 2) total_memory = round(total_memory / (1024 * 1024 * 1024), 2) logging.info( f'Running on {ctx} / free memory : {free_memory}GB / total memory {total_memory}GB' ) else: logging.info(f'Running on {ctx}') logging.info(f"test {load_name}") netheight = int(load_name.split("_")[0]) netwidth = int(load_name.split("_")[1]) if not isinstance(netheight, int) and not isinstance(netwidth, int): logging.info("height is not int") logging.info("width is not int") raise ValueError else: logging.info(f"network input size : {(netheight, netwidth)}") try: _, test_dataset = testdataloader() except Exception: logging.info("The dataset does not exist") exit(0) weight_path = os.path.join(weight_path, load_name) sym = os.path.join(weight_path, f'{load_name}-symbol.json') params = os.path.join(weight_path, f'{load_name}-{load_period:04d}.params') logging.info("symbol model test") if os.path.exists(sym) and os.path.exists(params): logging.info(f"loading {os.path.basename(params)} weights\n") net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx) else: raise FileExistsError try: net = export_block_for_cplusplus( block=net, data_shape=tuple((netheight, netwidth)) + tuple((3, )), preprocess=True, # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨 layout='HWC', ctx=ctx) except Exception as E: logging.error(f"adding preprocessing layer 실패 : {E}") else: logging.info(f"adding preprocessing layer 성공 ") net.hybridize(active=True, static_alloc=True, static_shape=True) # BoxEncoder, BoxDecoder 에서 같은 값을 가져야함 prediction = Prediction(from_sigmoid=False, num_classes=test_dataset.num_class, decode_number=decode_number, nms_thresh=nms_thresh, nms_topk=nms_topk, except_class_thresh=except_class_thresh, multiperclass=multiperclass) fourcc = cv2.VideoWriter_fourcc(*'DIVX') cap = cv2.VideoCapture(0) fps = cap.get(cv2.CAP_PROP_FPS) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) out = cv2.VideoWriter(os.path.join(video_save_path, f'{video_name}.avi'), fourcc, fps, (width, height)) logging.info(f"real input size : {(height, width)}") while True: ret, image = cap.read() if ret: origin_image = image.copy() image = cv2.resize(image, (netwidth, netheight), interpolation=3) image[:, :, (0, 1, 2)] = image[:, :, (2, 1, 0)] # BGR to RGB image = mx.nd.array(image, ctx=ctx) image = image.expand_dims(axis=0) cls_preds, box_preds, anchors = net(image) ids, scores, bboxes = prediction(cls_preds, box_preds, anchors) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) result = plot_bbox(origin_image, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes) if video_save: out.write(result) if video_show: cv2.imshow(video_name, result) cv2.waitKey(1) cap.release() out.release() cv2.destroyAllWindows()
def onnx_export(path="weights", newpath="exportweights", load_name="608_608_SGD_PDark_53", load_period=1, target_size=(768, 768), anchors={"shallow": [(10, 13), (16, 30), (33, 23)], "middle": [(30, 61), (62, 45), (59, 119)], "deep": [(116, 90), (156, 198), (373, 326)]}, dtype=np.float32): try: _, test_dataset = testdataloader() except Exception: logging.info("The dataset does not exist") exit(0) weight_path = os.path.join(path, load_name) if not os.path.exists(weight_path): raise FileExistsError params = os.path.join(weight_path, f'{load_period}.params') temp = load_name.split("_") version = int(temp[-1]) net = YoloV3output(Darknetlayer=version, anchors=anchors, num_classes=test_dataset.num_class) net.load_parameters(params, allow_missing=True, ignore_extra=True) anchoroffstnet = AnchorOffstNet(net=net, version=version, anchors=anchors, target_size=target_size) new_weight_path = os.path.join(newpath, load_name) if not os.path.exists(new_weight_path): os.makedirs(new_weight_path) newname = str(target_size[0]) + "_" + str(target_size[1]) + "_" + temp[2] + "_" + temp[3] + "_" + temp[4] sym_pre = os.path.join(new_weight_path, f'{newname}_pre-symbol.json') params_pre = os.path.join(new_weight_path, f'{newname}_pre-{load_period:04d}.params') onnx_pre_file_path = os.path.join(new_weight_path, f"{newname}_pre.onnx") export_block_for_cplusplus(path=os.path.join(new_weight_path, f"{newname}_pre"), block=anchoroffstnet, data_shape=tuple(target_size) + tuple((3,)), epoch=load_period, preprocess=True, # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨 layout='HWC', remove_amp_cast=True) try: export_block_for_cplusplus(path=os.path.join(new_weight_path, f"{newname}_pre"), block=anchoroffstnet, data_shape=tuple(target_size) + tuple((3,)), epoch=load_period, preprocess=True, # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨 layout='HWC', remove_amp_cast=True) except Exception as E: logging.error(f"json, param model export 예외 발생 : {E}") else: logging.info("json, param model export 성공") try: onnx_mxnet.export_model(sym=sym_pre, params=params_pre, input_shape=[tuple((1,)) + tuple(target_size) + tuple((3,))], input_type=dtype, onnx_file_path=onnx_pre_file_path, verbose=False) except Exception as E: logging.error(f"ONNX model export 예외 발생 : {E}") else: logging.info(f"ONNX model export 성공") try: check_onnx(onnx_pre_file_path) logging.info(f"{os.path.basename(onnx_pre_file_path)} saved completed") except Exception as E: logging.error(f"ONNX model check 예외 발생 : {E}") else: logging.info("ONNX model check completed")
def export( originpath="weights", newpath="exportweights", load_name="512_512_ADAM_PVGG16_512", load_period=1, target_size=(768, 768), box_sizes300=[21, 45, 101.25, 157.5, 213.75, 270, 326.25], box_ratios300=[[1, 2, 0.5]] + # conv4_3 [[1, 2, 0.5, 3, 1.0 / 3]] * 3 + # conv7, conv8_2, conv9_2, conv10_2 [[1, 2, 0.5]] * 2, # conv11_2, conv12_2 box_sizes512=[21, 51.2, 133.12, 215.04, 296.96, 378.88, 460.8, 542.72], box_ratios512=[[1, 2, 0.5]] + # conv4_3 [[1, 2, 0.5, 3, 1.0 / 3]] * 4 + # conv7, conv8_2, conv9_2, conv10_2 [[1, 2, 0.5]] * 2, # conv11_2, conv12_2 anchor_box_offset=(0.5, 0.5), anchor_box_clip=False, dtype=np.float32): _, test_dataset = testdataloader() weight_path = os.path.join(originpath, load_name) if not os.path.exists(weight_path): raise FileExistsError params = os.path.join(weight_path, f'{load_period}.params') temp = load_name.split("_") version = int(temp[-1]) if version == 300: box_sizes = box_sizes300 box_ratios = box_ratios300 elif version == 512: box_sizes = box_sizes512 box_ratios = box_ratios512 net = SSD_VGG16_Except_Anchor(version=int(load_name.split("_")[-1]), input_size=target_size, box_sizes=box_sizes, box_ratios=box_ratios, num_classes=test_dataset.num_class) net.load_parameters(params, allow_missing=True, ignore_extra=True) ''' vgg16을 AnchorNet에서 선언한 순간 내부의 auxiliary param으로 인식하기 때문에 반드시 initialization을 해줘야 하는데, (외부에서 선언해서 보내면 이럴 필요없고 net.export만 수정해주면 된다. defer init을 쓴 상태라서 실제 forward를 한번 해줘야 한다.(anchornet.forward(mx.nd.ones(shape=(1, 3) + target_size, ctx=ctx))) 현재는 밖에서 보내면, 순간 내부의 auxiliary param으로 인식하지는 않아서, forward를 할 필요는 없다. 어쨌든 두 방법 모두 사용하지 않는 변수가 생기기 때문에, net.export(내부 코드)의 assert name in aux_names 부분을 주석 처리 해야한다. 단 위와 같이 저장 한 경우, json, param을 불러 올 때, 아래와 같이 allow_missing=True, ignore_extra=True 인자를 gluon.SymbolBlock.imports(내부코드)를 수정해야 한다. ret.collect_params().load 함수에 allow_missing=True, ignore_extra=True 를 주면 된다 net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx, allow_missing=True, ignore_extra=True) --> 인자로 주게 만들어 놓지... < 상세 설명 > target_size에 맞는 anchor를 얻기 위해서는 아래의 AnchorNet에서 VGG16 네트워크를 또 한번 호출해야 한다. -> 이렇게 되면 새롭게 호출하는 VGG16가 새로 저장하는 json에 추가적으로 써지고, 파라미터도 저장이 되기 때문에 비효율적이다.(해결책? 아직은...) 이에 따라 또다른 문제가 생기는데(정확히 말해서 net.export에 내가 말하고자 하는 기능이 고려가 안되있다.), 현재 net.export는 할당한 파라미터들을 forward 에서 다 사용하지 않으면, AssertionError를 발생시킨다. 실제 연산에 사용되는 파라미터만 저장하려고 하기 떄문에 이러한 오류가 발생하는데, 그냥 다 저장하게 net.export의 내부 코드 한줄을 수정하면 된다. 이렇게 저장한 json, param을 불러 올때는 아래와 같이 불러와야 하는데, allow_missing=True, ignore_extra=True 는 본인이 직접 추가한 것이다.(gluon.SymbolBlock.imports 에는 allow_missing, ignore_extra 인자가 고려 되어 있지 않다.) gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx, allow_missing=True, ignore_extra=True) 아래와 같이 gluon.SymbolBlock.imports을 수정하면 된다. def imports(symbol_file, input_names, param_file=None, ctx=None, allow_missing=True, ignore_extra=True): sym = symbol.load(symbol_file) if isinstance(input_names, str): input_names = [input_names] if param_file is None: # Get a valid type inference by using fp32 inputs = [symbol.var(i, dtype=mx_real_t) for i in input_names] else: # Do not specify type, rely on saved params type instead inputs = [symbol.var(i) for i in input_names] ret = SymbolBlock(sym, inputs) if param_file is not None: # allow_missing=True, ignore_extra=True 추가 함. ret.collect_params().load(param_file, ctx=ctx, cast_dtype=True, dtype_source='saved', allow_missing=allow_missing, ignore_extra=ignore_extra) return ret 따라서 안쓰는 파라미터를 저장하지 않으면 net.export 내부를 수정해야 한다.(아래 설명) ''' anchornet = AnchorNet(net=net, version=version, box_sizes300=box_sizes300, box_ratios300=box_ratios300, box_sizes512=box_sizes512, box_ratios512=box_ratios512, anchor_box_clip=anchor_box_clip, anchor_box_offset=anchor_box_offset, target_size=target_size) new_weight_path = os.path.join(newpath, load_name) if not os.path.exists(new_weight_path): os.makedirs(new_weight_path) newname = str(target_size[0]) + "_" + str( target_size[1]) + "_" + temp[2] + "_" + temp[3] + "_" + temp[4] sym_pre = os.path.join(new_weight_path, f'{newname}_pre-symbol.json') params_pre = os.path.join(new_weight_path, f'{newname}_pre-{load_period:04d}.params') onnx_pre_file_path = os.path.join(new_weight_path, f"{newname}_pre.onnx") try: ''' def export(self, path, epoch=0, remove_amp_cast=True): """Export HybridBlock to json format that can be loaded by `SymbolBlock.imports`, `mxnet.mod.Module` or the C++ interface. .. note:: When there are only one input, it will have name `data`. When there Are more than one inputs, they will be named as `data0`, `data1`, etc. Parameters ---------- path : str Path to save model. Two files `path-symbol.json` and `path-xxxx.params` will be created, where xxxx is the 4 digits epoch number. epoch : int Epoch number of saved model. """ if not self._cached_graph: raise RuntimeError( "Please first call block.hybridize() and then run forward with " "this block at least once before calling export.") sym = self._cached_graph[1] sym.save('%s-symbol.json'%path, remove_amp_cast=remove_amp_cast) arg_names = set(sym.list_arguments()) aux_names = set(sym.list_auxiliary_states()) arg_dict = {} for name, param in self.collect_params().items(): if name in arg_names: arg_dict['arg:%s'%name] = param._reduce() else: #assert name in aux_names # 여기 주석 처리 해야함 arg_dict['aux:%s'%name] = param._reduce() ndarray.save('%s-%04d.params'%(path, epoch), arg_dict) ''' export_block_for_cplusplus( path=os.path.join(new_weight_path, f"{newname}_pre"), block=anchornet, data_shape=tuple(target_size) + tuple((3, )), epoch=load_period, preprocess=True, # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨 layout='HWC', remove_amp_cast=True) except Exception as E: logging.error(f"json, param model export 예외 발생 : {E}") else: logging.info("json, param model export 성공") try: onnx_mxnet.export_model( sym=sym_pre, params=params_pre, input_shape=[tuple((1, )) + tuple(target_size) + tuple((3, ))], input_type=dtype, onnx_file_path=onnx_pre_file_path, verbose=False) except Exception as E: logging.error(f"ONNX model export 예외 발생 : {E}") else: logging.info(f"ONNX model export 성공") try: check_onnx(onnx_pre_file_path) logging.info(f"{os.path.basename(onnx_pre_file_path)} saved completed") except Exception as E: logging.error(f"ONNX model check 예외 발생 : {E}") else: logging.info("ONNX model check completed")
def run(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], load_name="512_512_ADAM_PEFF_0", load_period=10, GPU_COUNT=0, test_weight_path="weights", test_dataset_path="Dataset/test", test_save_path="result", test_graph_path="test_Graph", foreground_iou_thresh=0.5, background_iou_thresh=0.4, num_workers=4, show_flag=True, save_flag=True, decode_number=5000, multiperclass=True, nms_thresh=0.5, nms_topk=500, except_class_thresh=0.05, plot_class_thresh=0.5): if GPU_COUNT <= 0: ctx = mx.cpu(0) elif GPU_COUNT > 0: ctx = mx.gpu(0) # 운영체제 확인 if platform.system() == "Linux": logging.info(f"{platform.system()} OS") elif platform.system() == "Windows": logging.info(f"{platform.system()} OS") else: logging.info(f"{platform.system()} OS") if GPU_COUNT > 0: free_memory, total_memory = mx.context.gpu_memory_info(0) free_memory = round(free_memory / (1024 * 1024 * 1024), 2) total_memory = round(total_memory / (1024 * 1024 * 1024), 2) logging.info( f'Running on {ctx} / free memory : {free_memory}GB / total memory {total_memory}GB' ) else: logging.info(f'Running on {ctx}') logging.info(f"test {load_name}") netheight = int(load_name.split("_")[0]) netwidth = int(load_name.split("_")[1]) if not isinstance(netheight, int) and not isinstance(netwidth, int): logging.info("height is not int") logging.info("width is not int") raise ValueError else: logging.info(f"network input size : {(netheight, netwidth)}") try: test_dataloader, test_dataset = testdataloader(path=test_dataset_path, input_size=(netheight, netwidth), num_workers=num_workers, mean=mean, std=std) except Exception: logging.info("The dataset does not exist") exit(0) weight_path = os.path.join(test_weight_path, load_name) sym = os.path.join(weight_path, f'{load_name}-symbol.json') params = os.path.join(weight_path, f'{load_name}-{load_period:04d}.params') test_update_number_per_epoch = len(test_dataloader) if test_update_number_per_epoch < 1: logging.warning(" test batch size가 데이터 수보다 큼 ") exit(0) num_classes = test_dataset.num_class # 클래스 수 name_classes = test_dataset.classes logging.info("symbol model test") try: net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx) except Exception: # DEBUG, INFO, WARNING, ERROR, CRITICAL 의 5가지 등급 logging.info("loading symbol weights 실패") exit(0) else: logging.info("loading symbol weights 성공") net.hybridize(active=True, static_alloc=True, static_shape=True) confidence_loss = FocalLoss( alpha=0.25, # 논문에서 가장 좋다고 한 숫자 gamma=1.5, # 논문에서 가장 좋다고 한 숫자 sparse_label=True, from_sigmoid=False, batch_axis=None, num_class=num_classes, reduction="sum", exclude=False) localization_loss = HuberLoss(rho=1, batch_axis=None, reduction="sum", exclude=False) targetgenerator = TargetGenerator( foreground_iou_thresh=foreground_iou_thresh, background_iou_thresh=background_iou_thresh) prediction = Prediction(from_sigmoid=False, num_classes=num_classes, decode_number=decode_number, nms_thresh=nms_thresh, nms_topk=nms_topk, except_class_thresh=except_class_thresh, multiperclass=multiperclass) precision_recall = Voc_2007_AP(iou_thresh=0.5, class_names=name_classes) ground_truth_colors = {} for i in range(num_classes): ground_truth_colors[i] = (0, 0, 1) conf_loss_sum = 0 loc_loss_sum = 0 for image, label, name, origin_image, origin_box in tqdm(test_dataloader): _, height, width, _ = origin_image.shape logging.info(f"real input size : {(height, width)}") origin_image = origin_image.asnumpy()[0] origin_box = origin_box.asnumpy()[0] image = image.as_in_context(ctx) label = label.as_in_context(ctx) gt_boxes = label[:, :, :4] gt_ids = label[:, :, 4:5] cls_preds, box_preds, anchors = net(image) ids, scores, bboxes = prediction(cls_preds, box_preds, anchors) precision_recall.update(pred_bboxes=bboxes, pred_labels=ids, pred_scores=scores, gt_boxes=gt_boxes, gt_labels=gt_ids) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) ground_truth = plot_bbox(origin_image, origin_box[:, :4], scores=None, labels=origin_box[:, 4:5], thresh=None, reverse_rgb=True, class_names=test_dataset.classes, absolute_coordinates=True, colors=ground_truth_colors) plot_bbox(ground_truth, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes, absolute_coordinates=True, image_show=show_flag, image_save=save_flag, image_save_path=test_save_path, image_name=name[0]) cls_targets, box_targets = targetgenerator(anchors, gt_boxes, gt_ids) except_ignore_samples = cls_targets > -1 positive_samples = cls_targets > 0 positive_numbers = positive_samples.sum() conf_loss = confidence_loss(cls_preds, cls_targets, except_ignore_samples.expand_dims(axis=-1)) conf_loss = mx.nd.divide(conf_loss, positive_numbers + 1) conf_loss_sum += conf_loss.asscalar() loc_loss = localization_loss(box_preds, box_targets, positive_samples.expand_dims(axis=-1)) loc_loss_sum += loc_loss.asscalar() # epoch 당 평균 loss test_conf_loss_mean = np.divide(conf_loss_sum, test_update_number_per_epoch) test_loc_loss_mean = np.divide(loc_loss_sum, test_update_number_per_epoch) test_total_loss_mean = test_conf_loss_mean + test_loc_loss_mean logging.info( f"test confidence loss : {test_conf_loss_mean} / test localization loss : {test_loc_loss_mean} / test total loss : {test_total_loss_mean}" ) AP_appender = [] round_position = 2 class_name, precision, recall, true_positive, false_positive, threshold = precision_recall.get_PR_list( ) for j, c, p, r in zip(range(len(recall)), class_name, precision, recall): name, AP = precision_recall.get_AP(c, p, r) logging.info( f"class {j}'s {name} AP : {round(AP * 100, round_position)}%") AP_appender.append(AP) mAP_result = np.mean(AP_appender) logging.info(f"mAP : {round(mAP_result * 100, round_position)}%") precision_recall.get_PR_curve(name=class_name, precision=precision, recall=recall, threshold=threshold, AP=AP_appender, mAP=mAP_result, folder_name=test_graph_path)
def run(image_list=False, image_path="", weight_path="weights", load_name="512_512_ADAM_PRES_18", load_period=10, GPU_COUNT=1, decode_number=5000, multiperclass=True, nms_thresh=0.5, nms_topk=500, except_class_thresh=0.05, plot_class_thresh=0.5, image_save_path="result_image", image_show=True, image_save=True): if GPU_COUNT <= 0: ctx = mx.cpu(0) elif GPU_COUNT > 0: ctx = mx.gpu(0) # 운영체제 확인 if platform.system() == "Linux": logging.info(f"{platform.system()} OS") elif platform.system() == "Windows": logging.info(f"{platform.system()} OS") else: logging.info(f"{platform.system()} OS") if GPU_COUNT > 0: free_memory, total_memory = mx.context.gpu_memory_info(0) free_memory = round(free_memory / (1024 * 1024 * 1024), 2) total_memory = round(total_memory / (1024 * 1024 * 1024), 2) logging.info( f'Running on {ctx} / free memory : {free_memory}GB / total memory {total_memory}GB' ) else: logging.info(f'Running on {ctx}') logging.info(f"test {load_name}") netheight = int(load_name.split("_")[0]) netwidth = int(load_name.split("_")[1]) if not isinstance(netheight, int) and not isinstance(netwidth, int): logging.info("height is not int") logging.info("width is not int") raise ValueError else: logging.info(f"network input size : {(netheight, netwidth)}") try: _, test_dataset = testdataloader() except Exception: logging.info("The dataset does not exist") exit(0) weight_path = os.path.join(weight_path, load_name) sym = os.path.join(weight_path, f'{load_name}-symbol.json') params = os.path.join(weight_path, f'{load_name}-{load_period:04d}.params') logging.info("symbol model test") if os.path.exists(sym) and os.path.exists(params): logging.info(f"loading {os.path.basename(params)} weights\n") net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx) else: raise FileExistsError try: net = export_block_for_cplusplus( block=net, data_shape=tuple((netheight, netwidth)) + tuple((3, )), preprocess=True, # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨 layout='HWC', ctx=ctx) except Exception as E: logging.error(f"adding preprocessing layer 실패 : {E}") else: logging.info(f"adding preprocessing layer 성공 ") net.hybridize(active=True, static_alloc=True, static_shape=True) # BoxEncoder, BoxDecoder 에서 같은 값을 가져야함 prediction = Prediction(from_sigmoid=False, num_classes=test_dataset.num_class, decode_number=decode_number, nms_thresh=nms_thresh, nms_topk=nms_topk, except_class_thresh=except_class_thresh, multiperclass=multiperclass) if image_list: types = ('*.jpg', '*.png') images_path = [] for type in types: images_path.extend(glob.glob(os.path.join(image_path, type))) if images_path: for img_path in tqdm(images_path): name = os.path.splitext(os.path.basename(img_path))[0] image = cv2.imread(img_path, cv2.IMREAD_COLOR) height, width, _ = image.shape logging.info(f"real input size : {(height, width)}") origin_image = image.copy() image = cv2.resize(image, (netwidth, netheight), interpolation=3) image[:, :, (0, 1, 2)] = image[:, :, (2, 1, 0)] # BGR to RGB image = mx.nd.array(image, ctx=ctx) image = image.expand_dims(axis=0) cls_preds, box_preds, anchors = net(image) ids, scores, bboxes = prediction(cls_preds, box_preds, anchors) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) plot_bbox(origin_image, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes, image_show=image_show, image_save=image_save, image_save_path=image_save_path, image_name=name) else: raise FileNotFoundError else: name = os.path.splitext(os.path.basename(image_path))[0] image = cv2.imread(image_path, cv2.IMREAD_COLOR) height, width, _ = image.shape logging.info(f"real input size : {(height, width)}") origin_image = image.copy() image = cv2.resize(image, (netwidth, netheight), interpolation=3) image[:, :, (0, 1, 2)] = image[:, :, (2, 1, 0)] # BGR to RGB image = mx.nd.array(image, ctx=ctx) image = image.expand_dims(axis=0) cls_preds, box_preds, anchors = net(image) ids, scores, bboxes = prediction(cls_preds, box_preds, anchors) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) plot_bbox(origin_image, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes, image_show=image_show, image_save=image_save, image_save_path=image_save_path, image_name=name) cv2.destroyAllWindows()
def run(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], load_name="608_608_ADAM_PDark_53", load_period=10, GPU_COUNT=0, test_weight_path="weights", test_dataset_path="Dataset/test", test_save_path="result", test_graph_path="test_Graph", num_workers=4, show_flag=True, save_flag=True, ignore_threshold=0.5, dynamic=False, multiperclass=True, nms_thresh=0.5, nms_topk=500, iou_thresh=0.5, except_class_thresh=0.05, plot_class_thresh=0.5): if GPU_COUNT <= 0: ctx = mx.cpu(0) elif GPU_COUNT > 0: ctx = mx.gpu(0) # 운영체제 확인 if platform.system() == "Linux": logging.info(f"{platform.system()} OS") elif platform.system() == "Windows": logging.info(f"{platform.system()} OS") else: logging.info(f"{platform.system()} OS") if GPU_COUNT > 0: free_memory, total_memory = mx.context.gpu_memory_info(0) free_memory = round(free_memory / (1024 * 1024 * 1024), 2) total_memory = round(total_memory / (1024 * 1024 * 1024), 2) logging.info( f'Running on {ctx} / free memory : {free_memory}GB / total memory {total_memory}GB' ) else: logging.info(f'Running on {ctx}') logging.info(f"test {load_name}") netheight = int(load_name.split("_")[0]) netwidth = int(load_name.split("_")[1]) if not isinstance(netheight, int) and not isinstance(netwidth, int): logging.info("height is not int") logging.info("width is not int") raise ValueError else: logging.info(f"network input size : {(netheight, netwidth)}") try: test_dataloader, test_dataset = testdataloader(path=test_dataset_path, input_size=(netheight, netwidth), num_workers=num_workers, mean=mean, std=std) except Exception: logging.info("The dataset does not exist") exit(0) weight_path = os.path.join(test_weight_path, load_name) sym = os.path.join(weight_path, f'{load_name}-symbol.json') params = os.path.join(weight_path, f'{load_name}-{load_period:04d}.params') test_update_number_per_epoch = len(test_dataloader) if test_update_number_per_epoch < 1: logging.warning(" test batch size가 데이터 수보다 큼 ") exit(0) num_classes = test_dataset.num_class # 클래스 수 name_classes = test_dataset.classes logging.info("symbol model test") try: net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx) except Exception: # DEBUG, INFO, WARNING, ERROR, CRITICAL 의 5가지 등급 logging.info("loading symbol weights 실패") exit(0) else: logging.info("loading symbol weights 성공") net.hybridize(active=True, static_alloc=True, static_shape=True) targetgenerator = TargetGenerator(ignore_threshold=ignore_threshold, dynamic=dynamic, from_sigmoid=False) loss = Yolov3Loss(sparse_label=True, from_sigmoid=False, batch_axis=None, num_classes=num_classes, reduction="sum", exclude=False) prediction = Prediction(from_sigmoid=False, num_classes=num_classes, nms_thresh=nms_thresh, nms_topk=nms_topk, except_class_thresh=except_class_thresh, multiperclass=multiperclass) precision_recall = Voc_2007_AP(iou_thresh=iou_thresh, class_names=name_classes) ground_truth_colors = {} for i in range(num_classes): ground_truth_colors[i] = (0, 0, 1) object_loss_sum = 0 xcyc_loss_sum = 0 wh_loss_sum = 0 class_loss_sum = 0 for image, label, name, origin_image, origin_box in tqdm(test_dataloader): _, height, width, _ = origin_image.shape logging.info(f"real input size : {(height, width)}") origin_image = origin_image.asnumpy()[0] origin_box = origin_box.asnumpy()[0] image = image.as_in_context(ctx) label = label.as_in_context(ctx) gt_boxes = label[:, :, :4] gt_ids = label[:, :, 4:5] output1, output2, output3, \ anchor1, anchor2, anchor3, \ offset1, offset2, offset3, \ stride1, stride2, stride3 = net(image) ids, scores, bboxes = prediction(output1, output2, output3, anchor1, anchor2, anchor3, offset1, offset2, offset3, stride1, stride2, stride3) precision_recall.update(pred_bboxes=bboxes, pred_labels=ids, pred_scores=scores, gt_boxes=gt_boxes, gt_labels=gt_ids) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) ground_truth = plot_bbox(origin_image, origin_box[:, :4], scores=None, labels=origin_box[:, 4:5], thresh=None, reverse_rgb=True, class_names=test_dataset.classes, absolute_coordinates=True, colors=ground_truth_colors) plot_bbox(ground_truth, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes, absolute_coordinates=True, image_show=show_flag, image_save=save_flag, image_save_path=test_save_path, image_name=name[0]) xcyc_target, wh_target, objectness, class_target, weights = targetgenerator( [output1, output2, output3], [anchor1, anchor2, anchor3], gt_boxes, gt_ids, (netheight, netwidth)) xcyc_loss, wh_loss, object_loss, class_loss = loss( output1, output2, output3, xcyc_target, wh_target, objectness, class_target, weights) xcyc_loss_sum += xcyc_loss.asscalar() wh_loss_sum += wh_loss.asscalar() object_loss_sum += object_loss.asscalar() class_loss_sum += class_loss.asscalar() train_xcyc_loss_mean = np.divide(xcyc_loss_sum, test_update_number_per_epoch) train_wh_loss_mean = np.divide(wh_loss_sum, test_update_number_per_epoch) train_object_loss_mean = np.divide(object_loss_sum, test_update_number_per_epoch) train_class_loss_mean = np.divide(class_loss_sum, test_update_number_per_epoch) train_total_loss_mean = train_xcyc_loss_mean + train_wh_loss_mean + train_object_loss_mean + train_class_loss_mean logging.info(f"train xcyc loss : {train_xcyc_loss_mean} / " f"train wh loss : {train_wh_loss_mean} / " f"train object loss : {train_object_loss_mean} / " f"train class loss : {train_class_loss_mean} / " f"train total loss : {train_total_loss_mean}") AP_appender = [] round_position = 2 class_name, precision, recall, true_positive, false_positive, threshold = precision_recall.get_PR_list( ) for j, c, p, r in zip(range(len(recall)), class_name, precision, recall): name, AP = precision_recall.get_AP(c, p, r) logging.info( f"class {j}'s {name} AP : {round(AP * 100, round_position)}%") AP_appender.append(AP) mAP_result = np.mean(AP_appender) logging.info(f"mAP : {round(mAP_result * 100, round_position)}%") precision_recall.get_PR_curve(name=class_name, precision=precision, recall=recall, threshold=threshold, AP=AP_appender, mAP=mAP_result, folder_name=test_graph_path)
def run( video_list=True, # True일 때, 폴더에 있는 비디오(mp4)들 전부다 평가 / False일 때, 비디오 한개 평가 # video_path='test_video/C050105_001.mp4', video_path='test_video', weight_path="weights", load_name="480_640_ADAM_PCENTER_RES18", load_period=100, topk=500, nms=False, except_class_thresh=0.01, nms_thresh=0.5, plot_class_thresh=0.5, video_save_path="result_video", video_show=True, video_save=True): if video_save: if not os.path.exists(video_save_path): os.makedirs(video_save_path) if mx.context.num_gpus() > 0: GPU_COUNT = mx.context.num_gpus() else: GPU_COUNT = 0 if GPU_COUNT <= 0: ctx = mx.cpu(0) elif GPU_COUNT > 0: ctx = mx.gpu(0) # 운영체제 확인 if platform.system() == "Linux": logging.info(f"{platform.system()} OS") elif platform.system() == "Windows": logging.info(f"{platform.system()} OS") else: logging.info(f"{platform.system()} OS") if GPU_COUNT > 0: free_memory, total_memory = mx.context.gpu_memory_info(0) free_memory = round(free_memory / (1024 * 1024 * 1024), 2) total_memory = round(total_memory / (1024 * 1024 * 1024), 2) logging.info( f'Running on {ctx} / free memory : {free_memory}GB / total memory {total_memory}GB' ) else: logging.info(f'Running on {ctx}') logging.info(f"test {load_name}") scale_factor = 4 # 고정 logging.info(f"scale factor {scale_factor}") netheight = int(load_name.split("_")[0]) netwidth = int(load_name.split("_")[1]) if not isinstance(netheight, int) and not isinstance(netwidth, int): logging.info("height is not int") logging.info("width is not int") raise ValueError else: logging.info(f"network input size : {(netheight, netwidth)}") _, test_dataset = testdataloader() weight_path = os.path.join(weight_path, load_name) sym = os.path.join(weight_path, f'{load_name}-symbol.json') params = os.path.join(weight_path, f'{load_name}-{load_period:04d}.params') logging.info("symbol model test") if os.path.exists(sym) and os.path.exists(params): logging.info(f"loading {os.path.basename(params)} weights\n") net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx) else: raise FileExistsError try: net = export_block_for_cplusplus( block=net, data_shape=tuple((netheight, netwidth)) + tuple((3, )), preprocess=True, # c++ 에서 inference시 opencv에서 읽은 이미지 그대로 넣으면 됨 layout='HWC', ctx=ctx) except Exception as E: logging.error(f"adding preprocessing layer 실패 : {E}") else: logging.info(f"adding preprocessing layer 성공 ") net.hybridize(active=True, static_alloc=True, static_shape=True) prediction = Prediction(topk=topk, scale=scale_factor, nms=nms, except_class_thresh=except_class_thresh, nms_thresh=nms_thresh) fourcc = cv2.VideoWriter_fourcc(*'DIVX') if video_list: types = ('*.mp4', '*.avi') videos_path = [] for type in types: videos_path.extend(glob.glob(os.path.join(video_path, type))) if videos_path: for v_path in tqdm(videos_path): cap = cv2.VideoCapture(v_path) nframe = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) fps = cap.get(cv2.CAP_PROP_FPS) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) name = os.path.splitext(os.path.basename(v_path))[0] out = cv2.VideoWriter( os.path.join(video_save_path, f'{name}.avi'), fourcc, fps, (width, height)) logging.info(f"real input size : {(height, width)}") # while(cap.isOpened()): for _ in tqdm(range(0, nframe)): ret, image = cap.read() if ret: origin_image = image.copy() image = cv2.resize(image, (netwidth, netheight), interpolation=3) image[:, :, (0, 1, 2)] = image[:, :, (2, 1, 0)] # BGR to RGB image = mx.nd.array(image, ctx=ctx) image = image.expand_dims(axis=0) heatmap_pred, offset_pred, wh_pred = net(image) ids, scores, bboxes = prediction( heatmap_pred, offset_pred, wh_pred) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) result = plot_bbox(origin_image, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes) if video_save: out.write(result) if video_show: cv2.imshow(name, result) cv2.waitKey(1) cap.release() out.release() cv2.destroyAllWindows() else: raise FileNotFoundError else: cap = cv2.VideoCapture(video_path) nframe = int(cap.get(cv2.CAP_PROP_FRAME_COUNT)) fps = cap.get(cv2.CAP_PROP_FPS) height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) name = os.path.splitext(os.path.basename(video_path))[0] out = cv2.VideoWriter(os.path.join(video_save_path, f'{name}.avi'), fourcc, fps, (width, height)) logging.info(f"real input size : {(height, width)}") # while(cap.isOpened()): for _ in tqdm(range(0, nframe)): ret, image = cap.read() if ret: origin_image = image.copy() image = cv2.resize(image, (netwidth, netheight), interpolation=3) image[:, :, (0, 1, 2)] = image[:, :, (2, 1, 0)] # BGR to RGB image = mx.nd.array(image, ctx=ctx) image = image.expand_dims(axis=0) heatmap_pred, offset_pred, wh_pred = net(image) ids, scores, bboxes = prediction(heatmap_pred, offset_pred, wh_pred) bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) result = plot_bbox(origin_image, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes) if video_save: out.write(result) if video_show: cv2.imshow(name, result) cv2.waitKey(1) cap.release() out.release() cv2.destroyAllWindows()
def run(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225], load_name="480_640_ADAM_PCENTER_RES18", load_period=10, GPU_COUNT=0, test_weight_path="weights", test_dataset_path="Dataset/test", test_save_path="result", test_graph_path="test_Graph", test_html_auto_open=False, lambda_off=1, lambda_size=0.1, num_workers=4, show_flag=True, save_flag=True, topk=100, iou_thresh=0.5, nms=False, except_class_thresh=0.01, nms_thresh=0.5, plot_class_thresh=0.5): if GPU_COUNT <= 0: ctx = mx.cpu(0) elif GPU_COUNT > 0: ctx = mx.gpu(0) # 운영체제 확인 if platform.system() == "Linux": logging.info(f"{platform.system()} OS") elif platform.system() == "Windows": logging.info(f"{platform.system()} OS") else: logging.info(f"{platform.system()} OS") if GPU_COUNT > 0: free_memory, total_memory = mx.context.gpu_memory_info(0) free_memory = round(free_memory / (1024 * 1024 * 1024), 2) total_memory = round(total_memory / (1024 * 1024 * 1024), 2) logging.info( f'Running on {ctx} / free memory : {free_memory}GB / total memory {total_memory}GB' ) else: logging.info(f'Running on {ctx}') logging.info(f"test {load_name}") scale_factor = 4 # 고정 logging.info(f"scale factor {scale_factor}") netheight = int(load_name.split("_")[0]) netwidth = int(load_name.split("_")[1]) if not isinstance(netheight, int) and not isinstance(netwidth, int): logging.info("height is not int") logging.info("width is not int") raise ValueError else: logging.info(f"network input size : {(netheight, netwidth)}") try: test_dataloader, test_dataset = testdataloader( path=test_dataset_path, input_size=(netheight, netwidth), num_workers=num_workers, mean=mean, std=std, scale_factor=scale_factor) except Exception: logging.info("The dataset does not exist") exit(0) weight_path = os.path.join(test_weight_path, load_name) sym = os.path.join(weight_path, f'{load_name}-symbol.json') params = os.path.join(weight_path, f'{load_name}-{load_period:04d}.params') test_update_number_per_epoch = len(test_dataloader) if test_update_number_per_epoch < 1: logging.warning(" test batch size가 데이터 수보다 큼 ") exit(0) num_classes = test_dataset.num_class # 클래스 수 name_classes = test_dataset.classes logging.info("symbol model test") try: net = gluon.SymbolBlock.imports(sym, ['data'], params, ctx=ctx) except Exception: # DEBUG, INFO, WARNING, ERROR, CRITICAL 의 5가지 등급 logging.info("loading symbol weights 실패") exit(0) else: logging.info("loading symbol weights 성공") net.hybridize(active=True, static_alloc=True, static_shape=True) heatmapfocalloss = HeatmapFocalLoss(from_sigmoid=True, alpha=2, beta=4) normedl1loss = NormedL1Loss() targetgenerator = TargetGenerator(num_classes=num_classes) prediction = Prediction(topk=topk, scale=scale_factor, nms=nms, except_class_thresh=except_class_thresh, nms_thresh=nms_thresh) precision_recall = Voc_2007_AP(iou_thresh=iou_thresh, class_names=name_classes) ground_truth_colors = {} for i in range(num_classes): ground_truth_colors[i] = (0, 0, 1) heatmap_loss_sum = 0 offset_loss_sum = 0 wh_loss_sum = 0 for image, label, name, origin_image, origin_box in tqdm(test_dataloader): _, height, width, _ = origin_image.shape logging.info(f"real input size : {(height, width)}") origin_image = origin_image.asnumpy()[0] origin_box = origin_box.asnumpy()[0] image = image.as_in_context(ctx) label = label.as_in_context(ctx) gt_boxes = label[:, :, :4] gt_ids = label[:, :, 4:5] heatmap_pred, offset_pred, wh_pred = net(image) ids, scores, bboxes = prediction(heatmap_pred, offset_pred, wh_pred) precision_recall.update(pred_bboxes=bboxes, pred_labels=ids, pred_scores=scores, gt_boxes=gt_boxes * scale_factor, gt_labels=gt_ids) heatmap = mx.nd.multiply(heatmap_pred[0], 255.0) # 0 ~ 255 범위로 바꾸기 heatmap = mx.nd.max(heatmap, axis=0, keepdims=True) # channel 축으로 가장 큰것 뽑기 heatmap = mx.nd.transpose(heatmap, axes=(1, 2, 0)) # (height, width, channel=1) heatmap = mx.nd.repeat(heatmap, repeats=3, axis=-1) # (height, width, channel=3) heatmap = heatmap.asnumpy() # mxnet.ndarray -> numpy.ndarray heatmap = cv2.resize(heatmap, dsize=(width, height)) # 사이즈 원복 heatmap = heatmap.astype("uint8") heatmap = cv2.applyColorMap(heatmap, cv2.COLORMAP_JET) # heatmap, image add하기 bbox = box_resize(bboxes[0], (netwidth, netheight), (width, height)) ground_truth = plot_bbox(origin_image, origin_box[:, :4], scores=None, labels=origin_box[:, 4:5], thresh=None, reverse_rgb=True, class_names=test_dataset.classes, absolute_coordinates=True, colors=ground_truth_colors) plot_bbox(ground_truth, bbox, scores=scores[0], labels=ids[0], thresh=plot_class_thresh, reverse_rgb=False, class_names=test_dataset.classes, absolute_coordinates=True, image_show=show_flag, image_save=save_flag, image_save_path=test_save_path, image_name=name[0], heatmap=heatmap) heatmap_target, offset_target, wh_target, mask_target = targetgenerator( gt_boxes, gt_ids, netwidth // scale_factor, netheight // scale_factor, image.context) heatmap_loss = heatmapfocalloss(heatmap_pred, heatmap_target) offset_loss = normedl1loss(offset_pred, offset_target, mask_target) * lambda_off wh_loss = normedl1loss(wh_pred, wh_target, mask_target) * lambda_size heatmap_loss_sum += heatmap_loss.asscalar() offset_loss_sum += offset_loss.asscalar() wh_loss_sum += wh_loss.asscalar() # epoch 당 평균 loss test_heatmap_loss_mean = np.divide(heatmap_loss_sum, test_update_number_per_epoch) test_offset_loss_mean = np.divide(offset_loss_sum, test_update_number_per_epoch) test_wh_loss_mean = np.divide(wh_loss_sum, test_update_number_per_epoch) test_total_loss_mean = test_heatmap_loss_mean + test_offset_loss_mean + test_wh_loss_mean logging.info( f"test heatmap loss : {test_heatmap_loss_mean} / test offset loss : {test_offset_loss_mean} / test wh loss : {test_wh_loss_mean} / test total loss : {test_total_loss_mean}" ) AP_appender = [] round_position = 2 class_name, precision, recall, true_positive, false_positive, threshold = precision_recall.get_PR_list( ) for j, c, p, r in zip(range(len(recall)), class_name, precision, recall): name, AP = precision_recall.get_AP(c, p, r) logging.info( f"class {j}'s {name} AP : {round(AP * 100, round_position)}%") AP_appender.append(AP) AP_appender = np.nan_to_num(AP_appender) mAP_result = np.mean(AP_appender) logging.info(f"mAP : {round(mAP_result * 100, round_position)}%") precision_recall.get_PR_curve(name=class_name, precision=precision, recall=recall, threshold=threshold, AP=AP_appender, mAP=mAP_result, folder_name=test_graph_path, epoch=load_period, auto_open=test_html_auto_open)