From bc0087617cb6530ea80210b35cc66be95821379f Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Fri, 26 Aug 2022 19:38:23 +0800 Subject: [PATCH 01/21] Update grammar_list_cn.md --- docs/guides/jit/grammar_list_cn.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/jit/grammar_list_cn.md b/docs/guides/jit/grammar_list_cn.md index 6963c2d2928..3ca786e4889 100644 --- a/docs/guides/jit/grammar_list_cn.md +++ b/docs/guides/jit/grammar_list_cn.md @@ -135,9 +135,9 @@ def break_usage(x): break # <------- jump out of while loop when break ; return tensor_idx ``` -当时输入 x = Tensor([1.0, 2.0 ,3.0]) 时,输出的 tensor_idx 是 Tensor([1])。 +当输入 x = Tensor([1.0, 2.0 ,3.0]) 时,输出的 tensor_idx 是 Tensor([1])。 -> 注:这里虽然 idx 是-1,但是返回值还是 Tensor。因为`tensor_idx` 在 while loop 中转化为了`Tensor`。 +> 注:这里虽然 tensor_idx 初始值是-1,但是返回值还是 Tensor。因为`idx` 在 while loop 中转化为了只含一个索引值的`Tensor`。 ### 3.5 与、或、非 From 1254cbc69040105348101cd5a1c918807b7283ca Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Fri, 26 Aug 2022 21:48:42 +0800 Subject: [PATCH 02/21] Update grammar_list_cn.md --- docs/guides/jit/grammar_list_cn.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/guides/jit/grammar_list_cn.md b/docs/guides/jit/grammar_list_cn.md index 3ca786e4889..ee9c2934129 100644 --- a/docs/guides/jit/grammar_list_cn.md +++ b/docs/guides/jit/grammar_list_cn.md @@ -167,9 +167,11 @@ def and(x, y): **主要逻辑:** -动态图中可以直接用 Python 的类型转化语法来转化 Tensor 类型。如若 x 是 Tensor 时,float(x)可以将 x 的类型转化为 float。 +动态图中可以直接用 Python 的类型转化语法来转化 Tensor 类型。如若 x 是 Tensor 时(只支持含有一个元素的Tensor), -动转静在运行时判断 x 是否是 Tensor,若是,则在动转静时使用静态图`cast`接口转化相应的 Tensor 类型。 +float(x)可以将 x 的类型转化为 float。动转静在运行时判断 x 是否是 Tensor,若是,则在动转静时使用静态图`cast`接口 + +转化相应的 Tensor 类型。 **使用样例**: From 8af1affc01189c695475633fe3ee488df60a6bcd Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Fri, 26 Aug 2022 22:06:35 +0800 Subject: [PATCH 03/21] Update grammar_list_cn.md --- docs/guides/jit/grammar_list_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/grammar_list_cn.md b/docs/guides/jit/grammar_list_cn.md index ee9c2934129..3336eb0722d 100644 --- a/docs/guides/jit/grammar_list_cn.md +++ b/docs/guides/jit/grammar_list_cn.md @@ -241,7 +241,7 @@ def recur_call(x): def list_example(x, y): a = [ x ] # < ------ 支持直接创建 a.append(x) # < ------ 支持调用 append、pop 操作 - a[1] = y # < ------ 支持下标修改 append + a[1] = y # < ------ 支持下标修改 return a[0] # < ------ 支持下标获取 ``` From d2198e26ee8960cf68a92b5c73d0e49f22eadf80 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 07:31:01 +0800 Subject: [PATCH 04/21] Update grammar_list_cn.md --- docs/guides/jit/grammar_list_cn.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guides/jit/grammar_list_cn.md b/docs/guides/jit/grammar_list_cn.md index 3336eb0722d..30ff5532d44 100644 --- a/docs/guides/jit/grammar_list_cn.md +++ b/docs/guides/jit/grammar_list_cn.md @@ -137,7 +137,7 @@ def break_usage(x): ``` 当输入 x = Tensor([1.0, 2.0 ,3.0]) 时,输出的 tensor_idx 是 Tensor([1])。 -> 注:这里虽然 tensor_idx 初始值是-1,但是返回值还是 Tensor。因为`idx` 在 while loop 中转化为了只含一个索引值的`Tensor`。 +> 注:这里虽然 tensor_idx 初始值是-1,但是返回值还是 Tensor。因为 `idx` 在 while loop 中转化为了只含一个索引值的 `Tensor`。 ### 3.5 与、或、非 @@ -167,9 +167,9 @@ def and(x, y): **主要逻辑:** -动态图中可以直接用 Python 的类型转化语法来转化 Tensor 类型。如若 x 是 Tensor 时(只支持含有一个元素的Tensor), +动态图中可以直接用 Python 的类型转化语法来转化 Tensor 类型。如若 x 是 Tensor 时(只支持含有一个元素的 Tensor ), -float(x)可以将 x 的类型转化为 float。动转静在运行时判断 x 是否是 Tensor,若是,则在动转静时使用静态图`cast`接口 +float(x) 可以将 x 的类型转化为 float。动转静在运行时判断 x 是否是 Tensor,若是,则在动转静时使用静态图 `cast` 接口 转化相应的 Tensor 类型。 From e34740397a5cf7eed4dbc8352d57812236e956c7 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 09:35:45 +0800 Subject: [PATCH 05/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index 81595f75b7b..e2b34c5c5f2 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -96,10 +96,10 @@ def forward(self, x): out = self.linear(x) # [bs, 3] - # 以下将 tensor 转为了 numpy 进行一系列操作 + # 以下将 tensor 转为了 numpy array 进行一系列操作 x_data = x.numpy().astype('float32') # [bs, 10] - weight = np.random.randn([10,3]) - mask = paddle.to_tensor(x_data * weight) # 此处又转回了 Tensor + weight = np.random.randn(10, 3) + mask = paddle.to_tensor(x_data @ weight) # 此处又转回了 Tensor out = out * mask return out @@ -113,7 +113,7 @@ def forward(self, x): out = self.linear(x) # [bs, 3] weight = paddle.randn([10,3], 'float32') - mask = x * weight + mask = paddle.matmul(x, weight) out = out * mask return out From 70f3a2421a80bb342cb9760c61f856c36c14a987 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 09:40:31 +0800 Subject: [PATCH 06/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index e2b34c5c5f2..eac870d8a38 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -129,7 +129,7 @@ def forward(self, x): ## 四、to_tensor() 的使用 -``paddle.to_tensor()`` 接口是动态图模型代码中使用比较频繁的一个接口。 ``to_tensor`` 功能强大,将可以将一个 ``scalar`` , ``list`` ,``tuple`` , ``numpy.ndarray`` 转为 ``paddle.Tensor`` 类型。 +``paddle.to_tensor()`` 接口是动态图模型代码中使用比较频繁的一个接口。 ``to_tensor`` 功能强大,可以将一个 ``scalar`` , ``list`` ,``tuple`` , ``numpy.ndarray`` 转为 ``paddle.Tensor`` 类型。 此接口是动态图独有的接口,在动转静时,会转换为 ``assign`` 接口: From 7dc64c1145b41b2dab6ca7e6396af53d51f30ec8 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 10:09:17 +0800 Subject: [PATCH 07/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index eac870d8a38..86609b134c6 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -193,7 +193,7 @@ class SimpleNet(paddle.nn.Layer): 动态图模型常常包含很多嵌套的子网络,建议各个自定义的子网络 ``sublayer`` **无论是否包含了参数,都继承 ``nn.Layer`` .** -从 **Parameters 和 Buffers** 章节可知,有些 ``paddle.to_tensor`` 接口转来的 ``Tensor`` 也可能参与预测逻辑分支的计算,即模型导出时,也需要作为参数序列化保存到 ``.pdiparams`` 文件中。 +从 [**Parameters 和 Buffers**](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/guides/jit/principle_cn.html#buffer) 章节可知,有些 ``paddle.to_tensor`` 接口转来的 ``Tensor`` 也可能参与预测逻辑分支的计算,即模型导出时,也需要作为参数序列化保存到 ``.pdiparams`` 文件中。 > **原因**: 若某个 sublayer 包含了 buffer Variables,但却没有继承 ``nn.Layer`` ,则可能导致保存的 ``.pdiparams`` 文件缺失部分重要参数。 From b20eac78d163da1fd0005faf29d102da9d026a87 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 10:14:28 +0800 Subject: [PATCH 08/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index 86609b134c6..ff8c34284bb 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -200,7 +200,7 @@ class SimpleNet(paddle.nn.Layer): **举个例子:** ```python -class SimpleNet(object): # <---- 继承 Object +class SimpleNet(object): # <---- 继承 object def __init__(self, mask): super(SimpleNet, self).__init__() self.linear = paddle.nn.Linear(10, 3) # <---- Linear 参数永远都不会被更新 From d6846267dddd409e46d8041cc45a028d7356f7f7 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 10:16:54 +0800 Subject: [PATCH 09/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index ff8c34284bb..edd1f62e9c4 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -215,7 +215,7 @@ class SimpleNet(object): # <---- 继承 object 同时,所有继承 ``nn.Layer`` 的 ``sublayer`` 都建议: -+ 重写 ``forward`` 函数,尽量避免重写 ``__call__``` 函数 ++ 重写 ``forward`` 函数,尽量避免重写 __call__ 函数 > ``__call__`` 函数通常会包含框架层面的一些通用的处理逻辑,比如 ``pre_hook`` 和 ``post_hook`` 。重写此函数可能会覆盖框架层面的逻辑。 + 尽量将 ``forward`` 函数作为 sublayers 的调用入口 From c613926508e9ddc6096924964c44d902b1ba6194 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 10:18:09 +0800 Subject: [PATCH 10/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index edd1f62e9c4..e1fc557a446 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -215,7 +215,7 @@ class SimpleNet(object): # <---- 继承 object 同时,所有继承 ``nn.Layer`` 的 ``sublayer`` 都建议: -+ 重写 ``forward`` 函数,尽量避免重写 __call__ 函数 ++ 重写 ``forward`` 函数,尽量避免重写 ``__call__`` 函数 > ``__call__`` 函数通常会包含框架层面的一些通用的处理逻辑,比如 ``pre_hook`` 和 ``post_hook`` 。重写此函数可能会覆盖框架层面的逻辑。 + 尽量将 ``forward`` 函数作为 sublayers 的调用入口 From d56ff68ce0d6d76ba54faca8c604fc2e03d5076d Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 12:41:11 +0800 Subject: [PATCH 11/21] Update basic_usage_cn.md --- docs/guides/jit/basic_usage_cn.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/guides/jit/basic_usage_cn.md b/docs/guides/jit/basic_usage_cn.md index 7d0518c1a9a..cee68aad39d 100644 --- a/docs/guides/jit/basic_usage_cn.md +++ b/docs/guides/jit/basic_usage_cn.md @@ -882,6 +882,9 @@ class SimpleNet(Layer): 若被装饰函数的参数列表除了 Tensor 类型,还包含其他如 Int、 String 等非 Tensor 类型时,推荐在函数中使用 kwargs 形式定义非 Tensor 参数,如下述样例中的 ``use_act`` 参数。 ```python +import paddle +from paddle.jit import to_static + class SimpleNet(Layer): def __init__(self, ): super(SimpleNet, self).__init__() @@ -896,11 +899,11 @@ class SimpleNet(Layer): net = SimpleNet() # 方式一:save inference model with use_act=False -net = to_static(input_spec=[InputSpec(shape=[None, 10], name='x')]) +net = to_static(net, input_spec=[InputSpec(shape=[None, 10], name='x')]) paddle.jit.save(net, path='./simple_net') # 方式二:save inference model with use_act=True -net = to_static(input_spec=[InputSpec(shape=[None, 10], name='x'), True]) +net = to_static(net, input_spec=[InputSpec(shape=[None, 10], name='x'), True]) paddle.jit.save(net, path='./simple_net') ``` From a7bc2324e9a5b67e0f9350160b3e1db05f3a3b21 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 12:50:18 +0800 Subject: [PATCH 12/21] Update basic_usage_cn.md --- docs/guides/jit/basic_usage_cn.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/guides/jit/basic_usage_cn.md b/docs/guides/jit/basic_usage_cn.md index cee68aad39d..eb80bddbe2c 100644 --- a/docs/guides/jit/basic_usage_cn.md +++ b/docs/guides/jit/basic_usage_cn.md @@ -884,6 +884,8 @@ class SimpleNet(Layer): ```python import paddle from paddle.jit import to_static +from paddle.nn import Layer +from paddle.static import InputSpec class SimpleNet(Layer): def __init__(self, ): From bb1140124d6e690fe8059e27ee55d2ba915d8e79 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 13:25:31 +0800 Subject: [PATCH 13/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index e1fc557a446..316c7f2141d 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -265,7 +265,7 @@ def forward(self, x): model = SimpleNet() model.eval() # <---- 一键切换分支,则只会导出 eval 相关的预测分支 -jit.save(mode, model_path) +paddle.jit.save(model, model_path) ``` From 7fdd1471fe6122f5edd279c6b1a754cdadb3d34d Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 14:21:15 +0800 Subject: [PATCH 14/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index 316c7f2141d..0f352b1848a 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -271,13 +271,17 @@ paddle.jit.save(model, model_path) 推荐使用 ``self.training`` 或其他非 Tensor 类型的 bool 值进行区分。 -此 flag 继承自 ``nn.Layer`` ,因此可通过 ``model.train()`` 和 ``model.eval()`` 来全局切换所有 sublayers 的分支状态。 +此 flag 继承自 ``paddle.nn.Layer`` ,因此可通过 ``model.train()`` 和 ``model.eval()`` 来全局切换所有 sublayers 的分支状态。 ## 七、非 forward 函数导出 -`@to_static` 与 `jit.save` 接口搭配也支持导出非 forward 的其他函数,具体使用方式如下: +`@paddle.jit.to_static` 与 `paddle.jit.save` 接口搭配也支持导出非 forward 的其他函数,具体使用方式如下: ```python +import paddle +from paddle.jit import to_static +from paddle.static import InputSpec + class SimpleNet(paddle.nn.Layer): def __init__(self): super(SimpleNet, self).__init__() @@ -300,7 +304,7 @@ net = SimpleNet() net.eval() # step 2: 定义 InputSpec 信息 (同上) -x_spec = InputSpec(shape=[None, 3], dtype='float32', name='x') +x_spec = InputSpec(shape=[None, 10], dtype='float32', name='x') # step 3: @to_static 装饰 static_func = to_static(net.another_func, input_spec=[x_spec]) @@ -312,12 +316,12 @@ net = paddle.jit.save(static_func, path='another_func') 使用上的区别主要在于: + **`@to_static` 装饰**:导出其他函数时需要显式地用 `@to_static` 装饰,以告知动静转换模块将其识别、并转为静态图 Program; -+ **`save`接口参数**:调用`jit.save`接口时,需将上述被`@to_static` 装饰后的函数作为**参数**; ++ **`save`接口参数**:调用`paddle.jit.save`接口时,需将上述被`@to_static` 装饰后的函数作为**参数**; 执行上述代码样例后,在当前目录下会生成三个文件: ``` another_func.pdiparams // 存放模型中所有的权重数据 -another_func.pdimodel // 存放模型的网络结构 +another_func.pdmodel // 存放模型的网络结构 another_func.pdiparams.info // 存放额外的其他信息 ``` From 10b91f70a5d652390ff65ce0ab5b05cd0e33094f Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 14:45:55 +0800 Subject: [PATCH 15/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index 0f352b1848a..41609f4ff45 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -309,8 +309,8 @@ x_spec = InputSpec(shape=[None, 10], dtype='float32', name='x') # step 3: @to_static 装饰 static_func = to_static(net.another_func, input_spec=[x_spec]) -# step 4: 调用 jit.save 接口 -net = paddle.jit.save(static_func, path='another_func') +# step 4: 调用 paddle.jit.save 接口 +paddle.jit.save(static_func, path='another_func') ``` 使用上的区别主要在于: From 6c04fca035fe43457e648744a8c61625ca9d1814 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 15:11:15 +0800 Subject: [PATCH 16/21] Update save_cn.rst --- docs/api/paddle/jit/save_cn.rst | 94 ++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/docs/api/paddle/jit/save_cn.rst b/docs/api/paddle/jit/save_cn.rst index 51bbeddde63..c2df6ad3b8a 100644 --- a/docs/api/paddle/jit/save_cn.rst +++ b/docs/api/paddle/jit/save_cn.rst @@ -34,4 +34,96 @@ save 代码示例 ::::::::: -COPY-FROM: paddle.jit.save +```python +# example 1: save layer +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, )).astype('int64') + return image, label + + def __len__(self): + return self.num_samples + +class LinearNet(nn.Layer): + def __init__(self): + super(LinearNet, self).__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, (images, labels) in enumerate(loader()): + out = layer(images) + loss = loss_fn(out, labels) + 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) +``` + +```python +# example 2: save function +import paddle +from paddle.static import InputSpec + + +def save_function(): + @paddle.jit.to_static + def fun(inputs): + return paddle.tanh(inputs) + + path = 'test_jit_save_load_function/func' + inps = paddle.rand([3, 6]) + origin = fun(inps) + + paddle.jit.save(fun, path) + load_func = paddle.jit.load(path) + + load_result = load_func(inps) + print((load_result - origin).abs().max() < 1e-10) + +save_function() +``` From 7ab8bfa254b54b20cebaf88a8590113c69d48ae9 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 15:15:33 +0800 Subject: [PATCH 17/21] Update save_cn.rst --- docs/api/paddle/jit/save_cn.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api/paddle/jit/save_cn.rst b/docs/api/paddle/jit/save_cn.rst index c2df6ad3b8a..ad1ec87a34e 100644 --- a/docs/api/paddle/jit/save_cn.rst +++ b/docs/api/paddle/jit/save_cn.rst @@ -34,7 +34,7 @@ save 代码示例 ::::::::: -```python + ```python # example 1: save layer import numpy as np import paddle @@ -102,9 +102,9 @@ train(layer, loader, loss_fn, adam) # save path = "example_model/linear" paddle.jit.save(layer, path) -``` + ``` -```python + ```python # example 2: save function import paddle from paddle.static import InputSpec @@ -126,4 +126,4 @@ def save_function(): print((load_result - origin).abs().max() < 1e-10) save_function() -``` + ``` From 1ee2cc351c32d891caef13972aaa65d708f50efd Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 15:16:31 +0800 Subject: [PATCH 18/21] Update save_cn.rst --- docs/api/paddle/jit/save_cn.rst | 164 ++++++++++++++++---------------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/docs/api/paddle/jit/save_cn.rst b/docs/api/paddle/jit/save_cn.rst index ad1ec87a34e..547a8fd7d78 100644 --- a/docs/api/paddle/jit/save_cn.rst +++ b/docs/api/paddle/jit/save_cn.rst @@ -35,95 +35,95 @@ save ::::::::: ```python -# example 1: save layer -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, )).astype('int64') - return image, label - - def __len__(self): - return self.num_samples - -class LinearNet(nn.Layer): - def __init__(self): - super(LinearNet, self).__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, (images, labels) in enumerate(loader()): - out = layer(images) - loss = loss_fn(out, labels) - 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) + # example 1: save layer + 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, )).astype('int64') + return image, label + + def __len__(self): + return self.num_samples + + class LinearNet(nn.Layer): + def __init__(self): + super(LinearNet, self).__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, (images, labels) in enumerate(loader()): + out = layer(images) + loss = loss_fn(out, labels) + 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) ``` ```python -# example 2: save function -import paddle -from paddle.static import InputSpec + # example 2: save function + import paddle + from paddle.static import InputSpec -def save_function(): - @paddle.jit.to_static - def fun(inputs): - return paddle.tanh(inputs) + def save_function(): + @paddle.jit.to_static + def fun(inputs): + return paddle.tanh(inputs) - path = 'test_jit_save_load_function/func' - inps = paddle.rand([3, 6]) - origin = fun(inps) + path = 'test_jit_save_load_function/func' + inps = paddle.rand([3, 6]) + origin = fun(inps) - paddle.jit.save(fun, path) - load_func = paddle.jit.load(path) + paddle.jit.save(fun, path) + load_func = paddle.jit.load(path) - load_result = load_func(inps) - print((load_result - origin).abs().max() < 1e-10) + load_result = load_func(inps) + print((load_result - origin).abs().max() < 1e-10) -save_function() + save_function() ``` From 408ce26cf1bea566626f25c14a5284ace02dda05 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 15:59:35 +0800 Subject: [PATCH 19/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index 41609f4ff45..dae1b866d25 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -330,7 +330,7 @@ another_func.pdiparams.info // 存放额外的其他信息 ## 八、再谈控制流 -前面[【控制流转写】(./basic_usage_cn.html#sikongzhiliuzhuanxie)]提到,不论控制流 ``if/for/while`` 语句是否需要转为静态图中的 ``cond_op/while_op`` ,都会先进行代码规范化,如 ``IfElse`` 语句会规范为如下范式: +前面[【控制流转写】](./basic_usage_cn.html#sikongzhiliuzhuanxie)提到,不论控制流 ``if/for/while`` 语句是否需要转为静态图中的 ``cond_op/while_op`` ,都会先进行代码规范化,如 ``IfElse`` 语句会规范为如下范式: ```python def true_fn_0(out): From 0f1a89eec30b0e3d98f0fc61e0f028547c5a2af4 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 16:03:40 +0800 Subject: [PATCH 20/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index dae1b866d25..f6428fa0b04 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -330,7 +330,7 @@ another_func.pdiparams.info // 存放额外的其他信息 ## 八、再谈控制流 -前面[【控制流转写】](./basic_usage_cn.html#sikongzhiliuzhuanxie)提到,不论控制流 ``if/for/while`` 语句是否需要转为静态图中的 ``cond_op/while_op`` ,都会先进行代码规范化,如 ``IfElse`` 语句会规范为如下范式: +前面[【控制流转写】](./principle_cn.html#kongzhiliuzhuanxie)提到,不论控制流 ``if/for/while`` 语句是否需要转为静态图中的 ``cond_op/while_op`` ,都会先进行代码规范化,如 ``IfElse`` 语句会规范为如下范式: ```python def true_fn_0(out): From 2643b2e5113d6a836ba748c9efa71872e86d8f97 Mon Sep 17 00:00:00 2001 From: OccupyMars2025 <31559413+OccupyMars2025@users.noreply.github.com> Date: Sat, 27 Aug 2022 16:15:49 +0800 Subject: [PATCH 21/21] Update case_analysis_cn.md --- docs/guides/jit/case_analysis_cn.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guides/jit/case_analysis_cn.md b/docs/guides/jit/case_analysis_cn.md index f6428fa0b04..42bc6b232bd 100644 --- a/docs/guides/jit/case_analysis_cn.md +++ b/docs/guides/jit/case_analysis_cn.md @@ -352,7 +352,7 @@ out = convert_ifelse(paddle.mean(x) > 5.0, true_fn_0, false_fn_0, (x,), (x,), (o 当控制流中,出现了 ``list.append`` 类似语法时,情况会有一点点特殊。 -Paddle 框架中的 ``cond_op`` 和 [``while_loop``](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/layers/while_loop_cn.html#cn-api-fluid-layers-while-loop) 对输入和返回类型有一个要求: +Paddle 框架中的 [``cond_op``](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api/paddle/static/nn/cond_cn.html#cond) 和 [``while_loop``](https://www.paddlepaddle.org.cn/documentation/docs/zh/develop/api/paddle/static/nn/while_loop_cn.html) 对输入和返回类型有一个要求: > 输入或者返回类型必须是:LoDTensor 或者 LoDTensorArray

> 即:不支持其他非 LoDTensor 类型