def test_save_inference_model_with_auc(self): MODEL_DIR = "./tmp/inference_model4" init_program = Program() program = Program() # fake program without feed/fetch with program_guard(program, init_program): x = layers.data(name='x', shape=[2], dtype='float32') y = layers.data(name='y', shape=[1], dtype='int32') predict = fluid.layers.fc(input=x, size=2, act='softmax') acc = fluid.layers.accuracy(input=predict, label=y) auc_var, batch_auc_var, auc_states = fluid.layers.auc( input=predict, label=y) cost = fluid.layers.cross_entropy(input=predict, label=y) avg_cost = fluid.layers.mean(x=cost) place = core.CPUPlace() exe = executor.Executor(place) exe.run(init_program, feed={}, fetch_list=[]) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") save_inference_model(MODEL_DIR, ["x", "y"], [avg_cost], exe, program) expected_warn = "please ensure that you have set the auc states to zeros before saving inference model" self.assertTrue(len(w) > 0) self.assertTrue(expected_warn == str(w[0].message))
def test_save_inference_model(self): MODEL_DIR = "./tmp/inference_model3" init_program = Program() program = Program() # fake program without feed/fetch with program_guard(program, init_program): x = layers.data(name='x', shape=[2], dtype='float32') y = layers.data(name='y', shape=[1], dtype='float32') y_predict = layers.fc(input=x, size=1, act=None) cost = layers.square_error_cost(input=y_predict, label=y) avg_cost = layers.mean(cost) place = core.CPUPlace() exe = executor.Executor(place) exe.run(init_program, feed={}, fetch_list=[]) # will print warning message cp_prog = CompiledProgram(program).with_data_parallel( loss_name=avg_cost.name) save_inference_model(MODEL_DIR, ["x", "y"], [avg_cost], exe, cp_prog) self.assertRaises(TypeError, save_inference_model, [MODEL_DIR, ["x", "y"], [avg_cost], [], cp_prog])
def __init__(self, exe=None, place=None): # To make sure that calls __init__ only once. if self._initialized: return self._initialized = True self._place = core.CPUPlace() if place is None else place if exe is None: self._exe = executor.Executor(self._place) else: self._exe = exe self._program_cache = ProgramCache() self._optimizer = None self._already_minimized = False # Once main_program is changed, should run startup_program. self._need_startup = True
def test_normalize_program(self): init_program = fluid.default_startup_program() program = fluid.default_main_program() # fake program without feed/fetch with program_guard(program, init_program): x = layers.data(name='x', shape=[2], dtype='float32') y = layers.data(name='y', shape=[1], dtype='float32') y_predict = layers.fc(input=x, size=1, act=None) cost = layers.square_error_cost(input=y_predict, label=y) avg_cost = layers.mean(cost) sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.001) sgd_optimizer.minimize(avg_cost, init_program) place = core.CPUPlace() exe = executor.Executor(place) exe.run(init_program, feed={}, fetch_list=[]) tensor_x = np.array([[1, 1], [1, 2], [5, 2]]).astype("float32") tensor_y = np.array([[-2], [-3], [-7]]).astype("float32") for i in six.moves.xrange(3): exe.run(program, feed={ 'x': tensor_x, 'y': tensor_y }, fetch_list=[avg_cost]) # test if return type of serialize_program is bytes res = paddle.static.normalize_program(program, [x, y], [avg_cost]) self.assertTrue(isinstance(res, Program)) # test program type self.assertRaises(TypeError, paddle.static.normalize_program, None, [x, y], [avg_cost]) # test feed_vars type self.assertRaises(TypeError, paddle.static.normalize_program, program, 'x', [avg_cost]) # test fetch_vars type self.assertRaises(TypeError, paddle.static.normalize_program, program, [x, y], 'avg_cost')
def test_save_inference_model(self): MODEL_DIR = "./tmp/inference_model2" init_program = Program() program = Program() # fake program without feed/fetch with program_guard(program, init_program): x = layers.data(name='x', shape=[2], dtype='float32') y = layers.data(name='y', shape=[1], dtype='float32') y_predict = layers.fc(input=x, size=1, act=None) cost = layers.square_error_cost(input=y_predict, label=y) avg_cost = layers.mean(cost) place = core.CPUPlace() exe = executor.Executor(place) exe.run(init_program, feed={}, fetch_list=[]) save_inference_model(MODEL_DIR, ["x", "y"], [avg_cost], exe, program)
def test_fit_line_inference_model(self): MODEL_DIR = "./tmp/inference_model" UNI_MODEL_DIR = "./tmp/inference_model1" init_program = Program() program = Program() with program_guard(program, init_program): x = layers.data(name='x', shape=[2], dtype='float32') y = layers.data(name='y', shape=[1], dtype='float32') y_predict = layers.fc(input=x, size=1, act=None) cost = layers.square_error_cost(input=y_predict, label=y) avg_cost = layers.mean(cost) sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.001) sgd_optimizer.minimize(avg_cost, init_program) place = core.CPUPlace() exe = executor.Executor(place) exe.run(init_program, feed={}, fetch_list=[]) for i in six.moves.xrange(100): tensor_x = np.array([[1, 1], [1, 2], [3, 4], [5, 2]]).astype("float32") tensor_y = np.array([[-2], [-3], [-7], [-7]]).astype("float32") exe.run(program, feed={ 'x': tensor_x, 'y': tensor_y }, fetch_list=[avg_cost]) # Separated model and unified model save_inference_model(MODEL_DIR, ["x", "y"], [avg_cost], exe, program) save_inference_model(UNI_MODEL_DIR, ["x", "y"], [avg_cost], exe, program, 'model', 'params') main_program = program.clone()._prune_with_input( feeded_var_names=["x", "y"], targets=[avg_cost]) params_str = save_persistables(exe, None, main_program, None) expected = exe.run(program, feed={ 'x': tensor_x, 'y': tensor_y }, fetch_list=[avg_cost])[0] six.moves.reload_module(executor) # reload to build a new scope model_0 = InferModel(load_inference_model(MODEL_DIR, exe)) with open(os.path.join(UNI_MODEL_DIR, 'model'), "rb") as f: model_str = f.read() model_1 = InferModel( load_inference_model(None, exe, model_str, params_str)) for model in [model_0, model_1]: outs = exe.run(model.program, feed={ model.feed_var_names[0]: tensor_x, model.feed_var_names[1]: tensor_y }, fetch_list=model.fetch_vars) actual = outs[0] self.assertEqual(model.feed_var_names, ["x", "y"]) self.assertEqual(len(model.fetch_vars), 1) print("fetch %s" % str(model.fetch_vars[0])) self.assertEqual(expected, actual) self.assertRaises(ValueError, fluid.io.load_inference_model, None, exe, model_str, None)
def test_load_model_not_exist(self): place = core.CPUPlace() exe = executor.Executor(place) self.assertRaises(ValueError, load_inference_model, './test_not_exist_dir', exe)
def test_save_and_load_inference_model(self): MODEL_DIR = "./tmp/inference_model5" init_program = fluid.default_startup_program() program = fluid.default_main_program() # fake program without feed/fetch with program_guard(program, init_program): x = layers.data(name='x', shape=[2], dtype='float32') y = layers.data(name='y', shape=[1], dtype='float32') y_predict = layers.fc(input=x, size=1, act=None) cost = layers.square_error_cost(input=y_predict, label=y) avg_cost = layers.mean(cost) sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.001) sgd_optimizer.minimize(avg_cost, init_program) place = core.CPUPlace() exe = executor.Executor(place) exe.run(init_program, feed={}, fetch_list=[]) tensor_x = np.array([[1, 1], [1, 2], [5, 2]]).astype("float32") tensor_y = np.array([[-2], [-3], [-7]]).astype("float32") for i in six.moves.xrange(3): exe.run(program, feed={ 'x': tensor_x, 'y': tensor_y }, fetch_list=[avg_cost]) self.assertRaises(ValueError, paddle.static.save_inference_model, None, ['x', 'y'], [avg_cost], exe) self.assertRaises(ValueError, paddle.static.save_inference_model, MODEL_DIR + "/", [x, y], [avg_cost], exe) self.assertRaises(ValueError, paddle.static.save_inference_model, MODEL_DIR, ['x', 'y'], [avg_cost], exe) self.assertRaises(ValueError, paddle.static.save_inference_model, MODEL_DIR, 'x', [avg_cost], exe) self.assertRaises(ValueError, paddle.static.save_inference_model, MODEL_DIR, [x, y], ['avg_cost'], exe) self.assertRaises(ValueError, paddle.static.save_inference_model, MODEL_DIR, [x, y], 'avg_cost', exe) model_path = MODEL_DIR + "_isdir.pdmodel" os.makedirs(model_path) self.assertRaises(ValueError, paddle.static.save_inference_model, MODEL_DIR + "_isdir", [x, y], [avg_cost], exe) os.rmdir(model_path) params_path = MODEL_DIR + "_isdir.pdmodel" os.makedirs(params_path) self.assertRaises(ValueError, paddle.static.save_inference_model, MODEL_DIR + "_isdir", [x, y], [avg_cost], exe) os.rmdir(params_path) paddle.static.io.save_inference_model(MODEL_DIR, [x, y], [avg_cost], exe) self.assertTrue(os.path.exists(MODEL_DIR + ".pdmodel")) self.assertTrue(os.path.exists(MODEL_DIR + ".pdiparams")) expected = exe.run(program, feed={ 'x': tensor_x, 'y': tensor_y }, fetch_list=[avg_cost])[0] six.moves.reload_module(executor) # reload to build a new scope self.assertRaises(ValueError, paddle.static.load_inference_model, None, exe) self.assertRaises(ValueError, paddle.static.load_inference_model, MODEL_DIR + "/", exe) self.assertRaises(ValueError, paddle.static.load_inference_model, [MODEL_DIR], exe) self.assertRaises(ValueError, paddle.static.load_inference_model, MODEL_DIR, exe, pserver_endpoints=None) self.assertRaises(ValueError, paddle.static.load_inference_model, MODEL_DIR, exe, unsupported_param=None) self.assertRaises((TypeError, ValueError), paddle.static.load_inference_model, None, exe, model_filename="illegal", params_filename="illegal") model = InferModel( paddle.static.io.load_inference_model(MODEL_DIR, exe)) outs = exe.run(model.program, feed={ model.feed_var_names[0]: tensor_x, model.feed_var_names[1]: tensor_y }, fetch_list=model.fetch_vars) actual = outs[0] self.assertEqual(model.feed_var_names, ["x", "y"]) self.assertEqual(len(model.fetch_vars), 1) self.assertEqual(expected, actual) # test save_to_file content type should be bytes self.assertRaises(ValueError, paddle.static.io.save_to_file, '', 123) # test _get_valid_program self.assertRaises(TypeError, paddle.static.io._get_valid_program, 0) p = Program() cp = CompiledProgram(p) paddle.static.io._get_valid_program(cp) self.assertTrue(paddle.static.io._get_valid_program(cp) is p) cp._program = None self.assertRaises(TypeError, paddle.static.io._get_valid_program, cp)
def test_fit_line_inference_model(self): MODEL_DIR = "./tmp/inference_model" init_program = Program() program = Program() with program_guard(program, init_program): x = layers.data(name='x', shape=[2], dtype='float32') y = layers.data(name='y', shape=[1], dtype='float32') y_predict = layers.fc(input=x, size=1, act=None) cost = layers.square_error_cost(input=y_predict, label=y) avg_cost = layers.mean(cost) sgd_optimizer = optimizer.SGDOptimizer(learning_rate=0.001) sgd_optimizer.minimize(avg_cost, init_program) place = core.CPUPlace() exe = executor.Executor(place) exe.run(init_program, feed={}, fetch_list=[]) for i in six.moves.xrange(100): tensor_x = np.array([[1, 1], [1, 2], [3, 4], [5, 2]]).astype("float32") tensor_y = np.array([[-2], [-3], [-7], [-7]]).astype("float32") exe.run(program, feed={ 'x': tensor_x, 'y': tensor_y }, fetch_list=[avg_cost]) save_inference_model(MODEL_DIR, ["x", "y"], [avg_cost], exe, program) expected = exe.run(program, feed={ 'x': tensor_x, 'y': tensor_y }, fetch_list=[avg_cost])[0] six.moves.reload_module(executor) # reload to build a new scope exe = executor.Executor(place) [infer_prog, feed_var_names, fetch_vars] = load_inference_model(MODEL_DIR, exe) outs = exe.run(infer_prog, feed={ feed_var_names[0]: tensor_x, feed_var_names[1]: tensor_y }, fetch_list=fetch_vars) actual = outs[0] self.assertEqual(feed_var_names, ["x", "y"]) self.assertEqual(len(fetch_vars), 1) print("fetch %s" % str(fetch_vars[0])) self.assertTrue("scale" in str(fetch_vars[0])) self.assertEqual(expected, actual)
def save_inference_model(self, dirname, feed=None, fetch=None): """ Saves current model as the inference model. It will prune the main_program to build a new program especially for inference, and then save it and all related parameters to given `dirname` . The saved inference model can be loaded by `:ref:`api_fluid_io_load_inference_model` or `C++ inference APIs. Args: dirname (str): the directory to save the inference model. feed (list[int], optional): the input variable indices of the saved inference model. If None, all input variables of the ProgramTranslator would be the inputs of the saved inference model. Default None. fetch (list[int], optional): the output variable indices of the saved inference model. If None, all output variables of the TracedLayer object would be the outputs of the saved inference model. Default None. Returns: None Examples: .. code-block:: python import numpy as np import paddle.fluid as fluid from paddle.fluid.dygraph import Linear from paddle.fluid.dygraph import declarative from paddle.fluid.dygraph import ProgramTranslator class SimpleNet(fluid.dygraph.Layer): def __init__(self, in_size, out_size): super(SimpleNet, self).__init__() self._linear = Linear(in_size, out_size) @declarative def forward(self, x): y = self._linear(x) z = self._linear(y) loss = fluid.layers.mean(z) return z, loss with fluid.dygraph.guard(fluid.CPUPlace()): net = SimpleNet(8, 8) adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) for i in range(10): loss, out = net(x) loss.backward() adam.minimize(loss) net.clear_gradients() # Save inference model. # Note that fetch=[0] means we set 'y' as the inference output. prog_trans = ProgramTranslator() prog_trans.save_inference_model("./dy2stat_infer_model", fetch=[0]) # In this example, the inference model will be pruned based on input (x) and # output (y). The pruned inference program is going to be saved in the folder # "./dy2stat_infer_model" and parameters are going to be saved in separate # files in the folder. """ def get_feed_fetch(var_list, partial_vars, return_name=False): vars = [ var for var in var_list if isinstance(var, framework.Variable) ] if partial_vars: vars = [vars[idx] for idx in partial_vars] if return_name: vars = [var.name for var in vars] return vars func_spec, (concrete_program, partial_layer) = self._program_cache.last() # share paramBase data with parameter scope = core.Scope() for param_base in concrete_program.parameters: param_tensor = scope.var(param_base.name).get_tensor() src_tensor = param_base.value().get_tensor() param_tensor._share_data_with(src_tensor) feed_var_names = get_feed_fetch(concrete_program.inputs, feed, True) fetch_vars = get_feed_fetch(concrete_program.outputs, fetch) from paddle.fluid.io import save_inference_model with scope_guard(scope): save_inference_model( dirname=dirname, feeded_var_names=feed_var_names, target_vars=fetch_vars, executor=executor.Executor( framework._current_expected_place()), main_program=concrete_program.main_program.clone())