Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
models
提交
c682043f
M
models
项目概览
PaddlePaddle
/
models
大约 1 年 前同步成功
通知
222
Star
6828
Fork
2962
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
602
列表
看板
标记
里程碑
合并请求
255
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
models
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
602
Issue
602
列表
看板
标记
里程碑
合并请求
255
合并请求
255
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
c682043f
编写于
10月 12, 2021
作者:
D
dyning
提交者:
GitHub
10月 12, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
updata ThesisReproduction_CV (#5355)
上级
d1dd17b7
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
59 addition
and
103 deletion
+59
-103
docs/ThesisReproduction_CV.md
docs/ThesisReproduction_CV.md
+59
-103
未找到文件。
docs/ThesisReproduction_CV.md
浏览文件 @
c682043f
...
...
@@ -11,7 +11,7 @@
### 1.2 前序工作
基于本
文规范
复现论文过程中,建议开发者准备以下内容。
基于本
指南
复现论文过程中,建议开发者准备以下内容。
*
了解该模型输入输出格式。以AlexNet图像分类任务为例,通过阅读论文与参考代码,了解到模型输入为
`[batch_size, 3, 224, 244]`
的tensor,类型为
`float32`
或者
`float16`
,label为
`[batch, ]`
的label,类型为
`int64`
。
*
准备好训练/验证数据集,用于模型训练与评估
...
...
@@ -27,21 +27,21 @@
### 2.1 流程概览
基于通用的计算机视觉任务,论文复现整体流程图如下
所示。
面对一篇计算机视觉论文,复现该论文的整体流程如下图
所示。
![
图片
](
images/framework.png
)
总共包含11个步骤。为了高效复现论文,设置了5个验收节点。如上图中黄色框所示。后续章节会详细介绍上述步骤和验收节点,具体内容安排如下:
总共包含11个步骤,为了高效复现论文,设置了5个验收节点。如上图中黄色框所示。对应地,第3章到第5章的内容安排如下:
*
第3章:介绍11个复现步骤的理论知识以及操作方法
*
第3章:介绍11个复现步骤的理论知识以及实战
*
第4章:介绍5个验收节点的自查与验收方法
*
第5章:针对
第3章在复现流程过程中可能出现的问题,在第5章会进行详细介绍。如果还是不能解决问题的话,可以
进交流群讨论
*
第5章:针对
复现流程过程中每个步骤可能出现的问题,本章会进行详细介绍。如果还是不能解决问题,可以提ISSUE或
进交流群讨论
### 2.2 reprod_log whl包
使用说明
### 2.2 reprod_log whl包
`reprod_log`
是用于论文复现赛自动化测试和验收的工具,源代码地址在:
[
https://github.com/WenmuZhou/reprod_log
](
https://github.com/WenmuZhou/reprod_log
)
。主要功能包括:
#### 2.2.1 reprod_log工具简介
`reprod_log`
是用于论文复现赛中辅助自查和验收工具。该工具源代码地址在:
[
https://github.com/WenmuZhou/reprod_log
](
https://github.com/WenmuZhou/reprod_log
)
。主要功能如下:
*
存取指定节点的输入输出tensor
*
基于文件的tensor读写
...
...
@@ -96,9 +96,9 @@
*
diff_threshold (float): 阈值,如果diff大于该阈值,则核验失败,默认为
`1e-6`
*
path (str): 日志保存的路径,默认为
`./diff.txt`
###
2.3
使用demo
###
# 2.2.2 reprod_log
使用demo
下面基于代码:
[
https://github.com/littletomatodonkey/AlexNet-Prod/tree/master/pipeline/reprod_log_demo
](
https://github.com/littletomatodonkey/AlexNet-Prod/tree/master/pipeline/reprod_log_demo
)
,给出
详细的工具包API使用功能
。
下面基于代码:
[
https://github.com/littletomatodonkey/AlexNet-Prod/tree/master/pipeline/reprod_log_demo
](
https://github.com/littletomatodonkey/AlexNet-Prod/tree/master/pipeline/reprod_log_demo
)
,给出
如何使用该工具
。
文件夹中包含
`write_log.py`
和
`check_log_diff.py`
文件,其中
`write_log.py`
中给出了
`ReprodLogger`
类的使用方法,
`check_log_diff.py`
给出了
`ReprodDiffHelper`
类的使用方法,依次运行两个python文件,使用下面的方式运行代码。
...
...
@@ -123,9 +123,9 @@ python3.7 check_log_diff.py
可以看出:对于key为
`demo_test_1`
的矩阵,由于diff为0,小于设置的阈值
`1e-6`
,核验成功;对于key为
`demo_test_2`
的矩阵,由于diff为0.33,大于设置的阈值
`1e-6`
,核验失败。
###
2.4 论文复现赛自动化测试
###
# 2.2.3 reprod_log在论文复现中应用
假设基于上述工具
的结果记录模块,产出下面若干文件
在论文复现中,基于reprod_log
的结果记录模块,产出下面若干文件
```
log_reprod
├── forward_paddle.npy
...
...
@@ -140,7 +140,7 @@ log_reprod
├── train_align_benchmark.npy # PaddlePaddle提供的参考评估指标
```
使用该工具中的
`ReprodDiffHelper`
模块,产出下面的
日志文件。
基于reprod_log的
`ReprodDiffHelper`
模块,产出下面5个
日志文件。
```
├── forward_diff.log # forward_paddle.npy与forward_torch.npy生成的diff结果文件
...
...
@@ -150,79 +150,11 @@ log_reprod
├── train_align_diff.log # train_align_paddle.npy与train_align_benchmark.npy生成的diff结果文件
```
5个结果文件中,会显示基于
`repod_log`
的检查结果。
下面以后续的前向对齐为例,介绍下基于
`repord_log`
工具对齐的检查流程。其中与
`reprod_log`
工具有关的部分都是需要开发者需要去添加的部分。
具体代码地址为:
[
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/pipeline/Step1/AlexNet_paddle/forward_alexnet.py
](
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/pipeline/Step1/AlexNet_paddle/forward_alexnet.py
)
。
下载代码后,按照下面的步骤运行脚本。
```
shell
# 进入文件夹
cd
pipeline/Step1/
# 下载预训练模型
wget
-P
../weights https://paddle-model-ecology.bj.bcebos.com/model/alexnet_reprod/alexnet_paddle.pdparams
wget
-P
../weights https://paddle-model-ecology.bj.bcebos.com/model/alexnet_reprod/alexnet-owt-7be5be79.pth
# 生成paddle的前向数据
cd
AlexNet_paddle/
&&
python3.7 forward_alexnet.py
# 生成torch的前向数据
cd
../AlexNet_torch
&&
python3.7 forward_alexnet.py
# 对比生成log
cd
..
python3.7 check_step1.py
```
以PaddlePaddle为例,
`forward_alexnet.py`
的具体代码如下所示。
```
python
import
numpy
as
np
import
paddle
# 导入模型
from
paddlevision.models.alexnet
import
alexnet
# 导入reprod_log中的ReprodLogger类
from
reprod_log
import
ReprodLogger
reprod_logger
=
ReprodLogger
()
# 组网并初始化
model
=
alexnet
(
pretrained
=
"../../weights/alexnet_paddle.pdparams"
num_classes
=
1000
)
model
.
eval
()
# 读入fake data并转换为tensor,这里也可以固定seed在线生成fake data
fake_data
=
np
.
load
(
"../../fake_data/fake_data.npy"
)
fake_data
=
paddle
.
to_tensor
(
fake_data
)
# 模型前向
out
=
model
(
fake_data
)
# 保存前向结果,对于不同的任务,需要开发者添加。
reprod_logger
.
add
(
"logits"
,
fake_data
.
cpu
().
detach
().
numpy
())
reprod_logger
.
save
(
"forward_paddle.npy"
)
```
diff检查的代码可以参考:
[
check_step1.py
](
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/pipeline/Step1/check_step1.py
)
,具体代码如下所示。
```
python
# https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/pipeline/Step1/check_step1.py
# 使用reprod_log排查diff
from
reprod_log
import
ReprodDiffHelper
if
__name__
==
"__main__"
:
diff_helper
=
ReprodDiffHelper
()
torch_info
=
diff_helper
.
load_info
(
"AlexNet_torch/forward_torch.npy"
)
paddle_info
=
diff_helper
.
load_info
(
"AlexNet_paddle/forward_paddle.npy"
)
diff_helper
.
compare_info
(
torch_info
,
paddle_info
)
diff_helper
.
report
(
path
=
"forward_diff.log"
)
```
产出日志如下。
```
2021-09-27 10:35:46,172 - reprod_log.utils - INFO - logits:
2021-09-27 10:35:46,173 - reprod_log.utils - INFO - mean diff: check passed: True, value: 0.0
2021-09-27 10:35:46,173 - reprod_log.utils - INFO - diff check passed
```
平均绝对误差为0,测试通过。
上述文件的生成代码都需要开发者进行开发,验收时需要提供上面罗列的所有文件(不需要提供产生这些文件的可运行程序)以及完整的模型训练评估程序和日志。
AlexNet-Prod项目提供了基于reprod_log的5个验收点对齐验收示例,具体代码地址为:
[
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/pipeline/
](
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/pipeline/
)
,
每个文件夹中的README.md文档提供了使用说明。
## 3. 论文复现
赛操作流程规范
## 3. 论文复现
理论知识以及实战
### 3.1 模型结构对齐
...
...
@@ -230,23 +162,40 @@ if __name__ == "__main__":
*
网络结构代码转换
*
权重转换
*
给定完全相同输入,生成tensor,验证模型的正确性
*
模型组网正确性验证
下面详细介绍这3个部分。
#### 3.1.1 网络结构代码转换
由于PyTorch的API和PaddlePaddle的API非常相似,所以组网部分代码直接手动转换即可。如果是PaddlePaddle没有的API,可以尝试用多种API来组合,高优的API如果希望获得支持,也可以提给PaddlePaddle团队提
[
ISSUE
](
https://github.com/PaddlePaddle/Paddle/issues
)
。API对应的列表也可以参考:
[
PyTorch-PaddlePaddle API映射表
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/08_api_mapping/pytorch_api_mapping_cn.html
)
。
**【基本流程】**
由于PyTorch的API和PaddlePaddle的API非常相似,可以参考
[
PyTorch-PaddlePaddle API映射表
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/guides/08_api_mapping/pytorch_api_mapping_cn.html
)
,组网部分代码直接进行手动转换即可。
**【注意事项】**
对于AlexNet,PyTorch实现为:
[
alexnet-pytorch
](
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/AlexNet-torch/torchvision/models/alexnet.py
)
, 复现的PaddlePaddle实现为:
[
alexnet-paddle
](
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/AlexNet-paddle/paddlevision/models/alexnet.py
)
。
如果遇到PaddlePaddle没有的API,可以尝试用多种API来组合,也可以给PaddlePaddle团队提
[
ISSUE
](
https://github.com/PaddlePaddle/Paddle/issues
)
,获得支持。
**【实战】**
对于AlexNet网络结构的PyTorch实现
[
alexnet-pytorch
](
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/AlexNet-torch/torchvision/models/alexnet.py
)
,
[
alexnet-paddle
](
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/AlexNet-paddle/paddlevision/models/alexnet.py
)
提供了网络结构代码转换为PaddlePaddle的实现。
#### 3.1.2 权重转换
**【基本流程】**
组网代码转换完成之后,需要对模型权重进行转换,如果PyTorch repo中已经提供权重,那么可以直接下载并进行后续的转换;如果没有提供,则可以基于PyTorch代码,随机生成一个初始化权重(定义完model以后,使用
`torch.save()`
API保存模型权重),然后进行权重转换。
**【注意事项】**
在权重转换的时候,需要注意
`paddle.nn.Linear`
以及
`paddle.nn.BatchNorm2D`
等API的权重保存格式和名称等与PyTorch稍有diff,具体内容可以参考
`5.1章节`
。
**【实战】**
AlexNet的代码转换脚本可以在这里查看:
[
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/pipeline/weights/torch2paddle.py
](
https://github.com/littletomatodonkey/AlexNet-Prod/blob/master/pipeline/weights/torch2paddle.py
)
,核心函数如下所示。
注:运行该代码需要首先下载PyTorch的AlexNet预训练模型到该目录下,下载地址为:
[
https://download.pytorch.org/models/alexnet-owt-7be5be79.pth
](
https://download.pytorch.org/models/alexnet-owt-7be5be79.pth
)
注
意
:运行该代码需要首先下载PyTorch的AlexNet预训练模型到该目录下,下载地址为:
[
https://download.pytorch.org/models/alexnet-owt-7be5be79.pth
](
https://download.pytorch.org/models/alexnet-owt-7be5be79.pth
)
```
python
# https://github.com/littletomatodonkey/AlexNet-Prod/blob/d7b1977c2043a346b3fee0039949d5334fb990a3/pipeline/weights/torch2paddle.py#L6
...
...
@@ -277,27 +226,32 @@ transfer()
运行完成之后,会在这里生成
`alexnet_paddle.pdparams`
文件,为PaddlePaddle的预训练模型。
在权重转换的时候,需要注意
`paddle.nn.Linear`
以及
`paddle.nn.BatchNorm2D`
等API的权重保存格式和名称等与PyTorch稍有diff,具体内容可以参考
`5.1章节`
。
#### 3.1.3 模型组网正确性验证
*
操作流程
**【基本流程】**
* 定义PyTorch模型,加载权重,固定seed,基于numpy生成随机数,转换为PyTorch可以处理的tensor,送入网络,获取输出,使用reprod_log保存结果。
* 定义PaddlePaddle模型,加载权重,固定seed,基于numpy生成随机数,转换为PaddlePaddle可以处理的tensor,送入网络,获取输出,使用reprod_log保存结果。
* 使用reprod_log排查diff,小于阈值,即可完成自测。
*
注意事项
**【注意事项】**
* 模型在前向对齐验证时,需要调用`model.eval()`方法,保证组网中的随机量被关闭,比如BatchNorm、Dropout等。
*
给定相同的输入数据,为保证可复现性,建议随机数生成时,固定seed进行生成。
*
输出diff可以使用
`np.mean(np.abs(o1 - o2))`
进行计算,一般小于1e-6的话,可以认为前向没有问题。
*
如果最终输出结果diff较大,可以使用二分的方法进行排查,比如说ResNet50,包含1个stem、4个res-stage、global avg-pooling以及最后的fc层,那么完成模型组网和权重转换之后,如果模型输出没有对齐,可以尝试输出中间某一个res-stage的tensor进行对比,如果相同,则向后进行排查;如果不同,则继续向前进行排查,以此类推,直到找到导致没有对齐的操作。
* 给定相同的输入数据,为保证可复现性,如果有随机数生成,固定相关的随机种子。
* 输出diff可以使用`np.mean(np.abs(o1 - o2))`进行计算,一般小于1e-6的话,可以认为前向没有问题。如果最终输出结果diff较大,可以使用二分的方法进行排查,比如说ResNet50,包含1个stem、4个res-stage、global avg-pooling以及最后的fc层,那么完成模型组网和权重转换之后,如果模型输出没有对齐,可以尝试输出中间某一个res-stage的tensor进行对比,如果相同,则向后进行排查;如果不同,则继续向前进行排查,以此类推,直到找到导致没有对齐的操作。
**【实战】**
### 3.2 验证/测试集数据读取对齐
AlexNet模型组网正确性验证可以参考如下示例代码:
[
https://github.com/littletomatodonkey/AlexNet-Prod/tree/master/pipeline/Step1
](
https://github.com/littletomatodonkey/AlexNet-Prod/tree/master/pipeline/Step1
)
### 3.2 验证/测试集数据读取对齐
#### 3.2.1 数据集类Dataset复现方法
**【基本流程】**
对于一个数据集,一般有以下一些信息需要重点关注
*
数据集名称、下载地址
...
...
@@ -305,9 +259,11 @@ transfer()
*
数据集标注格式、标注信息
*
数据集通用的预处理方法
PaddlePaddle中数据集
类为
`paddle.io.Dataset`
,PyTorch中对应为
`torch.utils.data.Dataset`
,二者功能一致,在绝大多数情况下,可以使用该类构建数据集。它是描述Dataset方法和行为的抽象类,在具体实现的时候,需要继承这个基类,实现其中的
`__getitem__`
和
`__len__`
方法。更多使用细节可以参考
论文中的说明。
PaddlePaddle中数据集
相关的API为
`paddle.io.Dataset`
,PyTorch中对应为
`torch.utils.data.Dataset`
,二者功能一致,在绝大多数情况下,可以使用该类构建数据集。它是描述Dataset方法和行为的抽象类,在具体实现的时候,需要继承这个基类,实现其中的
`__getitem__`
和
`__len__`
方法。除了参考代码中相关实现,也可以参考待复现
论文中的说明。
论文中一般会提供数据集的名称以及基本信息。复现过程中,我们在下载完数据之后,建议先检查下是否和论文中描述一致,否则可能存在的问题有:
**【注意事项】**
此外,论文中一般会提供数据集的名称以及基本信息。复现过程中,我们在下载完数据之后,建议先检查下是否和论文中描述一致,否则可能存在的问题有:
*
数据集年份不同,比如论文中使用了MS-COCO2014数据集,但是我们下载的是MS-COCO2017数据集,如果不对其进行检查,可能会导致我们最终训练的数据量等与论文中有diff
*
数据集使用方式不同,有些论文中,可能只是抽取了该数据集的子集进行方法验证,此时需要注意抽取方法,需要保证抽取出的子集完全相同
...
...
@@ -318,6 +274,9 @@ PaddlePaddle中数据集类为`paddle.io.Dataset`,PyTorch中对应为`torch.ut
*
有些自定义的数据处理方法,如果不涉及到深度学习框架的部分,可以直接复用。
*
对于特定任务中的数据预处理方法,比如说图像分类、检测、分割等,如果没有现成的API可以调用,可以参考官方模型套件中的一些实现方法,比如PaddleClas、PaddleDetection、PaddleSeg等。
**【实战】**
#### 3.2.2 数据加载器Dataloader复现方法
复现完Dataset之后,可以构建Dataloader,对数据进行组batch、批处理,送进网络进行计算。
...
...
@@ -392,9 +351,6 @@ INFO:reprod_log.utils: mean diff: check passed: True, value: 0.0
INFO:reprod_log.utils:diff check passed
```
### 3.3 评估指标对齐
#### 3.3.1 复现方法
...
...
@@ -751,7 +707,7 @@ python3.7 -m paddle.distributed.launch \
注意:这里8卡训练时,虽然单卡的batch size没有变化(32),但是总卡的batch size相当于是单卡的8倍,因此学习率也设置为了单卡时的8倍。
## 4. 验收
点
与验收方法
## 4. 验收
节点自查
与验收方法
### 4.1 模型结构对齐验收方法
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录