load¶
将接口 paddle.jit.save
或者 paddle.static.save_inference_model
存储的模型载入为 paddle.jit.TranslatedLayer
,用于预测推理或者 fine-tune 训练。
注解
如果载入的模型是通过 paddle.static.save_inference_model
存储的,在使用它进行 fine-tune 训练时会存在一些局限: 1. 命令式编程模式不支持 LoDTensor
,所有原先输入变量或者参数依赖于 LoD 信息的模型暂时无法使用; 2. 所有存储模型的 feed 变量都需要被传入 Translatedlayer
的 forward 方法; 3. 原模型变量的 stop_gradient
信息已丢失且无法准确恢复; 4. 原模型参数的 trainable
信息已丢失且无法准确恢复。
参数¶
path (str) - 载入模型的路径前缀。格式为
dirname/file_prefix
或者file_prefix
。
- config (dict,可选) - 其他用于兼容的载入配置选项。这些选项将来可能被移除,如果不是必须使用,不推荐使用这些配置选项。默认为
None
。目前支持以下配置选项:
model_filename (str) - paddle 1.x 版本
save_inference_model
接口存储格式的预测模型文件名,原默认文件名为__model__
;params_filename (str) - paddle 1.x 版本
save_inference_model
接口存储格式的参数文件名,没有默认文件名,默认将各个参数分散存储为单独的文件。
返回¶
TranslatedLayer,一个能够执行存储模型的 Layer
对象。
代码示例¶
载入由接口 paddle.jit.save 存储的模型进行预测推理及 fine-tune 训练。
>>> import numpy as np
>>> import paddle
>>> import paddle.nn as nn
>>> import paddle.optimizer as opt
>>> BATCH_SIZE = 16
>>> BATCH_NUM = 4
>>> EPOCH_NUM = 4
>>> IMAGE_SIZE = 784
>>> CLASS_NUM = 10
>>> # define a random dataset
>>> class RandomDataset(paddle.io.Dataset):
... def __init__(self, num_samples):
... self.num_samples = num_samples
...
... 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
>>> class LinearNet(nn.Layer):
... def __init__(self):
... super().__init__()
... self._linear = nn.Linear(IMAGE_SIZE, CLASS_NUM)
...
... @paddle.jit.to_static
... def forward(self, 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())))
>>> # 1. train & save model.
>>> # create network
>>> layer = LinearNet()
>>> loss_fn = nn.CrossEntropyLoss()
>>> adam = opt.Adam(learning_rate=0.001, parameters=layer.parameters())
>>> # create data loader
>>> dataset = RandomDataset(BATCH_NUM * BATCH_SIZE)
>>> loader = paddle.io.DataLoader(
... dataset,
... batch_size=BATCH_SIZE,
... shuffle=True,
... drop_last=True,
... num_workers=2
... )
>>> # train
>>> train(layer, loader, loss_fn, adam)
>>> # save
>>> path = "example_model/linear"
>>> paddle.jit.save(layer, path)
>>> # 2. load model
>>> # load
>>> loaded_layer = paddle.jit.load(path)
>>> # inference
>>> loaded_layer.eval()
>>> x = paddle.randn([1, IMAGE_SIZE], 'float32')
>>> pred = loaded_layer(x)
>>> # fine-tune
>>> loaded_layer.train()
>>> adam = opt.Adam(learning_rate=0.001, parameters=loaded_layer.parameters())
>>> train(loaded_layer, loader, loss_fn, adam)
兼容载入由接口 paddle.static.save_inference_model 存储的模型进行预测推理及 fine-tune 训练。
>>> import numpy as np
>>> import paddle
>>> import paddle.static as static
>>> import paddle.nn as nn
>>> import paddle.optimizer as opt
>>> import paddle.nn.functional as F
>>> BATCH_SIZE = 16
>>> BATCH_NUM = 4
>>> EPOCH_NUM = 4
>>> IMAGE_SIZE = 784
>>> CLASS_NUM = 10
>>> # define a random dataset
>>> class RandomDataset(paddle.io.Dataset):
... def __init__(self, num_samples):
... self.num_samples = num_samples
...
... 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
>>> paddle.enable_static()
>>> image = static.data(name='image', shape=[None, 784], dtype='float32')
>>> label = static.data(name='label', shape=[None, 1], dtype='int64')
>>> pred = static.nn.fc(x=image, size=10, activation='softmax')
>>> loss = F.cross_entropy(input=pred, label=label)
>>> avg_loss = paddle.mean(loss)
>>> optimizer = paddle.optimizer.SGD(learning_rate=0.001)
>>> optimizer.minimize(avg_loss)
>>> place = paddle.CPUPlace()
>>> exe = static.Executor(place)
>>> exe.run(static.default_startup_program())
>>> # create data loader
>>> dataset = RandomDataset(BATCH_NUM * BATCH_SIZE)
>>> loader = paddle.io.DataLoader(dataset,
... feed_list=[image, label],
... places=place,
... batch_size=BATCH_SIZE,
... shuffle=True,
... drop_last=True,
... return_list=False,
... num_workers=2
... )
>>> # 1. train and save inference model
>>> for data in loader():
... exe.run(
... static.default_main_program(),
... feed=data,
... fetch_list=[avg_loss]
... )
>>> model_path = "fc.example.model"
>>> paddle.static.save_inference_model(
... model_path,
... [image],
... [pred],
... exe
... )
>>> # 2. load model
>>> # enable dygraph mode
>>> paddle.disable_static(place)
>>> # load
>>> fc = paddle.jit.load(model_path)
>>> # inference
>>> fc.eval()
>>> x = paddle.randn([1, IMAGE_SIZE], 'float32')
>>> pred = fc(x)
>>> # fine-tune
>>> fc.train()
>>> loss_fn = nn.CrossEntropyLoss()
>>> adam = opt.Adam(learning_rate=0.001, parameters=fc.parameters())
>>> loader = paddle.io.DataLoader(dataset,
... places=place,
... batch_size=BATCH_SIZE,
... shuffle=True,
... drop_last=True,
... num_workers=2
... )
>>> for epoch_id in range(EPOCH_NUM):
... for batch_id, (image, label) in enumerate(loader()):
... out = fc(image)
... loss = loss_fn(out, label)
... loss.backward()
... adam.step()
... adam.clear_grad()
... print("Epoch {} batch {}: loss = {}".format(
... epoch_id, batch_id, np.mean(loss.numpy())))