| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922 |
- # copytrue (c) 2020 PaddlePaddle Authors. All Rights Reserve.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import os.path as osp
- import os
- import numpy as np
- from PIL import Image
- import sys
- import cv2
- import psutil
- import shutil
- import pickle
- import base64
- import multiprocessing as mp
- from ..utils import (pkill, set_folder_status, get_folder_status, TaskStatus,
- PredictStatus, PruneStatus)
- from .evaluate.draw_pred_result import visualize_classified_result, visualize_detected_result, visualize_segmented_result
- from .visualize import plot_det_label, plot_insseg_label, get_color_map_list
- def _call_paddle_prune(best_model_path, prune_analysis_path, params):
- mode = 'w'
- sys.stdout = open(
- osp.join(prune_analysis_path, 'out.log'), mode, encoding='utf-8')
- sys.stderr = open(
- osp.join(prune_analysis_path, 'err.log'), mode, encoding='utf-8')
- sensitivities_path = osp.join(prune_analysis_path, "sensitivities.data")
- task_type = params['task_type']
- dataset_path = params['dataset_path']
- os.environ['CUDA_VISIBLE_DEVICES'] = params['train'].cuda_visible_devices
- if task_type == "classification":
- from .prune.classification import prune
- elif task_type in ["detection", "instance_segmentation"]:
- from .prune.detection import prune
- elif task_type == "segmentation":
- from .prune.segmentation import prune
- batch_size = params['train'].batch_size
- prune(best_model_path, dataset_path, sensitivities_path, batch_size)
- import paddlex as pdx
- from paddlex.cv.models.slim.visualize import visualize
- model = pdx.load_model(best_model_path)
- visualize(model, sensitivities_path, prune_analysis_path)
- set_folder_status(prune_analysis_path, PruneStatus.XSPRUNEDONE)
- def _call_paddlex_train(task_path, params):
- '''
- Args:
- params为dict,字段包括'pretrain_weights_download_save_dir': 预训练模型保存路径,
- 'task_type': 任务类型,'dataset_path': 数据集路径,'train':训练参数
- '''
- mode = 'w'
- if params['train'].resume_checkpoint is not None:
- mode = 'a'
- sys.stdout = open(osp.join(task_path, 'out.log'), mode, encoding='utf-8')
- sys.stderr = open(osp.join(task_path, 'err.log'), mode, encoding='utf-8')
- sys.stdout.write("This log file path is {}\n".format(
- osp.join(task_path, 'out.log')))
- sys.stdout.write("注意:标志为WARNING/INFO类的仅为警告或提示类信息,非错误信息\n")
- sys.stderr.write("This log file path is {}\n".format(
- osp.join(task_path, 'err.log')))
- sys.stderr.write("注意:标志为WARNING/INFO类的仅为警告或提示类信息,非错误信息\n")
- os.environ['CUDA_VISIBLE_DEVICES'] = params['train'].cuda_visible_devices
- import paddlex as pdx
- pdx.gui_mode = True
- pdx.log_level = 3
- pdx.pretrain_dir = params['pretrain_weights_download_save_dir']
- task_type = params['task_type']
- dataset_path = params['dataset_path']
- if task_type == "classification":
- from .train.classification import train
- elif task_type in ["detection", "instance_segmentation"]:
- from .train.detection import train
- elif task_type == "segmentation":
- from .train.segmentation import train
- train(task_path, dataset_path, params['train'])
- set_folder_status(task_path, TaskStatus.XTRAINDONE)
- def _call_paddlex_evaluate_model(task_path,
- model_path,
- task_type,
- epoch,
- topk=5,
- score_thresh=0.3,
- overlap_thresh=0.5):
- evaluate_status_path = osp.join(task_path, './logs/evaluate')
- sys.stdout = open(
- osp.join(evaluate_status_path, 'out.log'), 'w', encoding='utf-8')
- sys.stderr = open(
- osp.join(evaluate_status_path, 'err.log'), 'w', encoding='utf-8')
- if task_type == "classification":
- from .evaluate.classification import Evaluator
- evaluator = Evaluator(model_path, topk=topk)
- elif task_type == "detection":
- from .evaluate.detection import DetEvaluator
- evaluator = DetEvaluator(
- model_path,
- score_threshold=score_thresh,
- overlap_thresh=overlap_thresh)
- elif task_type == "instance_segmentation":
- from .evaluate.detection import InsSegEvaluator
- evaluator = InsSegEvaluator(
- model_path,
- score_threshold=score_thresh,
- overlap_thresh=overlap_thresh)
- elif task_type == "segmentation":
- from .evaluate.segmentation import Evaluator
- evaluator = Evaluator(model_path)
- report = evaluator.generate_report()
- report['epoch'] = epoch
- pickle.dump(report, open(osp.join(task_path, "eval_res.pkl"), "wb"))
- set_folder_status(evaluate_status_path, TaskStatus.XEVALUATED)
- set_folder_status(task_path, TaskStatus.XEVALUATED)
- def _call_paddlex_predict(task_path,
- predict_status_path,
- params,
- img_list,
- img_data,
- save_dir,
- score_thresh,
- epoch=None):
- total_num = open(
- osp.join(predict_status_path, 'total_num'), 'w', encoding='utf-8')
- def write_file_num(total_file_num):
- total_num.write(str(total_file_num))
- total_num.close()
- sys.stdout = open(
- osp.join(predict_status_path, 'out.log'), 'w', encoding='utf-8')
- sys.stderr = open(
- osp.join(predict_status_path, 'err.log'), 'w', encoding='utf-8')
- import paddlex as pdx
- pdx.log_level = 3
- task_type = params['task_type']
- dataset_path = params['dataset_path']
- if epoch is None:
- model_path = osp.join(task_path, 'output', 'best_model')
- else:
- model_path = osp.join(task_path, 'output', 'epoch_{}'.format(epoch))
- model = pdx.load_model(model_path)
- file_list = dict()
- predicted_num = 0
- if task_type == "classification":
- if img_data is None:
- if len(img_list) == 0 and osp.exists(
- osp.join(dataset_path, "test_list.txt")):
- with open(osp.join(dataset_path, "test_list.txt")) as f:
- for line in f:
- items = line.strip().split()
- file_list[osp.join(dataset_path, items[0])] = items[1]
- else:
- for image in img_list:
- file_list[image] = None
- total_file_num = len(file_list)
- write_file_num(total_file_num)
- for image, label_id in file_list.items():
- pred_result = {}
- if label_id is not None:
- pred_result["gt_label"] = model.labels[int(label_id)]
- results = model.predict(img_file=image)
- pred_result["label"] = []
- pred_result["score"] = []
- pred_result["topk"] = len(results)
- for res in results:
- pred_result["label"].append(res['category'])
- pred_result["score"].append(res['score'])
- visualize_classified_result(save_dir, image, pred_result)
- predicted_num += 1
- else:
- img_data = base64.b64decode(img_data)
- img_array = np.frombuffer(img_data, np.uint8)
- img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)
- results = model.predict(img)
- pred_result = {}
- pred_result["label"] = []
- pred_result["score"] = []
- pred_result["topk"] = len(results)
- for res in results:
- pred_result["label"].append(res['category'])
- pred_result["score"].append(res['score'])
- visualize_classified_result(save_dir, img, pred_result)
- elif task_type in ["detection", "instance_segmentation"]:
- if img_data is None:
- if task_type == "detection" and osp.exists(
- osp.join(dataset_path, "test_list.txt")):
- if len(img_list) == 0 and osp.exists(
- osp.join(dataset_path, "test_list.txt")):
- with open(osp.join(dataset_path, "test_list.txt")) as f:
- for line in f:
- items = line.strip().split()
- file_list[osp.join(dataset_path, items[0])] = \
- osp.join(dataset_path, items[1])
- else:
- for image in img_list:
- file_list[image] = None
- total_file_num = len(file_list)
- write_file_num(total_file_num)
- for image, anno in file_list.items():
- results = model.predict(img_file=image)
- image_pred = pdx.det.visualize(
- image, results, threshold=score_thresh, save_dir=None)
- save_name = osp.join(save_dir, osp.split(image)[-1])
- image_gt = None
- if anno is not None:
- image_gt = plot_det_label(image, anno, model.labels)
- visualize_detected_result(save_name, image_gt, image_pred)
- predicted_num += 1
- elif len(img_list) == 0 and osp.exists(
- osp.join(dataset_path, "test.json")):
- from pycocotools.coco import COCO
- anno_path = osp.join(dataset_path, "test.json")
- coco = COCO(anno_path)
- img_ids = coco.getImgIds()
- total_file_num = len(img_ids)
- write_file_num(total_file_num)
- for img_id in img_ids:
- img_anno = coco.loadImgs(img_id)[0]
- file_name = img_anno['file_name']
- name = (osp.split(file_name)[-1]).split(".")[0]
- anno = osp.join(dataset_path, "Annotations", name + ".npy")
- img_file = osp.join(dataset_path, "JPEGImages", file_name)
- results = model.predict(img_file=img_file)
- image_pred = pdx.det.visualize(
- img_file,
- results,
- threshold=score_thresh,
- save_dir=None)
- save_name = osp.join(save_dir, osp.split(img_file)[-1])
- if task_type == "detection":
- image_gt = plot_det_label(img_file, anno, model.labels)
- else:
- image_gt = plot_insseg_label(img_file, anno,
- model.labels)
- visualize_detected_result(save_name, image_gt, image_pred)
- predicted_num += 1
- else:
- total_file_num = len(img_list)
- write_file_num(total_file_num)
- for image in img_list:
- results = model.predict(img_file=image)
- image_pred = pdx.det.visualize(
- image, results, threshold=score_thresh, save_dir=None)
- save_name = osp.join(save_dir, osp.split(image)[-1])
- visualize_detected_result(save_name, None, image_pred)
- predicted_num += 1
- else:
- img_data = base64.b64decode(img_data)
- img_array = np.frombuffer(img_data, np.uint8)
- img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)
- results = model.predict(img)
- image_pred = pdx.det.visualize(
- img, results, threshold=score_thresh, save_dir=None)
- image_gt = None
- save_name = osp.join(save_dir, 'predict_result.png')
- visualize_detected_result(save_name, image_gt, image_pred)
- elif task_type == "segmentation":
- if img_data is None:
- if len(img_list) == 0 and osp.exists(
- osp.join(dataset_path, "test_list.txt")):
- with open(osp.join(dataset_path, "test_list.txt")) as f:
- for line in f:
- items = line.strip().split()
- file_list[osp.join(dataset_path, items[0])] = \
- osp.join(dataset_path, items[1])
- else:
- for image in img_list:
- file_list[image] = None
- total_file_num = len(file_list)
- write_file_num(total_file_num)
- color_map = get_color_map_list(256)
- legend = {}
- for i in range(len(model.labels)):
- legend[model.labels[i]] = color_map[i]
- for image, anno in file_list.items():
- results = model.predict(img_file=image)
- image_pred = pdx.seg.visualize(image, results, save_dir=None)
- pse_pred = pdx.seg.visualize(
- image, results, weight=0, save_dir=None)
- image_ground = None
- pse_label = None
- if anno is not None:
- label = np.asarray(Image.open(anno)).astype('uint8')
- image_ground = pdx.seg.visualize(
- image, {'label_map': label}, save_dir=None)
- pse_label = pdx.seg.visualize(
- image, {'label_map': label}, weight=0, save_dir=None)
- save_name = osp.join(save_dir, osp.split(image)[-1])
- visualize_segmented_result(save_name, image_ground, pse_label,
- image_pred, pse_pred, legend)
- predicted_num += 1
- else:
- img_data = base64.b64decode(img_data)
- img_array = np.frombuffer(img_data, np.uint8)
- img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)
- color_map = get_color_map_list(256)
- legend = {}
- for i in range(len(model.labels)):
- legend[model.labels[i]] = color_map[i]
- results = model.predict(img)
- image_pred = pdx.seg.visualize(image, results, save_dir=None)
- pse_pred = pdx.seg.visualize(
- image, results, weight=0, save_dir=None)
- image_ground = None
- pse_label = None
- save_name = osp.join(save_dir, 'predict_result.png')
- visualize_segmented_result(save_name, image_ground, pse_label,
- image_pred, pse_pred, legend)
- set_folder_status(predict_status_path, PredictStatus.XPREDONE)
- def _call_paddlex_export_infer(task_path, save_dir, export_status_path, epoch):
- # 导出模型不使用GPU
- sys.stdout = open(
- osp.join(export_status_path, 'out.log'), 'w', encoding='utf-8')
- sys.stderr = open(
- osp.join(export_status_path, 'err.log'), 'w', encoding='utf-8')
- import os
- os.environ['CUDA_VISIBLE_DEVICES'] = ''
- import paddlex as pdx
- if epoch is not None:
- model_dir = "epoch_{}".format(epoch)
- model_path = osp.join(task_path, 'output', model_dir)
- else:
- model_path = osp.join(task_path, 'output', 'best_model')
- model = pdx.load_model(model_path)
- model.export_inference_model(save_dir)
- set_folder_status(export_status_path, TaskStatus.XEXPORTED)
- set_folder_status(task_path, TaskStatus.XEXPORTED)
- def _call_paddlex_export_quant(task_path, params, save_dir, export_status_path,
- epoch):
- sys.stdout = open(
- osp.join(export_status_path, 'out.log'), 'w', encoding='utf-8')
- sys.stderr = open(
- osp.join(export_status_path, 'err.log'), 'w', encoding='utf-8')
- dataset_path = params['dataset_path']
- task_type = params['task_type']
- os.environ['CUDA_VISIBLE_DEVICES'] = params['train'].cuda_visible_devices
- import paddlex as pdx
- if epoch is not None:
- model_dir = "epoch_{}".format(epoch)
- model_path = osp.join(task_path, 'output', model_dir)
- else:
- model_path = osp.join(task_path, 'output', 'best_model')
- model = pdx.load_model(model_path)
- if task_type == "classification":
- train_file_list = osp.join(dataset_path, 'train_list.txt')
- val_file_list = osp.join(dataset_path, 'val_list.txt')
- label_list = osp.join(dataset_path, 'labels.txt')
- quant_dataset = pdx.datasets.ImageNet(
- data_dir=dataset_path,
- file_list=train_file_list,
- label_list=label_list,
- transforms=model.test_transforms)
- eval_dataset = pdx.datasets.ImageNet(
- data_dir=dataset_path,
- file_list=val_file_list,
- label_list=label_list,
- transforms=model.eval_transforms)
- elif task_type == "detection":
- train_file_list = osp.join(dataset_path, 'train_list.txt')
- val_file_list = osp.join(dataset_path, 'val_list.txt')
- label_list = osp.join(dataset_path, 'labels.txt')
- quant_dataset = pdx.datasets.VOCDetection(
- data_dir=dataset_path,
- file_list=train_file_list,
- label_list=label_list,
- transforms=model.test_transforms)
- eval_dataset = pdx.datasets.VOCDetection(
- data_dir=dataset_path,
- file_list=val_file_list,
- label_list=label_list,
- transforms=model.eval_transforms)
- elif task_type == "instance_segmentation":
- train_json = osp.join(dataset_path, 'train.json')
- val_json = osp.join(dataset_path, 'val.json')
- quant_dataset = pdx.datasets.CocoDetection(
- data_dir=osp.join(dataset_path, 'JPEGImages'),
- ann_file=train_json,
- transforms=model.test_transforms)
- eval_dataset = pdx.datasets.CocoDetection(
- data_dir=osp.join(dataset_path, 'JPEGImages'),
- ann_file=val_json,
- transforms=model.eval_transforms)
- elif task_type == "segmentation":
- train_file_list = osp.join(dataset_path, 'train_list.txt')
- val_file_list = osp.join(dataset_path, 'val_list.txt')
- label_list = osp.join(dataset_path, 'labels.txt')
- quant_dataset = pdx.datasets.SegDataset(
- data_dir=dataset_path,
- file_list=train_file_list,
- label_list=label_list,
- transforms=model.test_transforms)
- eval_dataset = pdx.datasets.SegDataset(
- data_dir=dataset_path,
- file_list=val_file_list,
- label_list=label_list,
- transforms=model.eval_transforms)
- metric_before = model.evaluate(eval_dataset)
- pdx.log_level = 3
- pdx.slim.export_quant_model(
- model, quant_dataset, batch_size=1, save_dir=save_dir, cache_dir=None)
- model_quant = pdx.load_model(save_dir)
- metric_after = model_quant.evaluate(eval_dataset)
- metrics = {}
- if task_type == "segmentation":
- metrics['before'] = {'miou': metric_before['miou']}
- metrics['after'] = {'miou': metric_after['miou']}
- else:
- metrics['before'] = metric_before
- metrics['after'] = metric_after
- import json
- with open(
- osp.join(export_status_path, 'quant_result.json'),
- 'w',
- encoding='utf-8') as f:
- json.dump(metrics, f)
- set_folder_status(export_status_path, TaskStatus.XEXPORTED)
- set_folder_status(task_path, TaskStatus.XEXPORTED)
- def _call_paddlelite_export_lite(model_path, save_dir=None, place="arm"):
- import paddlelite.lite as lite
- opt = lite.Opt()
- model_file = os.path.join(model_path, '__model__')
- params_file = os.path.join(model_path, '__params__')
- if save_dir is None:
- save_dir = osp.join(model_path, "lite_model")
- if not osp.exists(save_dir):
- os.makedirs(save_dir)
- path = osp.join(save_dir, "model")
- opt.run_optimize("", model_file, params_file, "naive_buffer", place, path)
- def safe_clean_folder(folder):
- if osp.exists(folder):
- try:
- shutil.rmtree(folder)
- os.makedirs(folder)
- except Exception as e:
- pass
- if osp.exists(folder):
- for root, dirs, files in os.walk(folder):
- for name in files:
- try:
- os.remove(os.path.join(root, name))
- except Exception as e:
- pass
- else:
- os.makedirs(folder)
- else:
- os.makedirs(folder)
- if not osp.exists(folder):
- os.makedirs(folder)
- def get_task_max_saved_epochs(task_path):
- saved_epoch_num = -1
- output_path = osp.join(task_path, "output")
- if osp.exists(output_path):
- for f in os.listdir(output_path):
- if f.startswith("epoch_"):
- if not osp.exists(osp.join(output_path, f, '.success')):
- continue
- curr_epoch_num = int(f[6:])
- if curr_epoch_num > saved_epoch_num:
- saved_epoch_num = curr_epoch_num
- return saved_epoch_num
- def get_task_status(task_path):
- status, message = get_folder_status(task_path, True)
- task_id = os.path.split(task_path)[-1]
- err_log = os.path.join(task_path, 'err.log')
- if status in [TaskStatus.XTRAINING, TaskStatus.XPRUNETRAIN]:
- pid = int(message)
- is_dead = False
- if not psutil.pid_exists(pid):
- is_dead = True
- else:
- p = psutil.Process(pid)
- if p.status() == 'zombie':
- is_dead = True
- if is_dead:
- status = TaskStatus.XTRAINFAIL
- message = "训练任务{}异常终止,请查阅错误日志具体确认原因{}。\n\n 如若通过日志无法确定原因,可尝试以下几种方法,\n" \
- "1. 尝试重新启动训练,看是否能正常训练; \n" \
- "2. 调低batch_size(需同时按比例调低学习率等参数)排除是否是显存或内存不足的原因导致;\n" \
- "3. 前往GitHub提ISSUE,描述清楚问题会有工程师及时回复: https://github.com/PaddlePaddle/PaddleX/issues ; \n" \
- "3. 加QQ群1045148026或邮件至paddlex@baidu.com在线咨询工程师".format(task_id, err_log)
- set_folder_status(task_path, status, message)
- return status, message
- def train_model(task_path):
- """训练模型
- Args:
- task_path(str): 模型训练的参数保存在task_path下的'params.pkl'文件中
- """
- params_conf_file = osp.join(task_path, 'params.pkl')
- assert osp.exists(
- params_conf_file), "任务无法启动,路径{}下不存在参数配置文件params.pkl".format(task_path)
- with open(params_conf_file, 'rb') as f:
- params = pickle.load(f)
- sensitivities_path = params['train'].sensitivities_path
- p = mp.Process(target=_call_paddlex_train, args=(task_path, params))
- p.start()
- if sensitivities_path is None:
- set_folder_status(task_path, TaskStatus.XTRAINING, p.pid)
- else:
- set_folder_status(task_path, TaskStatus.XPRUNETRAIN, p.pid)
- return p
- def stop_train_model(task_path):
- """停止正在训练的模型
- Args:
- task_path(str): 从task_path下的'XTRANING'文件中获取训练的进程id
- """
- status, message = get_task_status(task_path)
- if status in [TaskStatus.XTRAINING, TaskStatus.XPRUNETRAIN]:
- pid = int(message)
- pkill(pid)
- best_model_saved = True
- if not osp.exists(osp.join(task_path, 'output', 'best_model')):
- best_model_saved = False
- set_folder_status(task_path, TaskStatus.XTRAINEXIT, best_model_saved)
- else:
- raise Exception("模型训练任务没在运行中")
- def prune_analysis_model(task_path):
- """模型裁剪分析
- Args:
- task_path(str): 模型训练的参数保存在task_path
- dataset_path(str) 模型裁剪中评估数据集的路径
- """
- best_model_path = osp.join(task_path, 'output', 'best_model')
- assert osp.exists(best_model_path), "该任务暂未保存模型,无法进行模型裁剪分析"
- prune_analysis_path = osp.join(task_path, 'prune')
- if not osp.exists(prune_analysis_path):
- os.makedirs(prune_analysis_path)
- params_conf_file = osp.join(task_path, 'params.pkl')
- assert osp.exists(
- params_conf_file), "任务无法启动,路径{}下不存在参数配置文件params.pkl".format(task_path)
- with open(params_conf_file, 'rb') as f:
- params = pickle.load(f)
- assert params['train'].model.lower() not in [
- "ppyolo", "fasterrcnn", "maskrcnn", "fastscnn", "HRNet_W18"
- ], "暂不支持PPYOLO、FasterRCNN、MaskRCNN、HRNet_W18、FastSCNN模型裁剪"
- p = mp.Process(
- target=_call_paddle_prune,
- args=(best_model_path, prune_analysis_path, params))
- p.start()
- set_folder_status(prune_analysis_path, PruneStatus.XSPRUNEING, p.pid)
- set_folder_status(task_path, TaskStatus.XPRUNEING, p.pid)
- return p
- def get_prune_status(prune_path):
- status, message = get_folder_status(prune_path, True)
- if status in [PruneStatus.XSPRUNEING]:
- pid = int(message)
- is_dead = False
- if not psutil.pid_exists(pid):
- is_dead = True
- else:
- p = psutil.Process(pid)
- if p.status() == 'zombie':
- is_dead = True
- if is_dead:
- status = PruneStatus.XSPRUNEFAIL
- message = "模型裁剪异常终止,可能原因如下:\n1.暂不支持FasterRCNN、MaskRCNN模型的模型裁剪\n2.模型裁剪过程中进程被异常结束,建议重新启动模型裁剪任务"
- set_folder_status(prune_path, status, message)
- return status, message
- def stop_prune_analysis(prune_path):
- """停止正在裁剪分析的模型
- Args:
- prune_path(str): prune_path'XSSLMING'文件中获取训练的进程id
- """
- status, message = get_prune_status(prune_path)
- if status == PruneStatus.XSPRUNEING:
- pid = int(message)
- pkill(pid)
- set_folder_status(prune_path, PruneStatus.XSPRUNEEXIT)
- else:
- raise Exception("模型裁剪分析任务未在运行中")
- def evaluate_model(task_path,
- task_type,
- epoch=None,
- topk=5,
- score_thresh=0.3,
- overlap_thresh=0.5):
- """评估最优模型
- Args:
- task_path(str): 模型训练相关结果的保存路径
- """
- output_path = osp.join(task_path, 'output')
- if not osp.exists(osp.join(output_path, 'best_model')):
- raise Exception("未在训练路径{}下发现保存的best_model,无法进行评估".format(output_path))
- evaluate_status_path = osp.join(task_path, './logs/evaluate')
- safe_clean_folder(evaluate_status_path)
- if epoch is None:
- model_path = osp.join(output_path, 'best_model')
- else:
- epoch_dir = "{}_{}".format('epoch', epoch)
- model_path = osp.join(output_path, epoch_dir)
- p = mp.Process(
- target=_call_paddlex_evaluate_model,
- args=(task_path, model_path, task_type, epoch, topk, score_thresh,
- overlap_thresh))
- p.start()
- set_folder_status(evaluate_status_path, TaskStatus.XEVALUATING, p.pid)
- return p
- def get_evaluate_status(task_path):
- """获取导出状态
- Args:
- task_path(str): 训练任务文件夹
- """
- evaluate_status_path = osp.join(task_path, './logs/evaluate')
- if not osp.exists(evaluate_status_path):
- return None, "No evaluate fold in path {}".format(task_path)
- status, message = get_folder_status(evaluate_status_path, True)
- if status == TaskStatus.XEVALUATING:
- pid = int(message)
- is_dead = False
- if not psutil.pid_exists(pid):
- is_dead = True
- else:
- p = psutil.Process(pid)
- if p.status() == 'zombie':
- is_dead = True
- if is_dead:
- status = TaskStatus.XEVALUATEFAIL
- message = "评估过程出现异常,请尝试重新评估!"
- set_folder_status(evaluate_status_path, status, message)
- if status not in [
- TaskStatus.XEVALUATING, TaskStatus.XEVALUATED,
- TaskStatus.XEVALUATEFAIL
- ]:
- raise ValueError("Wrong status in evaluate task {}".format(status))
- return status, message
- def get_predict_status(task_path):
- """获取预测任务状态
- Args:
- task_path(str): 从predict_path下的'XPRESTART'文件中获取训练的进程id
- """
- from ..utils import list_files
- predict_status_path = osp.join(task_path, "./logs/predict")
- save_dir = osp.join(task_path, "visualized_test_results")
- if not osp.exists(save_dir):
- return None, "任务目录下没有visualized_test_results文件夹,{}".format(
- task_path), 0, 0
- status, message = get_folder_status(predict_status_path, True)
- if status == PredictStatus.XPRESTART:
- pid = int(message)
- is_dead = False
- if not psutil.pid_exists(pid):
- is_dead = True
- else:
- p = psutil.Process(pid)
- if p.status() == 'zombie':
- is_dead = True
- if is_dead:
- status = PredictStatus.XPREFAIL
- message = "图片预测过程出现异常,请尝试重新预测!"
- set_folder_status(predict_status_path, status, message)
- if status not in [
- PredictStatus.XPRESTART, PredictStatus.XPREDONE,
- PredictStatus.XPREFAIL
- ]:
- raise ValueError("预测任务状态异常,{}".format(status))
- predict_num = len(list_files(save_dir))
- if predict_num > 0:
- if predict_num == 1:
- total_num = 1
- else:
- total_num = int(
- open(
- osp.join(predict_status_path, "total_num"),
- encoding='utf-8').readline().strip())
- else:
- predict_num = 0
- total_num = 0
- return status, message, predict_num, total_num
- def predict_test_pics(task_path,
- img_list=[],
- img_data=None,
- save_dir=None,
- score_thresh=0.5,
- epoch=None):
- """模型预测
- Args:
- task_path(str): 模型训练的参数保存在task_path下的'params.pkl'文件中
- """
- params_conf_file = osp.join(task_path, 'params.pkl')
- assert osp.exists(
- params_conf_file), "任务无法启动,路径{}下不存在参数配置文件params.pkl".format(task_path)
- with open(params_conf_file, 'rb') as f:
- params = pickle.load(f)
- predict_status_path = osp.join(task_path, "./logs/predict")
- safe_clean_folder(predict_status_path)
- save_dir = osp.join(task_path, 'visualized_test_results')
- safe_clean_folder(save_dir)
- p = mp.Process(
- target=_call_paddlex_predict,
- args=(task_path, predict_status_path, params, img_list, img_data,
- save_dir, score_thresh, epoch))
- p.start()
- set_folder_status(predict_status_path, PredictStatus.XPRESTART, p.pid)
- return p, save_dir
- def stop_predict_task(task_path):
- """停止预测任务
- Args:
- task_path(str): 从predict_path下的'XPRESTART'文件中获取训练的进程id
- """
- from ..utils import list_files
- predict_status_path = osp.join(task_path, "./logs/predict")
- save_dir = osp.join(task_path, "visualized_test_results")
- if not osp.exists(save_dir):
- return None, "任务目录下没有visualized_test_results文件夹,{}".format(
- task_path), 0, 0
- status, message = get_folder_status(predict_status_path, True)
- if status == PredictStatus.XPRESTART:
- pid = int(message)
- is_dead = False
- if not psutil.pid_exists(pid):
- is_dead = True
- else:
- p = psutil.Process(pid)
- if p.status() == 'zombie':
- is_dead = True
- if is_dead:
- status = PredictStatus.XPREFAIL
- message = "图片预测过程出现异常,请尝试重新预测!"
- set_folder_status(predict_status_path, status, message)
- else:
- pkill(pid)
- status = PredictStatus.XPREFAIL
- message = "图片预测进程已停止!"
- set_folder_status(predict_status_path, status, message)
- if status not in [
- PredictStatus.XPRESTART, PredictStatus.XPREDONE,
- PredictStatus.XPREFAIL
- ]:
- raise ValueError("预测任务状态异常,{}".format(status))
- predict_num = len(list_files(save_dir))
- if predict_num > 0:
- total_num = int(
- open(
- osp.join(predict_status_path, "total_num"), encoding='utf-8')
- .readline().strip())
- else:
- predict_num = 0
- total_num = 0
- return status, message, predict_num, total_num
- def get_export_status(task_path):
- """获取导出状态
- Args:
- task_path(str): 从task_path下的'export/XEXPORTING'文件中获取训练的进程id
- Return:
- 导出的状态和其他消息.
- """
- export_status_path = osp.join(task_path, './logs/export')
- if not osp.exists(export_status_path):
- return None, "{}任务目录下没有export文件夹".format(task_path)
- status, message = get_folder_status(export_status_path, True)
- if status == TaskStatus.XEXPORTING:
- pid = int(message)
- is_dead = False
- if not psutil.pid_exists(pid):
- is_dead = True
- else:
- p = psutil.Process(pid)
- if p.status() == 'zombie':
- is_dead = True
- if is_dead:
- status = TaskStatus.XEXPORTFAIL
- message = "导出过程出现异常,请尝试重新评估!"
- set_folder_status(export_status_path, status, message)
- if status not in [
- TaskStatus.XEXPORTING, TaskStatus.XEXPORTED, TaskStatus.XEXPORTFAIL
- ]:
- # raise ValueError("获取到的导出状态异常,{}。".format(status))
- return None, "获取到的导出状态异常,{}。".format(status)
- return status, message
- def export_quant_model(task_path, save_dir, epoch=None):
- """导出量化模型
- Args:
- task_path(str): 模型训练的路径
- save_dir(str): 导出后的模型保存路径
- """
- output_path = osp.join(task_path, 'output')
- if not osp.exists(osp.join(output_path, 'best_model')):
- raise Exception("未在训练路径{}下发现保存的best_model,导出失败".format(output_path))
- export_status_path = osp.join(task_path, './logs/export')
- safe_clean_folder(export_status_path)
- params_conf_file = osp.join(task_path, 'params.pkl')
- assert osp.exists(
- params_conf_file), "任务无法启动,路径{}下不存在参数配置文件params.pkl".format(task_path)
- with open(params_conf_file, 'rb') as f:
- params = pickle.load(f)
- p = mp.Process(
- target=_call_paddlex_export_quant,
- args=(task_path, params, save_dir, export_status_path, epoch))
- p.start()
- set_folder_status(export_status_path, TaskStatus.XEXPORTING, p.pid)
- set_folder_status(task_path, TaskStatus.XEXPORTING, p.pid)
- return p
- def export_noquant_model(task_path, save_dir, epoch=None):
- """导出inference模型
- Args:
- task_path(str): 模型训练的路径
- save_dir(str): 导出后的模型保存路径
- """
- output_path = osp.join(task_path, 'output')
- if not osp.exists(osp.join(output_path, 'best_model')):
- raise Exception("未在训练路径{}下发现保存的best_model,导出失败".format(output_path))
- export_status_path = osp.join(task_path, './logs/export')
- safe_clean_folder(export_status_path)
- p = mp.Process(
- target=_call_paddlex_export_infer,
- args=(task_path, save_dir, export_status_path, epoch))
- p.start()
- set_folder_status(export_status_path, TaskStatus.XEXPORTING, p.pid)
- set_folder_status(task_path, TaskStatus.XEXPORTING, p.pid)
- return p
- def opt_lite_model(model_path, save_dir=None, place='arm'):
- p = mp.Process(
- target=_call_paddlelite_export_lite,
- args=(model_path, save_dir, place))
- p.start()
- p.join()
- def stop_export_task(task_path):
- """停止导出
- Args:
- task_path(str): 从task_path下的'export/XEXPORTING'文件中获取训练的进程id
- Return:
- the export status and message.
- """
- export_status_path = osp.join(task_path, './logs/export')
- if not osp.exists(export_status_path):
- return None, "{}任务目录下没有export文件夹".format(task_path)
- status, message = get_folder_status(export_status_path, True)
- if status == TaskStatus.XEXPORTING:
- pid = int(message)
- is_dead = False
- if not psutil.pid_exists(pid):
- is_dead = True
- else:
- p = psutil.Process(pid)
- if p.status() == 'zombie':
- is_dead = True
- if is_dead:
- status = TaskStatus.XEXPORTFAIL
- message = "导出过程出现异常,请尝试重新评估!"
- set_folder_status(export_status_path, status, message)
- else:
- pkill(pid)
- status = TaskStatus.XEXPORTFAIL
- message = "已停止导出进程!"
- set_folder_status(export_status_path, status, message)
- if status not in [
- TaskStatus.XEXPORTING, TaskStatus.XEXPORTED, TaskStatus.XEXPORTFAIL
- ]:
- raise ValueError("获取到的导出状态异常,{}。".format(status))
- return status, message
|