# copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved. # # 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 import os.path as osp import paddle.fluid as fluid import paddlex as pdx import numpy as np from paddle.fluid.param_attr import ParamAttr from paddlex.interpret.as_data_reader.readers import preprocess_image def gen_user_home(): if "HOME" in os.environ: home_path = os.environ["HOME"] if os.path.exists(home_path) and os.path.isdir(home_path): return home_path return os.path.expanduser('~') def paddle_get_fc_weights(var_name="fc_0.w_0"): fc_weights = fluid.global_scope().find_var(var_name).get_tensor() return np.array(fc_weights) def paddle_resize(extracted_features, outsize): resized_features = fluid.layers.resize_bilinear(extracted_features, outsize) return resized_features def get_precomputed_normlime_weights(): root_path = gen_user_home() root_path = osp.join(root_path, '.paddlex') h_pre_models = osp.join(root_path, "pre_models") normlime_weights_file = osp.join( h_pre_models, "normlime_weights_imagenet_resnet50vc.npy") return np.load(normlime_weights_file, allow_pickle=True).item() def compute_features_for_kmeans(data_content): root_path = gen_user_home() root_path = osp.join(root_path, '.paddlex') h_pre_models = osp.join(root_path, "pre_models") if not osp.exists(h_pre_models): if not osp.exists(root_path): os.makedirs(root_path) url = "https://bj.bcebos.com/paddlex/interpret/pre_models.tar.gz" pdx.utils.download_and_decompress(url, path=root_path) def conv_bn_layer(input, num_filters, filter_size, stride=1, groups=1, act=None, name=None, is_test=True, global_name='for_kmeans_'): conv = fluid.layers.conv2d( input=input, num_filters=num_filters, filter_size=filter_size, stride=stride, padding=(filter_size - 1) // 2, groups=groups, act=None, param_attr=ParamAttr(name=global_name + name + "_weights"), bias_attr=False, name=global_name + name + '.conv2d.output.1') if name == "conv1": bn_name = "bn_" + name else: bn_name = "bn" + name[3:] return fluid.layers.batch_norm( input=conv, act=act, name=global_name + bn_name + '.output.1', param_attr=ParamAttr(global_name + bn_name + '_scale'), bias_attr=ParamAttr(global_name + bn_name + '_offset'), moving_mean_name=global_name + bn_name + '_mean', moving_variance_name=global_name + bn_name + '_variance', use_global_stats=is_test) startup_prog = fluid.default_startup_program().clone(for_test=True) prog = fluid.Program() with fluid.program_guard(prog, startup_prog): with fluid.unique_name.guard(): image_op = fluid.data( name='image', shape=[None, 3, 224, 224], dtype='float32') conv = conv_bn_layer( input=image_op, num_filters=32, filter_size=3, stride=2, act='relu', name='conv1_1') conv = conv_bn_layer( input=conv, num_filters=32, filter_size=3, stride=1, act='relu', name='conv1_2') conv = conv_bn_layer( input=conv, num_filters=64, filter_size=3, stride=1, act='relu', name='conv1_3') extracted_features = conv resized_features = fluid.layers.resize_bilinear(extracted_features, image_op.shape[2:]) gpu_id = int(os.environ.get('FLAGS_selected_gpus', 0)) place = fluid.CUDAPlace(gpu_id) # place = fluid.CPUPlace() exe = fluid.Executor(place) exe.run(startup_prog) fluid.io.load_persistables(exe, h_pre_models, prog) images = preprocess_image( data_content) # transpose to [N, 3, H, W], scaled to [0.0, 1.0] result = exe.run(prog, fetch_list=[resized_features], feed={'image': images}) return result[0][0]