未验证 提交 af4654b6 编写于 作者: S SunAhong1993 提交者: GitHub

Add docs and project convertor code (#571)

* fix the convert.py args

* fix teh pad and add log_softmax

* rewrite docs

* rewrite docs

* rewrite docs

* rewrite docs

* rewrite docs

* Update torch.narrow.md

* Update x2paddle_model_zoo.md

* Update x2paddle_model_zoo.md

* fix the README.md

* Update README.md

* add code

* rm

* Update README.md

* Update demo.md

* Update README.md

* Update README.md

* remove tools

* modify README

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update demo.md

* Update demo.md

* Update demo.md

* Update demo.md

* Update demo.md

* add commitid

* Update pytorch2paddle.md

* Update README.md

* Update demo.md

* Update FAQ.md

* Update README.md

* Update README.md

* Update __init__.py

* Update torch.zeros.md

* Update README.md

* Update README.md

* Update README.md

* Update torchvision.models.md
上级 01e67698
......@@ -4,18 +4,16 @@
![python version](https://img.shields.io/badge/python-3.5+-orange.svg)
## 简介
X2Paddle用于不同框架模型或项目到PaddlePaddle框架模型或项目的迁移,旨在为飞桨开发者提升框架间迁移的效率。
X2Paddle支持Caffe/TensorFlow/ONNX/PyTorch的预测模型,一步转换至PaddlePaddle预测模型;同时,支持PyTorch训练项目,转换至PaddlePaddle项目,助力用户在PaddlePaddlePaddle上进行模型训练。
### 架构设计
X2Paddle的架构设计着重考虑了对多深度学习框架的的支持以及代码的易读性、易扩展性,并且在多个层面的对转换后OP进行优化处理。
![](./docs/images/frame.png)
X2Paddle用于不同框架模型或项目到PaddlePaddle框架模型或项目的转换,旨在为飞桨开发者提升框架间转换的效率。
X2Paddle主要有***2大功能***
1. ***预测模型转换***:X2Paddle支持Caffe/TensorFlow/ONNX/PyTorch的预测模型,一步转换至PaddlePaddle预测模型。
2. ***训练项目转换***:heart::heart::PyTorch训练项目,转换至PaddlePaddle项目,助力用户在PaddlePaddlePaddle上进行模型训练。
### 特性
- **支持主流深度学习框架**:目前已经支持Caffe/TensorFlow/ONNX/PyTorch四大框架的迁移,涵盖目前市面主流深度学习框架。
- **支持主流深度学习框架**:目前已经支持Caffe/TensorFlow/ONNX/PyTorch四大框架的预测模型的转换,PyTorch训练项目的转换,涵盖了目前市面主流深度学习框架。
- **支持的模型丰富**:在主流的CV和NLP模型上均支持转换,涵盖了19+个Caffe模型转换、27+个TensorFlow模型转换、32+个ONNX模型转换、27+个PyTorch模型转换、2+个PyTorch项目转换
- **支持的模型丰富**:在主流的CV和NLP模型上均支持转换,涵盖了19+个Caffe预测模型转换、27+个TensorFlow预测模型转换、32+个ONNX预测模型转换、27+个PyTorch预测模型转换、2+个PyTorch训练项目转换,详见 ***[支持列表](./docs/introduction/x2paddle_model_zoo.md)***
- **简洁易用**:一条命令行或者一个API即可完成模型转换。
......@@ -30,7 +28,7 @@ X2Paddle的架构设计着重考虑了对多深度学习框架的的支持以及
- tensorflow : tensorflow == 1.14.0
- caffe : 无
- onnx : onnx >= 1.6.0
- pytorch:torch >=1.5.0 (script方式暂不支持1.7.0)
- pytorch:torch >=1.5.0 (预测模型转换中的script方式暂不支持1.7.0+)
## 安装
### 方式一:源码安装
......@@ -47,7 +45,7 @@ python setup.py install
pip install x2paddle --index https://pypi.python.org/simple/
```
## 快速开始
### 预测模型转换
### 功能一:预测模型转换
| 参数 | 作用 |
| -------------------- | ------------------------------------------------------------ |
| --framework | 源模型类型 (tensorflow、caffe、onnx) |
......@@ -56,63 +54,61 @@ pip install x2paddle --index https://pypi.python.org/simple/
| --save_dir | 指定转换后的模型保存目录路径 |
| --model | 当framework为tensorflow/onnx时,该参数指定tensorflow的pb模型文件或onnx模型路径 |
| --caffe_proto | **[可选]** 由caffe.proto编译成caffe_pb2.py文件的存放路径,当存在自定义Layer时使用,默认为None |
| --define_input_shape | **[可选]** For TensorFlow, 当指定该参数时,强制用户输入每个Placeholder的shape,见[文档Q2](./docs/user_guides/FAQ.md) |
| --paddle_type | **[可选]** 该参数指定转换为动态图代码(dygraph)或者静态图代码(static),默认为dygraph |
| --define_input_shape | **[可选]** For TensorFlow, 当指定该参数时,强制用户输入每个Placeholder的shape,见[文档Q2](./docs/inference_model_convertor/FAQ.md) |
#### TensorFlow
```shell
x2paddle --framework=tensorflow --model=tf_model.pb --save_dir=pd_model
```
x2paddle --framework=tensorflow --model=tf_model.pb --save_dir=pd_model --paddle_type dygraph
```
【注意】目前只支持FrozenModel格式的TensorFlow模型到PaddlePaddle模型的转换,若为checkpoint或者SavedModel格式的TensorFlow模型参见[文档](./docs/inference_model_convertor/export_tf_model.md)导出FrozenModel格式模型。
#### Caffe
```shell
x2paddle --framework=caffe --prototxt=deploy.prototxt --weight=deploy.caffemodel --save_dir=pd_model
```
x2paddle --framework=caffe --prototxt=deploy.prototxt --weight=deploy.caffemodel --save_dir=pd_model --paddle_type dygraph
```
【注意】若caffe模型中出现自定义层,需要按照[相关流程](./docs/inference_model_convertor/add_caffe_custom_layer.md)自行添加自定义层的转换代码。
#### ONNX
```shell
x2paddle --framework=onnx --model=onnx_model.onnx --save_dir=pd_model
```
x2paddle --framework=onnx --model=onnx_model.onnx --save_dir=pd_model --paddle_type dygraph
```
【注意】如若需要将PyTorch模型转换为ONNX模型,可参见[PyTorch2ONNX转换文档](./docs/inference_model_convertor/pytorch2onnx.md)
#### PyTorch
PyTorch仅支持API使用方式,详见[PyTorch预测模型转换文档](./docs/user_guides/pytorch2paddle.md)
PyTorch仅支持API使用方式,详见[PyTorch预测模型转换文档](./docs/inference_model_convertor/pytorch2paddle.md)
### 训练项目转换
***[预测模型转换常见问题](./docs/inference_model_convertor/FAQ.md)***
#### PyTorch
【待更新】可安装[分支](https://github.com/PaddlePaddle/X2Paddle/tree/pytorch_project_convertor)源码进行使用。
详见[PyTorch训练项目转换文档](https://github.com/SunAhong1993/X2Paddle/blob/code_convert_last/docs/pytorch_project_convertor/README.md)
### 功能二:训练项目转换:heart: :heart:
## 小工具
X2Paddle提供了工具解决如下问题,详见[tools/README.md](tools/README.md)
1. 检测模型是否在PaddleLite中支持
2. 合并模型参数文件
| 参数 | 作用 |
|----------|--------------|
|--convert_torch_project | 表示使用对PyTorch Project进行转换的功能 |
|--project_dir | PyTorch的项目路径 |
|--save_dir | 指定转换后项目的保存路径 |
|--pretrain_model | **[可选]**需要转换的预训练模型的路径(文件后缀名为“.pth”、“.pt”、“.ckpt”)或者包含预训练模型的文件夹路径,转换后的模型将将保在当前路径,后缀名为“.pdiparams” |
```shell
x2paddle --convert_torch_project --project_dir=torch_project --save_dir=paddle_project --pretrain_model=model.pth
```
【注意】需要搭配预处理和后处理一起使用,详细可参见[训练项目转换文档](./docs/pytorch_project_convertor/README.md)。 此外,我们为用户提供了:star:[PyTorch-PaddlePaddle API映射表](docs/pytorch_project_convertor/API_docs/README.md):star:供用户查阅。
## 使用相关文档
1. [X2Paddle使用过程中常见问题](./docs/user_guides/FAQ.md)
2. [如何导出TensorFlow的Frozen Model](./docs/user_guides/export_tf_model.md)
3. [PyTorch模型导出为ONNX模型](./docs/user_guides/pytorch2onnx.md)
4. [X2Paddle添加内置的Caffe自定义层](./docs/user_guides/add_caffe_custom_layer.md)
5. [转换后PaddlePaddle预测模型简介](./docs/user_guides/pd_folder_introduction.py)
6. [Paddle到ONNX的转换](https://github.com/PaddlePaddle/Paddle2ONNX)
7. [X2Paddle测试模型库](./docs/introduction/x2paddle_model_zoo.md)
8. [X2Paddle支持的op列表](./docs/introduction/op_list.md)
***[训练项目转换常见问题](./docs/pytorch_project_convertor/FAQ.md)***
## 转换教程
1. [TensorFlow预测模型转换教程](./docs/demo/tensorflow2paddle.ipynb)
2. [PyTorch预测模型转换教程](./docs/demo/pytorch2paddle.ipynb)
1. [TensorFlow预测模型转换教程](./docs/inference_model_convertor/demo/tensorflow2paddle.ipynb)
2. [PyTorch预测模型转换教程](./docs/inference_model_convertor/demo/pytorch2paddle.ipynb)
3. [PyTorch训练项目转换教程](./docs/pytorch_project_convertor/demo.md)
## 更新历史
2020.12.09
**2020.12.09**
1. 新增PyTorch2Paddle转换方式,转换得到Paddle动态图代码,并动转静获得inference_model。
方式一:trace方式,转换后的代码有模块划分,每个模块的功能与PyTorch相同。
方式一:trace方式,转换后的代码有模块划分,每个模块的功能与PyTorch相同。
方式二:script方式,转换后的代码按执行顺序逐行出现。
2. 新增Caffe/ONNX/Tensorflow到Paddle动态图的转换。
3. 新增TensorFlow op映射(14个):Neg、Greater、FloorMod、LogicalAdd、Prd、Equal、Conv3D、Ceil、AddN、DivNoNan、Where、MirrorPad、Size、TopKv2。
4. 新增Optimizer模块,主要包括op融合、op消除功能,转换后的代码可读性更强,进行预测时耗时更短。
2021.04.30
**2021.04.30**
1. 新增支持转换的模型:[SwinTransformer](https://github.com/microsoft/Swin-Transformer/)[BASNet](https://github.com/xuebinqin/BASNet)[DBFace](https://github.com/dlunion/DBFace)[EasyOCR](https://github.com/JaidedAI/EasyOCR)[CifarNet](https://github.com/tensorflow/models/blob/master/research/slim/nets/cifarnet.py)等。
2. 支持Windows上使用本工具。
3. 新增TensorFlow op映射(4个):SplitV、ReverseV2、BatchToSpaceND、SpaceToBatchND。
......@@ -120,6 +116,11 @@ X2Paddle提供了工具解决如下问题,详见[tools/README.md](tools/README
5. 新增ONNX op映射(1个):DepthToSpace。
6. 新增Caffe op映射(1个):MemoryData。
## 贡献代码
**2021.05.13**
- 新增PyTorch训练项目功能:
支持转换的项目有[StarGAN](https://github.com/yunjey/stargan)[Ultra-Light-Fast-Generic-Face-Detector-1MB](https://github.com/Linzaer/Ultra-Light-Fast-Generic-Face-Detector-1MB)
## :hugs:贡献代码:hugs:
我们非常欢迎您为X2Paddle贡献代码或者提供使用建议。如果您可以修复某个issue或者增加一个新功能,欢迎给我们提交Pull Requests
我们非常欢迎您为X2Paddle贡献代码或者提供使用建议。如果您可以修复某个issue或者增加一个新功能,欢迎给我们提交Pull Requests,如果有PyTorch训练项目转换需求欢迎随时提issue~
# 一、 introduction
1. op_list.md:当前转换各个框架支持的op。
2. x2paddle_model_zoo.md:测试过的模型列表。
# 二、 user_guides
1. FQA.md:常见问题集合。
2. add_caffe_custom_layer.md:添加caffe自定义Layer的方法,以及当前支持的自定义Layer列表。
3. export_tf_model.md:导出本工具支持的TensorFlow模型。
4. pytorch2onnx.md:将PyTorch导出为ONNX。
5. pytorch2paddle.md:将PyTorch模型转换为Paddle模型。
## 常见问题
**Q1. TensorFlow模型转换过程中,提示『Unknown shape for input tensor[tensor name: "input"], Please define shape of input here』?**
A:该提示信息表示无法从TensorFlow的pb模型中获取到输入tensor(tensor名为"input:)的shape信息,所以需要用户手动在提示后输入详细的shape信息,如None,224,224,3 其中None表示Batch
A:该提示信息表示无法从TensorFlow的pb模型中获取到输入tensor(tensor名为"input:)的shape信息,所以需要用户手动在提示后输入详细的shape信息,如None,224,224,3 其中None表示Batch
**Q2. TensorFlow模型转换失败怎么解决?**
A: 如果并非是由缺少OP导致,那可能是由于TensorFlow模型转换时(NHWC->NCHW格式转换导致),在这种情况下,采用如下方式进行转换,同时固化输入大小的方式,继续尝试转换,见如下命令,转换过程中,根据提示,输入相应tensor的固化shape大小
A: 如果并非是由缺少OP导致,那可能是由于TensorFlow模型转换时(NHWC->NCHW格式转换导致),在这种情况下,采用如下方式进行转换,同时固化输入大小的方式,继续尝试转换,见如下命令,转换过程中,根据提示,输入相应tensor的固化shape大小
```
x2paddle -f tensorflow -m tf.pb -s pd-model --without_data_format_optimization --define_input_shape
x2paddle -f tensorflow -m tf.pb -s pd-model --define_input_shape
```
> 1. 目前Tensorflow的CV模型大部分均为`NHWC`的输入格式,而Paddle的默认输入格式为`NCHW`,因此X2Paddle在转换过程中,会对如`axis`, `shape`等参数进行转换,适应Paddle的NCHW格式。但在这种情况下,可能会由于TensorFlow模型太复杂,导致出错。 指定`--without_data_format_optimization`后,会停止对`axis`,`shape`等参数的优化(这可能会带来一定数量的transpose操作)
**Q3. ONNX模型转换过程中,提示『Unknown shape for input tensor[tensor name: "input"] -> shape: ['batch', 'sequence'], Please define shape of input here』**
A:该提示信息表示从ONNX的模型中获取到输入tensor(tensor名为"input:)的shape是语义象征性的['batch', 'sequence'],而不是dim为int类型的shape,从而可能会因为部分node的shape无法推理,导致转换失败。所以用户可以尝试手动在提示后输入详细的shape信息,如:-1,3,224,224 其中-1表示Batch
**Q4. Paddle模型转至ONNX模型过程中,提示『The parameter normalized of multiclass_nms OP of Paddle is False, which has diff with ONNX』**
A: 此提示为警告信息,模型仍然会正常进行转换。Paddle中`fluid.layers.multiclass_nms`算子中提供了`normalized`参数,用于表示输入box是否进行了归一化。而ONNX中的NMS算子只支持`normalized`参数为True的情况,当你转换的模型(一般是YOLOv3模型)中该参数为`False`的情况下,转换后的模型可能会与原模型存在diff。
A:该提示信息表示从ONNX的模型中获取到输入tensor(tensor名为"input:)的shape是语义象征性的['batch', 'sequence'],而不是dim为int类型的shape,从而可能会因为部分node的shape无法推理,导致转换失败。所以用户可以尝试手动在提示后输入详细的shape信息,如:-1,3,224,224 其中-1表示Batch。
**Q5. Paddle模型转至ONNX模型过程中,提示『Converting this model to ONNX need with static input shape, please fix input shape of this model』**
A: 此提示为错误信息,表示该模型的转换需要固定的输入大小:
> 1. 模型来源于PaddleX导出,可以在导出的命令中,指定--fixed_input_shape=[Height,Width],详情可见:[PaddleX模型导出文档](https://github.com/PaddlePaddle/PaddleX/blob/develop/docs/deploy/export_model.md)。
> 2. 模型来源于PaddleDetection导出,可以在导出模型的时候,指定 TestReader.inputs_def.image_shape=[Channel,Height,Width], 详情可见:[PaddleDetection模型导出文档](https://github.com/PaddlePaddle/PaddleDetection/blob/master/docs/advanced_tutorials/deploy/EXPORT_MODEL.md#设置导出模型的输入大小)。
> 3. 模型来源于自己构建,可在网络构建的`fluid.data(shape=[])`中,指定shape参数来固定模型的输入大小。
**Q4. 如果我的tensorflow模型是checkpoint或者SavedModel格式,怎么办?**
A:我们提供相关文档将export_tf_model.md
**Q6. 进行动态图转换时,提示『Fail to generate inference model! Problem happend while export inference model from python code...』**
**Q4. 进行动态图转换时,提示『Fail to generate inference model! Problem happend while export inference model from python code...』**
A: 此提示为无法将动态图代码转换为静态图模型,有两种可能:
> 使用动态图代码确认转换后的代码是否正确,可使用如下代码进行确认:
```
......@@ -39,4 +31,7 @@ paddle.disable_static()
from pd_model_dygraph.x2paddle_code import main
out =main(ipt)
```
> 若运行代码无误,则说明代码中有op不支持动转静,我们将会再未来支持;若报错,则说明pytorch2paddle转换出错,请提issue,我们将及时回复。
\ No newline at end of file
> 若运行代码无误,则说明代码中有op不支持动转静,我们将会再未来支持;若报错,则说明pytorch2paddle转换出错,请提issue,我们将及时回复。
**Q5. 目前支持了哪些op的转换呢?**
A: 可详见[X2Paddle支持的op列表](./docs/introduction/op_list.md)
## 如何转换Caffe自定义Layer
本文档介绍如何将Caffe自定义Layer转换为PaddlePaddle模型中的对应实现, 用户可根据自己需要,添加代码实现自定义层,从而支持模型的完整转换。
本文档介绍如何将Caffe自定义Layer转换为PaddlePaddle模型中的对应实现, 用户可根据自己需要,添加代码实现自定义层,从而支持模型的完整转换。
目前,代码中已经提供了10个非官方op(不在[官网](http://caffe.berkeleyvision.org/tutorial/layers)上的op)的转换,这些op对应的Caffe实现源码如下:
| op | 该版本实现源码 |
......@@ -49,7 +49,7 @@ def Permute(self, node):
node.inputs) == 1, "The count of Permute node\'s input is not 1."
input = self.graph.get_input_node(node, idx=0, copy=True)
params = node.layer.permute_param
order = list(params.order)
order = list(params.order)
self.paddle_graph.add_layer(
"paddle.transpose",
inputs={"x": input.name},
......@@ -80,7 +80,7 @@ def shape_permute(layer, input_shape):
- 方式二:
1. 进入./x2paddle/op_mapper/dygraph/caffe2paddle/caffe_custom_layer,创建.py文件,例如mylayer.py
2. 仿照./x2paddle/op_mapper/dygraph/caffe2paddle/caffe_custom_layer中的其他文件,在mylayer.py中主要需要实现1个类,下面以roipooling.py为例分析代码:
```python
class ROIPooling(object):
def __init__(self, pooled_height, pooled_width, spatial_scale):
......@@ -90,10 +90,10 @@ class ROIPooling(object):
"spatial_scale": spatial_scale}
def __call__(self, x0, x1):
slice_x1 = paddle.slice(input=x1, axes=[1],
slice_x1 = paddle.slice(input=x1, axes=[1],
starts=[1], ends=[5])
out = fluid.layers.roi_pool(input=x0,
rois=slice_x1,
out = fluid.layers.roi_pool(input=x0,
rois=slice_x1,
**self.roipooling_layer_attrs)
return out
```
......
......@@ -66,7 +66,7 @@ def freeze_model(sess, output_tensor_names, freeze_model_path):
f.write(out_graph.SerializeToString())
print("freeze model saved in {}".format(freeze_model_path))
# 加载模型参数
# 此处需要修改input_checkpoint(checkpoint的前缀)和save_pb_file(模型导出的文件路径)
input_checkpoint = "./tfhub_models/save/model.ckpt"
......
......@@ -5,20 +5,20 @@ PyTorch2Paddle支持trace和script两种方式的转换,均是PyTorch动态图
## 环境依赖
python == 2.7 | python >= 3.5
paddlepaddle >= 1.8.0
paddlepaddle >= 2.0.0
pytorch:torch >=1.5.0 (script方式暂不支持1.7.0)
**使用trace方式需安装以下依赖**
**使用trace方式需安装以下依赖**
pandas
treelib
treelib
## 使用方式
``` python
from x2paddle.convert import pytorch2paddle
pytorch2paddle(module=torch_module,
save_dir="./pd_model",
jit_type="trace",
pytorch2paddle(module=torch_module,
save_dir="./pd_model",
jit_type="trace",
input_examples=[torch_input])
# module (torch.nn.Module): PyTorch的Module。
# save_dir (str): 转换后模型的保存路径。
......@@ -46,8 +46,8 @@ torch_module.load_state_dict(torch_state_dict)
torch_module.eval()
# 进行转换
from x2paddle.convert import pytorch2paddle
pytorch2paddle(torch_module,
save_dir="pd_model_trace",
jit_type="trace",
pytorch2paddle(torch_module,
save_dir="pd_model_trace",
jit_type="trace",
input_examples=[torch.tensor(input_data)])
```
## 架构设计
X2Paddle的架构设计着重考虑了对多深度学习框架的的支持以及代码的易读性、易扩展性。预测模型转换在多个层面的对转换后OP进行优化处理,转换后的模型可直接用于预测部署;训练代码转换则运用了AST的方式进行转换,转换后的代码与源代码格式一致。2种方式的转换满足不同人的需求。
![](../images/frame.png)
# X2Paddle模型测试库
> 目前X2Paddle支持80+的TensorFlow OP,30+的Caffe Layer,60+的ONNX OP,110+的PyTorch Aten,10+的PyTorch Prim,覆盖了大部分CV分类模型常用的操作。我们在如下模型列表中测试了X2Paddle的转换。
# X2Paddle转换库
**注:** 受限于不同框架的差异,部分模型可能会存在目前无法转换的情况,如TensorFlow中包含控制流的模型,NLP模型等。对于CV常见的模型,如若您发现无法转换或转换失败,存在较大diff等问题,欢迎通过[ISSUE反馈](https://github.com/PaddlePaddle/X2Paddle/issues/new)的方式告知我们(模型名,代码实现或模型获取方式),我们会及时跟进:)
## TensorFlow
## TensorFlow预测模型
| 模型 | 代码 |
|------|----------|
......@@ -28,7 +25,7 @@
| Bert(chinese_L-12_H-768_A-12) | [code](https://github.com/google-research/bert#pre-trained-models) |
| Bert(multi_cased_L-12_H-768_A-12) | [code](https://github.com/google-research/bert#pre-trained-models) |
## Caffe
## Caffe预测模型
| 模型 | 代码 |
|-------|--------|
......@@ -51,7 +48,7 @@
## ONNX
## ONNX预测模型
**注:** 部分模型来源于PyTorch,PyTorch的转换可参考[pytorch_to_onnx.md](pytorch_to_onnx.md)
| 模型 | 来源 | operator version|备注|
......@@ -72,11 +69,12 @@
| EfficientNet | [pytorch(personal practice)](https://github.com/rwightman/gen-efficientnet-pytorch) |9|
| SqueezeNet | [onnx official](https://s3.amazonaws.com/download.onnx/models/opset_9/squeezenet.tar.gz) |9|
|Ultra-Light-Fast-Generic-Face-Detector-1MB| [onnx_model](https://github.com/Linzaer/Ultra-Light-Fast-Generic-Face-Detector-1MB/tree/master/models/onnx)|9 |
|BERT| [pytorch(huggingface)](https://github.com/huggingface/transformers/blob/master/notebooks/04-onnx-export.ipynb)|11|转换时需指定input shape,见[文档Q3](../user_guides/FAQ.md)|
|GPT2| [pytorch(huggingface)](https://github.com/huggingface/transformers/blob/master/notebooks/04-onnx-export.ipynb)|11|转换时需指定input shape,见[文档Q3](../user_guides/FAQ.md)|
|BERT| [pytorch(huggingface)](https://github.com/huggingface/transformers/blob/master/notebooks/04-onnx-export.ipynb)|11|转换时需指定input shape,见[文档Q3](../inference_model_convertor/FAQ.md)|
|GPT2| [pytorch(huggingface)](https://github.com/huggingface/transformers/blob/master/notebooks/04-onnx-export.ipynb)|11|转换时需指定input shape,见[文档Q3](../inference_model_convertor/FAQ.md)|
|CifarNet | [tensorflow](https://github.com/tensorflow/models/blob/master/research/slim/nets/cifarnet.py)|9||
## PyTorch
## PyTorch预测模型
| 模型 | 代码 | 备注 |
|------|----------|------|
......@@ -98,4 +96,15 @@
| XLMRobertaForTokenClassification|[code](https://huggingface.co/transformers/model_doc/xlmroberta.html) |只支持trace模式|
| EasyOCR_detector|[code](https://github.com/JaidedAI/EasyOCR/blob/master/easyocr/detection.py) |-|
| EasyOCR_recognizer|[code](https://github.com/JaidedAI/EasyOCR/blob/master/easyocr/recognition.py) |-|
| SwinTransformer|[code](https://github.com/microsoft/Swin-Transformer/) |-|
| BASNet|[code](https://github.com/xuebinqin/BASNet) |-|
| DBFace |[code](https://github.com/dlunion/DBFacet) |-|
## PyTorch训练项目
| 模型 | 转换前代码 | 转换后代码 |
|------|----------|------|
| StaGAN | [code](https://github.com/yunjey/stargan)|[code](https://github.com/SunAhong1993/stargan/tree/paddle)|
| Ultra-Light-Fast-Generic-Face-Detector | [code](https://github.com/Linzaer/Ultra-Light-Fast-Generic-Face-Detector-1MB) |[code](https://github.com/SunAhong1993/Ultra-Light-Fast-Generic-Face-Detector-1MB/tree/paddle)|
**注:** 受限于不同框架的差异,部分模型可能会存在目前无法转换的情况,如TensorFlow中包含控制流的模型,NLP模型等。对于CV常见的模型,如若您发现无法转换或转换失败,存在较大diff等问题,欢迎通过[ISSUE反馈](https://github.com/PaddlePaddle/X2Paddle/issues/new)的方式告知我们(模型名,代码实现或模型获取方式),我们会及时跟进:
# PyTorch-PaddlePaddle API对应表
本文档梳理了常用PyTorch 1.8.1 API与PaddlePaddle 2.0.0 API对应关系和差异分析。根据文档对应关系,有PyTorch使用经验的用户,可根据对应关系,快速熟悉PaddlePaddle的API使用。
## [基础操作类](./ops/README.md)
## [组网类](./nn/README.md)
## [Loss类](./loss/README.md)
## [工具类](./utils/README.md)
## [视觉类](./vision/README.md)
***持续更新...***
***持续更新...***## Loss类
| 序号 | PyTorch API | PaddlePaddle API | 备注 |
| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| 1 | [torch.nn.L1Loss](https://pytorch.org/docs/stable/generated/torch.nn.L1Loss.html?highlight=l1loss#torch.nn.L1Loss) | [paddle.nn.loss.L1Loss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/L1Loss_cn.html#l1loss) | 功能一致,PyTroch存在废弃参数`size_average``reduce`。 |
| 2 | [torch.nn.MSELoss](https://pytorch.org/docs/stable/generated/torch.nn.MSELoss.html?highlight=mseloss#torch.nn.MSELoss) | [paddle.nn.MSELoss](https://pytorch.org/docs/stable/generated/torch.nn.MSELoss.html?highlight=mseloss#torch.nn.MSELoss) | 功能一致,PyTroch存在废弃参数`size_average``reduce`。 |
| 3 | [torch.nn.CrossEntropyLoss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/CrossEntropyLoss_cn.html#crossentropyloss) | [paddle.nn.CrossEntropyLoss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/CrossEntropyLoss_cn.html#crossentropyloss) | [差异对比](torch.nn.CrossEntropyLoss.md) |
| 4 | [torch.nn.KLDivLoss](https://pytorch.org/docs/stable/generated/torch.nn.KLDivLoss.html?highlight=kldivloss#torch.nn.KLDivLoss) | [paddle.nn.KLDivLoss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/KLDivLoss_cn.html) | [差异对比](torch.nn.KLDivLoss.md) |
| 5 | [torch.nn.BCELoss](https://pytorch.org/docs/stable/generated/torch.nn.BCELoss.html?highlight=bceloss#torch.nn.BCELoss) | [paddle.nn.BCELoss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/BCELoss_cn.html#bceloss) | 功能一致,PyTroch存在废弃参数`size_average``reduce`。 |
| 6 | [torch.nn.BCEWithLogitsLoss](https://pytorch.org/docs/stable/generated/torch.nn.BCEWithLogitsLoss.html?highlight=bcewithlogitsloss#torch.nn.BCEWithLogitsLoss) | [paddle.nn.BCEWithLogitsLoss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/BCEWithLogitsLoss_cn.html#bcewithlogitsloss) | 功能一致,PyTroch存在废弃参数`size_average``reduce`。 |
| 7 | [torch.nn.SmoothL1Loss](https://pytorch.org/docs/stable/generated/torch.nn.SmoothL1Loss.html?highlight=torch%20nn%20smoothl1loss#torch.nn.SmoothL1Loss) | [paddle.nn.SmoothL1Loss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/SmoothL1Loss_cn.html#smoothl1loss) | 功能一致,参数名不一致,PyTroch存在废弃参数`size_average``reduce`。 |
***持续更新...***
## torch.nn.CrossEntropyLoss
### [torch.nn.CrossEntropyLoss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/CrossEntropyLoss_cn.html#crossentropyloss)
```python
torch.nn.CrossEntropyLoss(weight=None,
size_average=None,
ignore_index=-100,
reduce=None,
reduction='mean')
```
### [paddle.nn.CrossEntropyLoss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/CrossEntropyLoss_cn.html#crossentropyloss)
```python
paddle.nn.CrossEntropyLoss(weight=None,
ignore_index=-100,
reduction='mean',
soft_label=False,
axis=-1,
use_softmax=True,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size_average | - | PyTorch废弃参数。 |
| reduce | - | PyTorch废弃参数。 |
| - | use_softmax | 表示在使用交叉熵之前是否计算softmax,PyTorch无此参数。 |
| - | soft_label | 指明label是否为软标签,PyTorch无此参数。 |
| - | axis | 表示进行softmax计算的维度索引,PyTorch无此参数。 |
### 功能差异
#### 计算方式
***PyTorch***:只支持在使用交叉熵之前计算softmax且为硬标签的计算方式。
***PaddlePaddle***:支持使用交叉熵之前是否计算softmax的设置,且支持软、硬标签两种计算方式,其计算方式可参见[文档](https://www.paddlepaddle.org.cn/documentation/docs/en/api/paddle/nn/layer/loss/CrossEntropyLoss_en.html)
## torch.nn.KLDivLoss
### [torch.nn.KLDivLoss](https://pytorch.org/docs/stable/generated/torch.nn.KLDivLoss.html?highlight=kldivloss#torch.nn.KLDivLoss)
```python
torch.nn.KLDivLoss(size_average=None,
reduce=None,
reduction='mean',
log_target=False)
```
### [paddle.nn.KLDivLoss](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/loss/KLDivLoss_cn.html)
```python
paddle.nn.KLDivLoss(reduction='mean')
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size_average | - | PyTorch废弃参数。 |
| reduce | - | PyTorch废弃参数。 |
| log_target | - | 表示是否对目标值进行log处理,PaddlePaddle无此参数。 |
### 功能差异
#### 计算方式
***PyTorch***
> 当`log_target`为`True`时:
> $ l(input,label)= e^{target}∗(label−input) $
>
> 当`log_target`为`False`时:
> 1. $ l(input,label)=target*(log(target)-input) $
> 2. $ l(input,label) $中值小于0的取0
***PaddlePaddle***
> $ l(input,label)=label∗(log(label)−input) $
在PaddlePaddle中可使用如下代码组合实现该API。
```python
import paddle
# 定义KLDivLoss
class KLDivLoss(paddle.nn.Layer):
def __init__(self,
size_average=None,
reduce=None,
reduction='mean',
log_target=False):
super().__init__()
self.reduction = reduction
self.log_target = log_target
def forward(self, input, target):
if self.log_target:
out = paddle.exp(target) * (target - input)
else:
out_pos = target * (paddle.log(target) - input)
zeros = paddle.zeros_like(out_pos)
out = paddle.where(target > 0, out_pos, zeros)
out_sum = paddle.sum(out)
if self.reduction == "sum":
return out_sum
elif self.reduction == "batchmean":
n = input.shape[0]
return out_sum / n
elif self.reduction == "mean":
return paddle.mean(out)
else:
return out
# 构造输入
import numpy as np
shape = (5, 20)
x = np.random.uniform(-10, 10, shape).astype('float32')
target = np.random.uniform(-10, 10, shape).astype('float32')
# 计算loss
kldiv_criterion = KLDivLoss()
pred_loss = kldiv_criterion(paddle.to_tensor(x),
paddle.to_tensor(target))
```
## 组网类
| 序号 | PyTorch API | PaddlePaddle API | 备注 |
| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| 1 | [torch.nn.Conv1d](https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html?highlight=torch%20nn%20conv1d#torch.nn.Conv1d) | [paddle.nn.Conv1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv1D_cn.html#conv1d) | [差异对比](torch.nn.Conv1d.md) |
| 2 | [torch.nn.Conv2d](https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html?highlight=conv2d#torch.nn.Conv2d) | [paddle.nn.Conv2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv2D_cn.html#conv2d) | [差异对比](torch.nn.Conv2d.md) |
| 3 | [torch.nn.Conv3d](https://pytorch.org/docs/stable/generated/torch.nn.Conv3d.html?highlight=conv3d#torch.nn.Conv3d) | [paddle.nn.Conv3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv3D_cn.html#conv3d) | [差异对比](torch.nn.Conv3d.md) |
| 4 | [torch.nn.ConvTranspose1d](https://pytorch.org/docs/stable/generated/torch.nn.ConvTranspose1d.html?highlight=torch%20nn%20convtranspose1d#torch.nn.ConvTranspose1d) | [paddle.nn.Conv1DTranspose](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv1DTranspose_cn.html#conv1dtranspose) | [差异对比](torch.nn.ConvTranspose1d.md) |
| 5 | [torch.nn.ConvTranspose2d](https://pytorch.org/docs/stable/generated/torch.nn.ConvTranspose2d.html?highlight=convtranspose2d#torch.nn.ConvTranspose2d) | [paddle.nn.Conv2DTranspose](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv2DTranspose_cn.html#conv2dtranspose) | [差异对比](torch.nn.ConvTranspose2d.md) |
| 6 | [torch.nn.ConvTranspose3d](https://pytorch.org/docs/stable/generated/torch.nn.ConvTranspose3d.html?highlight=convtranspose3d#torch.nn.ConvTranspose3d) | [paddle.nn.Conv3DTranspose](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv3DTranspose_cn.html#conv3dtranspose) | [差异对比](torch.nn.ConvTranspose3d.md) |
| 7 | [torch.nn.Linear](https://pytorch.org/docs/stable/generated/torch.nn.Linear.html?highlight=linear#torch.nn.Linear) | [paddle.nn.Linear](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Linear_cn.html#linear) | [差异对比](torch.nn.Linear.md) |
| 8 | [torch.nn.MaxPool1d](https://pytorch.org/docs/stable/generated/torch.nn.MaxPool1d.html?highlight=maxpool1d#torch.nn.MaxPool1d) | [paddle.nn.MaxPool1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/MaxPool1D_cn.html#maxpool1d) | [差异对比](torch.nn.MaxPool1d.md) |
| 9 | [torch.nn.MaxPool2d](https://pytorch.org/docs/stable/generated/torch.nn.MaxPool2d.html?highlight=maxpool2d#torch.nn.MaxPool2d) | [paddle.nn.MaxPool2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/MaxPool2D_cn.html#maxpool2d) | [差异对比](torch.nn.MaxPool2d.md) |
| 10 | [torch.nn.MaxPool3d](https://pytorch.org/docs/stable/generated/torch.nn.MaxPool3d.html?highlight=maxpool3d#torch.nn.MaxPool3d) | [paddle.nn.MaxPool3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/MaxPool3D_cn.html#maxpool3d) | [差异对比](torch.nn.MaxPool3d.md) |
| 11 | [torch.nn.MaxUnpool1d](https://pytorch.org/docs/stable/generated/torch.nn.MaxUnpool1d.html?highlight=unpool#torch.nn.MaxUnpool1d) | 无对应实现 | [组合实现](torch.nn.MaxUnpool1d.md) |
| 12 | [torch.nn.MaxUnpool2d](https://pytorch.org/docs/stable/generated/torch.nn.MaxUnpool2d.html?highlight=unpool#torch.nn.MaxUnpool2d) | 无对应实现 | [组合实现](torch.nn.MaxUnpool2d.md) |
| 13 | [torch.nn.MaxUnpool3d](https://pytorch.org/docs/stable/generated/torch.nn.MaxUnpool3d.html?highlight=unpool#torch.nn.MaxUnpool3d) | 无对应实现 | [组合实现](torch.nn.MaxUnpool3d.md) |
| 14 | [torch.nn.AvgPool1d](https://pytorch.org/docs/stable/generated/torch.nn.AvgPool1d.html?highlight=avgpool1d#torch.nn.AvgPool1d) | [paddle.nn.AvgPool1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AvgPool1D_cn.html#avgpool1d) | [差异对比](torch.nn.AvgPool1d.md) |
| 15 | [torch.nn.AvgPool2d](https://pytorch.org/docs/stable/generated/torch.nn.AvgPool2d.html?highlight=avgpool2d#torch.nn.AvgPool2d) | [paddle.nn.AvgPool2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AvgPool2D_cn.html#avgpool2d) | [差异对比](torch.nn.AvgPool2d.md) |
| 16 | [torch.nn.AvgPool3d](https://pytorch.org/docs/stable/generated/torch.nn.AvgPool3d.html?highlight=avgpool3d#torch.nn.AvgPool3d) | [paddle.nn.AvgPool3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AvgPool3D_cn.html#avgpool3d) | [差异对比](torch.nn.AvgPool3d.md) |
| 17 | [torch.nn.AdaptiveMaxPool1d](https://pytorch.org/docs/stable/generated/torch.nn.AdaptiveMaxPool1d.html?highlight=adaptivemaxpool1d#torch.nn.AdaptiveMaxPool1d) | [paddle.nn.AdaptiveMaxPool1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AdaptiveMaxPool1D_cn.html#adaptivemaxpool1d) | 功能一致,参数名不一致 |
| 18 | [torch.nn.AdaptiveMaxPool2d](https://pytorch.org/docs/stable/generated/torch.nn.AdaptiveMaxPool2d.html?highlight=adaptivemaxpool2d#torch.nn.AdaptiveMaxPool2d) | [paddle.nn.AdaptiveMaxPool2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AdaptiveMaxPool2D_cn.html#adaptivemaxpool2d) | 功能一致,参数名不一致 |
| 19 | [torch.nn.AdaptiveMaxPool3d](https://pytorch.org/docs/stable/generated/torch.nn.AdaptiveMaxPool3d.html?highlight=adaptivemaxpool3d#torch.nn.AdaptiveMaxPool3d) | [paddle.nn.AdaptiveMaxPool3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AdaptiveMaxPool3D_cn.html#adaptivemaxpool3d) | 功能一致,参数名不一致 |
| 20 | [torch.nn.AdaptiveAvgPool1d](https://pytorch.org/docs/stable/generated/torch.nn.AdaptiveAvgPool1d.html?highlight=adaptiveavgpool1d#torch.nn.AdaptiveAvgPool1d) | [paddle.nn.AdaptiveAvgPool1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AdaptiveAvgPool1D_cn.html#adaptiveavgpool1d) | 功能一致,参数名不一致 |
| 21 | [torch.nn.AdaptiveAvgPool2d](https://pytorch.org/docs/stable/generated/torch.nn.AdaptiveAvgPool2d.html?highlight=adaptiveavgpool2d#torch.nn.AdaptiveAvgPool2d) | [paddle.nn.AdaptiveAvgPool2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AdaptiveAvgPool2D_cn.html#adaptiveavgpool2d) | 功能一致,参数名不一致 |
| 22 | [torch.nn.AdaptiveAvgPool3d](https://pytorch.org/docs/stable/generated/torch.nn.AdaptiveAvgPool3d.html?highlight=adaptiveavgpool3d#torch.nn.AdaptiveAvgPool3d) | [paddle.nn.AdaptiveAvgPool3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AdaptiveAvgPool3D_cn.html#adaptiveavgpool3d) | 功能一致,参数名不一致 |
| 23 | [torch.nn.ConstantPad1d](https://pytorch.org/docs/stable/generated/torch.nn.ConstantPad1d.html?highlight=pad#torch.nn.ConstantPad1d) | [paddle.nn.Pad1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad1D_cn.html#pad1d) | [差异对比](torch.nn.ConstantPad1d.md) |
| 24 | [torch.nn.ConstantPad2d](https://pytorch.org/docs/stable/generated/torch.nn.ConstantPad2d.html?highlight=pad#torch.nn.ConstantPad2d) | [paddle.nn.Pad2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad2D_cn.html#pad2d) | [差异对比](torch.nn.ConstantPad2d.md) |
| 25 | [torch.nn.ConstantPad3d](https://pytorch.org/docs/stable/generated/torch.nn.ConstantPad3d.html?highlight=pad#torch.nn.ConstantPad3d) | [paddle.nn.Pad3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad3D_cn.html#pad3d) | [差异对比](torch.nn.ConstantPad3d.md) |
| 26 | [torch.nn.ReflectionPad1d](https://pytorch.org/docs/stable/generated/torch.nn.ReflectionPad1d.html?highlight=pad#torch.nn.ReflectionPad1d) | [paddle.nn.Pad1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad1D_cn.html#pad1d) | [差异对比](torch.nn.ReflectionPad1d.md) |
| 27 | [torch.nn.ReflectionPad2d](https://pytorch.org/docs/stable/generated/torch.nn.ReflectionPad2d.html?highlight=pad#torch.nn.ReflectionPad2d) | [paddle.nn.Pad2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad2D_cn.html#pad2d) | [差异对比](torch.nn.ReflectionPad2d.md) |
| 28 | [torch.nn.ReplicationPad1d](https://pytorch.org/docs/stable/generated/torch.nn.ReplicationPad1d.html?highlight=pad#torch.nn.ReplicationPad1d) | [paddle.nn.Pad1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad1D_cn.html#pad1d) | [差异对比](torch.nn.ReplicationPad1d.md) |
| 29 | [torch.nn.ReplicationPad2d](https://pytorch.org/docs/stable/generated/torch.nn.ReplicationPad2d.html?highlight=pad#torch.nn.ReplicationPad2d) | [paddle.nn.Pad2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad2D_cn.html#pad2d) | [差异对比](torch.nn.ReplicationPad2d.md) |
| 30 | [torch.nn.ReplicationPad3d](https://pytorch.org/docs/stable/generated/torch.nn.ReplicationPad3d.html?highlight=pad#torch.nn.ReplicationPad3d) | [paddle.nn.Pad3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad3D_cn.html#pad3d) | [差异对比](torch.nn.ReplicationPad3d.md) |
| 31 | [torch.nn.BatchNorm1d](https://pytorch.org/docs/stable/generated/torch.nn.BatchNorm1d.html?highlight=torch%20nn%20batchnorm1d#torch.nn.BatchNorm1d) | [paddle.nn.BatchNorm1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/norm/BatchNorm1D_cn.html#batchnorm1d) | [差异对比](torch.nn.BatchNorm1d.md) |
| 32 | [torch.nn.BatchNorm2d](https://pytorch.org/docs/stable/generated/torch.nn.BatchNorm2d.html?highlight=batchnorm2d#torch.nn.BatchNorm2d) | [paddle.nn.BatchNorm2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/norm/BatchNorm2D_cn.html#batchnorm2d) | [差异对比](torch.nn.BatchNorm2d.md) |
| 33 | [torch.nn.BatchNorm3d](https://pytorch.org/docs/stable/generated/torch.nn.BatchNorm3d.html?highlight=torch%20nn%20batchnorm3d#torch.nn.BatchNorm3d) | [paddle.nn.BatchNorm3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/norm/BatchNorm3D_cn.html#batchnorm3d) | [差异对比](torch.nn.BatchNorm3d.md) |
| 34 | [torch.nn.Upsample](https://pytorch.org/docs/stable/generated/torch.nn.Upsample.html?highlight=upsample#torch.nn.Upsample) | [paddle.nn.Upsample](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Upsample_cn.html#upsample) | [差异对比](torch.nn.Upsample.md) |
| 35 | [torch.nn.Dropout](https://pytorch.org/docs/stable/generated/torch.nn.Dropout.html?highlight=dropout#torch.nn.Dropout) | [paddle.nn.Dropout](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Dropout_cn.html#dropout) | [差异对比](torch.nn.Dropout.md) |
| 36 | [torch.nn.Dropout2d](https://pytorch.org/docs/stable/generated/torch.nn.Dropout2d.html?highlight=dropout2d#torch.nn.Dropout2d) | [paddle.nn.Dropout2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Dropout2D_cn.html#dropout2d) | [差异对比](torch.nn.Dropout2d.md) |
| 37 | [torch.nn.Dropout3d](https://pytorch.org/docs/stable/generated/torch.nn.Dropout3d.html?highlight=dropout3d#torch.nn.Dropout3d) | [paddle.nn.Dropout3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Dropout3D_cn.html#dropout3d) | [差异对比](torch.nn.Dropout3d.md) |
| 38 | [torch.nn.LSTM](https://pytorch.org/docs/stable/generated/torch.nn.LSTM.html?highlight=lstm#torch.nn.LSTM) | [paddle.nn.LSTM](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/rnn/LSTM_cn.html#lstm) | [差异对比](torch.nn.LSTM.md) |
| 39 | [torch.nn.GRU](https://pytorch.org/docs/stable/generated/torch.nn.GRU.html?highlight=torch%20nn%20gru#torch.nn.GRU) | [paddle.nn.GRU](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/rnn/GRU_cn.html#gru) | [差异对比](torch.nn.GRU.md) |
| 40 | [torch.nn.Embedding](https://pytorch.org/docs/stable/generated/torch.nn.Embedding.html?highlight=embedding#torch.nn.Embedding) | [paddle.nn.Embedding](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Embedding_cn.html#embedding) | [差异对比](torch.nn.Embedding.md) |
| 41 | [torch.nn.ELU](https://pytorch.org/docs/stable/generated/torch.nn.ELU.html?highlight=elu#torch.nn.ELU) | [paddle.nn.ELU](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/activation/ELU_cn.html#elu) | 功能一致,PaddlePaddle未定义`inplace`参数表示在不更改变量的内存地址的情况下,直接修改变量的值 |
| 42 | [torch.nn.Hardsigmoid](https://pytorch.org/docs/stable/generated/torch.nn.Hardsigmoid.html?highlight=hardsigmoid#torch.nn.Hardsigmoid) | [paddle.nn.Hardsigmoid](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/activation/Hardsigmoid_cn.html#hardsigmoid) | 功能一致,PaddlePaddle未定义`inplace`参数表示在不更改变量的内存地址的情况下,直接修改变量的值 |
| 43 | [torch.nn.LeakyReLU](https://pytorch.org/docs/stable/generated/torch.nn.LeakyReLU.html?highlight=leakyrelu#torch.nn.LeakyReLU) | [paddle.nn.LeakyReLU](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/activation/LeakyReLU_cn.html#leakyrelu) | 功能一致,PaddlePaddle未定义`inplace`参数表示在不更改变量的内存地址的情况下,直接修改变量的值 |
| 44 | [torch.nn.PReLU](https://pytorch.org/docs/stable/generated/torch.nn.PReLU.html?highlight=prelu#torch.nn.PReLU) | [paddle.nn.PReLU](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/activation/PReLU_cn.html#prelu) | 功能一致 |
| 45 | [torch.nn.ReLU](https://pytorch.org/docs/stable/generated/torch.nn.ReLU.html?highlight=relu#torch.nn.ReLU) | [paddle.nn.ReLU](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/activation/ReLU_cn.html#relu) | 功能一致,PaddlePaddle未定义`inplace`参数表示在不更改变量的内存地址的情况下,直接修改变量的值 |
| 46 | [torch.nn.Softmax](https://pytorch.org/docs/stable/generated/torch.nn.Softmax.html?highlight=softmax#torch.nn.Softmax) | [paddle.nn.Softmax](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/activation/Softmax_cn.html#softmax) | 功能一致,参数名不一致 |
***持续更新...***
# torch.nn.AvgPool1d
### [torch.nn.AvgPool1d](https://pytorch.org/docs/stable/generated/torch.nn.AvgPool1d.html?highlight=avgpool1d#torch.nn.AvgPool1d)
```python
torch.nn.AvgPool1d(kernel_size,
stride=None,
padding=0,
ceil_mode=False,
count_include_pad=True)
```
### [paddle.nn.AvgPool1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AvgPool1D_cn.html#avgpool1d)
```python
paddle.nn.AvgPool1D(kernel_size,
stride=None,
padding=0,
exclusive=True,
ceil_mode=False,
name=None)
```
### 功能差异
#### 池化方式
***PyTorch***: 使用`count_include_pad`表示是否使用额外padding的值计算平均池化结果,默认为True。
***PaddlePaddle***:使用`exclusive`表示是否不使用额外padding的值计算平均池化结果,默认为True。
## torch.nn.AvgPool2d
### [torch.nn.AvgPool2d](https://pytorch.org/docs/stable/generated/torch.nn.AvgPool2d.html?highlight=avgpool2d#torch.nn.AvgPool2d)
```python
torch.nn.AvgPool2d(kernel_size,
stride=None,
padding=0,
ceil_mode=False,
count_include_pad=True,
divisor_override=None)
```
### [paddle.nn.AvgPool2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AvgPool2D_cn.html#avgpool2d)
```python
paddle.nn.AvgPool2D(kernel_size,
stride=None,
padding=0,
ceil_mode=False,
exclusive=True,
divisor_override=None,
data_format='NCHW',
name=None)
```
### 功能差异
#### 池化方式
***PyTorch***: 使用`count_include_pad`表示是否使用额外padding的值计算平均池化结果,默认为True。
***PaddlePaddle***:使用`exclusive`表示是否不使用额外padding的值计算平均池化结果,默认为True。
## torch.nn.AvgPool3d
### [torch.nn.AvgPool3d](https://pytorch.org/docs/stable/generated/torch.nn.AvgPool3d.html?highlight=avgpool3d#torch.nn.AvgPool3d)
```python
torch.nn.AvgPool3d(kernel_size,
stride=None,
padding=0,
ceil_mode=False,
count_include_pad=True,
divisor_override=None)
```
### [paddle.nn.AvgPool3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/AvgPool3D_cn.html#avgpool3d)
```python
paddle.nn.AvgPool3D(kernel_size,
stride=None,
padding=0,
ceil_mode=False,
exclusive=True,
divisor_override=None,
data_format='NCDHW',
name=None)
```
### 功能差异
#### 池化方式
***PyTorch***: 使用`count_include_pad`表示是否使用额外padding的值计算平均池化结果,默认为True。
***PaddlePaddle***:使用`exclusive`表示是否不使用额外padding的值计算平均池化结果,默认为True。
## torch.nn.BatchNorm1d
### [torch.nn.BatchNorm1d](https://pytorch.org/docs/stable/generated/torch.nn.BatchNorm1d.html?highlight=torch%20nn%20batchnorm1d#torch.nn.BatchNorm1d)
```python
torch.nn.BatchNorm1d(num_features,
eps=1e-05,
momentum=0.1,
affine=True,
track_running_stats=True)
```
### [paddle.nn.BatchNorm1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/norm/BatchNorm1D_cn.html#batchnorm1d)
```python
paddle.nn.BatchNorm1D(num_features,
momentum=0.9,
epsilon=1e-05,
weight_attr=None,
bias_attr=None,
data_format='NCL',
use_global_stats=True,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| eps | epsilon | 为了数值稳定加在分母上的值。 |
| - | weight_attr | 指定权重参数属性的对象。如果为False, 则表示每个通道的伸缩固定为1,不可改变。默认值为None,表示使用默认的权重参数属性。 |
| - | bias_attr | 指定偏置参数属性的对象。如果为False, 则表示每一个通道的偏移固定为0,不可改变。默认值为None,表示使用默认的偏置参数属性。 |
| affine | - | 是否进行反射变换,PaddlePaddle无此参数。 |
| track_running_stats | use_global_stats | 表示是否已加载的全局均值和方差。 |
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCL`的输入。
***PaddlePaddle***:支持`NCL``NLC`两种格式的输入(通过`data_format`设置)。
#### 反射变换设置
当PyTorch的反射变换设置为`False`,表示weight和bias不进行更新,由于PaddlePaddle不具备这一功能,可使用如下代码组合实现该API。
```python
class BatchNorm1D(paddle.nn.BatchNorm1D):
def __init__(self,
num_features,
eps=1e-05,
momentum=0.1,
affine=True,
track_running_stats=True):
momentum = 1 - momentum
weight_attr = None
bias_attr = None
if not affine:
weight_attr = paddle.ParamAttr(learning_rate=0.0)
bias_attr = paddle.ParamAttr(learning_rate=0.0)
super().__init__(
num_features,
momentum=momentum,
epsilon=eps,
weight_attr=weight_attr,
bias_attr=bias_attr,
use_global_stats=track_running_stats)
```
## torch.nn.BatchNorm2d
### [torch.nn.BatchNorm2d](https://pytorch.org/docs/stable/generated/torch.nn.BatchNorm2d.html?highlight=batchnorm2d#torch.nn.BatchNorm2d)
```python
torch.nn.BatchNorm2d(num_features,
eps=1e-05,
momentum=0.1,
affine=True,
track_running_stats=True)
```
### [paddle.nn.BatchNorm2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/norm/BatchNorm2D_cn.html#batchnorm2d)
```python
paddle.nn.BatchNorm2D(num_features,
momentum=0.9,
epsilon=1e-05,
weight_attr=None,
bias_attr=None,
data_format='NCHW',
use_global_stats=True,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| eps | epsilon | 为了数值稳定加在分母上的值。 |
| - | weight_attr | 指定权重参数属性的对象。如果为False, 则表示每个通道的伸缩固定为1,不可改变。默认值为None,表示使用默认的权重参数属性。 |
| - | bias_attr | 指定偏置参数属性的对象。如果为False, 则表示每一个通道的偏移固定为0,不可改变。默认值为None,表示使用默认的偏置参数属性。 |
| affine | - | 是否进行反射变换,PaddlePaddle无此参数。 |
| track_running_stats | use_global_stats | 表示是否已加载的全局均值和方差。 |
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCHW``NHWC`两种格式的输入(通过`data_format`设置)。
#### 反射变换设置
当PyTorch的反射变换设置为`False`,表示weight和bias不进行更新,由于PaddlePaddle不具备这一功能,可使用如下代码组合实现该API。
```python
class BatchNorm2D(paddle.nn.BatchNorm2D):
def __init__(self,
num_features,
eps=1e-05,
momentum=0.1,
affine=True,
track_running_stats=True):
momentum = 1 - momentum
weight_attr = None
bias_attr = None
if not affine:
weight_attr = paddle.ParamAttr(learning_rate=0.0)
bias_attr = paddle.ParamAttr(learning_rate=0.0)
super().__init__(
num_features,
momentum=momentum,
epsilon=eps,
weight_attr=weight_attr,
bias_attr=bias_attr,
use_global_stats=track_running_stats)
```
## torch.nn.BatchNorm3d
### [torch.nn.BatchNorm3d](https://pytorch.org/docs/stable/generated/torch.nn.BatchNorm3d.html?highlight=torch%20nn%20batchnorm3d#torch.nn.BatchNorm3d)
```python
torch.nn.BatchNorm3d(num_features,
eps=1e-05,
momentum=0.1,
affine=True,
track_running_stats=True)
```
### [paddle.nn.BatchNorm3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/norm/BatchNorm3D_cn.html#batchnorm3d)
```python
paddle.nn.BatchNorm3D(num_features,
momentum=0.9,
epsilon=1e-05,
weight_attr=None,
bias_attr=None,
data_format='NCDHW',
use_global_stats=True,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| eps | epsilon | 为了数值稳定加在分母上的值。 |
| - | weight_attr | 指定权重参数属性的对象。如果为False, 则表示每个通道的伸缩固定为1,不可改变。默认值为None,表示使用默认的权重参数属性。 |
| - | bias_attr | 指定偏置参数属性的对象。如果为False, 则表示每一个通道的偏移固定为0,不可改变。默认值为None,表示使用默认的偏置参数属性。 |
| affine | - | 是否进行反射变换,PaddlePaddle无此参数。 |
| track_running_stats | use_global_stats | 表示是否已加载的全局均值和方差。 |
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCDHW`的输入。
***PaddlePaddle***:支持`NCDHW``NDHWC`两种格式的输入(通过`data_format`设置)。
#### 反射变换设置
当PyTorch的反射变换设置为`False`,表示weight和bias不进行更新,由于PaddlePaddle不具备这一功能,可使用如下代码组合实现该API。
```python
class BatchNorm3D(paddle.nn.BatchNorm3D):
def __init__(self,
num_features,
eps=1e-05,
momentum=0.1,
affine=True,
track_running_stats=True):
momentum = 1 - momentum
weight_attr = None
bias_attr = None
if not affine:
weight_attr = paddle.ParamAttr(learning_rate=0.0)
bias_attr = paddle.ParamAttr(learning_rate=0.0)
super().__init__(
num_features,
momentum=momentum,
epsilon=eps,
weight_attr=weight_attr,
bias_attr=bias_attr,
use_global_stats=track_running_stats)
```
## torch.nn.ConstantPad1d
### [torch.nn.ConstantPad1d](https://pytorch.org/docs/stable/generated/torch.nn.ConstantPad1d.html?highlight=pad#torch.nn.ConstantPad1d)
```python
torch.nn.ConstantPad1d(padding, value)
```
### [paddle.nn.Pad1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad1D_cn.html#pad1d)
```python
paddle.nn.Pad1D(padding, mode='constant', value=0.0, data_format='NCL', name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:只支持`constant`方式的Pad方式。
***PaddlePaddle***:支持`constant``reflect``replicate``circular`四种格式的输入(通过`mode`设置)。
#### 输入格式
***PyTorch***:只支持`NCL`的输入。
***PaddlePaddle***:支持`NCL``NLC`两种格式的输入(通过`data_format`设置)。
#### padding的设置
***PyTorch***:padding参数的类型只能为int或tuple。
***PaddlePaddle***:padding参数的类型只能为Tensor或list。
### 代码示例
``` python
# PyTorch示例:
import torch
import torch.nn as nn
import numpy as np
input_shape = (1, 2, 3)
pad = 1
data = torch.arange(np.prod(input_shape), dtype=torch.float32).reshape(input_shape) + 1
my_pad = nn.ConstantPad1d(padding=pad, value=0)
result = my_pad(data)
# 输出
# tensor([[[0., 1., 2., 3., 0.],
# [0., 4., 5., 6., 0.]]])
```
``` python
# PaddlePaddle示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 2, 3)
pad = [1, 1]
mode = "constant"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad1D(padding=pad, value=0, mode=mode)
result = my_pad(data)
# 输出
# Tensor(shape=[1, 2, 5], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[0., 1., 2., 3., 0.],
# [0., 4., 5., 6., 0.]]])
```
## torch.nn.ConstantPad2d
### [torch.nn.ConstantPad2d](https://pytorch.org/docs/stable/generated/torch.nn.ConstantPad2d.html?highlight=pad#torch.nn.ConstantPad2d)
```python
torch.nn.ConstantPad2d(padding, value)
```
### [paddle.nn.Pad2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad2D_cn.html#pad2d)
```python
paddle.nn.Pad2D(padding, mode='constant', value=0.0, data_format='NCHW', name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:只支持`constant`方式的Pad方式。
***PaddlePaddle***:支持`constant``reflect``replicate``circular`四种格式的输入(通过`mode`设置)。
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCHW``NHWC`两种格式的输入(通过`data_format`设置)。
#### padding的设置
***PyTorch***:padding参数的类型只能为int或tuple。
***PaddlePaddle***:padding参数的类型只能为Tensor或list。
### 代码示例
``` python
# PyTorch示例:
import torch
import torch.nn as nn
import numpy as np
input_shape = (1, 1, 2, 3)
pad = [1, 0, 1, 2]
data = torch.arange(np.prod(input_shape), dtype=torch.float32).reshape(input_shape) + 1
my_pad = nn.ConstantPad2d(padding=pad, value=0)
result = my_pad(data)
# 输出
# tensor([[[[0., 0., 0., 0.],
# [0., 1., 2., 3.],
# [0., 4., 5., 6.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.]]]])
```
``` python
# PaddlePaddle示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 1, 2, 3)
pad = [1, 0, 1, 2]
mode = "constant"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad2D(padding=pad, mode=mode)
result = my_pad(data)
# 输出
# Tensor(shape=[1, 1, 5, 4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[0., 0., 0., 0.],
# [0., 1., 2., 3.],
# [0., 4., 5., 6.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.]]]])
```
## torch.nn.ConstantPad3d
### [torch.nn.ConstantPad3d](https://pytorch.org/docs/stable/generated/torch.nn.ConstantPad3d.html?highlight=pad#torch.nn.ConstantPad3d)
```python
torch.nn.ConstantPad3d(padding, value)
```
### [paddle.nn.Pad3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad3D_cn.html#pad3d)
```python
paddle.nn.Pad3D(padding, mode='constant', value=0.0, data_format='NCDHW', name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:只支持`constant`方式的Pad方式。
***PaddlePaddle***:支持`constant``reflect``replicate``circular`四种格式的输入(通过`mode`设置)。
#### 输入格式
***PyTorch***:只支持`NCDHW`的输入。
***PaddlePaddle***:支持`NCDHW``NCDHW`两种格式的输入(通过`data_format`设置)。
#### padding的设置
***PyTorch***:padding参数的类型只能为int或tuple。
***PaddlePaddle***:padding参数的类型只能为Tensor或list。
### 代码示例
``` python
# PyTorch示例:
import torch
import torch.nn as nn
import numpy as np
input_shape = (1, 1, 1, 2, 3)
pad = [1, 0, 1, 2, 0, 0]
data = torch.arange(np.prod(input_shape), dtype=torch.float32).reshape(input_shape) + 1
my_pad = nn.ConstantPad3d(padding=pad, value=0)
result = my_pad(data)
# 输出
# tensor([[[[[0., 0., 0., 0.],
# [0., 1., 2., 3.],
# [0., 4., 5., 6.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.]]]]])
```
``` python
# PaddlePaddle示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 1, 1, 2, 3)
pad = [1, 0, 1, 2, 0, 0]
mode = "constant"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad3D(padding=pad, mode=mode)
result = my_pad(data)
# 输出
# Tensor(shape=[1, 1, 1, 5, 4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[[0., 0., 0., 0.],
# [0., 1., 2., 3.],
# [0., 4., 5., 6.],
# [0., 0., 0., 0.],
# [0., 0., 0., 0.]]]]])
```
# torch.nn.Conv1d
### [torch.nn.Conv1d](https://pytorch.org/docs/stable/generated/torch.nn.Conv1d.html?highlight=conv1d#torch.nn.Conv1d)
```python
torch.nn.Conv1d(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
bias=True,
padding_mode='zeros')
```
### [paddle.nn.Conv1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv1D_cn.html#conv1d)
```python
paddle.nn.Conv1D(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
padding_mode='zeros',
weight_attr=None,
bias_attr=None,
data_format='NCL')
```
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCL`的输入。
***PaddlePaddle***:支持`NCL``NLC`两种格式的输入(通过`data_format`设置)。
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_attr`/`bias_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_attr`设置为bool类型与PyTorch的作用一致。
#### padding的设置
***PyTorch***`padding`只能支持list或tuple类型。
***PaddlePaddle***`padding`支持list或tuple类型或str类型。
# torch.nn.Conv2d
### [torch.nn.Conv2d](https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html?highlight=conv2d#torch.nn.Conv2d)
```python
torch.nn.Conv2d(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
bias=True,
padding_mode='zeros')
```
### [paddle.nn.Conv2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv2D_cn.html#conv2d)
```python
paddle.nn.Conv2D(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
padding_mode='zeros',
weight_attr=None,
bias_attr=None,
data_format='NCHW')
```
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCHW``NHWC`两种格式的输入(通过`data_format`设置)。
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_attr`/`bias_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_attr`设置为bool类型与PyTorch的作用一致。
#### padding的设置
***PyTorch***`padding`只能支持list或tuple类型。它可以有3种格式:
(1)包含4个二元组:\[\[0,0\], \[0,0\], \[padding_height_top, padding_height_bottom\], \[padding_width_left, padding_width_right\]\],其中每个元组都可使用整数值替换,代表元组中的2个值相等;
(2)包含2个二元组:\[\[padding_height_top, padding_height_bottom\], \[padding_width_left, padding_width_right\]\],其中每个元组都可使用整数值替换,代表元组中的2个值相等;
(3)包含一个整数值,padding_height = padding_width = padding。
***PaddlePaddle***`padding`支持list或tuple类型或str类型。如果它是一个list或tuple,它可以有4种格式:
(1)包含4个二元组:当 data_format 为"NCHW"时为 \[\[0,0\], \[0,0\], \[padding_height_top, padding_height_bottom\], \[padding_width_left, padding_width_right\]\],当 data_format 为"NHWC"时为\[\[0,0\], \[padding_height_top, padding_height_bottom\], \[padding_width_left, padding_width_right\], \[0,0\]\]
(2)包含4个整数值:\[padding_height_top, padding_height_bottom, padding_width_left, padding_width_right\]
(3)包含2个整数值:\[padding_height, padding_width\],此时padding_height_top = padding_height_bottom = padding_height, padding_width_left = padding_width_right = padding_width;
(4)包含一个整数值,padding_height = padding_width = padding。如果它为一个字符串时,可以是"VALID"或者"SAME",表示填充算法。
# torch.nn.Conv3d
### [torch.nn.Conv3d](https://pytorch.org/docs/stable/generated/torch.nn.Conv3d.html?highlight=conv3d#torch.nn.Conv3d)
```python
torch.nn.Conv3d(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
bias=True,
padding_mode='zeros')
```
### [paddle.nn.Conv3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv3D_cn.html#conv3d)
```python
paddle.nn.Conv3D(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
dilation=1,
groups=1,
padding_mode='zeros',
weight_attr=None,
bias_attr=None,
data_format='NCDHW')
```
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCDHW``NDHWC`两种格式的输入(通过`data_format`设置)。
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_attr`/`bias_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_attr`设置为bool类型与PyTorch的作用一致。
#### padding的设置
***PyTorch***`padding`只能支持list或tuple类型。它可以有3种格式:
(1)包含4个二元组:\[\[0,0\], \[0,0\], \[padding_depth_front, padding_depth_back\], \[padding_height_top, padding_height_bottom\], \[padding_width_left, padding_width_right\]\],其中每个元组都可使用整数值替换,代表元组中的2个值相等;
(2)包含3个二元组:\[\[padding_depth_front, padding_depth_back\], \[padding_height_top, padding_height_bottom\], \[padding_width_left, padding_width_right\]\],其中每个元组都可使用整数值替换,代表元组中的2个值相等;
(3)包含一个整数值,padding_height = padding_width = padding。
***PaddlePaddle***`padding`支持list或tuple类型或str类型。如果它是一个list或tuple,它可以有4种格式:
(1)包含5个二元组:当 data_format 为"NCDHW"时为 \[\[0,0], \[0,0\], \[padding_depth_front, padding_depth_back\], \[padding_height_top, padding_height_bottom\], \[padding_width_left, padding_width_right\]\],当 data_format 为"NDHWC"时为\[\[0,0\], \[padding_depth_front, padding_depth_back\], \[padding_height_top, padding_height_bottom\], \[padding_width_left, padding_width_right\], \[0,0\]\]
(2)包含6个整数值:\[padding_depth_front, padding_depth_back, padding_height_top, padding_height_bottom, padding_width_left, padding_width_right\]
(3)包含3个整数值:\[padding_depth, padding_height, padding_width\],此时 padding_depth_front = padding_depth_back = padding_depth, padding_height_top = padding_height_bottom = padding_height, padding_width_left = padding_width_right = padding_width;
(4)包含一个整数值,padding_height = padding_width = padding。如果它为一个字符串时,可以是"VALID"或者"SAME",表示填充算法。
## torch.nn.ConvTranspose1d
### [torch.nn.ConvTranspose1d](https://pytorch.org/docs/stable/generated/torch.nn.ConvTranspose1d.html?highlight=torch%20nn%20convtranspose1d#torch.nn.ConvTranspose1d)
```python
torch.nn.ConvTranspose1d(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
output_padding=0,
groups=1,
bias=True,
dilation=1,
padding_mode='zeros')
```
### [paddle.nn.Conv1DTranspose](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv1DTranspose_cn.html#conv1dtranspose)
```python
paddle.nn.Conv1DTranspose(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
output_padding=0,
groups=1,
dilation=1,
weight_attr=None,
bias_attr=None,
data_format='NCL')
```
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCL`的输入。
***PaddlePaddle***:支持`NCL``NLC`两种格式的输入(通过`data_format`设置)。
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_attr`/`bias_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_attr`设置为bool类型与PyTorch的作用一致。
#### padding大小的设置
***PyTorch***`padding`只能支持list或tuple类型。
***PaddlePaddle***`padding`支持list或tuple类型或str类型。
#### padding值的设置
***PyTorch***:通过设置`padding_mode`确定padding的值。
***PaddlePaddle***:PaddlePaddle无此参数。
## torch.nn.ConvTranspose2d
### [torch.nn.ConvTranspose2d](https://pytorch.org/docs/stable/generated/torch.nn.ConvTranspose2d.html?highlight=convtranspose2d#torch.nn.ConvTranspose2d)
```python
torch.nn.ConvTranspose1d(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
output_padding=0,
groups=1,
bias=True,
dilation=1,
padding_mode='zeros')
```
### [paddle.nn.Conv2DTranspose](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv2DTranspose_cn.html#conv2dtranspose)
```python
paddle.nn.Conv2DTranspose(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
output_padding=0,
groups=1,
dilation=1,
weight_attr=None,
bias_attr=None,
data_format='NCHW')
```
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCHW``NHWC`两种格式的输入(通过`data_format`设置)。
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_attr`/`bias_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_attr`设置为bool类型与PyTorch的作用一致。
#### padding大小的设置
***PyTorch***`padding`只能支持list或tuple类型。
***PaddlePaddle***`padding`支持list或tuple类型或str类型。
#### padding值的设置
***PyTorch***:通过设置`padding_mode`确定padding的值。
***PaddlePaddle***:PaddlePaddle无此参数。
## torch.nn.ConvTranspose3d
### [torch.nn.ConvTranspose3d](https://pytorch.org/docs/stable/generated/torch.nn.ConvTranspose3d.html?highlight=convtranspose3d#torch.nn.ConvTranspose3d)
```python
torch.nn.ConvTranspose1d(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
output_padding=0,
groups=1,
bias=True,
dilation=1,
padding_mode='zeros')
```
### [paddle.nn.Conv3DTranspose](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/conv/Conv3DTranspose_cn.html#conv3dtranspose)
```python
paddle.nn.Conv2DTranspose(in_channels,
out_channels,
kernel_size,
stride=1,
padding=0,
output_padding=0,
groups=1,
dilation=1,
weight_attr=None,
bias_attr=None,
data_format='NCDHW')
```
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCDHW`的输入。
***PaddlePaddle***:支持`NCDHW``NDHWC`两种格式的输入(通过`data_format`设置)。
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_attr`/`bias_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_attr`设置为bool类型与PyTorch的作用一致。
#### padding大小的设置
***PyTorch***`padding`只能支持list或tuple类型。
***PaddlePaddle***`padding`支持list或tuple类型或str类型。
#### padding值的设置
***PyTorch***:通过设置`padding_mode`确定padding的值。
***PaddlePaddle***:PaddlePaddle无此参数。
## torch.nn.Dropout
### [torch.nn.Dropout](https://pytorch.org/docs/stable/generated/torch.nn.Dropout.html?highlight=dropout#torch.nn.Dropout)
```python
torch.nn.Dropout(p=0.5, inplace=False)
```
### [paddle.nn.Dropout](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Dropout_cn.html#dropout)
```python
paddle.nn.Dropout(p=0.5, axis=None, mode="upscale_in_train”, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| inplace | - | 表示在不更改变量的内存地址的情况下,直接修改变量的值,PaddlePaddle无此参数。 |
| - | axis | 指定对输入Tensor进行Dropout操作的轴,PyTorch无此参数。 |
| - | mode | 表示丢弃单元的方式,PyTorch无此参数。|
### 功能差异
#### 丢弃方式
***PyTorch***:只支持`upscale_in_train`的丢弃方式。
***PaddlePaddle***:支持`upscale_in_train``downscale_in_infer`两种丢弃方式(通过`mode`设置),计算方法可参考[文档](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Dropout_cn.html#dropout)
## torch.nn.Dropout2d
### [torch.nn.Dropout2d](https://pytorch.org/docs/stable/generated/torch.nn.Dropout2d.html?highlight=dropout2d#torch.nn.Dropout2d)
```python
torch.nn.Dropout2d(p=0.5, inplace=False)
```
### [paddle.nn.Dropout2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Dropout2D_cn.html#dropout2d)
```python
paddle.nn.Dropout2D(p=0.5, data_format='NCHW', name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| inplace | - | 表示在不更改变量的内存地址的情况下,直接修改变量的值,PaddlePaddle无此参数。 |
| - | data_format | 指定对输入的数据格式,PyTorch无此参数。 |
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCHW``NHWC`两种格式的输入(通过`data_format`设置)。
## torch.nn.Dropout3d
### [torch.nn.Dropout3d](https://pytorch.org/docs/stable/generated/torch.nn.Dropout3d.html?highlight=dropout3d#torch.nn.Dropout3d)
```python
torch.nn.Dropout3d(p=0.5, inplace=False)
```
### [paddle.nn.Dropout3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Dropout3D_cn.html#dropout3d)
```python
paddle.nn.Dropout3D(p=0.5, data_format='NCDHW', name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| inplace | - | 表示在不更改变量的内存地址的情况下,直接修改变量的值,PaddlePaddle无此参数。 |
| - | data_format | 指定对输入的数据格式,PyTorch无此参数。 |
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCDHW`的输入。
***PaddlePaddle***:支持`NCDHW``NDHWC`两种格式的输入(通过`data_format`设置)。
## torch.nn.Embedding
### [torch.nn.Embedding](https://pytorch.org/docs/stable/generated/torch.nn.Embedding.html?highlight=embedding#torch.nn.Embedding)
```python
torch.nn.Embedding(num_embeddings,
embedding_dim,
padding_idx=None,
max_norm=None,
norm_type=2.0,
scale_grad_by_freq=False,
sparse=False)
```
### [paddle.nn.Embedding](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Embedding_cn.html#embedding)
```python
paddle.nn.Embedding(num_embeddings,
embedding_dim,
padding_idx=None,
sparse=False,
weight_attr=None,
name=None)
```
### 功能差异
#### 归一化设置
***PyTorch***:当max_norm不为`None`时,如果Embeddding向量的范数(范数的计算方式由norm_type决定)超过了max_norm这个界限,就要再进行归一化。
***PaddlePaddle***:PaddlePaddle无此要求,因此不需要归一化。
#### 梯度缩放设置
***PyTorch***:若scale_grad_by_freq设置为`True`,会根据单词在mini-batch中出现的频率,对梯度进行放缩。
***PaddlePaddle***:PaddlePaddle无此功能。
## torch.nn.GRU
### [torch.nn.GRU](https://pytorch.org/docs/stable/generated/torch.nn.GRU.html?highlight=torch%20nn%20gru#torch.nn.GRU)
```python
torch.nn.GRU(input_size,
hidden_size,
num_layers=1,
bias=True,
batch_first=False,
dropout=0,
bidirectional=False)
```
### [paddle.nn.GRU](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/rnn/GRU_cn.html#gru)
```python
paddle.nn.GRU(input_size,
hidden_size,
num_layers=1,
direction='forward',
dropout=0.,
time_major=False,
weight_ih_attr=None,
weight_hh_attr=None,
bias_ih_attr=None,
bias_hh_attr=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| batch_first | time_major | PyTorch表示batch size是否为第一维,PaddlePaddle表示time steps是否为第一位,它们的意义相反。 |
| bidirectional | direction | PyTorch表示是否进行双向LSTM,PyTorch使用字符串表示是双向LSTM(`bidirectional`)还是单向LSTM(`forward`)。 |
### 功能差异
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_ih_attr`/`weight_hh_attr`/`bias_ih_attr`/`bias_hh_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_ih_attr`/`bias_hh_attr`设置为bool类型与PyTorch的作用一致。
## torch.nn.LSTM
### [torch.nn.LSTM](https://pytorch.org/docs/stable/generated/torch.nn.LSTM.html?highlight=lstm#torch.nn.LSTM)
```python
torch.nn.LSTM(input_size,
hidden_size,
num_layers=1,
bias=True,
batch_first=False,
dropout=0,
bidirectional=False,
proj_size=0)
```
### [paddle.nn.LSTM](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/rnn/LSTM_cn.html#lstm)
```python
paddle.nn.LSTM(input_size,
hidden_size,
num_layers=1,
direction='forward',
dropout=0.,
time_major=False,
weight_ih_attr=None,
weight_hh_attr=None,
bias_ih_attr=None,
bias_hh_attr=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| batch_first | time_major | PyTorch表示batch size是否为第一维,PaddlePaddle表示time steps是否为第一位,它们的意义相反。 |
| bidirectional | direction | PyTorch表示是否进行双向LSTM,PyTorch使用字符串表示是双向LSTM(`bidirectional`)还是单向LSTM(`forward`)。 |
| proj_size | - | 表示LSTM后将映射到对应的大小,PaddlePaddle无此功能。 |
### 功能差异
#### 映射大小的设置
***PyTorch***:支持将LSTM的结果映射到到对应大小,其具体方式可参见[论文](https://arxiv.org/abs/1402.1128)
***PaddlePaddle***:无此功能。
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_ih_attr`/`weight_hh_attr`/`bias_ih_attr`/`bias_hh_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_ih_attr`/`bias_hh_attr`设置为bool类型与PyTorch的作用一致。
## torch.nn.Linear
### [torch.nn.Linear](https://pytorch.org/docs/stable/generated/torch.nn.Linear.html?highlight=linear#torch.nn.Linear)
```python
torch.nn.Linear(in_features, out_features, bias=True)
```
### [paddle.nn.Linear](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Linear_cn.html#linear)
```python
paddle.nn.Linear(in_features, out_features, weight_attr=None, bias_attr=None, name=None)
```
### 功能差异
#### 更新参数设置
***PyTorch***`bias`默认为True,表示使用可更新的偏置参数。
***PaddlePaddle***`weight_attr`/`bias_attr`默认使用默认的权重/偏置参数属性,否则为指定的权重/偏置参数属性,具体用法参见[ParamAttr](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/param_attr/ParamAttr_cn.html#cn-api-fluid-paramattr);当`bias_attr`设置为bool类型与PyTorch的作用一致。
## torch.nn.MaxPool1d
### [torch.nn.MaxPool1d](https://pytorch.org/docs/stable/generated/torch.nn.MaxPool1d.html?highlight=maxpool1d#torch.nn.MaxPool1d)
```python
torch.nn.MaxPool1d(kernel_size,
stride=None,
padding=0,
dilation=1,
return_indices=False,
ceil_mode=False)
```
### [paddle.nn.MaxPool1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/MaxPool1D_cn.html#maxpool1d)
```python
paddle.nn.MaxPool1D(kernel_size,
stride=None,
padding=0,
return_mask=False,
ceil_mode=False,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| dilation | - | 设置空洞池化的大小,PaddlePaddle无此参数。 |
### 功能差异
#### 池化方式
***PyTorch***:可以使用空洞池化。
***PaddlePaddle***:无此池化方式。
## torch.nn.MaxPool2d
### [torch.nn.MaxPool2d](https://pytorch.org/docs/stable/generated/torch.nn.MaxPool2d.html?highlight=maxpool2d#torch.nn.MaxPool2d)
```python
torch.nn.MaxPool2d(kernel_size,
stride=None,
padding=0,
dilation=1,
return_indices=False,
ceil_mode=False)
```
### [paddle.nn.MaxPool2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/MaxPool2D_cn.html#maxpool2d)
```python
paddle.nn.MaxPool2D(kernel_size,
stride=None,
padding=0,
return_mask=False,
ceil_mode=False,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| dilation | - | 设置空洞池化的大小,PaddlePaddle无此参数。 |
### 功能差异
#### 池化方式
***PyTorch***:可以使用空洞池化。
***PaddlePaddle***:无此池化方式。
## torch.nn.MaxPool3d
### [torch.nn.MaxPool3d](https://pytorch.org/docs/stable/generated/torch.nn.MaxPool3d.html?highlight=maxpool3d#torch.nn.MaxPool3d)
```python
torch.nn.MaxPool3d(kernel_size,
stride=None,
padding=0,
dilation=1,
return_indices=False,
ceil_mode=False)
```
### [paddle.nn.MaxPool3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/pooling/MaxPool3D_cn.html#maxpool3d)
```python
paddle.nn.MaxPool3D(kernel_size,
stride=None,
padding=0,
ceil_mode=False,
return_mask=False,
data_format='NCDHW',
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| dilation | - | 设置空洞池化的大小,PaddlePaddle无此参数。 |
### 功能差异
#### 池化方式
***PyTorch***:可以使用空洞池化。
***PaddlePaddle***:无此池化方式。
## torch.nn.MaxUnpool1d
### [torch.nn.MaxUnpool1d](https://pytorch.org/docs/stable/generated/torch.nn.MaxUnpool1d.html?highlight=unpool#torch.nn.MaxUnpool1d)
```python
torch.nn.MaxUnpool1d(kernel_size, stride=None, padding=0)
```
### 功能介绍
用于实现一维反池化,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
import paddle
import paddle.nn as nn
TYPE_MAPPER = {"fp16": "float16", "fp32": "float32", "fp64": "float64"}
# 定义MaxUnpool1D
class MaxUnpool1D(paddle.nn.Layer):
def __init__(self, kernel_size, stride=None, padding=0):
super().__init__()
if isinstance(stride, int):
self.kernel_size = [kernel_size]
else:
self.kernel_size = kernel_size
if stride is None:
self.stride = self.kernel_size
else:
if isinstance(stride, int):
self.stride = [stride]
else:
self.stride = stride
if isinstance(padding, int):
self.padding = [padding]
else:
self.padding = padding
def forward(self, input, indices, output_size=None):
if output_size is None:
n, c, l = input.shape
out_l = (l - 1) * self.stride[0] - 2 * self.padding[0] + self.kernel_size[0]
output_size = (n, c, out_l)
else:
if len(output_size) == len(self.kernel_size) + 2:
output_size = output_size[2:]
t = str(input.dtype).lower().strip().split(".")[-1]
t = TYPE_MAPPER[t]
out = paddle.zeros(output_size, dtype=t)
flatten_out = paddle.flatten(out)
for i in range(indices.shape[0]):
for j in range(indices.shape[1]):
for k in range(indices.shape[2]):
indices[i, j, k] = (out.shape[1] * out.shape[2]) * i + out.shape[2] * j + indices[i, j, k]
flatten_indices = paddle.flatten(indices)
flatten_input = paddle.flatten(input)
for i in range(flatten_indices.shape[0]):
flatten_out[flatten_indices[i].tolist()] = flatten_input[i].tolist()
out = paddle.reshape(flatten_out, out.shape)
return out
# 组网
pool = nn.MaxPool1D(2, stride=2, return_mask=True)
unpool = MaxUnpool1D(2, stride=2)
# 构造输入
input = paddle.to_tensor([[[ 1., 2, 3, 4]]])
# 进行池化
pool_res, indices = pool(input)
# pool_res:
# Tensor(shape=[1, 1, 2], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[2., 4.]]])
# indices:
# Tensor(shape=[1, 1, 2], dtype=int32, place=CPUPlace, stop_gradient=True,
# [[[1, 3]]])
# 进行反池化
res = unpool(pool_res, indices)
# res:
# Tensor(shape=[1, 1, 4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[0., 2., 0., 4.]]])
```
## torch.nn.MaxUnpool2d
### [torch.nn.MaxUnpool2d](https://pytorch.org/docs/stable/generated/torch.nn.MaxUnpool2d.html?highlight=maxunpool2d#torch.nn.MaxUnpool2d)
```python
torch.nn.MaxUnpool2d(kernel_size, stride=None, padding=0)
```
### 功能介绍
用于实现一维反池化,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
import paddle
import paddle.nn as nn
TYPE_MAPPER = {"fp16": "float16", "fp32": "float32", "fp64": "float64"}
# 定义MaxUnpool2D
class MaxUnpool2D(paddle.nn.Layer):
def __init__(self, kernel_size, stride=None, padding=0):
super().__init__()
if isinstance(stride, int):
self.kernel_size = (kernel_size, kernel_size)
else:
self.kernel_size = kernel_size
if stride is None:
self.stride = self.kernel_size
else:
if isinstance(stride, int):
self.stride = (stride, stride)
else:
self.stride = stride
if isinstance(padding, int):
self.padding = (padding, padding)
else:
self.padding = padding
def forward(self, input, indices, output_size=None):
if output_size is None:
n, c, h, w = input.shape
out_h = (h - 1) * self.stride[0] - 2 * self.padding[0] + self.kernel_size[0]
out_w = (w - 1) * self.stride[1] - 2 * self.padding[1] + self.kernel_size[1]
output_size = (n, c, out_h, out_w)
else:
if len(output_size) == len(self.kernel_size) + 2:
output_size = output_size[2:]
t = str(input.dtype).lower().strip().split(".")[-1]
t = TYPE_MAPPER[t]
out = paddle.zeros(output_size, dtype=t)
flatten_out = paddle.flatten(out)
for i in range(indices.shape[0]):
for j in range(indices.shape[1]):
for k in range(indices.shape[2]):
for m in range(indices.shape[3]):
indices[i, j, k, m] = (out.shape[1] * out.shape[2] * out.shape[3]) * i + \
(out.shape[2] * out.shape[3]) * j + indices[i, j, k, m]
flatten_indices = paddle.flatten(indices)
flatten_input = paddle.flatten(input)
for i in range(flatten_indices.shape[0]):
flatten_out[flatten_indices[i].tolist()] = flatten_input[i].tolist()
out = paddle.reshape(flatten_out, out.shape)
return out
# 组网
pool = nn.MaxPool2D(2, stride=2, return_mask=True)
unpool = MaxUnpool2D(2, stride=2)
# 构造输入
input = paddle.to_tensor([[[[ 1., 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]]]])
# 进行池化
pool_res, indices = pool(input)
# pool_res:
# Tensor(shape=[1, 1, 2, 2], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[6. , 8. ],
# [14., 16.]]]])
# indices:
# Tensor(shape=[1, 1, 2, 2], dtype=int32, place=CPUPlace, stop_gradient=True,
# [[[[5 , 7 ],
# [13, 15]]]])
# 进行反池化
res = unpool(pool_res, indices)
# res:
# Tensor(shape=[1, 1, 4, 4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[0. , 0. , 0. , 0. ],
# [0. , 6. , 0. , 8. ],
# [0. , 0. , 0. , 0. ],
# [0. , 14., 0. , 16.]]]])
```
## torch.nn.MaxUnpool3d
### [torch.nn.MaxUnpool3d](https://pytorch.org/docs/stable/generated/torch.nn.MaxUnpool3d.html?highlight=maxunpool3d#torch.nn.MaxUnpool3d)
```python
torch.nn.MaxUnpool3d(kernel_size, stride=None, padding=0)
```
### 功能介绍
用于实现一维反池化,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
import paddle
import paddle.nn as nn
TYPE_MAPPER = {"fp16": "float16", "fp32": "float32", "fp64": "float64"}
# 定义MaxUnpool3D
class MaxUnpool3D(paddle.nn.Layer):
def __init__(self, kernel_size, stride=None, padding=0):
super().__init__()
if isinstance(stride, int):
self.kernel_size = (kernel_size, kernel_size, kernel_size)
else:
self.kernel_size = kernel_size
if stride is None:
self.stride = self.kernel_size
else:
if isinstance(stride, int):
self.stride = (stride, stride, stride)
else:
self.stride = stride
if isinstance(padding, int):
self.padding = (padding, padding, padding)
else:
self.padding = padding
def forward(self, input, indices, output_size=None):
if output_size is None:
n, c, d, h, w = input.shape
out_d = (d - 1) * self.stride[0] - 2 * self.padding[0] + self.kernel_size[0]
out_h = (h - 1) * self.stride[1] - 2 * self.padding[1] + self.kernel_size[1]
out_w = (w - 1) * self.stride[2] - 2 * self.padding[2] + self.kernel_size[2]
output_size = (n, c, out_d, out_h, out_w)
else:
if len(output_size) == len(self.kernel_size) + 2:
output_size = output_size[2:]
t = str(input.dtype).lower().strip().split(".")[-1]
t = TYPE_MAPPER[t]
out = paddle.zeros(output_size, dtype=t)
flatten_out = paddle.flatten(out)
for i in range(indices.shape[0]):
for j in range(indices.shape[1]):
for k in range(indices.shape[2]):
for m in range(indices.shape[3]):
for n in range(indices.shape[4]):
indices[i, j, k, m, n] = (out.shape[1] * out.shape[2] * out.shape[3] * out.shape[4]) * i + \
(out.shape[2] * out.shape[3] * out.shape[4]) * j + \
indices[i, j, k, m, n]
flatten_indices = paddle.flatten(indices)
flatten_input = paddle.flatten(input)
for i in range(flatten_indices.shape[0]):
flatten_out[flatten_indices[i].tolist()] = flatten_input[i].tolist()
out = paddle.reshape(flatten_out, out.shape)
return out
# 组网
pool = nn.MaxPool3D(2, stride=2, padding=0, return_mask=True)
unpool = MaxUnpool3D(2, stride=2, padding=0)
# 构造输入
input = paddle.to_tensor([[[[[ 1., 2, 3, 4],
[ 5, 6, 7, 8]],
[[ 1., 2, 3, 4],
[ 5, 6, 7, 8]]]]])
# 进行池化
pool_res, indices = pool(input)
# pool_res:
# Tensor(shape=[1, 1, 1, 1, 2], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[[6., 8.]]]]])
# indices
# Tensor(shape=[1, 1, 1, 1, 2], dtype=int32, place=CPUPlace, stop_gradient=True,
# [[[[[5, 7]]]]])
# 进行反池化
res = unpool(pool_res, indices)
# res:
# Tensor(shape=[1, 1, 2, 2, 4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[[0., 0., 0., 0.],
# [0., 6., 0., 8.]],
# [[0., 0., 0., 0.],
# [0., 0., 0., 0.]]]]])
```
## torch.nn.ReflectionPad1d
### [torch.nn.ReflectionPad1d](https://pytorch.org/docs/stable/generated/torch.nn.ReflectionPad1d.html?highlight=pad#torch.nn.ReflectionPad1d)
```python
torch.nn.ReflectionPad1d(padding)
```
### [paddle.nn.Pad1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad1D_cn.html#pad1d)
```python
paddle.nn.Pad1D(padding, mode='constant', value=0.0, data_format='NCL', name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:只支持`reflect`方式的Pad方式。
***PaddlePaddle***:支持`constant``reflect``replicate``circular`四种格式的输入(通过`mode`设置)。
#### 输入格式
***PyTorch***:只支持`NCL`的输入。
***PaddlePaddle***:支持`NCL``NLC`两种格式的输入(通过`data_format`设置)。
#### padding的设置
***PyTorch***:padding参数的类型只能为int或tuple。
***PaddlePaddle***:padding参数的类型只能为Tensor或list。
### 代码示例
``` python
# PyTorch示例:
import torch
import torch.nn as nn
import numpy as np
input_shape = (1, 2, 3)
pad = 2
data = torch.arange(np.prod(input_shape), dtype=torch.float32).reshape(input_shape) + 1
my_pad = nn.ReflectionPad1d(padding=pad)
result = my_pad(data)
# 输出
# tensor([[[3., 2., 1., 2., 3., 2., 1.],
# [6., 5., 4., 5., 6., 5., 4.]]])
```
``` python
# PaddlePaddle示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 2, 3)
pad = [2, 2]
mode = "reflect"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad1D(padding=pad, mode=mode)
result = my_pad(data)
# 输出
# Tensor(shape=[1, 2, 7], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[3., 2., 1., 2., 3., 2., 1.],
# [6., 5., 4., 5., 6., 5., 4.]]])
```
## torch.nn.ReflectionPad2d
### [torch.nn.ReflectionPad2d](https://pytorch.org/docs/stable/generated/torch.nn.ReflectionPad2d.html?highlight=pad#torch.nn.ReflectionPad2d)
```python
torch.nn.ReflectionPad2d(padding)
```
### [paddle.nn.Pad2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad2D_cn.html#pad2d)
```python
paddle.nn.Pad2D(padding, mode='constant', value=0.0, data_format='NCHW', name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:只支持`reflect`方式的Pad方式。
***PaddlePaddle***:支持`constant``reflect``replicate``circular`四种格式的输入(通过`mode`设置)。
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCHW``NHWC`两种格式的输入(通过`data_format`设置)。
#### padding的设置
***PyTorch***:padding参数的类型只能为int或tuple。
***PaddlePaddle***:padding参数的类型只能为Tensor或list。
### 代码示例
``` python
# PyTorch示例:
import torch
import torch.nn as nn
import numpy as np
input_shape = (1, 1, 2, 3)
pad = [1, 0, 1, 0]
data = torch.arange(np.prod(input_shape), dtype=torch.float32).reshape(input_shape) + 1
my_pad = nn.ReflectionPad2d(padding=pad)
result = my_pad(data)
# 输出
# tensor([[[[5., 4., 5., 6.],
# [2., 1., 2., 3.],
# [5., 4., 5., 6.]]]])
```
``` python
# PaddlePaddle示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 1, 2, 3)
pad = [1, 0, 1, 0]
mode = "reflect"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad2D(padding=pad, mode=mode)
result = my_pad(data)
# 输出
# Tensor(shape=[1, 1, 3, 4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[5., 4., 5., 6.],
# [2., 1., 2., 3.],
# [5., 4., 5., 6.]]]])
```
## torch.nn.ReplicationPad1d
### [torch.nn.ReplicationPad1d](https://pytorch.org/docs/stable/generated/torch.nn.ReplicationPad1d.html?highlight=pad#torch.nn.ReplicationPad1d)
```python
torch.nn.ReplicationPad1d(padding)
```
### [paddle.nn.Pad1D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad1D_cn.html#pad1d)
```python
paddle.nn.Pad1D(padding, mode='constant', value=0.0, data_format='NCL', name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:只支持`replicate`方式的Pad方式。
***PaddlePaddle***:支持`constant``reflect``replicate``circular`四种格式的输入(通过`mode`设置)。
#### 输入格式
***PyTorch***:只支持`NCL`的输入。
***PaddlePaddle***:支持`NCL``NLC`两种格式的输入(通过`data_format`设置)。
#### padding的设置
***PyTorch***:padding参数的类型只能为int或tuple。
***PaddlePaddle***:padding参数的类型只能为Tensor或list。
### 代码示例
``` python
# PyTorch示例:
import torch
import torch.nn as nn
import numpy as np
input_shape = (1, 2, 3)
pad = 2
data = torch.arange(np.prod(input_shape), dtype=torch.float32).reshape(input_shape) + 1
my_pad = nn.ReplicationPad1d(padding=pad)
result = my_pad(data)
# 输出
# tensor([[[1., 1., 1., 2., 3., 3., 3.],
# [4., 4., 4., 5., 6., 6., 6.]]])
```
``` python
# PaddlePaddle示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 2, 3)
pad = [2, 2]
mode = "replicate"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad1D(padding=pad, mode=mode)
result = my_pad(data)
# 输出
# Tensor(shape=[1, 2, 7], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[1., 1., 1., 2., 3., 3., 3.],
# [4., 4., 4., 5., 6., 6., 6.]]])
```
## torch.nn.ReplicationPad2d
### [torch.nn.ReplicationPad2d](https://pytorch.org/docs/stable/generated/torch.nn.ReplicationPad2d.html?highlight=pad#torch.nn.ReplicationPad2d)
```python
torch.nn.ReplicationPad2d(padding)
```
### [paddle.nn.Pad2D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad2D_cn.html#pad2d)
```python
paddle.nn.Pad2D(padding, mode='constant', value=0.0, data_format='NCHW', name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:只支持`replicate`方式的Pad方式。
***PaddlePaddle***:支持`constant``reflect``replicate``circular`四种格式的输入(通过`mode`设置)。
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCHW``NHWC`两种格式的输入(通过`data_format`设置)。
#### padding的设置
***PyTorch***:padding参数的类型只能为int或tuple。
***PaddlePaddle***:padding参数的类型只能为Tensor或list。
### 代码示例
``` python
# PyTorch示例:
import torch
import torch.nn as nn
import numpy as np
input_shape = (1, 1, 2, 3)
pad = [1, 0, 1, 0]
data = torch.arange(np.prod(input_shape), dtype=torch.float32).reshape(input_shape) + 1
my_pad = nn.ReplicationPad2d(padding=pad)
result = my_pad(data)
# 输出
# tensor([[[[1., 1., 2., 3.],
# [1., 1., 2., 3.],
# [4., 4., 5., 6.]]]])
```
``` python
# PaddlePaddle示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 1, 2, 3)
pad = [1, 0, 1, 0]
mode = "replicate"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad2D(padding=pad, mode=mode)
result = my_pad(data)
# 输出
# Tensor(shape=[1, 1, 3, 4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[1., 1., 2., 3.],
# [1., 1., 2., 3.],
# [4., 4., 5., 6.]]]])
```
## torch.nn.ReplicationPad3d
### [torch.nn.ReplicationPad3d](https://pytorch.org/docs/stable/generated/torch.nn.ReplicationPad3d.html?highlight=pad#torch.nn.ReplicationPad3d)
```python
torch.nn.ReplicationPad3d(padding)
```
### [paddle.nn.Pad3D](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Pad3D_cn.html#pad3d)
```python
paddle.nn.Pad3D(padding, mode='constant', value=0.0, data_format='NCDHW', name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:只支持`replicate`方式的Pad方式。
***PaddlePaddle***:支持`constant``reflect``replicate``circular`四种格式的输入(通过`mode`设置)。
#### 输入格式
***PyTorch***:只支持`NCDHW`的输入。
***PaddlePaddle***:支持`NCDHW``NCDHW`两种格式的输入(通过`data_format`设置)。
#### padding的设置
***PyTorch***:padding参数的类型只能为int或tuple。
***PaddlePaddle***:padding参数的类型只能为Tensor或list。
### 代码示例
``` python
# PyTorch示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 1, 1, 2, 3)
pad = [1, 0, 1, 2, 0, 0]
mode = "constant"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad3D(padding=pad, mode=mode)
result = my_pad(data)
# 输出
# tensor([[[[[1., 1., 2., 3.],
# [1., 1., 2., 3.],
# [4., 4., 5., 6.],
# [4., 4., 5., 6.],
# [4., 4., 5., 6.]]]]])
```
``` python
# PaddlePaddle示例:
import paddle
import paddle.nn as nn
import numpy as np
input_shape = (1, 1, 1, 2, 3)
pad = [1, 0, 1, 2, 0, 0]
mode = "constant"
data = paddle.arange(np.prod(input_shape), dtype="float32").reshape(input_shape) + 1
my_pad = nn.Pad3D(padding=pad, mode=mode)
result = my_pad(data)
# 输出
# Tensor(shape=[1, 1, 1, 5, 4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[[[[1., 1., 2., 3.],
# [1., 1., 2., 3.],
# [4., 4., 5., 6.],
# [4., 4., 5., 6.],
# [4., 4., 5., 6.]]]]])
```
## torch.nn.Upsample
### [torch.nn.Upsample](https://pytorch.org/docs/stable/generated/torch.nn.Upsample.html?highlight=upsample#torch.nn.Upsample)
```python
torch.nn.Upsample(size=None,
scale_factor=None,
mode='nearest',
align_corners=False)
```
### [paddle.nn.Upsample](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Upsample_cn.html#upsample)
```python
paddle.nn.Upsample(size=None,
scale_factor=None,
mode='nearest',
align_corners=False,
align_mode=0,
data_format='NCHW',
name=None)
```
### 功能差异
#### 输入格式
***PyTorch***:只支持`NCHW`的输入。
***PaddlePaddle***:支持`NCHW``NHWC`两种格式的输入(通过`data_format`设置)。
#### 计算方式
***PyTorch***:在mode为`bilinear``trilinear`时,只支持align_mode为0的上采样。
***PaddlePaddle***:在mode为`bilinear``trilinear`时,支持align_mode为0和1的上采样。
【注意】align_mode为0或1时的上采样方式可参见[文档](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/nn/layer/common/Upsample_cn.html#upsample)
此差异已折叠。
## torch.arange
### [torch.arange](https://pytorch.org/docs/stable/generated/torch.arange.html?highlight=arange#torch.arange)
```python
torch.arange(start=0,
end,
step=1,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.arange](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/arange_cn.html#arange)
```python
paddle.arange(start=0,
end=None,
step=1,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
## torch.bernoulli
### [torch.bernoulli](https://pytorch.org/docs/stable/generated/torch.bernoulli.html?highlight=bernoulli#torch.bernoulli)
```python
torch.bernoulli(input, *, generator=None, out=None)
```
### [paddle.bernoulli](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/random/bernoulli_cn.html#bernoulli)
```python
paddle.bernoulli(x, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| input | x | 表示输入Tensor。 |
| generator | - | 用于采样的伪随机数生成器,PaddlePaddle无此参数。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
***【注意】*** 这类生成器的用法如下:
```python
G = torch.Generator()
G.manual_seed(1)
# 生成指定分布Tensor
torch.randperm(5, generator=G)
```
## torch.div
### [torch.div](https://pytorch.org/docs/stable/generated/torch.div.html?highlight=div#torch.div)
```python
torch.div(input, other, *, rounding_mode=None, out=None)
```
### [paddle.divide](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/math/divide_cn.html#divide)
```python
paddle.divide(x, y, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| rounding_mode | - | 表示舍入模式,PaddlePaddle无此参数。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
### 功能差异
#### 舍入模式设置
***PyTorch***:可以通过`rounding_mode`设置舍入模式,`"trunc"`表示向0取整,`"floor"`表示向下取整,默认值为`None`表示不进行任何舍入操作。
***PaddlePaddle***:PaddlePaddle无此功能,需要组合实现。
### 代码示例
``` python
# PyTorch示例:
import torch
a = torch.tensor([ 0.3810, 1.2774, -0.3719, 0.4637])
b = torch.tensor([ 1.8032, 0.2930, 0.5091, -0.1392])
out = torch.div(a, b, rounding_mode='trunc')
# 输出
# tensor([ 0., 4., -0., -3.])
```
``` python
# PaddlePaddle示例:
import paddle
a = paddle.to_tensor([0.3810, 1.2774, -0.3719, 0.4637], dtype="float32")
b = paddle.to_tensor([1.8032, 0.2930, 0.5091, -0.1392], dtype="float32")
ipt = paddle.divide(a, b)
sign_ipt = paddle.sign(ipt)
abs_ipt = paddle.abs(ipt)
abs_ipt = paddle.floor(abs_ipt)
out = paddle.multiply(sign_ipt, abs_ipt)
# 输出
# Tensor(shape=[4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [ 0., 4., -0., -3.])
```
## torch.divide
### [torch.divide](https://pytorch.org/docs/stable/generated/torch.divide.html?highlight=divide#torch.divide)
```python
torch.divide(input, other, *, rounding_mode=None, out=None)
```
### [paddle.divide](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/math/divide_cn.html#divide)
```python
paddle.divide(x, y, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| rounding_mode | - | 表示舍入模式,PaddlePaddle无此参数。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
### 功能差异
#### 舍入模式设置
***PyTorch***:可以通过`rounding_mode`设置舍入模式,`"trunc"`表示向0取整,`"floor"`表示向下取整,默认值为`None`表示不进行任何舍入操作。
***PaddlePaddle***:PaddlePaddle无此功能,需要组合实现。
### 代码示例
``` python
# PyTorch示例:
import torch
a = torch.tensor([ 0.3810, 1.2774, -0.3719, 0.4637])
b = torch.tensor([ 1.8032, 0.2930, 0.5091, -0.1392])
out = torch.divide(a, b, rounding_mode='trunc')
# 输出
# tensor([ 0., 4., -0., -3.])
```
``` python
# PaddlePaddle示例:
import paddle
a = paddle.to_tensor([0.3810, 1.2774, -0.3719, 0.4637], dtype="float32")
b = paddle.to_tensor([1.8032, 0.2930, 0.5091, -0.1392], dtype="float32")
ipt = paddle.divide(a, b)
sign_ipt = paddle.sign(ipt)
abs_ipt = paddle.abs(ipt)
abs_ipt = paddle.floor(abs_ipt)
out = paddle.multiply(sign_ipt, abs_ipt)
# 输出
# Tensor(shape=[4], dtype=float32, place=CPUPlace, stop_gradient=True,
# [ 0., 4., -0., -3.])
```
## torch.empty
### [torch.empty](https://pytorch.org/docs/stable/generated/torch.empty.html?highlight=empty#torch.empty)
```python
torch.empty(*size,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False,
pin_memory=False)
```
### [paddle.empty](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/empty_cn.html#empty)
```python
paddle.empty(shape,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size | shape | 表示输出形状大小。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
| pin_memeory | - | 表示是否使用锁页内存,PaddlePaddle无此参数。 |
### 功能差异
#### 使用方式
***PyTorch***:生成Tensor的形状大小以可变参数的方式传入。
***PaddlePaddle***:生成Tensor的形状大小以list的方式传入。
### 代码示例
``` python
# PyTorch示例:
torch.empty(2, 3)
# 输出
# tensor([[9.1835e-41, 0.0000e+00, 0.0000e+00],
# [0.0000e+00, 0.0000e+00, 0.0000e+00]])
```
``` python
# PaddlePaddle示例:
paddle.empty([2, 3])
# 输出
# Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[0., 0., 0.],
# [0., 0., 0.]])
```
## torch.empty_like
### [torch.empty_like](https://pytorch.org/docs/stable/generated/torch.empty_like.html?highlight=empty_like#torch.empty_like)
```python
torch.empty_like(input,
*,
dtype=None,
layout=None,
device=None,
requires_grad=False,
memory_format=torch.preserve_format)
```
### [paddle.empty_like](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/empty_like_cn.html#empty-like)
```python
paddle.empty_like(x, dtype=None, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| input | x | 表示输入Tensor。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
| pin_memeory | - | 表示是否使用锁页内存,PaddlePaddle无此参数。 |
## torch.eye
### [torch.eye](https://pytorch.org/docs/stable/generated/torch.eye.html?highlight=eye#torch.eye)
```python
torch.eye(n,
m=None,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.eye](https://pytorch.org/docs/stable/generated/torch.eye.html?highlight=eye#torch.eye)
```python
paddle.eye(num_rows,
num_columns=None,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| n | num_rows | 生成2-D Tensor的行数。 |
| m | num_columns | 生成2-D Tensor的列数。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
## torch.tensor
### [torch.from_numpy](https://pytorch.org/docs/stable/generated/torch.from_numpy.html?highlight=from_numpy#torch.from_numpy)
```python
torch.from_numpy(ndarray)
```
### [paddle.to_tensor](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/to_tensor_cn.html#to-tensor)
```python
paddle.to_tensor(data,
dtype=None,
place=None,
stop_gradient=True)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| ndarray | data | 表示需要转换的数据。 |
| - | dtype | 表示数据类型,PyTorch无此参数。 |
| - | place | 表示Tensor存放位置,PyTorch无此参数。 |
| - | stop_gradient | 表示是否阻断梯度传导,PyTorch无此参数。 |
### 功能差异
#### 使用方式
***PyTorch***:只能传入一个numpy.ndarray。
***PaddlePaddle***:可以传入scalar、list、tuple、numpy.ndarray、paddle.Tensor。
## torch.full
### [torch.full](https://pytorch.org/docs/stable/generated/torch.full.html?highlight=full#torch.full)
```python
torch.full(size,
fill_value,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.full](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/full_cn.html#full)
```python
paddle.full(shape,
fill_value,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size | shape | 表示输出形状大小。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
## torch.full_like
### [torch.full_like](https://pytorch.org/docs/stable/generated/torch.full_like.html?highlight=full_like#torch.full_like)
```python
torch.full_like(input,
fill_value,
*,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False,
memory_format=torch.preserve_format)
```
### [paddle.full_like](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/full_like_cn.html#full-like)
```python
paddle.full_like(x, fill_value, dtype=None, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| input | x | 表示输入Tensor。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否阻断梯度传导,PaddlePaddle无此参数。 |
| memory_format | - | 表示是内存格式,PaddlePaddle无此参数。 |
## torch.gather
### [torch.gather](https://pytorch.org/docs/stable/generated/torch.gather.html?highlight=gather#torch.gather)
```python
torch.gather(input, dim, index, *, sparse_grad=False, out=None)
```
### [paddle.gather](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/manipulation/gather_cn.html#gather)
```python
paddle.gather(x, index, axis=None, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| input | x | 表示输入Tensor。 |
| dim | axis | 用于指定index获取输入的维度,PyTorch中类型仅能为int,PaddlePaddle中类型可以为int32/int64/Tensor。 |
| sparse_grad | - | 表示是否对梯度稀疏化,PaddlePaddle无此参数。 |
| out | - | 表示目标Tensor,PaddlePaddle无此参数。 |
### 功能差异
#### 使用方式
***PyTorch***:索引(index)的维度数和输入(input)的维度数一致,索引(index)的形状大小要小于等于输入(input)的形状大小。
***PaddlePaddle***:索引(index)的秩有且只能等于1。
#### 计算方式
***PyTorch***:沿指定的轴(dim)收集值。以2-D Tensor输入为例,其输出结果如下:
```
if dim == 0:
out[i][j] = input[index[i][j]][j]
if dim == 1:
out[i][j] = input[i][index[i][j]]
```
***PaddlePaddle***:根据索引(index)获取输入(x)的指定维度(axis)的条目,并将它们拼接在一起。以2-D Tensor输入为例,其输出结果如下:
```
if axis == 0:
tensor_list = list()
for i in index:
tensor_list.append(index[i, :])
将tensor_list中的tensor沿axis轴拼接
if axis == 1:
tensor_list = list()
for i in index:
tensor_list.append(index[:, i])
将tensor_list中的tensor沿axis轴拼接
```
### 代码示例
``` python
# PyTorch示例:
t = torch.tensor([[1, 2], [3, 4]])
torch.gather(t, 1, torch.tensor([[0, 0], [1, 0]]))
# 输出
# tensor([[ 1, 1],
# [ 4, 3]])
```
``` python
# PaddlePaddle示例:
t = paddle.to_tensor([[1, 2], [3, 4]])
paddle.gather(t, paddle.to_tensor([1, 0]), 1)
# 输出
# Tensor(shape=[2, 2], dtype=int64, place=CPUPlace, stop_gradient=True,
# [[2, 1],
# [4, 3]])
```
## torch.linspace
### [torch.linspace](https://pytorch.org/docs/stable/generated/torch.linspace.html?highlight=linspace#torch.linspace)
```python
torch.linspace(start,
end,
steps,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.linspace](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/layers/linspace_cn.html#linspace)
```python
paddle.linspace(start,
stop,
num,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
## torch.load
### [torch.load](https://pytorch.org/docs/stable/generated/torch.load.html?highlight=load#torch.load)
```python
torch.load(f,
map_location=None,
pickle_module=pickle,
**pickle_load_args)
```
### [paddle.load](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/framework/io/load_cn.html#load)
```python
paddle.load(path, **configs)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| pickle_module | - | 表示用于unpickling元数据和对象的模块,PaddlePaddle无此参数。 |
| map_location | - | 表示加载模型的位置,PaddlePaddle无此参数。 |
### 功能差异
#### 加载类型
***PyTorch***:可从文件或者内存中的读缓冲区(例如`io.BytesIO``io.StringIO`)中加载。
***PaddlePaddle***:只能从文件中加载。
#### 加载内容
***PyTorch***:可以加载`torch.Tensor``torch.nn.Module`、优化器等多个类型的数据。
***PaddlePaddle***:只能加载`paddle.nn.Layer`、优化器这两个类型的数据。
### 代码示例
``` python
# PyTorch示例:
torch.load('tensors.pt', map_location=torch.device('cpu'))
```
``` python
# PaddlePaddle示例:
load_layer_state_dict = paddle.load("emb.pdparams")
```
## torch.multinomial
### [torch.multinomial](https://pytorch.org/docs/stable/generated/torch.multinomial.html?highlight=multinomial#torch.multinomial)
```python
torch.multinomial(input, num_samples, replacement=False, *, generator=None, out=None)
```
### [paddle.multinomial](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/random/multinomial_cn.html#multinomial)
```python
paddle.multinomial(x, num_samples=1, replacement=False, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| input | x | 表示输入Tensor。 |
| generator | - | 用于采样的伪随机数生成器,PaddlePaddle无此参数。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
***【注意】*** 这类生成器的用法如下:
```python
G = torch.Generator()
G.manual_seed(1)
# 生成指定分布Tensor
torch.randperm(5, generator=G)
```
## torch.narrow
### [torch.narrow](https://pytorch.org/docs/stable/generated/torch.narrow.html?highlight=narrow#torch.narrow)
```python
torch.narrow(input, dim, start, length)
```
### [paddle.slice](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/layers/slice_cn.html#slice)
```python
paddle.slice(input, axes, starts, ends)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| dim | axes | 表示切片的轴。 |
| start | starts | 表示起始位置。 |
### 功能差异
#### 使用方式
***PyTorch***:只能在一个维度上进行切割,`dim``start``length`传入的值均只能为int型;使用该维度输出长度(`length`)来定位结束位置。
***PaddlePaddle***:可以在多个维度进行切割,`axes``starts``ends`传入的值为list/tuple(`starts``ends`传入的值可以为tensor);直接使用结束位置(`end`)来定位结束位置。
### 代码示例
``` python
# PyTorch示例:
x = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
torch.narrow(x, 0, 0, 2)
# 输出
# tensor([[ 1, 2, 3],
# [ 4, 5, 6]])
```
``` python
# PaddlePaddle示例:
x = paddle.to_tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
paddle.slice(x, [0], [0], [2])
# 输出
# Tensor(shape=[2, 3], dtype=int64, place=CPUPlace, stop_gradient=True,
# [[1, 2, 3],
# [4, 5, 6]])
```
## torch.normal
### [torch.normal](https://pytorch.org/docs/stable/generated/torch.normal.html?highlight=normal#torch.normal)
```python
torch.normal(mean, std, *, generator=None, out=None)
```
### [paddle.normal](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/random/normal_cn.html#normal)
```python
paddle.normal(mean=0.0, std=1.0, shape=None, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| - | shape | 表示输出Tensor的形状。 |
| generator | - | 用于采样的伪随机数生成器,PaddlePaddle无此参数。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
***【注意】*** 这类生成器的用法如下:
```python
G = torch.Generator()
G.manual_seed(1)
# 生成指定分布Tensor
torch.randperm(5, generator=G)
```
### 功能差异
#### 使用方式
***PyTorch***: `mean``std`只能是Tensor,表示输出Tensor中每个元素的正态分布的均值和标准差。
***PaddlePaddle***: `mean``std`既能是Tensor,也能是float,当为float时,则表示输出Tensor中所有元素的正态分布的均值和标准差,同时需要设置`shape`,表示生成的随机Tensor的形状。
## torch.ones
### [torch.ones](https://pytorch.org/docs/stable/generated/torch.ones.html?highlight=ones#torch.ones)
```python
torch.ones(*size,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.ones](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/ones_cn.html#ones)
```python
paddle.ones(shape,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size | shape | 表示输出形状大小。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
### 功能差异
#### 使用方式
***PyTorch***:生成Tensor的形状大小以可变参数的方式传入。
***PaddlePaddle***:生成Tensor的形状大小以list或tuple的方式传入。
### 代码示例
``` python
# PyTorch示例:
torch.ones(2, 3)
# 输出
# tensor([[ 1., 1., 1.],
# [ 1., 1., 1.]])
```
``` python
# PaddlePaddle示例:
paddle.ones([2, 3])
# 输出
# Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[1., 1., 1.],
# [1., 1., 1.]])
```
## torch.ones_like
### [torch.ones_like](https://pytorch.org/docs/stable/generated/torch.ones_like.html?highlight=ones_like#torch.ones_like)
```python
torch.ones_like(input,
*,
dtype=None,
layout=None,
device=None,
requires_grad=False,
memory_format=torch.preserve_format)
```
### [paddle.ones_like](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/ones_like_cn.html#ones-like)
```python
paddle.ones_like(x, dtype=None, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| input | x | 表示输入Tensor。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
| memory_format | - | 表示内存格式,PaddlePaddle无此参数。 |
### [torch.rand](https://pytorch.org/docs/stable/generated/torch.rand.html?highlight=rand#torch.rand)
```python
torch.rand(*size,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.rand](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/rand_cn.html#rand)
```python
paddle.rand(shape,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size | shape | 表示输出形状大小。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
### 功能差异
#### 使用方式
***PyTorch***:生成Tensor的形状大小以可变参数的方式传入。
***PaddlePaddle***:生成Tensor的形状大小以list或tuple的方式传入。
### 代码示例
``` python
# PyTorch示例:
torch.rand(2, 3)
# 输出
# tensor([[0.0860, 0.2757, 0.3211],
# [0.5872, 0.5267, 0.4184]])
```
``` python
# PaddlePaddle示例:
paddle.rand([2, 3])
# 输出
# Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[0.18905126, 0.56219709, 0.00808361],
# [0.78120756, 0.32112977, 0.90572405]])
```
## torch.randint
### [torch.randint](https://pytorch.org/docs/stable/generated/torch.randint.html?highlight=randint#torch.randint)
```python
torch.randint(low=0,
high,
size,
*,
generator=None,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.randint](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/random/randint_cn.html#randint)
```python
paddle.randint(low=0,
high=None,
shape=[1],
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size | shape | 表示输出形状大小。 |
| generator | - | 用于采样的伪随机数生成器,PaddlePaddle无此参数。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
***【注意】*** 这类生成器的用法如下:
```python
G = torch.Generator()
G.manual_seed(1)
# 生成指定分布Tensor
torch.randperm(5, generator=G)
```
### [torch.randn](https://pytorch.org/docs/stable/generated/torch.randn.html?highlight=randn#torch.randn)
```python
torch.randn(*size,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.randn](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/randn_cn.html#randn)
```python
paddle.randn(shape,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size | shape | 表示输出形状大小。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
### 功能差异
#### 使用方式
***PyTorch***:生成Tensor的形状大小以可变参数的方式传入。
***PaddlePaddle***:生成Tensor的形状大小以list或tuple的方式传入。
### 代码示例
``` python
# PyTorch示例:
torch.randn(2, 3)
# 输出
# tensor([[ 1.3290, 1.4679, -1.2373],
# [-0.2354, -0.9818, 0.0877]])
```
``` python
# PaddlePaddle示例:
paddle.randn([2, 3])
# 输出
# Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[-1.74181163, -0.50677234, -0.14707172],
# [ 1.18375409, 1.52477348, -0.73248941]])
```
## torch.randperm
### [torch.randperm](https://pytorch.org/docs/stable/generated/torch.randperm.html?highlight=randperm#torch.randperm)
```python
torch.randperm(n,
*,
generator=None,
out=None,
dtype=torch.int64,
layout=torch.strided,
device=None,
requires_grad=False,
pin_memory=False)
```
### [paddle.randperm](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/random/randperm_cn.html#randperm)
```python
paddle.randperm(n, dtype='int64', name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| generator | - | 用于采样的伪随机数生成器,PaddlePaddle无此参数。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
| pin_memeory | - | 表示是否使用锁页内存,PaddlePaddle无此参数。 |
***【注意】*** 这类生成器的用法如下:
```python
G = torch.Generator()
G.manual_seed(1)
# 生成指定分布Tensor
torch.randperm(5, generator=G)
```
## torch.range
### [torch.range](https://pytorch.org/docs/stable/generated/torch.arange.html?highlight=arange#torch.range)
```python
torch.range(start=0,
end,
step=1,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.arange](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/arange_cn.html#arange)
```python
paddle.arange(start=0,
end=None,
step=1,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
## torch.save
### [torch.save](https://pytorch.org/docs/stable/generated/torch.save.html?highlight=save#torch.save)
```python
torch.save(obj,
f,
pickle_module=pickle,
pickle_protocol=2)
```
### [paddle.save](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/framework/io/save_cn.html#save)
```python
paddle.save(obj, path, pickle_protocol=2)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| f | path | 表示存储的路径。 |
| pickle_module | - | 表示用于pickling元数据和对象的模块,PaddlePaddle无此参数。 |
### 功能差异
#### 存储类型
***PyTorch***:可存储到文件或者内存中的写缓冲区(例如`io.BytesIO``io.StringIO`)。
***PaddlePaddle***:只能存储到文件中。
#### 存储内容
***PyTorch***:可以存储`torch.Tensor``torch.nn.Module`、优化器等多个类型的数据。
***PaddlePaddle***:只能存储`paddle.nn.Layer`、优化器这两个类型的数据。
### 代码示例
``` python
# PyTorch示例:
x = torch.tensor([0, 1, 2, 3, 4])
buffer = io.BytesIO()
torch.save(x, buffer)
```
``` python
# PaddlePaddle示例:
x = paddle.to_tensor([0, 1, 2, 3, 4])
padle.save(x, "tensor.pdiparams")
# 报错:
# NotImplementedError: Now only supports save state_dict of Layer or Optimizer, expect dict, but received <class 'paddle.VarBase'>.
emb = paddle.nn.Embedding(10, 10)
layer_state_dict = emb.state_dict()
paddle.save(layer_state_dict, "emb.pdparams")
# 正常保存
```
## torch.tensor
### [torch.tensor](https://pytorch.org/docs/stable/generated/torch.tensor.html?highlight=tensor#torch.tensor)
```python
torch.tensor(data,
dtype=None,
device=None,
requires_grad=False,
pin_memory=False)
```
### [paddle.to_tensor](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/to_tensor_cn.html#to-tensor)
```python
paddle.to_tensor(data,
dtype=None,
place=None,
stop_gradient=True)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| device | place | 表示Tensor存放位置。 |
| requires_grad | stop_gradient | PyTorch表示是否不阻断梯度传导,PaddlePaddle表示是否阻断梯度传导。 |
| pin_memeory | - | 表示是否使用锁页内存,PaddlePaddle无此参数。 |
## torch.transpose
### [torch.transpose](https://pytorch.org/docs/stable/generated/torch.transpose.html?highlight=transpose#torch.transpose)
```python
torch.transpose(input, dim0, dim1)
```
### [paddle.transpose](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/layers/transpose_cn.html#transpose)
```python
paddle.transpose(x, perm, name=None)
```
### 功能差异
#### 使用方式
***PyTorch***:需要设置2个维度值(`dim0``dim1`)表示需要交换的维度。
***PaddlePaddle***:需要设置一个重排顺序(`perm`),类型为list或者tuple。
### 代码示例
``` python
# PyTorch示例:
x = torch.ones((10,20,30))
out = torch.transpose(x, 0, 2)
out.shape
# 输出
# torch.Size([30, 20, 10])
```
``` python
# PaddlePaddle示例:
x = paddle.ones((10,20,30))
out = paddle.transpose(x, (2, 1, 0))
out.shape
# 输出
# [30, 20, 10]
```
## torch.zeros
### [torch.zeros](https://pytorch.org/docs/stable/generated/torch.zeros.html?highlight=zeros#torch.zeros)
```python
torch.zeros(*size,
*,
out=None,
dtype=None,
layout=torch.strided,
device=None,
requires_grad=False)
```
### [paddle.zeros](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/zeros_cn.html#zeros)
```python
paddle.zeros(shape,
dtype=None,
name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| size | shape | 表示输出形状大小。 |
| out | - | 表示输出的Tensor,PaddlePaddle无此参数。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
### 功能差异
#### 使用方式
***PyTorch***:生成Tensor的形状大小以可变参数的方式传入。
***PaddlePaddle***:生成Tensor的形状大小以list的方式传入。
### 代码示例
``` python
# PyTorch示例:
torch.zeros(2, 3)
# 输出
# tensor([[ 0., 0., 0.],
# [ 0., 0., 0.]])
```
``` python
# PaddlePaddle示例:
paddle.zeros([2, 3])
# 输出
# Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[0., 0., 0.],
# [0., 0., 0.]])
```
## torch.zeros_like
### [torch.zeros_like](https://pytorch.org/docs/stable/generated/torch.zeros_like.html?highlight=zeros_like#torch.zeros_like)
```python
torch.zeros_like(input,
*,
dtype=None,
layout=None,
device=None,
requires_grad=False,
memory_format=torch.preserve_format)
```
### [paddle.zeros_like](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/tensor/creation/zeros_like_cn.html#zeros-like)
```python
paddle.zeros_like(x, dtype=None, name=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| input | x | 表示输入Tensor。 |
| layout | - | 表示布局方式,PaddlePaddle无此参数。 |
| device | - | 表示Tensor存放位置,PaddlePaddle无此参数。 |
| requires_grad | - | 表示是否不阻断梯度传导,PaddlePaddle无此参数。 |
| memory_format | - | 表示内存格式,PaddlePaddle无此参数。 |
## 工具类
| 序号 | PyTorch API | PaddlePaddle API | 备注 |
| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| 1 | [torch.nn.DataParallel](https://pytorch.org/docs/stable/generated/torch.nn.DataParallel.html?highlight=dataparallel#torch.nn.DataParallel) | [paddle.DataParallel](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/dygraph/parallel/DataParallel_cn.html#dataparallel) | [差异对比](torch.nn.DataParallel.md) |
| 2 | [torch.nn.parameter.Parameter](https://pytorch.org/docs/stable/generated/torch.nn.parameter.Parameter.html?highlight=torch%20nn%20parameter#torch.nn.parameter.Parameter) | [paddle.create_parameter](https://github.com/PaddlePaddle/Paddle/blob/ce2bdb0afdc2a09a127e8d9aa394c8b00a877364/python/paddle/fluid/layers/tensor.py#L77) | [差异对比](torch.nn.parameter.Parameter.md) |
| 3 | [torch.nn.utils.clip_grad_value_](https://pytorch.org/docs/stable/generated/torch.nn.utils.clip_grad_value_.html?highlight=clip_grad_value_#torch.nn.utils.clip_grad_value_) | 无对应实现 | [组合实现](torch.nn.utils.clip_grad_value_.md) |
| 4 | [torch.utils.data.DataLoader](https://pytorch.org/docs/stable/data.html?highlight=dataloader#torch.utils.data.DataLoader) | [paddle.io.DataLoader](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/reader/DataLoader_cn.html#dataloader) | [差异对比](torch.utils.data.DataLoader.md) |
| 5 | [torch.utils.data.random_split](https://pytorch.org/docs/stable/data.html?highlight=random_split#torch.utils.data.random_split) | 无对应实现 | [组合实现](torch.utils.data.random_split.md) |
| 6 | [torch.utils.data.distributed.DistributedSampler](https://pytorch.org/docs/stable/data.html?highlight=distributedsampler#torch.utils.data.distributed.DistributedSampler) | 无对应实现 | [组合实现](torch.utils.data.distributed.DistributedSampler.md) |
| 7 | [torch.utils.data.Dataset](https://pytorch.org/docs/stable/data.html?highlight=torch%20utils%20data%20dataset#torch.utils.data.Dataset) | [paddle.io.Dataset](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/dataloader/dataset/Dataset_cn.html#dataset) | 功能一致 |
| 8 | [torch.utils.data.BatchSampler](https://pytorch.org/docs/stable/data.html?highlight=batchsampler#torch.utils.data.BatchSampler) | [paddle.io.BatchSampler](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/dataloader/batch_sampler/BatchSampler_cn.html#batchsampler) | [差异对比](torch.utils.data.BatchSampler.md) |
| 9 | [torch.utils.data.Sampler](https://pytorch.org/docs/stable/data.html?highlight=sampler#torch.utils.data.Sampler) | [paddle.io.Sampler](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/dataloader/sampler/Sampler_cn.html#sampler) | 功能一致 |
***持续更新...***
## torch.nn.DataParallel
### [torch.nn.DataParallel](https://pytorch.org/docs/stable/generated/torch.nn.DataParallel.html?highlight=dataparallel#torch.nn.DataParallel)
```python
torch.nn.DataParallel(module, device_ids=None, output_device=None, dim=0)
```
### [paddle.DataParallel](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/dygraph/parallel/DataParallel_cn.html#dataparallel)
```python
paddle.DataParallel(layers, strategy=None, comm_buffer_size=25, last_comm_buffer_size=1)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| module | layers | 需要通过数据并行方式执行的模型。 |
| device_ids | - | 表示训练在哪几块GPU上,PaddlePaddle无此参数。 |
| output_device | - | 表示结果输出在哪一块GPU上,PaddlePaddle无此参数。 |
| dim | - | 表示哪一维度上的数据进行划分,PaddlePaddle无此参数。 |
| - | strategy | PaddlePaddle即将废弃参数。 |
| - | comm_buffer_size | 它是通信调用(如NCCLAllReduce)时,参数梯度聚合为一组的内存大小(MB),PyTorch无此参数。 |
| - | last_comm_buffer_size | 它限制通信调用中最后一个缓冲区的内存大小(MB),PyTorch无此参数。 |
### 功能差异
#### 使用差异
***PyTorch***:在API中即可通过设置参数使用的GPU id。
***PaddlePaddle***:只能在启动代码时设置GPU id,设置方式如下:
> python -m paddle.distributed.launch –selected_gpus=0,1 demo.py
> 其中 demo.py 脚本的代码可以是下面的示例代码。
## torch.nn.parameter.Parameter
### [torch.nn.parameter.Parameter](https://pytorch.org/docs/stable/generated/torch.nn.parameter.Parameter.html?highlight=torch%20nn%20parameter#torch.nn.parameter.Parameter)
```python
torch.nn.parameter.Parameter(data, requires_grad=True)
```
## [paddle.create_parameter](https://github.com/PaddlePaddle/Paddle/blob/ce2bdb0afdc2a09a127e8d9aa394c8b00a877364/python/paddle/fluid/layers/tensor.py#L77)
```python
paddle.create_parameter(shape,
dtype,
name=None,
attr=None,
is_bias=False,
default_initializer=None)
```
### 功能差异
#### 使用方式
***PyTorch***:通过设置`data`将Tensor赋给Parameter。
***PaddlePaddle***:有2种方式创建Parameter。方式一:通过设置`attr`将ParamAttr赋给Parameter;方式二:通过设置`shape`(大小)、`dtype`(类型)、`default_initializer`(初始化方式)设置Parameter。
#### 梯度设置
***PyTorch***:通过设置`requires_grad`确定是否进行梯度反传。
***PaddlePaddle***:PaddlePaddle无此功能。
### 代码示例
``` python
# PyTorch示例:
import torch
x = torch.zeros(2, 3)
param = torch.nn.parameter.Parameter(x, requires_grad=False)
# 输出
# Parameter containing:
# tensor([[0., 0., 0.],
# [0., 0., 0.]])
```
``` python
# PaddlePaddle示例:
import paddle
x = paddle.zeros([2, 3], dtype="float32")
param = paddle.create_parameter(shape=x.shape,
dtype=str(x.numpy().dtype),
default_initializer=paddle.nn.initializer.Assign(x))
param.stop_gradient = True
# 输出
# Parameter containing:
# Tensor(shape=[2, 3], dtype=float32, place=CPUPlace, stop_gradient=True,
# [[0., 0., 0.],
# [0., 0., 0.]])
```
## torch.nn.utils.clip_grad_value_
### [torch.nn.utils.clip_grad_value_](https://pytorch.org/docs/stable/generated/torch.nn.utils.clip_grad_value_.html?highlight=clip_grad_value_#torch.nn.utils.clip_grad_value_)
```python
torch.nn.utils.clip_grad_value_(parameters, clip_value)
```
### 功能介绍
用于梯度裁剪,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
def clip_grad_value_(parameters, clip_value):
if isinstance(parameters, paddle.Tensor):
parameters = [parameters]
clip_value = float(clip_value)
for p in filter(lambda p: p.grad is not None, parameters):
paddle.clip(p.grad, min=-clip_value, max=clip_value)
```
## torch.utils.data.BatchSampler
### [torch.utils.data.BatchSampler](https://pytorch.org/docs/stable/data.html?highlight=batchsampler#torch.utils.data.BatchSampler)
```python
torch.utils.data.BatchSampler(sampler, batch_size, drop_last)
```
### [paddle.io.BatchSampler](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/dataloader/batch_sampler/BatchSampler_cn.html#batchsampler)
```python
paddle.io.BatchSampler(dataset=None, sampler=None, shuffle=Fasle, batch_size=1, drop_last=False)
```
### 功能差异
#### 使用方式
***PyTorch***:只能使用`sampler`来构建BatchSampler。
***PaddlePaddle***:能使用`sampler``dataset`来构建BatchSampler。
## torch.utils.data.DataLoader
### [torch.utils.data.DataLoader](https://pytorch.org/docs/stable/data.html?highlight=dataloader#torch.utils.data.DataLoader)
```python
torch.utils.data.DataLoader(dataset,
batch_size=1,
shuffle=False,
sampler=None,
batch_sampler=None,
num_workers=0,
collate_fn=None,
pin_memory=False,
drop_last=False,
timeout=0,
worker_init_fn=None,
multiprocessing_context=None,
generator=None,
prefetch_factor=2,
persistent_workers=False)
```
### [paddle.io.DataLoader](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/fluid/reader/DataLoader_cn.html#dataloader)
```python
paddle.io.DataLoader(dataset,
feed_list=None,
places=None,
return_list=False,
batch_sampler=None,
batch_size=1,
shuffle=False,
drop_last=False,
collate_fn=None,
num_workers=0,
use_buffer_reader=True,
use_shared_memory=False,
timeout=0,
worker_init_fn=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| sampler | - | 表示数据集采集器,PaddlePaddle无此参数。 |
| prefetch_factor | - | 表示每个worker预先加载的数据数量,PaddlePaddle无此参数。 |
| persistent_workers | - | 表示数据集使用一次后,数据加载器将会不会关闭工作进程,PaddlePaddle无此参数。 |
| generator | - | 用于采样的伪随机数生成器,PaddlePaddle无此参数。 |
| pin_memory | - | 表示数据最开始是属于锁页内存,PaddlePaddle无此参数。 |
| - | feed_list | 表示feed变量列表,PyTorch无此参数。 |
| - | use_buffer_reader | 表示是否使用缓存读取器,PyTorch无此参数。 |
| - | use_shared_memory | 表示是否使用共享内存来提升子进程将数据放入进程间队列的速度,PyTorch无此参数。 |
### 功能差异
#### 自定义数据采集器
***PyTorch***:可通过设置`sampler`自定义数据采集器。
***PaddlePaddle***:PaddlePaddle无此功能,可使用如下代码自定义一个DataLoader实现该功能。
```python
class DataLoader(paddle.io.DataLoader):
def __init__(self,
dataset,
batch_size=1,
shuffle=False,
sampler=None,
batch_sampler=None,
num_workers=0,
collate_fn=None,
pin_memory=False,
drop_last=False,
timeout=0,
worker_init_fn=None,
multiprocessing_context=None,
generator=None):
if isinstance(dataset[0], (tuple, list)):
return_list = True
else:
return_list = False
return_list = True
super().__init__(
dataset,
feed_list=None,
places=None,
return_list=return_list,
batch_sampler=batch_sampler,
batch_size=batch_size,
shuffle=shuffle,
drop_last=drop_last,
collate_fn=collate_fn,
num_workers=num_workers,
use_buffer_reader=True,
use_shared_memory=False,
timeout=timeout,
worker_init_fn=worker_init_fn)
if sampler is not None:
seld.batch_sampler.sampler = sampler
```
## torch.utils.data.distributed.DistributedSampler
### [torch.utils.data.distributed.DistributedSampler](https://pytorch.org/docs/stable/data.html?highlight=distributedsampler#torch.utils.data.distributed.DistributedSampler)
```python
torch.utils.data.distributed.DistributedSampler(dataset,
num_replicas=None,
rank=None,
shuffle=True,
seed=0,
drop_last=False)
```
### 功能介绍
用于实现分布式数据采集器,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
import paddle
class DistributedSampler(paddle.io.DistributedBatchSampler):
def __init__(self,
dataset,
num_replicas=None,
rank=None,
shuffle=True,
seed=0,
drop_last=False):
super().__init__(
dataset=dataset,
batch_size=1,
num_replicas=num_replicas,
rank=rank,
shuffle=shuffle,
drop_last=drop_last)
```
## torch.utils.data.random_split
### [torch.utils.data.random_split](https://pytorch.org/docs/stable/data.html?highlight=random_split#torch.utils.data.random_split)
```python
torch.utils.data.random_split(dataset, lengths, generator=<torch._C.Generator object>)
```
### 功能介绍
用于实现数据集划分,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
import paddle
from paddle.io import Dataset
def _accumulate(iterable, fn=lambda x, y: x + y):
it = iter(iterable)
try:
total = next(it)
except StopIteration:
return
yield total
for element in it:
total = fn(total, element)
yield total
class Subset(Dataset):
def __init__(self, dataset, indices):
self.dataset = dataset
self.indices = indices
def __getitem__(self, idx):
return self.dataset[self.indices[idx]]
def __len__(self):
return len(self.indices)
def random_split(dataset, lengths, generator=None):
if sum(lengths) != len(dataset):
raise ValueError(
"Sum of input lengths does not equal the length of the input dataset!"
)
indices = paddle.randperm(sum(lengths))
return [
Subset(dataset, indices[offset - length: offset])
for offset, length in zip(_accumulate(lengths), lengths)
]
```
## 视觉类
| 序号 | PyTorch API | PaddlePaddle API | 备注 |
| ---- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------- |
| 1 | [torchvision.transforms.Compose](https://pytorch.org/vision/stable/transforms.html?highlight=compose#torchvision.transforms.Compose) | [paddle.vision.transforms.Compose](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/Compose_cn.html#compose) | 功能一致 |
| 2 | [torchvision.transforms.ToPILImage](https://pytorch.org/vision/stable/transforms.html?highlight=topilimage#torchvision.transforms.ToPILImage) | 无对应实现 | [组合实现](torchvision.transforms.ToPILImage.md) |
| 3 | [torchvision.transforms.Resize](https://pytorch.org/vision/stable/transforms.html?highlight=resize#torchvision.transforms.Resize) | [paddle.vision.transforms.Resize](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/Resize_cn.html#resize) | 功能一致 |
| 4 | [torchvision.transforms.ToTensor](https://pytorch.org/vision/stable/transforms.html?highlight=totensor#torchvision.transforms.ToTensor) | [paddle.vision.transforms.ToTensor](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/ToTensor_cn.html#totensor) | 功能一致 |
| 5 | [torchvision.transforms.RandomHorizontalFlip](https://pytorch.org/vision/stable/transforms.html?highlight=randomhorizontalflip#torchvision.transforms.RandomHorizontalFlip) | [paddle.vision.transforms.RandomHorizontalFlip](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/RandomHorizontalFlip_cn.html#randomhorizontalflip) | 功能一致 |
| 6 | [torchvision.transforms.CenterCrop](https://pytorch.org/vision/stable/transforms.html?highlight=centercrop#torchvision.transforms.CenterCrop) | [paddle.vision.transforms.CenterCrop](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/CenterCrop_cn.html#centercrop) | 功能一致 |
| 7 | [torchvision.transforms.ColorJitter](https://pytorch.org/vision/stable/transforms.html?highlight=colorjitter#torchvision.transforms.ColorJitter) | [paddle.vision.transforms.ColorJitter](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/ColorJitter_cn.html#colorjitter) | 功能一致 |
| 8 | [torchvision.transforms.Grayscale](https://pytorch.org/vision/stable/transforms.html?highlight=grayscale#torchvision.transforms.Grayscale) | [paddle.vision.transforms.Grayscale](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/Grayscale_cn.html#grayscale) | 功能一致 |
| 9 | [torchvision.transforms.Normalize](https://pytorch.org/vision/stable/transforms.html?highlight=normalize#torchvision.transforms.Normalize) | [paddle.vision.transforms.Normalize](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/Normalize_cn.html#normalize) | [差异对比](torchvision.transforms.Normalize.md) |
| 10 | [torchvision.transforms.RandomResizedCrop](https://pytorch.org/vision/stable/transforms.html?highlight=randomresizedcrop#torchvision.transforms.RandomResizedCrop) | [paddle.vision.transforms.RandomResizedCrop](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/RandomResizedCrop_cn.html#randomresizedcrop) | 功能一致 |
| 11 | [torchvision.transforms.Pad](https://pytorch.org/vision/stable/transforms.html?highlight=pad#torchvision.transforms.Pad) | [paddle.vision.transforms.Pad](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/Pad_cn.html#pad) | 功能一致 |
| 12 | [torchvision.transforms.RandomCrop](https://pytorch.org/vision/stable/transforms.html?highlight=randomcrop#torchvision.transforms.RandomCrop) | [paddle.vision.transforms.RandomCrop](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/RandomCrop_cn.html#randomcrop) | 功能一致 |
| 13 | [torchvision.transforms.RandomRotation](https://pytorch.org/vision/stable/transforms.html?highlight=randomrotation#torchvision.transforms.RandomRotation) | [paddle.vision.transforms.RandomRotation](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/RandomRotation_cn.html#daimashili) | 功能一致 |
| 14 | [torchvision.transforms.RandomVerticalFlip](https://pytorch.org/vision/stable/transforms.html?highlight=randomverticalflip#torchvision.transforms.RandomVerticalFlip) | [paddle.vision.transforms.RandomVerticalFlip](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/RandomVerticalFlip_cn.html#randomverticalflip) | 功能一致 |
| 15 | [torchvision.transforms.Lambda](https://pytorch.org/vision/stable/transforms.html?highlight=lambda#torchvision.transforms.Lambda) | 无对应实现 | [组合实现](torchvision.transforms.Lambda.md) |
| 17 | [torchvision.utils.save_image](https://pytorch.org/vision/stable/utils.html?highlight=save_image#torchvision.utils.save_image) | 无对应实现 | [组合实现](torchvision.utils.save_image.md) |
| 18 | [torchvision.models 系列模型](https://pytorch.org/vision/stable/models.html?highlight=torchvision%20models) | X2Paddle提供 | [使用方式](torchvision.models.md) |
***持续更新...***
## [torchvision.models](https://pytorch.org/vision/stable/models.html?highlight=torchvision%20models)
目前PaddlePaddle官方提供的模型参数与PyTorch不一致,为此X2Paddle提供了一套与torchvision模型参数一致且使用方式一致的模型库,以resnet18为例,具体使用方式如下:
```python
from x2paddle import models
# 构造权重随机初始化的模型:
resnet18 = models.resnet18_pth()
x = paddle.rand([1, 3, 224, 224])
out = model(x)
# 构造预训练模型:
resnet18 = models.resnet18_pth(pretrained=True)
x = paddle.rand([1, 3, 224, 224])
out = model(x)
```
目前支持的模型为:
| PyTorch模型 | Paddle模型 |
| ------------------------------------------------------------ | -------------------------------- |
| [torchvision.models.resnet18](https://pytorch.org/vision/stable/models.html#torchvision.models.resnet18) | x2paddle.models.resnet18_pth |
| [torchvision.models.resnet34](https://pytorch.org/vision/stable/models.html#torchvision.models.resnet34) | x2paddle.models.resnet34_pth |
| [torchvision.models.resnet50](https://pytorch.org/vision/stable/models.html#torchvision.models.resnet50) | x2paddle.models.resnet50_pth |
| [torchvision.models.resnet101](https://pytorch.org/vision/stable/models.html#torchvision.models.resnet101) | x2paddle.models.resnet101_pth |
| [torchvision.models.resnet152](https://pytorch.org/vision/stable/models.html#torchvision.models.resnet152) | x2paddle.models.resnet152_pth |
| [torchvision.models.resnext50_32x4d](https://pytorch.org/vision/stable/models.html#torchvision.models.resnext50_32x4d) | x2paddle.models.resnext50_32x4d_pth |
| [torchvision.models.resnext101_32x8d](https://pytorch.org/vision/stable/models.html#torchvision.models.resnext101_32x8d) | x2paddle.resnext101_32x8d_pth |
| [torchvision.models.wide_resnet50_2](https://pytorch.org/vision/stable/models.html#torchvision.models.wide_resnet50_2) | x2paddle.models.wide_resnet50_2_pth |
| [torchvision.models.wide_resnet101_2](https://pytorch.org/vision/stable/models.html#torchvision.models.wide_resnet101_2) | x2paddle.models.wide_resnet101_2_pth |
| [torchvision.models.vgg11](https://pytorch.org/vision/stable/models.html#torchvision.models.vgg11) | x2paddle.models.vgg11_pth |
| [torchvision.models.vgg11_bn](https://pytorch.org/vision/stable/models.html#torchvision.models.vgg11_bn) | x2paddle.models.vgg11_bn_pth |
| [torchvision.models.vgg13](https://pytorch.org/vision/stable/models.html#torchvision.models.vgg13) | x2paddle.models.vgg13_pth |
| [torchvision.models.vgg13_bn](https://pytorch.org/vision/stable/models.html#torchvision.models.vgg13_bn) | x2paddle.models.vgg13_bn_pth |
| [torchvision.models.vgg16](https://pytorch.org/vision/stable/models.html#torchvision.models.vgg16) | x2paddle.models.vgg16_pth |
| [torchvision.models.vgg16_bn](https://pytorch.org/vision/stable/models.html#torchvision.models.vgg16_bn) | x2paddle.models.vgg16_bn_pth |
| [torchvision.models.vgg19](https://pytorch.org/vision/stable/models.html#torchvision.models.vgg19) | x2paddle.models.vgg19_pth |
| [torchvision.models.vgg19_bn](https://pytorch.org/vision/stable/models.html#torchvision.models.vgg19_bn) | x2paddle.models.vgg19_bn_pth |
## torchvision.transforms.Lambda
### [torchvision.transforms.Lambda](https://pytorch.org/vision/stable/transforms.html?highlight=lambda#torchvision.transforms.Lambda)
```python
torchvision.transforms.Lambda(lambd)
```
### 功能介绍
用于使用lamda定义的函数对数据进行预处理,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
import paddle
from paddle.vision.transforms import BaseTransform
class Lambda(BaseTransform):
def __init__(self, lambd):
if not callable(lambd):
raise TypeError("Argument lambd should be callable, got {}".format(repr(type(lambd).__name__)))
self.lambd = lambd
def _apply_image(self, img):
return self.lambd(img)
```
## torchvision.transforms.Normalize
### [torchvision.transforms.Normalize](https://pytorch.org/vision/stable/transforms.html?highlight=normalize#torchvision.transforms.Normalize)
```python
torchvision.transforms.Normalize(mean, std, inplace=False)
```
### [paddle.vision.transforms.Normalize](https://www.paddlepaddle.org.cn/documentation/docs/zh/api/paddle/vision/transforms/transforms/Normalize_cn.html#normalize)
```python
paddle.vision.transforms.Normalize(mean=0.0, std=1.0, data_format='CHW', to_rgb=False, keys=None)
```
### 参数差异
| PyTorch | PaddlePaddle | 备注 |
| ------------- | ------------ | ------------------------------------------------------ |
| inplace | - | 表示表示在不更改变量的内存地址的情况下,直接修改变量,PaddlePaddle无此参数。 |
| - | data_format | 表示数据的格式,PyTorch无此参数。 |
| - | to_rgb | 表示是否是否转换为rgb的格式,PyTorch无此参数。 |
### 功能差异
#### 使用方式
***PyTorch***:只支持`CHW`的输入数据,同时不支持转换为`rgb`
***PaddlePaddle***:支持`CHW``HWC`的输入数据,同时支持转换为`rgb`
## torchvision.transforms.ToPILImage
### [torchvision.transforms.ToPILImage](https://pytorch.org/vision/stable/transforms.html?highlight=topilimage#torchvision.transforms.ToPILImage)
```python
torchvision.transforms.ToPILImage(mode=None)
```
### 功能介绍
用于根据`mode`返回PIL类型的图像,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
import paddle
import PIL
import numbers
import numpy as np
from PIL import Image
from paddle.vision.transforms import BaseTransform
from paddle.vision.transforms import functional as F
class ToPILImage(BaseTransform):
def __init__(self, mode=None, keys=None):
super(ToTensor, self).__init__(keys)
self.data_format = data_format
def _apply_image(self, pic):
"""
Args:
pic (Tensor|np.ndarray): Image to be converted to PIL Image.
Returns:
PIL: Converted image.
"""
if not (isinstance(pic, paddle.Tensor) or isinstance(pic, np.ndarray)):
raise TypeError('pic should be Tensor or ndarray. Got {}.'.format(
type(pic)))
elif isinstance(pic, paddle.Tensor):
if pic.ndimension() not in {2, 3}:
raise ValueError(
'pic should be 2/3 dimensional. Got {} dimensions.'.format(
pic.ndimension()))
elif pic.ndimension() == 2:
# if 2D image, add channel dimension (CHW)
pic = pic.unsqueeze(0)
elif isinstance(pic, np.ndarray):
if pic.ndim not in {2, 3}:
raise ValueError(
'pic should be 2/3 dimensional. Got {} dimensions.'.format(
pic.ndim))
elif pic.ndim == 2:
# if 2D image, add channel dimension (HWC)
pic = np.expand_dims(pic, 2)
npimg = pic
if isinstance(pic, paddle.Tensor) and "float" in str(pic.numpy(
).dtype) and mode != 'F':
pic = pic.mul(255).byte()
if isinstance(pic, paddle.Tensor):
npimg = np.transpose(pic.numpy(), (1, 2, 0))
if not isinstance(npimg, np.ndarray):
raise TypeError(
'Input pic must be a paddle.Tensor or NumPy ndarray, ' +
'not {}'.format(type(npimg)))
if npimg.shape[2] == 1:
expected_mode = None
npimg = npimg[:, :, 0]
if npimg.dtype == np.uint8:
expected_mode = 'L'
elif npimg.dtype == np.int16:
expected_mode = 'I;16'
elif npimg.dtype == np.int32:
expected_mode = 'I'
elif npimg.dtype == np.float32:
expected_mode = 'F'
if mode is not None and mode != expected_mode:
raise ValueError(
"Incorrect mode ({}) supplied for input type {}. Should be {}"
.format(mode, np.dtype, expected_mode))
mode = expected_mode
elif npimg.shape[2] == 2:
permitted_2_channel_modes = ['LA']
if mode is not None and mode not in permitted_2_channel_modes:
raise ValueError("Only modes {} are supported for 2D inputs".
format(permitted_2_channel_modes))
if mode is None and npimg.dtype == np.uint8:
mode = 'LA'
elif npimg.shape[2] == 4:
permitted_4_channel_modes = ['RGBA', 'CMYK', 'RGBX']
if mode is not None and mode not in permitted_4_channel_modes:
raise ValueError("Only modes {} are supported for 4D inputs".
format(permitted_4_channel_modes))
if mode is None and npimg.dtype == np.uint8:
mode = 'RGBA'
else:
permitted_3_channel_modes = ['RGB', 'YCbCr', 'HSV']
if mode is not None and mode not in permitted_3_channel_modes:
raise ValueError("Only modes {} are supported for 3D inputs".
format(permitted_3_channel_modes))
if mode is None and npimg.dtype == np.uint8:
mode = 'RGB'
if mode is None:
raise TypeError('Input type {} is not supported'.format(
npimg.dtype))
return Image.fromarray(npimg, mode=mode)
```
## torchvision.utils.save_image
### [torchvision.utils.save_image](https://pytorch.org/vision/stable/utils.html?highlight=save_image#torchvision.utils.save_image)
```python
torchvision.utils.save_image(tensor: Union[torch.Tensor, List[torch.Tensor]],
fp: Union[str, pathlib.Path, BinaryIO],
format: Union[str, NoneType] = None,
**kwargs)
```
### 功能介绍
用于将Tensor保存至图像中,PaddlePaddle目前无对应API,可使用如下代码组合实现该API。
```python
import pathlib
import paddle
import warnings
import math
import numpy as np
from PIL import Image
from typing import Union, Optional, List, Tuple, Text, BinaryIO
@paddle.no_grad()
def make_grid(tensor: Union[paddle.Tensor, List[paddle.Tensor]],
nrow: int=8,
padding: int=2,
normalize: bool=False,
value_range: Optional[Tuple[int, int]]=None,
scale_each: bool=False,
pad_value: int=0,
**kwargs) -> paddle.Tensor:
if not (isinstance(tensor, paddle.Tensor) or
(isinstance(tensor, list) and all(
isinstance(t, paddle.Tensor) for t in tensor))):
raise TypeError(
f'tensor or list of tensors expected, got {type(tensor)}')
if "range" in kwargs.keys():
warning = "range will be deprecated, please use value_range instead."
warnings.warn(warning)
value_range = kwargs["range"]
# if list of tensors, convert to a 4D mini-batch Tensor
if isinstance(tensor, list):
tensor = paddle.stack(tensor, axis=0)
if tensor.dim() == 2: # single image H x W
tensor = tensor.unsqueeze(0)
if tensor.dim() == 3: # single image
if tensor.size(0) == 1: # if single-channel, convert to 3-channel
tensor = paddle.concat((tensor, tensor, tensor), 0)
tensor = tensor.unsqueeze(0)
if tensor.dim() == 4 and tensor.size(1) == 1: # single-channel images
tensor = paddle.concat((tensor, tensor, tensor), 1)
if normalize is True:
if value_range is not None:
assert isinstance(value_range, tuple), \
"value_range has to be a tuple (min, max) if specified. min and max are numbers"
def norm_ip(img, low, high):
img.clip(min=low, max=high)
img = img - low
img = img / max(high - low, 1e-5)
def norm_range(t, value_range):
if value_range is not None:
norm_ip(t, value_range[0], value_range[1])
else:
norm_ip(t, float(t.min()), float(t.max()))
if scale_each is True:
for t in tensor: # loop over mini-batch dimension
norm_range(t, value_range)
else:
norm_range(tensor, value_range)
if tensor.size(0) == 1:
return tensor.squeeze(0)
# make the mini-batch of images into a grid
nmaps = tensor.size(0)
xmaps = min(nrow, nmaps)
ymaps = int(math.ceil(float(nmaps) / xmaps))
height, width = int(tensor.shape[2] + padding), int(tensor.shape[3] +
padding)
num_channels = tensor.shape[1]
grid = paddle.full((num_channels, height * ymaps + padding,
width * xmaps + padding), pad_value)
k = 0
for y in range(ymaps):
for x in range(xmaps):
if k >= nmaps:
break
grid[:, y * height + padding:(y + 1) * height, x * width + padding:(
x + 1) * width] = tensor[k]
k = k + 1
return grid
@paddle.no_grad()
def save_image(tensor: Union[paddle.Tensor, List[paddle.Tensor]],
fp: Union[Text, pathlib.Path, BinaryIO],
format: Optional[str]=None,
**kwargs) -> None:
grid = make_grid(tensor, **kwargs)
ndarr = paddle.clip(grid * 255 + 0.5, 0, 255).transpose(
[1, 2, 0]).cast("uint8").numpy()
im = Image.fromarray(ndarr)
im.save(fp, format=format)
```
## 常见问题
1.出现如下提示如何处理?
> The no support Api are: [torchvision.transforms.RandomErasing, torchvision.transforms.functional, torchvision.transforms.RandomCrop.get_params, torch.all, torch.as_tensor].
A:这一提示说明仍有API未支持转换,用户可自行添加相应API的支持,具体添加流程参照[添加示例](./add_api.md),或及时提issue与我们联系。
2.运行时,出现如下2种错误,如何处理?
> AttributeError: 'Tensor' object has no attribute 'XX'
> AttributeError: 'Layer' object has no attribute 'XX'
A:这一提示说明`paddle.nn.Tensor``paddle.nn.Layer`仍有attribute未支持转换,用户可自行添加相应API的支持,具体添加流程参照[添加示例](./add_api.md),或及时提issue与我们联系。
3.运行时,出现DataLoader的报错异常,如何查找原因?
A:
步骤一:查看对应自定义Dataset中\_\_getiem\_\_的返回值是否为numpy;
步骤二:如若当前的设备为GPU,是否未将`num_workers`设置为0;
步骤三:查看图像预处理的transform中是否有使用出错。
4.当前是否支持torch.jit的转换?
A:不支持。
5.如何查看PyTorch与PaddlePaddle API的差异?
A:我们提供了[PyTorch-PaddlePaddle API对应表](./API_docs/README.md),您可从中获取对应关系。
# PyTorch训练项目转换
支持将PyTorch代码及预训练模型转换为PaddlePaddle代码及预训练模型。
## 使用方法
### 第一步:转换前代码预处理
由于部分PyTorch操作是目前PaddlePaddle暂不支持的操作(例如:不支持TensorBoard、自动下载模型等),因此我们需要手动将这部分操作去除或者修改,具体可参见[转换前代码预处理](./before_convert.md)
### 第二步:转换
``` shell
x2paddle --convert_torch_project --project_dir=torch_project --save_dir=paddle_project --pretrain_model=model.pth
```
| 参数 | |
|----------|--------------|
|--convert_torch_project | 当前方式为对PyTorch Project进行转换 |
|--project_dir | PyTorch的项目路径 |
|--save_dir | 指定转换后项目的保存路径 |
|--pretrain_model | **[可选]**需要转换的预训练模型的路径(文件后缀名为“.pth”、“.pt”、“.ckpt”)或者包含预训练模型的文件夹路径,转换后的模型将将保在当前路径,后缀名为“.pdiparams” |
### 第三步:转换后代码后处理
PaddlePaddle在使用上有部分限制(例如:自定义Dataset必须继承自`paddle.io.Dataset`、部分情况下DataLoader的num_worker只能为0等),用户需要手动修改代码,使代码运行,具体可参见[转换后代码后处理](./after_convert.md)
***[注意]*** 转换前后相应操作可以参考[转换示例](./demo.md)
# 添加API映射方式
在3种情况下需要添加的API映射,本文档将对添加方式逐一进行介绍,3种情况如下表所示:
| | 对应情况 |
| -------------------- | ------------------------------------------------------------ |
| [情况1](#situation1) | 在运行代码时出现错误:`AttributeError: 'Tensor' object has no attribute 'XX'`。 |
| [情况2](#situation2) | 在运行代码时出现错误:`AttributeError: 'Layer' object has no attribute 'XX'`。 |
| [情况3](#situation3) | 在转换代码时出现提示:`Can not convert the file XX.py. The unsupported packages or operators are: [torch.nn.Tanh, torch.nn.utils.spectral_norm].`<br/>[3.1](#situation3.1) PaddlePaddle存在对应API,功能完全一致,参数一致。 <br/>[3.2](#situation3.2) PaddlePaddle存在对应API,功能基本一致,参数不一致。 <br/>[3.3](#situation3.3) PaddlePaddle不存在对应API。 |
需要修改的文件在[x2paddle/project_convertor/pytorch](../../x2paddle/project_convertor/pytorch)中,具体文件如下所示:
> .
> |── api_mapper # 存放映射处理相关操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── \_\_init\_\_.py
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── learning_rate_scheduler.py # 学习率类API映射操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── nn.py # 组网、损失相关类API映射操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── ops.py # paddle.Tensor处理类API映射操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── torchvision.py # 图像处理相关的API映射操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;└── utils.py # 基础操作
> |── mapper.py # 存放映射关系
> └── torch2paddle # 存放需要重新封装实现的API
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|──\_\_init\_\_.py
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── device.py # 实现设备相关的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── io.py # 实现数据相关的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── layer.py # 实现paddle.nn.Layer类内方法/属性的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── nn_functional.py # 实现组网OP的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── nn_utils.py # 实现组网参数相关的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── ops.py # 实现Tensor处理OP的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── optimizer.py # 实现优化相关的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── tensor.py # 实现paddle.Tensor类内方法/属性操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── varbase.py # 实现paddle.Tensor取值的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|── vision_transforms.py # 实现视觉transform的操作
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;└── vision_utils.py # 实现视觉基础的操作
***[注意]*** 添加完映射后,需要重新安装X2Paddle:
```
cd X2Paddle
rm -rf bulid dist x2paddle.egg-info
pip uninstall x2paddle
python setup.py install
```
### <span id="situation1">情况1</span>
该情况出现的原因为paddle.Tensor缺乏类内方法/属性,因此需要将torch.Tensor的类内方法/属性注册为paddle.Tensor的类内方法/属性,在[x2paddle/project_convertor/pytorch/torch2paddle/tensor.py](../../x2paddle/project_convertor/pytorch/torch2paddle/tensor.py)添加相应代码。以item类内方法为例,PyTorch中item方法的作用是提取Scalar中的数值,以避免耗费内存和计算量,因此需要添加如下代码:
```python
# 添加注册装饰器
@add_tensor_function
def item(self):
# 实现item方法的对应功能
return self.numpy()[0]
```
当torch.Tensor的类内方法/属性与paddle.Tensor的内置方法/属性命名一致,但实现功能不一致,也需要重新实现该类内方法/属性。以reshape类内方法为例,PyTorch传入的为可变参数,而PaddlePaddle出入的参数为一个list,因此需要添加的代码如下:
```python
# 对原始的reshape进行重命名,此处添加"_tmp",防止与其他类内函数重名
reshape_tmp = partial(paddle.Tensor.reshape)
# 添加注册装饰器
@add_tensor_function
def reshape(self, *shape):
# 实现reshape方法的对应功能
return reshape_tmp(self, shape)
```
### <span id="situation2">情况2</span>
该情况出现的原因为paddle.nn.Layer缺乏类内方法/属性,因此需要将torch.nn.Module的类内方法/属性注册为paddle.nn.Layer的类内方法/属性,在[x2paddle/project_convertor/pytorch/torch2paddle/layer.py](../../x2paddle/project_convertor/pytorch/torch2paddle/layer.py)添加相应代码。以cuda类内方法为例,PyTorch的网络可以设置运行的的设备为cuda,而PaddlePaddle则不需要此操作,因此需要添加如下代码返回原网络即可:
```python
# 添加注册装饰器
@add_layer_function
def cuda(self):
return self
```
当torch.nn.Module的类内方法/属性与paddle.nn.Layer的内置方法/属性命名一致,但实现功能不一致,也需要重新实现该类内方法/属性。以train类内方法为例,PyTorch可以设置train的模式是train还是eval,PaddlePaddle则需要组合实现,因此需要添加的代码如下:
```python
# 对原始的train进行重命名,此处添加"_tmp",防止与其他类内函数重名
train_tmp = partial(paddle.nn.Layer.train)
# 添加注册装饰器
@add_layer_function
def train(self, mode=True):
# 实现train方法的对应功能
if mode:
return train_tmp(self)
else:
return paddle.nn.Layer.eval(self)
```
### <span id="situation3">情况3</span>
### <span id="situation3.1">3.1</span> PaddlePaddle存在对应API,功能完全一致,参数一致
该情况直接在[x2paddle/project_convertor/pytorch/mapper.py](../../x2paddle/project_convertor/pytorch/mapper.py)中对应的MAPPER中添加PyTorch API的字符串以及Paddle API的字符串,无需添加进行参数映射所需调用的类,具体实现如下:
```python
# key为PyTorch API字符串;
# value为列表,由Paddle API字符串和None组合而成。
...
NN_MAPPER = {
...
"torch.nn.Sequential":
["paddle.nn.Sequential", None],
"torch.nn.utils":
["paddle.nn.utils", None],
...
}
...
```
### <span id="situation3.2">3.2</span> PaddlePaddle存在对应API,功能基本一致,参数不一致
该情况需要完成以下几个步骤:
***步骤1***[x2paddle/project_convertor/pytorch/mapper.py](.../../x2paddle/project_convertor/pytorch/mapper.py)中对应的MAPPER中添加PyTorch API的字符串以及Paddle API的字符串、映射处理类,具体实现如下:
```python
# key为PyTorch API字符串;
# value为列表,由Paddle API字符串和参映射处理类组合而成。
...
NN_MAPPER = {
...
"torch.nn.Conv2d":
["paddle.nn.Conv2D", ClassConv2D],
...
"torch.nn.functional.relu":
["paddle.nn.functional.relu", FuncRelu],
...
}
...
# 类名以Class或Func开始,Class代表Paddle API为一个类,Func代表Paddle API为一个方法。
```
***步骤2***[x2paddle/project_convertor/pytorch/api_mapper/](../../x2paddle/project_convertor/pytorch/api_mapper)文件夹中找到对应的文件并在其中添加映射处理类,类型中用户需要重写process_attrs、delete_attrs、check_attrs以及run这三个函数,其中run只需要修改对应的x2paddle封装的API命名即可。以`torch.matmul``paddle.matmul`的映射为例,二者的参数名不一致,因此需要添加的代码如下所示:
```python
class FuncMatmul(Mapper):
def __init__(self, func_name, pytorch_api_name, args, kwargs, target_name=None):
super().__init__(func_name, pytorch_api_name, args, kwargs, target_name)
def process_attrs(self):
""" 更新参数。
"""
rename_key(self.kwargs, "input", "x")
rename_key(self.kwargs, "other", "y")
def delete_attrs(self):
""" 删除参数。
"""
delete_key(self.kwargs, "out")
def check_attrs(self):
""" 确认参数的值。
"""
pass
def run(self):
if self.rename_func_name("x2paddle.torch2paddle.matmul"):
# 作用:当出现可变参数或关键字参数,无法对参数进行处理;
# 需要根据x2paddle封装的对应API命名生成代码(x2paddle封装的对应API相关代码在步骤3中实现)
return [], generate_api_code(self.func_name, self.args, self.kwargs), []
else:
# 作用:将paddle与pytorch不同的可变参数替换成字典参数,并生成相应代码
self.convert_args2kwargs()
return self.convert_to_paddle()
```
其中,使用到的几个方法介绍如下:
| 方法 | 参数 | 作用 |
| ------------------------------------ | ------------------------------------------------------------ | ----------------------------------------------- |
| rename_key(kwargs, old_key, new_key) | kwargs:PyTorch API的关键字参数; old_key:PyTorch API的关键字参数的key; new_key:Paddle API的关键字参数的key。 | 若old_key存在于kwargs,将old_key替换为new_key。 |
| delete_key(kwargs, old_key) | kwargs:PyTorch API的关键字参数;old_key:PyTorch API的关键字参数的key。 | 删除kwargs中的old_key。 |
***步骤3*** 当PyTorch API传入的是可变参数或关键字参数,映射处理类无法对参数进行处理,此时只能调用x2paddle封装的API,所以需要在[x2paddle/project_convertor/pytorch/torch2paddle/](../../x2paddle/project_convertor/pytorch/torch2paddle)文件夹中找到对应的文件并在其中添加x2paddle API实现,其函数名或类名与步骤2中的`torch2paddle_func_name`命名一致,同样以`torch.matmul``paddle.matmul`的映射为例,其实现代码如下:
```python
def matmul(input, other, *, out=None):
return paddle.matmul(input, other)
```
### <span id="situation3.3">3.3</span> PaddlePaddle不存在对应API
### 3.3.1 API代码为必要代码
当前API在代码中必须存在,需要添加转换,因此要完成以下2个步骤:
***步骤1***[x2paddle/project_convertor/pytorch/mapper.py](../../x2paddle/project_convertor/pytorch/mapper.py)中对应的MAPPER中添加PyTorch API的字符串以及Paddle API的字符串,具体实现如下:
```python
# key为PyTorch API字符串;
# value为列表,由x2paddle自行实现API字符串和None组合而成。
...
UTILS_MAPPER = {
...
"torch.utils.data.random_split":
["x2paddle.torch2paddle.random_split", None],
...
"torch.utils.data.ConcatDataset":
["x2paddle.torch2paddle.ConcatDataset", None]
...
}
...
```
***步骤2***[x2paddle/project_convertor/pytorch/torch2paddle/](../../x2paddle/project_convertor/pytorch/torch2paddle)文件夹中找到对应的文件并在其中添加x2paddle API实现,其函数名或类名与步骤1中字典 value值中list的第一个值一致,以`torch.utils.data.random_split`的实现为例,其作用为划分数据集,因此需要添加的代码如下所示:
```python
def random_split(dataset, lengths, generator=None):
if sum(lengths) != len(dataset):
raise ValueError("Sum of input lengths does not equal the length of the input dataset!")
indices = paddle.randperm(sum(lengths))
return [Subset(dataset, indices[offset - length : offset]) for offset, length in zip(_accumulate(lengths), lengths)]
setattr(paddle.io, "random_split", random_split)
```
### 3.3.2 API代码为不必要代码
当前API为PaddlePaddle不需要的代码,应进行删除,因此需要在[x2paddle/project_convertor/pytorch/mapper.py](../../x2paddle/project_convertor/pytorch/mapper.py)中REMOVE_API中添加需要去除的PyTorch API,具体实现如下:
```python
REMOVE_API =["torch.backends.cudnn",
"torch.backends.cudnn.benchmark"]
```
### 3.3.3 API代码为可替换代码
若当前API可用其他PyTorch API`torch.YY``torch.YY`[已支持映射列表](./supported_API.md)中)代替且替换后精度影响不大,可在原PyTorch代码中将当前API替换为`torch.YY`,再进行转换。
# 转换后代码后处理
1. 若需要使用GPU,且预处理中使用了Tensor,`x2paddle.torch2paddle.DataLoader`中的`num_workers`必须设置为0。
2. 修改自定义Dataset(继承自`paddle.io.Dataset`)中的`__getitem__`的返回值,若返回值中存在Tensor,需添加相应代码将Tensor修改为numpy。
```
# 原始代码
class VocDataset(paddle.io.Dataset):
...
def __getitem__(self):
...
return out1, out2
...
# 替换后代码
class VocDataset(paddle.io.Dataset):
...
def __getitem__(self):
...
if isinstance(out1, paddle.Tensor):
out1 = out1.numpy()
if isinstance(out2, paddle.Tensor):
out2 = out2.numpy()
return out1, out2
...
```
3. 若存在Tensor对比操作(包含==、!=、<、<=、>、>=操作符),在对比操作符前添加对Tensor类型的判断,如果为bool型强转为int型,并在对比后转换回bool型。
```
# 原始代码(其中c_trg是Tensor)
c_trg = c_trg == 0
# 替换后代码
is_bool = False
if str(c_trg.dtype) == "VarType.BOOL":
c_trg = c_trg.cast("int32")
is_bool = True
c_trg = c_trg == 0
if is_bool:
c_trg = c_trg.cast("bool")
```
4. 如若转换后的运行代码的入口为sh脚本文件,且其中有预训练模型路径,应将其中的预训练模型的路径字符串中的“.pth”、“.pt”、“.ckpt”替换为“.pdiparams”。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册