未验证 提交 c1a88687 编写于 作者: C Chen Weihang 提交者: GitHub

Change jit.save/load configs to config & update code examples (#27056)

* change configs to config & update examples

* fix deprecate decorator conflict
上级 0443b480
...@@ -24,7 +24,7 @@ from . import learning_rate_scheduler ...@@ -24,7 +24,7 @@ from . import learning_rate_scheduler
import warnings import warnings
from .. import core from .. import core
from .base import guard from .base import guard
from paddle.fluid.dygraph.jit import SaveLoadConfig from paddle.fluid.dygraph.jit import SaveLoadConfig, deprecate_save_load_configs
from paddle.fluid.dygraph.io import _construct_program_holders, _construct_params_and_buffers from paddle.fluid.dygraph.io import _construct_program_holders, _construct_params_and_buffers
__all__ = [ __all__ = [
...@@ -42,9 +42,9 @@ def deprecate_keep_name_table(func): ...@@ -42,9 +42,9 @@ def deprecate_keep_name_table(func):
warnings.warn( warnings.warn(
"The argument `keep_name_table` has deprecated, please use `SaveLoadConfig.keep_name_table`.", "The argument `keep_name_table` has deprecated, please use `SaveLoadConfig.keep_name_table`.",
DeprecationWarning) DeprecationWarning)
configs = SaveLoadConfig() config = SaveLoadConfig()
configs.keep_name_table = keep_name_table config.keep_name_table = keep_name_table
return configs return config
# deal with arg `keep_name_table` # deal with arg `keep_name_table`
if len(args) > 1 and isinstance(args[1], bool): if len(args) > 1 and isinstance(args[1], bool):
...@@ -52,7 +52,7 @@ def deprecate_keep_name_table(func): ...@@ -52,7 +52,7 @@ def deprecate_keep_name_table(func):
args[1] = __warn_and_build_configs__(args[1]) args[1] = __warn_and_build_configs__(args[1])
# deal with kwargs # deal with kwargs
elif 'keep_name_table' in kwargs: elif 'keep_name_table' in kwargs:
kwargs['configs'] = __warn_and_build_configs__(kwargs[ kwargs['config'] = __warn_and_build_configs__(kwargs[
'keep_name_table']) 'keep_name_table'])
kwargs.pop('keep_name_table') kwargs.pop('keep_name_table')
else: else:
...@@ -135,8 +135,9 @@ def save_dygraph(state_dict, model_path): ...@@ -135,8 +135,9 @@ def save_dygraph(state_dict, model_path):
# TODO(qingqing01): remove dygraph_only to support loading static model. # TODO(qingqing01): remove dygraph_only to support loading static model.
# maybe need to unify the loading interface after 2.0 API is ready. # maybe need to unify the loading interface after 2.0 API is ready.
# @dygraph_only # @dygraph_only
@deprecate_save_load_configs
@deprecate_keep_name_table @deprecate_keep_name_table
def load_dygraph(model_path, configs=None): def load_dygraph(model_path, config=None):
''' '''
:api_attr: imperative :api_attr: imperative
...@@ -151,7 +152,7 @@ def load_dygraph(model_path, configs=None): ...@@ -151,7 +152,7 @@ def load_dygraph(model_path, configs=None):
Args: Args:
model_path(str) : The file prefix store the state_dict. model_path(str) : The file prefix store the state_dict.
(The path should Not contain suffix '.pdparams') (The path should Not contain suffix '.pdparams')
configs (SaveLoadConfig, optional): :ref:`api_imperative_jit_saveLoadConfig` config (SaveLoadConfig, optional): :ref:`api_imperative_jit_saveLoadConfig`
object that specifies additional configuration options, these options object that specifies additional configuration options, these options
are for compatibility with ``jit.save/io.save_inference_model`` formats. are for compatibility with ``jit.save/io.save_inference_model`` formats.
Default None. Default None.
...@@ -195,6 +196,7 @@ def load_dygraph(model_path, configs=None): ...@@ -195,6 +196,7 @@ def load_dygraph(model_path, configs=None):
opti_file_path = model_prefix + ".pdopt" opti_file_path = model_prefix + ".pdopt"
# deal with argument `configs` # deal with argument `configs`
configs = config
if configs is None: if configs is None:
configs = SaveLoadConfig() configs = SaveLoadConfig()
......
...@@ -17,6 +17,7 @@ from __future__ import print_function ...@@ -17,6 +17,7 @@ from __future__ import print_function
import os import os
import pickle import pickle
import warnings import warnings
import functools
import six import six
import paddle import paddle
...@@ -228,63 +229,60 @@ class SaveLoadConfig(object): ...@@ -228,63 +229,60 @@ class SaveLoadConfig(object):
.. code-block:: python .. code-block:: python
import numpy as np import paddle
import paddle.fluid as fluid import paddle.nn as nn
from paddle.fluid.dygraph import Linear import paddle.optimizer as opt
from paddle.fluid.dygraph import declarative
class SimpleNet(fluid.dygraph.Layer): class SimpleNet(nn.Layer):
def __init__(self, in_size, out_size): def __init__(self, in_size, out_size):
super(SimpleNet, self).__init__() super(SimpleNet, self).__init__()
self._linear = Linear(in_size, out_size) self._linear = nn.Linear(in_size, out_size)
@declarative @paddle.jit.to_static
def forward(self, x): def forward(self, x):
y = self._linear(x) y = self._linear(x)
z = self._linear(y) z = self._linear(y)
return z return z
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() paddle.disable_static()
# train model # train model
net = SimpleNet(8, 8) net = SimpleNet(8, 8)
adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) adam = opt.Adam(learning_rate=0.1, parameters=net.parameters())
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
for i in range(10): for i in range(10):
out = net(x) out = net(x)
loss = fluid.layers.mean(out) loss = paddle.tensor.mean(out)
loss.backward() loss.backward()
adam.minimize(loss) adam.step()
net.clear_gradients() adam.clear_grad()
# use SaveLoadconfig when saving model # use SaveLoadconfig when saving model
model_path = "simplenet.example.model" model_path = "simplenet.example.model"
configs = fluid.dygraph.jit.SaveLoadConfig() config = paddle.SaveLoadConfig()
configs.model_filename = "__simplenet__" config.model_filename = "__simplenet__"
fluid.dygraph.jit.save( paddle.jit.save(
layer=net, layer=net,
model_path=model_path, model_path=model_path,
input_spec=[x], config=config)
configs=configs)
2. Using ``SaveLoadConfig`` when loading model 2. Using ``SaveLoadConfig`` when loading model
.. code-block:: python .. code-block:: python
import numpy as np import paddle
import paddle.fluid as fluid
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() paddle.disable_static()
# use SaveLoadconfig when loading model # use SaveLoadconfig when loading model
model_path = "simplenet.example.model" model_path = "simplenet.example.model"
configs = fluid.dygraph.jit.SaveLoadConfig() config = paddle.SaveLoadConfig()
configs.model_filename = "__simplenet__" config.model_filename = "__simplenet__"
infer_net = fluid.dygraph.jit.load(model_path, configs=configs) infer_net = paddle.jit.load(model_path, config=config)
# inference # inference
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
pred = infer_net(x) pred = infer_net(x)
""" """
...@@ -324,51 +322,46 @@ class SaveLoadConfig(object): ...@@ -324,51 +322,46 @@ class SaveLoadConfig(object):
Examples: Examples:
.. code-block:: python .. code-block:: python
import numpy as np import paddle
import paddle.fluid as fluid import paddle.nn as nn
from paddle.fluid.dygraph import Linear import paddle.optimizer as opt
from paddle.fluid.dygraph import declarative
class SimpleNet(fluid.dygraph.Layer): class SimpleNet(nn.Layer):
def __init__(self, in_size, out_size): def __init__(self, in_size, out_size):
super(SimpleNet, self).__init__() super(SimpleNet, self).__init__()
self._linear = Linear(in_size, out_size) self._linear = nn.Linear(in_size, out_size)
@declarative @paddle.jit.to_static
def forward(self, x): def forward(self, x):
y = self._linear(x) y = self._linear(x)
z = self._linear(y) z = self._linear(y)
loss = fluid.layers.mean(z) loss = paddle.tensor.mean(z)
return z, loss return z, loss
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() paddle.disable_static()
# train model # train model
net = SimpleNet(8, 8) net = SimpleNet(8, 8)
adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) adam = opt.Adam(learning_rate=0.1, parameters=net.parameters())
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
for i in range(10): for i in range(10):
out, loss = net(x) out, loss = net(x)
loss.backward() loss.backward()
adam.minimize(loss) adam.step()
net.clear_gradients() adam.clear_grad()
# use SaveLoadconfig.output_spec # use SaveLoadconfig.output_spec
model_path = "simplenet.example.model.output_spec" model_path = "simplenet.example.model.output_spec"
configs = fluid.dygraph.jit.SaveLoadConfig() config = paddle.SaveLoadConfig()
# only keep the predicted output in saved model, discard loss config.output_spec = [out]
configs.output_spec = [out] paddle.jit.save(
fluid.dygraph.jit.save(
layer=net, layer=net,
model_path=model_path, model_path=model_path,
input_spec=[x], config=config)
configs=configs)
infer_net = fluid.dygraph.jit.load(model_path, configs=configs) infer_net = paddle.jit.load(model_path)
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
# only have the predicted output
pred = infer_net(x) pred = infer_net(x)
""" """
return self._output_spec return self._output_spec
...@@ -395,52 +388,47 @@ class SaveLoadConfig(object): ...@@ -395,52 +388,47 @@ class SaveLoadConfig(object):
Examples: Examples:
.. code-block:: python .. code-block:: python
import numpy as np import paddle
import paddle.fluid as fluid import paddle.nn as nn
from paddle.fluid.dygraph import Linear import paddle.optimizer as opt
from paddle.fluid.dygraph import declarative
class SimpleNet(fluid.dygraph.Layer): class SimpleNet(nn.Layer):
def __init__(self, in_size, out_size): def __init__(self, in_size, out_size):
super(SimpleNet, self).__init__() super(SimpleNet, self).__init__()
self._linear = Linear(in_size, out_size) self._linear = nn.Linear(in_size, out_size)
@declarative @paddle.jit.to_static
def forward(self, x): def forward(self, x):
y = self._linear(x) y = self._linear(x)
z = self._linear(y) z = self._linear(y)
return z return z
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() paddle.disable_static()
# train model # train model
net = SimpleNet(8, 8) net = SimpleNet(8, 8)
adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) adam = opt.Adam(learning_rate=0.1, parameters=net.parameters())
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
for i in range(10): for i in range(10):
out = net(x) out = net(x)
loss = fluid.layers.mean(out) loss = paddle.tensor.mean(out)
loss.backward() loss.backward()
adam.minimize(loss) adam.step()
net.clear_gradients() adam.clear_grad()
model_path = "simplenet.example.model.model_filename"
configs = fluid.dygraph.jit.SaveLoadConfig()
configs.model_filename = "__simplenet__"
# saving with configs.model_filename # saving with configs.model_filename
fluid.dygraph.jit.save( model_path = "simplenet.example.model.model_filename"
config = paddle.SaveLoadConfig()
config.model_filename = "__simplenet__"
paddle.jit.save(
layer=net, layer=net,
model_path=model_path, model_path=model_path,
input_spec=[x], config=config)
configs=configs)
# [result] the saved model directory contains:
# __simplenet__ __variables__ __variables.info__
# loading with configs.model_filename # loading with configs.model_filename
infer_net = fluid.dygraph.jit.load(model_path, configs=configs) infer_net = paddle.jit.load(model_path, config=config)
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
pred = infer_net(x) pred = infer_net(x)
""" """
return self._model_filename return self._model_filename
...@@ -465,52 +453,48 @@ class SaveLoadConfig(object): ...@@ -465,52 +453,48 @@ class SaveLoadConfig(object):
Examples: Examples:
.. code-block:: python .. code-block:: python
import numpy as np import paddle
import paddle.fluid as fluid import paddle.nn as nn
from paddle.fluid.dygraph import Linear import paddle.optimizer as opt
from paddle.fluid.dygraph import declarative
class SimpleNet(fluid.dygraph.Layer): class SimpleNet(nn.Layer):
def __init__(self, in_size, out_size): def __init__(self, in_size, out_size):
super(SimpleNet, self).__init__() super(SimpleNet, self).__init__()
self._linear = Linear(in_size, out_size) self._linear = nn.Linear(in_size, out_size)
@declarative @paddle.jit.to_static
def forward(self, x): def forward(self, x):
y = self._linear(x) y = self._linear(x)
z = self._linear(y) z = self._linear(y)
return z return z
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() paddle.disable_static()
# train model # train model
net = SimpleNet(8, 8) net = SimpleNet(8, 8)
adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) adam = opt.Adam(learning_rate=0.1, parameters=net.parameters())
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
for i in range(10): for i in range(10):
out = net(x) out = net(x)
loss = fluid.layers.mean(out) loss = paddle.tensor.mean(out)
loss.backward() loss.backward()
adam.minimize(loss) adam.step()
net.clear_gradients() adam.clear_grad()
model_path = "simplenet.example.model.params_filename" model_path = "simplenet.example.model.params_filename"
configs = fluid.dygraph.jit.SaveLoadConfig() config = paddle.SaveLoadConfig()
configs.params_filename = "__params__" config.params_filename = "__params__"
# saving with configs.params_filename # saving with configs.params_filename
fluid.dygraph.jit.save( paddle.jit.save(
layer=net, layer=net,
model_path=model_path, model_path=model_path,
input_spec=[x], config=config)
configs=configs)
# [result] the saved model directory contains:
# __model__ __params__ __variables.info__
# loading with configs.params_filename # loading with configs.params_filename
infer_net = fluid.dygraph.jit.load(model_path, configs=configs) infer_net = paddle.jit.load(model_path, config=config)
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
pred = infer_net(x) pred = infer_net(x)
""" """
return self._params_filename return self._params_filename
...@@ -544,52 +528,50 @@ class SaveLoadConfig(object): ...@@ -544,52 +528,50 @@ class SaveLoadConfig(object):
Examples: Examples:
.. code-block:: python .. code-block:: python
import numpy as np import paddle
import paddle.fluid as fluid import paddle.nn as nn
from paddle.fluid.dygraph import Linear import paddle.optimizer as opt
from paddle.fluid.dygraph import declarative
class SimpleNet(fluid.dygraph.Layer): class SimpleNet(nn.Layer):
def __init__(self, in_size, out_size): def __init__(self, in_size, out_size):
super(SimpleNet, self).__init__() super(SimpleNet, self).__init__()
self._linear = Linear(in_size, out_size) self._linear = nn.Linear(in_size, out_size)
@declarative @paddle.jit.to_static
def forward(self, x): def forward(self, x):
y = self._linear(x) y = self._linear(x)
z = self._linear(y) z = self._linear(y)
return z return z
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() paddle.disable_static()
# train model # train model
net = SimpleNet(8, 8) net = SimpleNet(8, 8)
adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) adam = opt.Adam(learning_rate=0.1, parameters=net.parameters())
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
for i in range(10): for i in range(10):
out = net(x) out = net(x)
loss = fluid.layers.mean(out) loss = paddle.tensor.mean(out)
loss.backward() loss.backward()
adam.minimize(loss) adam.step()
net.clear_gradients() adam.clear_grad()
model_path = "simplenet.example.model.separate_params" model_path = "simplenet.example.model.separate_params"
configs = fluid.dygraph.jit.SaveLoadConfig() config = paddle.jit.SaveLoadConfig()
configs.separate_params = True config.separate_params = True
# saving with configs.separate_params # saving with configs.separate_params
fluid.dygraph.jit.save( paddle.jit.save(
layer=net, layer=net,
model_path=model_path, model_path=model_path,
input_spec=[x], config=config)
configs=configs)
# [result] the saved model directory contains: # [result] the saved model directory contains:
# linear_0.b_0 linear_0.w_0 __model__ __variables.info__ # linear_0.b_0 linear_0.w_0 __model__ __variables.info__
# loading with configs.params_filename # loading with configs.params_filename
infer_net = fluid.dygraph.jit.load(model_path, configs=configs) infer_net = paddle.jit.load(model_path, config=config)
x = fluid.dygraph.to_variable(np.random.random((4, 8)).astype('float32')) x = paddle.randn([4, 8], 'float32')
pred = infer_net(x) pred = infer_net(x)
""" """
return self._separate_params return self._separate_params
...@@ -651,8 +633,21 @@ class SaveLoadConfig(object): ...@@ -651,8 +633,21 @@ class SaveLoadConfig(object):
self._keep_name_table = value self._keep_name_table = value
# NOTE(chenweihang): change jit.save/load argument `configs` to `config`
def deprecate_save_load_configs(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if 'configs' in kwargs:
kwargs['config'] = kwargs['configs']
kwargs.pop('configs')
return func(*args, **kwargs)
return wrapper
@deprecate_save_load_configs
@switch_to_static_graph @switch_to_static_graph
def save(layer, model_path, input_spec=None, configs=None): def save(layer, model_path, input_spec=None, config=None):
""" """
Saves input declarative Layer as :ref:`api_imperative_TranslatedLayer` Saves input declarative Layer as :ref:`api_imperative_TranslatedLayer`
format model, which can be used for inference or fine-tuning after loading. format model, which can be used for inference or fine-tuning after loading.
...@@ -677,7 +672,7 @@ def save(layer, model_path, input_spec=None, configs=None): ...@@ -677,7 +672,7 @@ def save(layer, model_path, input_spec=None, configs=None):
It is the example inputs that will be passed to saved TranslatedLayer's forward It is the example inputs that will be passed to saved TranslatedLayer's forward
function. If None, all input variables of the original Layer's forward function function. If None, all input variables of the original Layer's forward function
would be the inputs of the saved model. Default None. would be the inputs of the saved model. Default None.
configs (SaveLoadConfig, optional): :ref:`api_imperative_jit_saveLoadConfig` object config (SaveLoadConfig, optional): :ref:`api_imperative_jit_saveLoadConfig` object
that specifies additional configuration options. Default None. that specifies additional configuration options. Default None.
Returns: Returns:
None None
...@@ -686,65 +681,76 @@ def save(layer, model_path, input_spec=None, configs=None): ...@@ -686,65 +681,76 @@ def save(layer, model_path, input_spec=None, configs=None):
.. code-block:: python .. code-block:: python
import numpy as np import numpy as np
import paddle.fluid as fluid import paddle
from paddle.fluid.dygraph import Linear import paddle.nn as nn
from paddle.fluid.dygraph import declarative import paddle.optimizer as opt
BATCH_SIZE = 32 BATCH_SIZE = 16
BATCH_NUM = 20 BATCH_NUM = 4
EPOCH_NUM = 4
def random_batch_reader(): IMAGE_SIZE = 784
def _get_random_images_and_labels(image_shape, label_shape): CLASS_NUM = 10
image = np.random.random(size=image_shape).astype('float32')
label = np.random.random(size=label_shape).astype('int64')
return image, label
def __reader__(): # define a random dataset
for _ in range(BATCH_NUM): class RandomDataset(paddle.io.Dataset):
batch_image, batch_label = _get_random_images_and_labels( def __init__(self, num_samples):
[BATCH_SIZE, 784], [BATCH_SIZE, 1]) self.num_samples = num_samples
yield batch_image, batch_label
return __reader__ def __getitem__(self, idx):
image = np.random.random([IMAGE_SIZE]).astype('float32')
label = np.random.randint(0, CLASS_NUM - 1, (1, )).astype('int64')
return image, label
class LinearNet(fluid.dygraph.Layer): def __len__(self):
def __init__(self, in_size, out_size): return self.num_samples
class LinearNet(nn.Layer):
def __init__(self):
super(LinearNet, self).__init__() super(LinearNet, self).__init__()
self._linear = Linear(in_size, out_size) self._linear = nn.Linear(IMAGE_SIZE, CLASS_NUM)
@declarative @paddle.jit.to_static
def forward(self, x): def forward(self, x):
return self._linear(x) return self._linear(x)
def train(layer, loader, loss_fn, opt):
for epoch_id in range(EPOCH_NUM):
for batch_id, (image, label) in enumerate(loader()):
out = layer(image)
loss = loss_fn(out, label)
loss.backward()
opt.step()
opt.clear_grad()
print("Epoch {} batch {}: loss = {}".format(
epoch_id, batch_id, np.mean(loss.numpy())))
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() place = paddle.CPUPlace()
paddle.disable_static(place)
# create network # 1. train & save model.
net = LinearNet(784, 1)
adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters())
# create data loader
train_loader = fluid.io.DataLoader.from_generator(capacity=5)
train_loader.set_batch_generator(random_batch_reader())
# train
for data in train_loader():
img, label = data
label.stop_gradient = True
cost = net(img) # create network
layer = LinearNet()
loss_fn = nn.CrossEntropyLoss()
adam = opt.Adam(learning_rate=0.001, parameters=layer.parameters())
loss = fluid.layers.cross_entropy(cost, label) # create data loader
avg_loss = fluid.layers.mean(loss) dataset = RandomDataset(BATCH_NUM * BATCH_SIZE)
loader = paddle.io.DataLoader(dataset,
places=place,
batch_size=BATCH_SIZE,
shuffle=True,
drop_last=True,
num_workers=2)
avg_loss.backward() # train
adam.minimize(avg_loss) train(layer, loader, loss_fn, adam)
net.clear_gradients()
# save model # save
model_path = "linear.example.model" model_path = "linear.example.model"
fluid.dygraph.jit.save( paddle.jit.save(layer, model_path)
layer=net,
model_path=model_path,
input_spec=[img])
""" """
def get_inout_spec(all_vars, target_vars, return_name=False): def get_inout_spec(all_vars, target_vars, return_name=False):
...@@ -778,6 +784,7 @@ def save(layer, model_path, input_spec=None, configs=None): ...@@ -778,6 +784,7 @@ def save(layer, model_path, input_spec=None, configs=None):
"The input layer of paddle.jit.save should be 'Layer', but received layer type is %s." "The input layer of paddle.jit.save should be 'Layer', but received layer type is %s."
% type(layer)) % type(layer))
configs = config
if configs is None: if configs is None:
configs = SaveLoadConfig() configs = SaveLoadConfig()
...@@ -869,8 +876,9 @@ def save(layer, model_path, input_spec=None, configs=None): ...@@ -869,8 +876,9 @@ def save(layer, model_path, input_spec=None, configs=None):
pickle.dump(extra_var_info, f, protocol=2) pickle.dump(extra_var_info, f, protocol=2)
@deprecate_save_load_configs
@dygraph_only @dygraph_only
def load(model_path, configs=None): def load(model_path, config=None):
""" """
:api_attr: imperative :api_attr: imperative
...@@ -887,7 +895,7 @@ def load(model_path, configs=None): ...@@ -887,7 +895,7 @@ def load(model_path, configs=None):
Args: Args:
model_path (str): The directory path where the model is saved. model_path (str): The directory path where the model is saved.
configs (SaveLoadConfig, optional): :ref:`api_imperative_jit_saveLoadConfig` object that specifies config (SaveLoadConfig, optional): :ref:`api_imperative_jit_saveLoadConfig` object that specifies
additional configuration options. Default None. additional configuration options. Default None.
Returns: Returns:
...@@ -899,122 +907,126 @@ def load(model_path, configs=None): ...@@ -899,122 +907,126 @@ def load(model_path, configs=None):
.. code-block:: python .. code-block:: python
import numpy as np import numpy as np
import paddle.fluid as fluid import paddle
from paddle.fluid.dygraph import Linear import paddle.nn as nn
from paddle.fluid.dygraph import declarative import paddle.optimizer as opt
BATCH_SIZE = 32 BATCH_SIZE = 16
BATCH_NUM = 20 BATCH_NUM = 4
EPOCH_NUM = 4
def random_batch_reader(): IMAGE_SIZE = 784
def _get_random_images_and_labels(image_shape, label_shape): CLASS_NUM = 10
image = np.random.random(size=image_shape).astype('float32')
label = np.random.random(size=label_shape).astype('int64') # define a random dataset
return image, label class RandomDataset(paddle.io.Dataset):
def __init__(self, num_samples):
self.num_samples = num_samples
def __reader__(): def __getitem__(self, idx):
for _ in range(BATCH_NUM): image = np.random.random([IMAGE_SIZE]).astype('float32')
batch_image, batch_label = _get_random_images_and_labels( label = np.random.randint(0, CLASS_NUM - 1, (1, )).astype('int64')
[BATCH_SIZE, 784], [BATCH_SIZE, 1]) return image, label
yield batch_image, batch_label
return __reader__ def __len__(self):
return self.num_samples
class LinearNet(fluid.dygraph.Layer): class LinearNet(nn.Layer):
def __init__(self, in_size, out_size): def __init__(self):
super(LinearNet, self).__init__() super(LinearNet, self).__init__()
self._linear = Linear(in_size, out_size) self._linear = nn.Linear(IMAGE_SIZE, CLASS_NUM)
@declarative @paddle.jit.to_static
def forward(self, x): def forward(self, x):
return self._linear(x) return self._linear(x)
def train(layer, loader, loss_fn, opt):
for epoch_id in range(EPOCH_NUM):
for batch_id, (image, label) in enumerate(loader()):
out = layer(image)
loss = loss_fn(out, label)
loss.backward()
opt.step()
opt.clear_grad()
print("Epoch {} batch {}: loss = {}".format(
epoch_id, batch_id, np.mean(loss.numpy())))
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() place = paddle.CPUPlace()
paddle.disable_static(place)
# 1. train & save model. # 1. train & save model.
# create network # create network
net = LinearNet(784, 1) layer = LinearNet()
adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=net.parameters()) loss_fn = nn.CrossEntropyLoss()
adam = opt.Adam(learning_rate=0.001, parameters=layer.parameters())
# create data loader # create data loader
train_loader = fluid.io.DataLoader.from_generator(capacity=5) dataset = RandomDataset(BATCH_NUM * BATCH_SIZE)
train_loader.set_batch_generator(random_batch_reader()) loader = paddle.io.DataLoader(dataset,
# train places=place,
for data in train_loader(): batch_size=BATCH_SIZE,
img, label = data shuffle=True,
label.stop_gradient = True drop_last=True,
num_workers=2)
cost = net(img) # train
train(layer, loader, loss_fn, adam)
loss = fluid.layers.cross_entropy(cost, label) # save
avg_loss = fluid.layers.mean(loss) model_path = "linear.example.model"
paddle.jit.save(layer, model_path)
avg_loss.backward() # 2. load model
adam.minimize(avg_loss)
net.clear_gradients()
model_path = "linear.example.model" # load
fluid.dygraph.jit.save( loaded_layer = paddle.jit.load(model_path)
layer=net,
model_path=model_path,
input_spec=[img])
# 2. load model & inference
# load model
infer_net = fluid.dygraph.jit.load(model_path)
# inference # inference
x = fluid.dygraph.to_variable(np.random.random((1, 784)).astype('float32')) loaded_layer.eval()
pred = infer_net(x) x = paddle.randn([1, IMAGE_SIZE], 'float32')
pred = loaded_layer(x)
# 3. load model & fine-tune
# load model
train_net = fluid.dygraph.jit.load(model_path)
train_net.train()
adam = fluid.optimizer.AdamOptimizer(learning_rate=0.1, parameter_list=train_net.parameters())
# create data loader
train_loader = fluid.io.DataLoader.from_generator(capacity=5)
train_loader.set_batch_generator(random_batch_reader())
# fine-tune # fine-tune
for data in train_loader(): loaded_layer.train()
img, label = data adam = opt.Adam(learning_rate=0.001, parameters=loaded_layer.parameters())
label.stop_gradient = True train(loaded_layer, loader, loss_fn, adam)
cost = train_net(img)
loss = fluid.layers.cross_entropy(cost, label)
avg_loss = fluid.layers.mean(loss)
avg_loss.backward()
adam.minimize(avg_loss)
train_net.clear_gradients()
2. Load model saved by :ref:`api_fluid_io_save_inference_model` then performing and fine-tune training. 2. Load model saved by :ref:`api_fluid_io_save_inference_model` then performing and fine-tune training.
.. code-block:: python .. code-block:: python
import numpy as np import numpy as np
import paddle
import paddle.fluid as fluid import paddle.fluid as fluid
import paddle.nn as nn
import paddle.optimizer as opt
BATCH_SIZE = 32 BATCH_SIZE = 16
BATCH_NUM = 20 BATCH_NUM = 4
EPOCH_NUM = 4
def random_batch_reader(): IMAGE_SIZE = 784
def _get_random_images_and_labels(image_shape, label_shape): CLASS_NUM = 10
image = np.random.random(size=image_shape).astype('float32')
label = np.random.random(size=label_shape).astype('int64')
return image, label
def __reader__(): # define a random dataset
for _ in range(BATCH_NUM): class RandomDataset(paddle.io.Dataset):
batch_image, batch_label = _get_random_images_and_labels( def __init__(self, num_samples):
[BATCH_SIZE, 784], [BATCH_SIZE, 1]) self.num_samples = num_samples
yield batch_image, batch_label
return __reader__ def __getitem__(self, idx):
image = np.random.random([IMAGE_SIZE]).astype('float32')
label = np.random.randint(0, CLASS_NUM - 1, (1, )).astype('int64')
return image, label
def __len__(self):
return self.num_samples
img = fluid.data(name='img', shape=[None, 784], dtype='float32') image = fluid.data(name='image', shape=[None, 784], dtype='float32')
label = fluid.data(name='label', shape=[None, 1], dtype='int64') label = fluid.data(name='label', shape=[None, 1], dtype='int64')
pred = fluid.layers.fc(input=img, size=10, act='softmax') pred = fluid.layers.fc(input=image, size=10, act='softmax')
loss = fluid.layers.cross_entropy(input=pred, label=label) loss = fluid.layers.cross_entropy(input=pred, label=label)
avg_loss = fluid.layers.mean(loss) avg_loss = fluid.layers.mean(loss)
...@@ -1025,9 +1037,15 @@ def load(model_path, configs=None): ...@@ -1025,9 +1037,15 @@ def load(model_path, configs=None):
exe = fluid.Executor(place) exe = fluid.Executor(place)
exe.run(fluid.default_startup_program()) exe.run(fluid.default_startup_program())
loader = fluid.io.DataLoader.from_generator( # create data loader
feed_list=[img, label], capacity=5, iterable=True) dataset = RandomDataset(BATCH_NUM * BATCH_SIZE)
loader.set_batch_generator(random_batch_reader(), places=place) loader = paddle.io.DataLoader(dataset,
feed_list=[image, label],
places=place,
batch_size=BATCH_SIZE,
shuffle=True,
drop_last=True,
num_workers=2)
# 1. train and save inference model # 1. train and save inference model
for data in loader(): for data in loader():
...@@ -1038,39 +1056,42 @@ def load(model_path, configs=None): ...@@ -1038,39 +1056,42 @@ def load(model_path, configs=None):
model_path = "fc.example.model" model_path = "fc.example.model"
fluid.io.save_inference_model( fluid.io.save_inference_model(
model_path, ["img"], [pred], exe) model_path, ["image"], [pred], exe)
# 2. load model
# enable dygraph mode # enable dygraph mode
fluid.enable_dygraph() paddle.disable_static(place)
# 2. load model & inference # load
fc = fluid.dygraph.jit.load(model_path) fc = paddle.jit.load(model_path)
x = fluid.dygraph.to_variable(np.random.random((1, 784)).astype('float32'))
# inference
fc.eval()
x = paddle.randn([1, IMAGE_SIZE], 'float32')
pred = fc(x) pred = fc(x)
# 3. load model & fine-tune # fine-tune
fc = fluid.dygraph.jit.load(model_path)
fc.train() fc.train()
sgd = fluid.optimizer.SGD(learning_rate=0.001, loss_fn = nn.CrossEntropyLoss()
parameter_list=fc.parameters()) adam = opt.Adam(learning_rate=0.001, parameters=fc.parameters())
loader = paddle.io.DataLoader(dataset,
train_loader = fluid.io.DataLoader.from_generator(capacity=5) places=place,
train_loader.set_batch_generator( batch_size=BATCH_SIZE,
random_batch_reader(), places=place) shuffle=True,
drop_last=True,
for data in train_loader(): num_workers=2)
img, label = data for epoch_id in range(EPOCH_NUM):
label.stop_gradient = True for batch_id, (image, label) in enumerate(loader()):
out = fc(image)
cost = fc(img) loss = loss_fn(out, label)
loss.backward()
loss = fluid.layers.cross_entropy(cost, label) adam.step()
avg_loss = fluid.layers.mean(loss) adam.clear_grad()
print("Epoch {} batch {}: loss = {}".format(
avg_loss.backward() epoch_id, batch_id, np.mean(loss.numpy())))
sgd.minimize(avg_loss)
""" """
return TranslatedLayer._construct(model_path, configs) return TranslatedLayer._construct(model_path, config)
@dygraph_only @dygraph_only
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册