diff --git a/deploy/cpp/demo/classifier.cpp b/deploy/cpp/demo/classifier.cpp index 8b78d7e8975642b8d10d6c641c0245cdf661d3d9..6fd354d3f9cb6a366f0efb0b31e7ae073a90b4ad 100644 --- a/deploy/cpp/demo/classifier.cpp +++ b/deploy/cpp/demo/classifier.cpp @@ -37,6 +37,7 @@ DEFINE_int32(batch_size, 1, "Batch size of infering"); DEFINE_int32(thread_num, omp_get_num_procs(), "Number of preprocessing threads"); +DEFINE_bool(use_ir_optim, true, "use ir optimization"); int main(int argc, char** argv) { // Parsing command-line @@ -57,7 +58,8 @@ int main(int argc, char** argv) { FLAGS_use_gpu, FLAGS_use_trt, FLAGS_gpu_id, - FLAGS_key); + FLAGS_key, + FLAGS_use_ir_optim); // 进行预测 double total_running_time_s = 0.0; diff --git a/deploy/cpp/demo/detector.cpp b/deploy/cpp/demo/detector.cpp index 5b4e3a2ba9d2c921cf23774a17e34e0c8e26cc2a..54f93d2995fa24af73bba2855b6b26466129fa20 100644 --- a/deploy/cpp/demo/detector.cpp +++ b/deploy/cpp/demo/detector.cpp @@ -43,6 +43,7 @@ DEFINE_double(threshold, DEFINE_int32(thread_num, omp_get_num_procs(), "Number of preprocessing threads"); +DEFINE_bool(use_ir_optim, true, "use ir optimization"); int main(int argc, char** argv) { // 解析命令行参数 @@ -62,7 +63,8 @@ int main(int argc, char** argv) { FLAGS_use_gpu, FLAGS_use_trt, FLAGS_gpu_id, - FLAGS_key); + FLAGS_key, + FLAGS_use_ir_optim); double total_running_time_s = 0.0; double total_imread_time_s = 0.0; diff --git a/deploy/cpp/demo/segmenter.cpp b/deploy/cpp/demo/segmenter.cpp index 7dd48e551890f3c8e4550694c45bc3f84088ec0a..90adb5aea860bf5ad9f6cb9019990a188c37f871 100644 --- a/deploy/cpp/demo/segmenter.cpp +++ b/deploy/cpp/demo/segmenter.cpp @@ -39,6 +39,7 @@ DEFINE_int32(batch_size, 1, "Batch size of infering"); DEFINE_int32(thread_num, omp_get_num_procs(), "Number of preprocessing threads"); +DEFINE_bool(use_ir_optim, false, "use ir optimization"); int main(int argc, char** argv) { // 解析命令行参数 @@ -59,7 +60,8 @@ int main(int argc, char** argv) { FLAGS_use_gpu, FLAGS_use_trt, FLAGS_gpu_id, - FLAGS_key); + FLAGS_key, + FLAGS_use_ir_optim); double total_running_time_s = 0.0; double total_imread_time_s = 0.0; diff --git a/deploy/cpp/include/paddlex/paddlex.h b/deploy/cpp/include/paddlex/paddlex.h index af4d8898496fee47ed9b5c74599536ddf1fe9f6c..e0d0569341198d0a0b2a8c6d0637c3f5a61e1f3f 100644 --- a/deploy/cpp/include/paddlex/paddlex.h +++ b/deploy/cpp/include/paddlex/paddlex.h @@ -72,20 +72,23 @@ class Model { * @param use_trt: use Tensor RT or not when infering * @param gpu_id: the id of gpu when infering with using gpu * @param key: the key of encryption when using encrypted model + * @param use_ir_optim: use ir optimization when infering * */ void Init(const std::string& model_dir, bool use_gpu = false, bool use_trt = false, int gpu_id = 0, - std::string key = "") { - create_predictor(model_dir, use_gpu, use_trt, gpu_id, key); + std::string key = "", + bool use_ir_optim = true) { + create_predictor(model_dir, use_gpu, use_trt, gpu_id, key, use_ir_optim); } void create_predictor(const std::string& model_dir, bool use_gpu = false, bool use_trt = false, int gpu_id = 0, - std::string key = ""); + std::string key = "", + bool use_ir_optim = true); /* * @brief diff --git a/deploy/cpp/include/paddlex/visualize.h b/deploy/cpp/include/paddlex/visualize.h index 5a8e39a762ff5bbde966aff213f1751f520789e2..9ddba5387b427c60645db7c96a54bcba76fa9898 100644 --- a/deploy/cpp/include/paddlex/visualize.h +++ b/deploy/cpp/include/paddlex/visualize.h @@ -22,9 +22,14 @@ #include #else // Linux/Unix #include -#include +// #include +#ifdef __arm__ // for arm +#include +#include +#else #include #include +#endif #include #endif #include diff --git a/deploy/cpp/src/paddlex.cpp b/deploy/cpp/src/paddlex.cpp index bedd83b356baff41d7f9d16ac6de855e982332b2..cf1dfc955c43f9a61539e93a34c77c6ab4b198a9 100644 --- a/deploy/cpp/src/paddlex.cpp +++ b/deploy/cpp/src/paddlex.cpp @@ -22,7 +22,8 @@ void Model::create_predictor(const std::string& model_dir, bool use_gpu, bool use_trt, int gpu_id, - std::string key) { + std::string key, + bool use_ir_optim) { paddle::AnalysisConfig config; std::string model_file = model_dir + OS_PATH_SEP + "__model__"; std::string params_file = model_dir + OS_PATH_SEP + "__params__"; @@ -63,6 +64,8 @@ void Model::create_predictor(const std::string& model_dir, } config.SwitchUseFeedFetchOps(false); config.SwitchSpecifyInputNames(true); + // 开启图优化 + config.SwitchIrOptim(use_ir_optim); // 开启内存优化 config.EnableMemoryOptim(); if (use_trt) { diff --git a/docs/paddlex_gui/download.md b/docs/paddlex_gui/download.md index 77bb9962b37498ec3279a51cdc1faa34da1f498b..bf5d2ceaeadfc14612d2d83498796108469ae166 100644 --- a/docs/paddlex_gui/download.md +++ b/docs/paddlex_gui/download.md @@ -25,4 +25,3 @@ * **硬盘空间**:建议SSD剩余空间1T以上(非必须) ***注:PaddleX在Windows及Mac OS系统只支持单卡模型。Windows系统暂不支持NCCL。*** - diff --git a/docs/paddlex_gui/how_to_use.md b/docs/paddlex_gui/how_to_use.md index 32740c114242ccc2c6b7ecacc3088ba163fe7a3c..db5e9b1f58b3012e1104a7dfe8ff63394ecf3eee 100644 --- a/docs/paddlex_gui/how_to_use.md +++ b/docs/paddlex_gui/how_to_use.md @@ -42,7 +42,7 @@ PaddleX GUI是一个应用PaddleX实现的一个图形化开发客户端产品 在开始模型训练前,您需要根据不同的任务类型,将数据标注为相应的格式。目前PaddleX支持【图像分类】、【目标检测】、【语义分割】、【实例分割】四种任务类型。不同类型任务的数据处理方式可查看[数据标注方式](https://paddlex.readthedocs.io/zh_CN/latest/appendix/datasets.html)。 - + **第二步:导入我的数据集** @@ -116,26 +116,26 @@ PaddleX GUI是一个应用PaddleX实现的一个图形化开发客户端产品 PaddleX完全采用您本地的硬件进行计算,深度学习任务确实对算力要求较高,为了使您能快速体验应用PaddleX进行开发,我们适配了CPU硬件,但强烈建议您使用GPU以提升训练速度和开发体验。 - + 2. **我可以在服务器或云平台上部署PaddleX么?** PaddleX GUI是一个适配本地单机安装的客户端,无法在服务器上直接进行部署,您可以直接使用PaddleX API,或采用飞桨核心框架进行服务器上的部署。如果您希望使用公有算力,强烈建议您尝试飞桨产品系列中的 [EasyDL](https://ai.baidu.com/easydl/) 或 [AI Studio](https://aistudio.baidu.com/aistudio/index)进行开发。 - + 3. **PaddleX支持EasyData标注的数据吗?** 支持,PaddleX可顺畅读取EasyData标注的数据。但当前版本的PaddleX GUI暂时无法支持直接导入EasyData数据格式,您可以参照文档,将[数据集进行转换](https://paddlex.readthedocs.io/zh_CN/latest/appendix/how_to_convert_dataset.html)再导入PaddleX GUI进行后续开发。 同时,我们也在紧密开发PaddleX GUI可直接导入EasyData数据格式的功能。 - - + + 4. **为什么模型裁剪分析耗时这么长?** 模型裁剪分析过程是对模型各卷积层的敏感度信息进行分析,根据各参数对模型效果的影响进行不同比例的裁剪。此过程需要重复多次直至FLOPS满足要求,最后再进行精调训练获得最终裁剪后的模型,因此耗时较长。有关模型裁剪的原理,可参见文档[剪裁原理介绍](https://paddlepaddle.github.io/PaddleSlim/algo/algo.html#2-%E5%8D%B7%E7%A7%AF%E6%A0%B8%E5%89%AA%E8%A3%81%E5%8E%9F%E7%90%86) - + 5. **如何调用后端代码?** diff --git a/docs/tutorials/datasets.md b/docs/tutorials/datasets.md index b197b43b6c1ce2dd8c91bae3c484573365493ba0..8264d06a91ba1125036d4ab44f1fc06fe11d3049 100755 --- a/docs/tutorials/datasets.md +++ b/docs/tutorials/datasets.md @@ -224,7 +224,7 @@ labelB └--labels.txt # 标签列表文件 ``` -其中,图像文件名应与json文件名一一对应。 +其中,图像文件名应与json文件名一一对应。 每个json文件存储于`labels`相关的信息。如下所示: ``` @@ -269,17 +269,17 @@ labelB └--labels.txt # 标签列表文件 ``` -其中,图像文件名应与json文件名一一对应。 +其中,图像文件名应与json文件名一一对应。 每个json文件存储于`labels`相关的信息。如下所示: ``` -"labels": [{"y1": 18, "x2": 883, "x1": 371, "y2": 404, "name": "labelA", - "mask": "kVfc0`0Zg0', re.IGNORECASE) - obj_tag = pattern.findall( - str(ET.tostringlist(tree.getroot())))[0][1:-1] + obj_match = pattern.findall( + str(ET.tostringlist(tree.getroot()))) + if len(obj_match) == 0: + continue + obj_tag = obj_match[0][1:-1] objs = tree.findall(obj_tag) pattern = re.compile('', re.IGNORECASE) size_tag = pattern.findall( diff --git a/paddlex/cv/models/base.py b/paddlex/cv/models/base.py index e30a2529c5a7ff9cbcafb4a05d58f53ea5476e7e..1bf3a2c97a3ef9680aae64206aeb72207b759642 100644 --- a/paddlex/cv/models/base.py +++ b/paddlex/cv/models/base.py @@ -73,6 +73,7 @@ class BaseAPI: self.status = 'Normal' # 已完成迭代轮数,为恢复训练时的起始轮数 self.completed_epochs = 0 + self.scope = fluid.global_scope() def _get_single_card_bs(self, batch_size): if batch_size % len(self.places) == 0: @@ -84,6 +85,10 @@ class BaseAPI: 'place'])) def build_program(self): + if hasattr(paddlex, 'model_built') and paddlex.model_built: + logging.error( + "Function model.train() only can be called once in your code.") + paddlex.model_built = True # 构建训练网络 self.train_inputs, self.train_outputs = self.build_net(mode='train') self.train_prog = fluid.default_main_program() @@ -155,7 +160,7 @@ class BaseAPI: outputs=self.test_outputs, batch_size=batch_size, batch_nums=batch_num, - scope=None, + scope=self.scope, algo='KL', quantizable_op_type=["conv2d", "depthwise_conv2d", "mul"], is_full_quantize=False, @@ -244,8 +249,8 @@ class BaseAPI: logging.info( "Load pretrain weights from {}.".format(pretrain_weights), use_color=True) - paddlex.utils.utils.load_pretrain_weights( - self.exe, self.train_prog, pretrain_weights, fuse_bn) + paddlex.utils.utils.load_pretrain_weights(self.exe, self.train_prog, + pretrain_weights, fuse_bn) # 进行裁剪 if sensitivities_file is not None: import paddleslim @@ -349,27 +354,26 @@ class BaseAPI: logging.info("Model saved in {}.".format(save_dir)) def export_inference_model(self, save_dir): - test_input_names = [ - var.name for var in list(self.test_inputs.values()) - ] + test_input_names = [var.name for var in list(self.test_inputs.values())] test_outputs = list(self.test_outputs.values()) - if self.__class__.__name__ == 'MaskRCNN': - from paddlex.utils.save import save_mask_inference_model - save_mask_inference_model( - dirname=save_dir, - executor=self.exe, - params_filename='__params__', - feeded_var_names=test_input_names, - target_vars=test_outputs, - main_program=self.test_prog) - else: - fluid.io.save_inference_model( - dirname=save_dir, - executor=self.exe, - params_filename='__params__', - feeded_var_names=test_input_names, - target_vars=test_outputs, - main_program=self.test_prog) + with fluid.scope_guard(self.scope): + if self.__class__.__name__ == 'MaskRCNN': + from paddlex.utils.save import save_mask_inference_model + save_mask_inference_model( + dirname=save_dir, + executor=self.exe, + params_filename='__params__', + feeded_var_names=test_input_names, + target_vars=test_outputs, + main_program=self.test_prog) + else: + fluid.io.save_inference_model( + dirname=save_dir, + executor=self.exe, + params_filename='__params__', + feeded_var_names=test_input_names, + target_vars=test_outputs, + main_program=self.test_prog) model_info = self.get_model_info() model_info['status'] = 'Infer' @@ -388,8 +392,7 @@ class BaseAPI: # 模型保存成功的标志 open(osp.join(save_dir, '.success'), 'w').close() - logging.info("Model for inference deploy saved in {}.".format( - save_dir)) + logging.info("Model for inference deploy saved in {}.".format(save_dir)) def train_loop(self, num_epochs, @@ -513,13 +516,11 @@ class BaseAPI: eta = ((num_epochs - i) * total_num_steps - step - 1 ) * avg_step_time if time_eval_one_epoch is not None: - eval_eta = ( - total_eval_times - i // save_interval_epochs - ) * time_eval_one_epoch + eval_eta = (total_eval_times - i // save_interval_epochs + ) * time_eval_one_epoch else: - eval_eta = ( - total_eval_times - i // save_interval_epochs - ) * total_num_steps_eval * avg_step_time + eval_eta = (total_eval_times - i // save_interval_epochs + ) * total_num_steps_eval * avg_step_time eta_str = seconds_to_hms(eta + eval_eta) logging.info( diff --git a/paddlex/cv/models/classifier.py b/paddlex/cv/models/classifier.py index 17a307d8bdeed77467535bec1216cc9b97bd70e3..b329d90e0de7b246c43cde8ffdfe17e6dd406b91 100644 --- a/paddlex/cv/models/classifier.py +++ b/paddlex/cv/models/classifier.py @@ -1,11 +1,11 @@ # copyright (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. @@ -227,9 +227,10 @@ class BaseClassifier(BaseAPI): true_labels = list() pred_scores = list() if not hasattr(self, 'parallel_test_prog'): - self.parallel_test_prog = fluid.CompiledProgram( - self.test_prog).with_data_parallel( - share_vars_from=self.parallel_train_prog) + with fluid.scope_guard(self.scope): + self.parallel_test_prog = fluid.CompiledProgram( + self.test_prog).with_data_parallel( + share_vars_from=self.parallel_train_prog) batch_size_each_gpu = self._get_single_card_bs(batch_size) logging.info("Start to evaluating(total_samples={}, total_steps={})...". format(eval_dataset.num_samples, total_steps)) @@ -242,9 +243,11 @@ class BaseClassifier(BaseAPI): num_pad_samples = batch_size - num_samples pad_images = np.tile(images[0:1], (num_pad_samples, 1, 1, 1)) images = np.concatenate([images, pad_images]) - outputs = self.exe.run(self.parallel_test_prog, - feed={'image': images}, - fetch_list=list(self.test_outputs.values())) + with fluid.scope_guard(self.scope): + outputs = self.exe.run( + self.parallel_test_prog, + feed={'image': images}, + fetch_list=list(self.test_outputs.values())) outputs = [outputs[0][:num_samples]] true_labels.extend(labels) pred_scores.extend(outputs[0].tolist()) @@ -286,10 +289,11 @@ class BaseClassifier(BaseAPI): self.arrange_transforms( transforms=self.test_transforms, mode='test') im = self.test_transforms(img_file) - result = self.exe.run(self.test_prog, - feed={'image': im}, - fetch_list=list(self.test_outputs.values()), - use_program_cache=True) + with fluid.scope_guard(self.scope): + result = self.exe.run(self.test_prog, + feed={'image': im}, + fetch_list=list(self.test_outputs.values()), + use_program_cache=True) pred_label = np.argsort(result[0][0])[::-1][:true_topk] res = [{ 'category_id': l, diff --git a/paddlex/cv/models/deeplabv3p.py b/paddlex/cv/models/deeplabv3p.py index e548439a7ed81fd5758395244d26926d3c8010fe..cd9240e18594bd44a5acc9b03e4077fbf0f4434a 100644 --- a/paddlex/cv/models/deeplabv3p.py +++ b/paddlex/cv/models/deeplabv3p.py @@ -1,11 +1,11 @@ # copyright (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. @@ -317,19 +317,18 @@ class DeepLabv3p(BaseAPI): tuple (metrics, eval_details):当return_details为True时,增加返回dict (eval_details), 包含关键字:'confusion_matrix',表示评估的混淆矩阵。 """ - self.arrange_transforms( - transforms=eval_dataset.transforms, mode='eval') + self.arrange_transforms(transforms=eval_dataset.transforms, mode='eval') total_steps = math.ceil(eval_dataset.num_samples * 1.0 / batch_size) conf_mat = ConfusionMatrix(self.num_classes, streaming=True) data_generator = eval_dataset.generator( batch_size=batch_size, drop_last=False) if not hasattr(self, 'parallel_test_prog'): - self.parallel_test_prog = fluid.CompiledProgram( - self.test_prog).with_data_parallel( - share_vars_from=self.parallel_train_prog) - logging.info( - "Start to evaluating(total_samples={}, total_steps={})...".format( - eval_dataset.num_samples, total_steps)) + with fluid.scope_guard(self.scope): + self.parallel_test_prog = fluid.CompiledProgram( + self.test_prog).with_data_parallel( + share_vars_from=self.parallel_train_prog) + logging.info("Start to evaluating(total_samples={}, total_steps={})...". + format(eval_dataset.num_samples, total_steps)) for step, data in tqdm.tqdm( enumerate(data_generator()), total=total_steps): images = np.array([d[0] for d in data]) @@ -350,10 +349,12 @@ class DeepLabv3p(BaseAPI): pad_images = np.tile(images[0:1], (num_pad_samples, 1, 1, 1)) images = np.concatenate([images, pad_images]) feed_data = {'image': images} - outputs = self.exe.run(self.parallel_test_prog, - feed=feed_data, - fetch_list=list(self.test_outputs.values()), - return_numpy=True) + with fluid.scope_guard(self.scope): + outputs = self.exe.run( + self.parallel_test_prog, + feed=feed_data, + fetch_list=list(self.test_outputs.values()), + return_numpy=True) pred = outputs[0] if num_samples < batch_size: pred = pred[0:num_samples] @@ -399,10 +400,11 @@ class DeepLabv3p(BaseAPI): transforms=self.test_transforms, mode='test') im, im_info = self.test_transforms(im_file) im = np.expand_dims(im, axis=0) - result = self.exe.run(self.test_prog, - feed={'image': im}, - fetch_list=list(self.test_outputs.values()), - use_program_cache=True) + with fluid.scope_guard(self.scope): + result = self.exe.run(self.test_prog, + feed={'image': im}, + fetch_list=list(self.test_outputs.values()), + use_program_cache=True) pred = result[0] pred = np.squeeze(pred).astype('uint8') logit = result[1] diff --git a/paddlex/cv/models/faster_rcnn.py b/paddlex/cv/models/faster_rcnn.py index 45279bfc6014329ced089d39072221ceaf8dd683..408c9deab07ea22f3150778f3d7bb9dc636bafa8 100644 --- a/paddlex/cv/models/faster_rcnn.py +++ b/paddlex/cv/models/faster_rcnn.py @@ -1,11 +1,11 @@ # copyright (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. @@ -325,10 +325,12 @@ class FasterRCNN(BaseAPI): 'im_info': im_infos, 'im_shape': im_shapes, } - outputs = self.exe.run(self.test_prog, - feed=[feed_data], - fetch_list=list(self.test_outputs.values()), - return_numpy=False) + with fluid.scope_guard(self.scope): + outputs = self.exe.run( + self.test_prog, + feed=[feed_data], + fetch_list=list(self.test_outputs.values()), + return_numpy=False) res = { 'bbox': (np.array(outputs[0]), outputs[0].recursive_sequence_lengths()) @@ -388,15 +390,16 @@ class FasterRCNN(BaseAPI): im = np.expand_dims(im, axis=0) im_resize_info = np.expand_dims(im_resize_info, axis=0) im_shape = np.expand_dims(im_shape, axis=0) - outputs = self.exe.run(self.test_prog, - feed={ - 'image': im, - 'im_info': im_resize_info, - 'im_shape': im_shape - }, - fetch_list=list(self.test_outputs.values()), - return_numpy=False, - use_program_cache=True) + with fluid.scope_guard(self.scope): + outputs = self.exe.run(self.test_prog, + feed={ + 'image': im, + 'im_info': im_resize_info, + 'im_shape': im_shape + }, + fetch_list=list(self.test_outputs.values()), + return_numpy=False, + use_program_cache=True) res = { k: (np.array(v), v.recursive_sequence_lengths()) for k, v in zip(list(self.test_outputs.keys()), outputs) diff --git a/paddlex/cv/models/load_model.py b/paddlex/cv/models/load_model.py index 2d24abf4c75f1ff4b503138b3e18341da0b665c5..a80e2e93856621e12a38bfc174f2aba078bda312 100644 --- a/paddlex/cv/models/load_model.py +++ b/paddlex/cv/models/load_model.py @@ -24,6 +24,7 @@ import paddlex.utils.logging as logging def load_model(model_dir, fixed_input_shape=None): + model_scope = fluid.Scope() if not osp.exists(osp.join(model_dir, "model.yml")): raise Exception("There's not model.yml in {}".format(model_dir)) with open(osp.join(model_dir, "model.yml")) as f: @@ -51,38 +52,40 @@ def load_model(model_dir, fixed_input_shape=None): format(fixed_input_shape)) model.fixed_input_shape = fixed_input_shape - if status == "Normal" or \ - status == "Prune" or status == "fluid.save": - startup_prog = fluid.Program() - model.test_prog = fluid.Program() - with fluid.program_guard(model.test_prog, startup_prog): - with fluid.unique_name.guard(): - model.test_inputs, model.test_outputs = model.build_net( - mode='test') - model.test_prog = model.test_prog.clone(for_test=True) - model.exe.run(startup_prog) - if status == "Prune": - from .slim.prune import update_program - model.test_prog = update_program(model.test_prog, model_dir, - model.places[0]) - import pickle - with open(osp.join(model_dir, 'model.pdparams'), 'rb') as f: - load_dict = pickle.load(f) - fluid.io.set_program_state(model.test_prog, load_dict) - - elif status == "Infer" or \ - status == "Quant" or status == "fluid.save_inference_model": - [prog, input_names, outputs] = fluid.io.load_inference_model( - model_dir, model.exe, params_filename='__params__') - model.test_prog = prog - test_outputs_info = info['_ModelInputsOutputs']['test_outputs'] - model.test_inputs = OrderedDict() - model.test_outputs = OrderedDict() - for name in input_names: - model.test_inputs[name] = model.test_prog.global_block().var(name) - for i, out in enumerate(outputs): - var_desc = test_outputs_info[i] - model.test_outputs[var_desc[0]] = out + with fluid.scope_guard(model_scope): + if status == "Normal" or \ + status == "Prune" or status == "fluid.save": + startup_prog = fluid.Program() + model.test_prog = fluid.Program() + with fluid.program_guard(model.test_prog, startup_prog): + with fluid.unique_name.guard(): + model.test_inputs, model.test_outputs = model.build_net( + mode='test') + model.test_prog = model.test_prog.clone(for_test=True) + model.exe.run(startup_prog) + if status == "Prune": + from .slim.prune import update_program + model.test_prog = update_program(model.test_prog, model_dir, + model.places[0]) + import pickle + with open(osp.join(model_dir, 'model.pdparams'), 'rb') as f: + load_dict = pickle.load(f) + fluid.io.set_program_state(model.test_prog, load_dict) + + elif status == "Infer" or \ + status == "Quant" or status == "fluid.save_inference_model": + [prog, input_names, outputs] = fluid.io.load_inference_model( + model_dir, model.exe, params_filename='__params__') + model.test_prog = prog + test_outputs_info = info['_ModelInputsOutputs']['test_outputs'] + model.test_inputs = OrderedDict() + model.test_outputs = OrderedDict() + for name in input_names: + model.test_inputs[name] = model.test_prog.global_block().var( + name) + for i, out in enumerate(outputs): + var_desc = test_outputs_info[i] + model.test_outputs[var_desc[0]] = out if 'Transforms' in info: transforms_mode = info.get('TransformsMode', 'RGB') # 固定模型的输入shape @@ -107,6 +110,7 @@ def load_model(model_dir, fixed_input_shape=None): model.__dict__[k] = v logging.info("Model[{}] loaded.".format(info['Model'])) + model.scope = model_scope model.trainable = False model.status = status return model diff --git a/paddlex/cv/models/mask_rcnn.py b/paddlex/cv/models/mask_rcnn.py index 26d5e5cb4edc58be0fffaf6d778058c5846c1929..9e08808c94d7a9491bac21da9f3fd17f2d1a2bf8 100644 --- a/paddlex/cv/models/mask_rcnn.py +++ b/paddlex/cv/models/mask_rcnn.py @@ -1,11 +1,11 @@ # copyright (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. @@ -286,10 +286,12 @@ class MaskRCNN(FasterRCNN): 'im_info': im_infos, 'im_shape': im_shapes, } - outputs = self.exe.run(self.test_prog, - feed=[feed_data], - fetch_list=list(self.test_outputs.values()), - return_numpy=False) + with fluid.scope_guard(self.scope): + outputs = self.exe.run( + self.test_prog, + feed=[feed_data], + fetch_list=list(self.test_outputs.values()), + return_numpy=False) res = { 'bbox': (np.array(outputs[0]), outputs[0].recursive_sequence_lengths()), @@ -356,15 +358,16 @@ class MaskRCNN(FasterRCNN): im = np.expand_dims(im, axis=0) im_resize_info = np.expand_dims(im_resize_info, axis=0) im_shape = np.expand_dims(im_shape, axis=0) - outputs = self.exe.run(self.test_prog, - feed={ - 'image': im, - 'im_info': im_resize_info, - 'im_shape': im_shape - }, - fetch_list=list(self.test_outputs.values()), - return_numpy=False, - use_program_cache=True) + with fluid.scope_guard(self.scope): + outputs = self.exe.run(self.test_prog, + feed={ + 'image': im, + 'im_info': im_resize_info, + 'im_shape': im_shape + }, + fetch_list=list(self.test_outputs.values()), + return_numpy=False, + use_program_cache=True) res = { k: (np.array(v), v.recursive_sequence_lengths()) for k, v in zip(list(self.test_outputs.keys()), outputs) diff --git a/paddlex/cv/models/slim/post_quantization.py b/paddlex/cv/models/slim/post_quantization.py index 29ded34d20e3af85d43759b518169df9545b66e8..c5570087821d8441174aa276d8e5ce22d5ff8e03 100644 --- a/paddlex/cv/models/slim/post_quantization.py +++ b/paddlex/cv/models/slim/post_quantization.py @@ -85,13 +85,13 @@ class PaddleXPostTrainingQuantization(PostTrainingQuantization): self._support_quantize_op_type = \ list(set(QuantizationTransformPass._supported_quantizable_op_type + AddQuantDequantPass._supported_quantizable_op_type)) - + # Check inputs assert executor is not None, "The executor cannot be None." assert batch_size > 0, "The batch_size should be greater than 0." assert algo in self._support_algo_type, \ "The algo should be KL, abs_max or min_max." - + self._executor = executor self._dataset = dataset self._batch_size = batch_size @@ -154,20 +154,19 @@ class PaddleXPostTrainingQuantization(PostTrainingQuantization): logging.info("Start to run batch!") for data in self._data_loader(): start = time.time() - self._executor.run( - program=self._program, - feed=data, - fetch_list=self._fetch_list, - return_numpy=False) + with fluid.scope_guard(self._scope): + self._executor.run(program=self._program, + feed=data, + fetch_list=self._fetch_list, + return_numpy=False) if self._algo == "KL": self._sample_data(batch_id) else: self._sample_threshold() end = time.time() - logging.debug('[Run batch data] Batch={}/{}, time_each_batch={} s.'.format( - str(batch_id + 1), - str(batch_ct), - str(end-start))) + logging.debug( + '[Run batch data] Batch={}/{}, time_each_batch={} s.'.format( + str(batch_id + 1), str(batch_ct), str(end - start))) batch_id += 1 if self._batch_nums and batch_id >= self._batch_nums: break @@ -194,15 +193,16 @@ class PaddleXPostTrainingQuantization(PostTrainingQuantization): Returns: None ''' - feed_vars_names = [var.name for var in self._feed_list] - fluid.io.save_inference_model( - dirname=save_model_path, - feeded_var_names=feed_vars_names, - target_vars=self._fetch_list, - executor=self._executor, - params_filename='__params__', - main_program=self._program) - + with fluid.scope_guard(self._scope): + feed_vars_names = [var.name for var in self._feed_list] + fluid.io.save_inference_model( + dirname=save_model_path, + feeded_var_names=feed_vars_names, + target_vars=self._fetch_list, + executor=self._executor, + params_filename='__params__', + main_program=self._program) + def _load_model_data(self): ''' Set data loader. @@ -212,7 +212,8 @@ class PaddleXPostTrainingQuantization(PostTrainingQuantization): self._data_loader = fluid.io.DataLoader.from_generator( feed_list=feed_vars, capacity=3 * self._batch_size, iterable=True) self._data_loader.set_sample_list_generator( - self._dataset.generator(self._batch_size, drop_last=True), + self._dataset.generator( + self._batch_size, drop_last=True), places=self._place) def _calculate_kl_threshold(self): @@ -235,10 +236,12 @@ class PaddleXPostTrainingQuantization(PostTrainingQuantization): weight_threshold.append(abs_max_value) self._quantized_var_kl_threshold[var_name] = weight_threshold end = time.time() - logging.debug('[Calculate weight] Weight_id={}/{}, time_each_weight={} s.'.format( - str(ct), - str(len(self._quantized_weight_var_name)), - str(end-start))) + logging.debug( + '[Calculate weight] Weight_id={}/{}, time_each_weight={} s.'. + format( + str(ct), + str(len(self._quantized_weight_var_name)), str(end - + start))) ct += 1 ct = 1 @@ -257,10 +260,12 @@ class PaddleXPostTrainingQuantization(PostTrainingQuantization): self._quantized_var_kl_threshold[var_name] = \ self._get_kl_scaling_factor(np.abs(sampling_data)) end = time.time() - logging.debug('[Calculate activation] Activation_id={}/{}, time_each_activation={} s.'.format( - str(ct), - str(len(self._quantized_act_var_name)), - str(end-start))) + logging.debug( + '[Calculate activation] Activation_id={}/{}, time_each_activation={} s.'. + format( + str(ct), + str(len(self._quantized_act_var_name)), + str(end - start))) ct += 1 else: for var_name in self._quantized_act_var_name: @@ -270,10 +275,10 @@ class PaddleXPostTrainingQuantization(PostTrainingQuantization): self._quantized_var_kl_threshold[var_name] = \ self._get_kl_scaling_factor(np.abs(self._sampling_data[var_name])) end = time.time() - logging.debug('[Calculate activation] Activation_id={}/{}, time_each_activation={} s.'.format( - str(ct), - str(len(self._quantized_act_var_name)), - str(end-start))) + logging.debug( + '[Calculate activation] Activation_id={}/{}, time_each_activation={} s.'. + format( + str(ct), + str(len(self._quantized_act_var_name)), + str(end - start))) ct += 1 - - \ No newline at end of file diff --git a/paddlex/cv/models/yolo_v3.py b/paddlex/cv/models/yolo_v3.py index 85ee89fc86851ff9be104d0ee258eefce9843a69..0417431bdda69f109fc0a40f30d0ddac85174e82 100644 --- a/paddlex/cv/models/yolo_v3.py +++ b/paddlex/cv/models/yolo_v3.py @@ -1,11 +1,11 @@ # copyright (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. @@ -313,10 +313,12 @@ class YOLOv3(BaseAPI): images = np.array([d[0] for d in data]) im_sizes = np.array([d[1] for d in data]) feed_data = {'image': images, 'im_size': im_sizes} - outputs = self.exe.run(self.test_prog, - feed=[feed_data], - fetch_list=list(self.test_outputs.values()), - return_numpy=False) + with fluid.scope_guard(self.scope): + outputs = self.exe.run( + self.test_prog, + feed=[feed_data], + fetch_list=list(self.test_outputs.values()), + return_numpy=False) res = { 'bbox': (np.array(outputs[0]), outputs[0].recursive_sequence_lengths()) @@ -366,12 +368,13 @@ class YOLOv3(BaseAPI): im, im_size = self.test_transforms(img_file) im = np.expand_dims(im, axis=0) im_size = np.expand_dims(im_size, axis=0) - outputs = self.exe.run(self.test_prog, - feed={'image': im, - 'im_size': im_size}, - fetch_list=list(self.test_outputs.values()), - return_numpy=False, - use_program_cache=True) + with fluid.scope_guard(self.scope): + outputs = self.exe.run(self.test_prog, + feed={'image': im, + 'im_size': im_size}, + fetch_list=list(self.test_outputs.values()), + return_numpy=False, + use_program_cache=True) res = { k: (np.array(v), v.recursive_sequence_lengths()) for k, v in zip(list(self.test_outputs.keys()), outputs) diff --git a/paddlex/tools/x2coco.py b/paddlex/tools/x2coco.py index 4c893dcc9319ffc4353d4e376a802301d047120a..48a8b3d8ba4cc6a4261ad809d9e9c957390da40f 100644 --- a/paddlex/tools/x2coco.py +++ b/paddlex/tools/x2coco.py @@ -100,7 +100,7 @@ class LabelMe2COCO(X2COCO): image["height"] = json_info["imageHeight"] image["width"] = json_info["imageWidth"] image["id"] = image_id + 1 - image["file_name"] = json_info["imagePath"].split("/")[-1] + image["file_name"] = osp.split(json_info["imagePath"])[-1] return image def generate_polygon_anns_field(self, height, width,