Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
PaddlePaddle
PaddleSlim
提交
973efc15
P
PaddleSlim
项目概览
PaddlePaddle
/
PaddleSlim
接近 2 年 前同步成功
通知
51
Star
1434
Fork
344
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
53
列表
看板
标记
里程碑
合并请求
16
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleSlim
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
53
Issue
53
列表
看板
标记
里程碑
合并请求
16
合并请求
16
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
973efc15
编写于
12月 26, 2019
作者:
W
whs
提交者:
GitHub
12月 26, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Fix format of pruning doc and analysis doc. (#14)
上级
e2383b9b
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
73 addition
and
89 deletion
+73
-89
docs/docs/api/analysis_api.md
docs/docs/api/analysis_api.md
+23
-26
docs/docs/api/prune_api.md
docs/docs/api/prune_api.md
+47
-61
docs/mkdocs.yml
docs/mkdocs.yml
+3
-2
未找到文件。
docs/docs/api/analysis_api.md
浏览文件 @
973efc15
# 模型分析API文档
## FLOPs
paddleslim.analysis.flops(program, detail=False)
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/analysis/flops.py
)
## flops
: 获得指定网络的浮点运算次数(FLOPs)。
>paddleslim.analysis.flops(program, detail=False) [源代码]()
获得指定网络的每秒浮点运算次数(FLOPS)。
**参数:**
**参数:**
-
**program(paddle.fluid.Program):**
待分析的目标网络。更多关于Program的介绍请参考:
[
Program概念介绍
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Program_cn.html#program
)
。
-
**program(paddle.fluid.Program)**
- 待分析的目标网络。更多关于Program的介绍请参考:
[
Program概念介绍
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Program_cn.html#program
)
。
-
**detail(bool)**
- 是否返回每个卷积层的FLOPs。默认为False。
-
**
detail(bool):**
是否返回每个卷积层的FLOPS。默认为False
。
-
**
only_conv(bool)**
- 如果设置为True,则仅计算卷积层和全连接层的FLOPs,即浮点数的乘加(multiplication-adds)操作次数。如果设置为False,则也会计算卷积和全连接层之外的操作的FLOPs
。
**返回值:**
**返回值:**
-
**flops(float)
:**
整个网络的FLOPS
。
-
**flops(float)
**
- 整个网络的FLOPs
。
-
**params2flops(dict)
:**
每层卷积对应的FLOPS,其中key为卷积层参数名称,value为FLOPS
值。
-
**params2flops(dict)
**
- 每层卷积对应的FLOPs,其中key为卷积层参数名称,value为FLOPs
值。
**示例:**
**示例:**
...
@@ -73,22 +72,21 @@ with fluid.program_guard(main_program, startup_program):
...
@@ -73,22 +72,21 @@ with fluid.program_guard(main_program, startup_program):
conv5 = conv_bn_layer(sum2, 8, 3, "conv5")
conv5 = conv_bn_layer(sum2, 8, 3, "conv5")
conv6 = conv_bn_layer(conv5, 8, 3, "conv6")
conv6 = conv_bn_layer(conv5, 8, 3, "conv6")
print("FLOP
S
: {}".format(flops(main_program)))
print("FLOP
s
: {}".format(flops(main_program)))
```
```
## model_size
## model_size
paddleslim.analysis.model_size(program)
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/analysis/model_size.py
)
>paddleslim.analysis.model_size(program) [源代码]()
获得指定网络的参数数量。
获得指定网络的参数数量。
**参数:**
**参数:**
-
**program(paddle.fluid.Program)
:**
待分析的目标网络。更多关于Program的介绍请参考:
[
Program概念介绍
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Program_cn.html#program
)
。
-
**program(paddle.fluid.Program)
**
-
待分析的目标网络。更多关于Program的介绍请参考:
[
Program概念介绍
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Program_cn.html#program
)
。
**返回值:**
**返回值:**
-
**model_size(int)
:**
整个网络的参数数量。
-
**model_size(int)
**
-
整个网络的参数数量。
**示例:**
**示例:**
...
@@ -137,33 +135,32 @@ with fluid.program_guard(main_program, startup_program):
...
@@ -137,33 +135,32 @@ with fluid.program_guard(main_program, startup_program):
conv5 = conv_layer(sum2, 8, 3, "conv5")
conv5 = conv_layer(sum2, 8, 3, "conv5")
conv6 = conv_layer(conv5, 8, 3, "conv6")
conv6 = conv_layer(conv5, 8, 3, "conv6")
print("FLOP
S
: {}".format(model_size(main_program)))
print("FLOP
s
: {}".format(model_size(main_program)))
```
```
## TableLatencyEvaluator
## TableLatencyEvaluator
paddleslim.analysis.TableLatencyEvaluator(table_file, delimiter=",")
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/analysis/latency.py
)
>paddleslim.analysis.TableLatencyEvaluator(table_file, delimiter=",") [源代码]()
: 基于硬件延时表的模型延时评估器。
基于硬件延时表的模型延时评估器。
**参数:**
**参数:**
-
**table_file(str)
:**
所使用的延时评估表的绝对路径。关于演示评估表格式请参考:
[
PaddleSlim硬件延时评估表格式
](
../paddleslim/analysis/table_latency.md
)
-
**table_file(str)
**
-
所使用的延时评估表的绝对路径。关于演示评估表格式请参考:
[
PaddleSlim硬件延时评估表格式
](
../paddleslim/analysis/table_latency.md
)
-
**delimiter(str)
:**
硬件延时评估表中,操作信息之前所使用的分割符,默认为英文字符逗号。
-
**delimiter(str)
**
-
硬件延时评估表中,操作信息之前所使用的分割符,默认为英文字符逗号。
**返回值:**
**返回值:**
-
**Evaluator
:**
硬件延时评估器的实例。
-
**Evaluator
**
-
硬件延时评估器的实例。
>paddleslim.analysis.TableLatencyEvaluator.latency(graph) [源代码](
)
paddleslim.analysis.TableLatencyEvaluator.latency(graph)
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/analysis/latency.py
)
获得指定网络的预估延时。
:
获得指定网络的预估延时。
**参数:**
**参数:**
-
**graph(Program)
:**
待预估的目标网络。
-
**graph(Program)
**
-
待预估的目标网络。
**返回值:**
**返回值:**
-
**latency
:**
目标网络的预估延时。
-
**latency
**
-
目标网络的预估延时。
docs/docs/api/prune_api.md
浏览文件 @
973efc15
# 卷积通道剪裁API文档
## Pruner
paddleslim.prune.Pruner(criterion="l1_norm")
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/prune/pruner.py#L28
)
## class Pruner
: 对卷积网络的通道进行一次剪裁。剪裁一个卷积层的通道,是指剪裁该卷积层输出的通道。卷积层的权重形状为
`[output_channel, input_channel, kernel_size, kernel_size]`
,通过剪裁该权重的第一纬度达到剪裁输出通道数的目的。
---
>paddleslim.prune.Pruner(criterion="l1_norm")[源代码]()
对卷积网络的通道进行一次剪裁。剪裁一个卷积层的通道,是指剪裁该卷积层输出的通道。卷积层的权重形状为
`[output_channel, input_channel, kernel_size, kernel_size]`
,通过剪裁该权重的第一纬度达到剪裁输出通道数的目的。
**参数:**
**参数:**
-
**criterion
:**
评估一个卷积层内通道重要性所参考的指标。目前仅支持
`l1_norm`
。默认为
`l1_norm`
。
-
**criterion
**
-
评估一个卷积层内通道重要性所参考的指标。目前仅支持
`l1_norm`
。默认为
`l1_norm`
。
**返回:**
一个Pruner类的实例
**返回:**
一个Pruner类的实例
...
@@ -22,44 +17,42 @@ from paddleslim.prune import Pruner
...
@@ -22,44 +17,42 @@ from paddleslim.prune import Pruner
pruner = Pruner()
pruner = Pruner()
```
```
---
paddleslim.prune.Pruner.prune(program, scope, params, ratios, place=None, lazy=False, only_graph=False, param_backup=False, param_shape_backup=False)
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/prune/pruner.py#L36
)
>prune(program, scope, params, ratios, place=None, lazy=False, only_graph=False, param_backup=False, param_shape_backup=False)
: 对目标网络的一组卷积层的权重进行裁剪。
对目标网络的一组卷积层的权重进行裁剪。
**参数:**
**参数:**
-
**program(paddle.fluid.Program)
:**
要裁剪的目标网络。更多关于Program的介绍请参考:
[
Program概念介绍
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Program_cn.html#program
)
。
-
**program(paddle.fluid.Program)
**
-
要裁剪的目标网络。更多关于Program的介绍请参考:
[
Program概念介绍
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Program_cn.html#program
)
。
-
**scope(paddle.fluid.Scope)
:**
要裁剪的权重所在的
`scope`
,Paddle中用
`scope`
实例存放模型参数和运行时变量的值。Scope中的参数值会被
`inplace`
的裁剪。更多介绍请参考
[
Scope概念介绍
](
)
-
**scope(paddle.fluid.Scope)
**
-
要裁剪的权重所在的
`scope`
,Paddle中用
`scope`
实例存放模型参数和运行时变量的值。Scope中的参数值会被
`inplace`
的裁剪。更多介绍请参考
[
Scope概念介绍
](
)
-
**params(list<str>)
:**
需要被裁剪的卷积层的参数的名称列表。可以通过以下方式查看模型中所有参数的名称:
-
**params(list<str>)
**
-
需要被裁剪的卷积层的参数的名称列表。可以通过以下方式查看模型中所有参数的名称:
```
```
for block in program.blocks:
for block in program.blocks:
for param in block.all_parameters():
for param in block.all_parameters():
print("param: {}; shape: {}".format(param.name, param.shape))
print("param: {}; shape: {}".format(param.name, param.shape))
```
```
-
**ratios(list<float>)
:**
用于裁剪
`params`
的剪切率,类型为列表。该列表长度必须与
`params`
的长度一致。
-
**ratios(list<float>)
**
-
用于裁剪
`params`
的剪切率,类型为列表。该列表长度必须与
`params`
的长度一致。
-
**place(paddle.fluid.Place)
:**
待裁剪参数所在的设备位置,可以是
`CUDAPlace`
或
`CPUPlace`
。
[
Place概念介绍
](
)
-
**place(paddle.fluid.Place)
**
-
待裁剪参数所在的设备位置,可以是
`CUDAPlace`
或
`CPUPlace`
。
[
Place概念介绍
](
)
-
**lazy(bool)
:**
`lazy`
为True时,通过将指定通道的参数置零达到裁剪的目的,参数的
`shape保持不变`
;
`lazy`
为False时,直接将要裁的通道的参数删除,参数的
`shape`
会发生变化。
-
**lazy(bool)
**
-
`lazy`
为True时,通过将指定通道的参数置零达到裁剪的目的,参数的
`shape保持不变`
;
`lazy`
为False时,直接将要裁的通道的参数删除,参数的
`shape`
会发生变化。
-
**only_graph(bool)
:**
是否只裁剪网络结构。在Paddle中,Program定义了网络结构,Scope存储参数的数值。一个Scope实例可以被多个Program使用,比如定义了训练网络的Program和定义了测试网络的Program是使用同一个Scope实例的。
`only_graph`
为True时,只对Program中定义的卷积的通道进行剪裁;
`only_graph`
为false时,Scope中卷积参数的数值也会被剪裁。默认为False。
-
**only_graph(bool)
**
-
是否只裁剪网络结构。在Paddle中,Program定义了网络结构,Scope存储参数的数值。一个Scope实例可以被多个Program使用,比如定义了训练网络的Program和定义了测试网络的Program是使用同一个Scope实例的。
`only_graph`
为True时,只对Program中定义的卷积的通道进行剪裁;
`only_graph`
为false时,Scope中卷积参数的数值也会被剪裁。默认为False。
-
**param_backup(bool)
:**
是否返回对参数值的备份。默认为False。
-
**param_backup(bool)
**
-
是否返回对参数值的备份。默认为False。
-
**param_shape_backup(bool)
:**
是否返回对参数
`shape`
的备份。默认为False。
-
**param_shape_backup(bool)
**
-
是否返回对参数
`shape`
的备份。默认为False。
**返回:**
**返回:**
-
**pruned_program(paddle.fluid.Program)
:**
被裁剪后的Program。
-
**pruned_program(paddle.fluid.Program)
**
-
被裁剪后的Program。
-
**param_backup(dict)
:**
对参数数值的备份,用于恢复Scope中的参数数值。
-
**param_backup(dict)
**
-
对参数数值的备份,用于恢复Scope中的参数数值。
-
**param_shape_backup(dict)
:**
对参数形状的备份。
-
**param_shape_backup(dict)
**
-
对参数形状的备份。
**示例:**
**示例:**
...
@@ -144,18 +137,17 @@ for param in main_program.global_block().all_parameters():
...
@@ -144,18 +137,17 @@ for param in main_program.global_block().all_parameters():
---
---
## sensitivity
## sensitivity
paddleslim.prune.sensitivity(program, place, param_names, eval_func, sensitivities_file=None, pruned_ratios=None)
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/prune/sensitive.py#L34
)
>paddleslim.prune.sensitivity(program, place, param_names, eval_func, sensitivities_file=None, pruned_ratios=None) [源代码]()
: 计算网络中每个卷积层的敏感度。每个卷积层的敏感度信息统计方法为:依次剪掉当前卷积层不同比例的输出通道数,在测试集上计算剪裁后的精度损失。得到敏感度信息后,可以通过观察或其它方式确定每层卷积的剪裁率。
计算网络中每个卷积层的敏感度。每个卷积层的敏感度信息统计方法为:依次剪掉当前卷积层不同比例的输出通道数,在测试集上计算剪裁后的精度损失。得到敏感度信息后,可以通过观察或其它方式确定每层卷积的剪裁率。
**参数:**
**参数:**
-
**program(paddle.fluid.Program)
:**
待评估的目标网络。更多关于Program的介绍请参考:
[
Program概念介绍
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Program_cn.html#program
)
。
-
**program(paddle.fluid.Program)
**
-
待评估的目标网络。更多关于Program的介绍请参考:
[
Program概念介绍
](
https://www.paddlepaddle.org.cn/documentation/docs/zh/api_cn/fluid_cn/Program_cn.html#program
)
。
-
**place(paddle.fluid.Place)
:**
待分析的参数所在的设备位置,可以是
`CUDAPlace`
或
`CPUPlace`
。
[
Place概念介绍
](
)
-
**place(paddle.fluid.Place)
**
-
待分析的参数所在的设备位置,可以是
`CUDAPlace`
或
`CPUPlace`
。
[
Place概念介绍
](
)
-
**param_names(list<str>)
:**
待分析的卷积层的参数的名称列表。可以通过以下方式查看模型中所有参数的名称:
-
**param_names(list<str>)
**
-
待分析的卷积层的参数的名称列表。可以通过以下方式查看模型中所有参数的名称:
```
```
for block in program.blocks:
for block in program.blocks:
...
@@ -163,18 +155,18 @@ for block in program.blocks:
...
@@ -163,18 +155,18 @@ for block in program.blocks:
print("param: {}; shape: {}".format(param.name, param.shape))
print("param: {}; shape: {}".format(param.name, param.shape))
```
```
-
**eval_func(function)
:**
用于评估裁剪后模型效果的回调函数。该回调函数接受被裁剪后的
`program`
为参数,返回一个表示当前program的精度,用以计算当前裁剪带来的精度损失。
-
**eval_func(function)
**
-
用于评估裁剪后模型效果的回调函数。该回调函数接受被裁剪后的
`program`
为参数,返回一个表示当前program的精度,用以计算当前裁剪带来的精度损失。
-
**sensitivities_file(str)
:**
保存敏感度信息的本地文件系统的文件。在敏感度计算过程中,会持续将新计算出的敏感度信息追加到该文件中。重启任务后,文件中已有敏感度信息不会被重复计算。该文件可以用
`pickle`
加载。
-
**sensitivities_file(str)
**
-
保存敏感度信息的本地文件系统的文件。在敏感度计算过程中,会持续将新计算出的敏感度信息追加到该文件中。重启任务后,文件中已有敏感度信息不会被重复计算。该文件可以用
`pickle`
加载。
-
**pruned_ratios(list<float>)
:**
计算卷积层敏感度信息时,依次剪掉的通道数比例。默认为[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]。
-
**pruned_ratios(list<float>)
**
-
计算卷积层敏感度信息时,依次剪掉的通道数比例。默认为[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]。
**返回:**
**返回:**
-
**sensitivities(dict)
:**
存放敏感度信息的dict,其格式为:
-
**sensitivities(dict)
**
-
存放敏感度信息的dict,其格式为:
```
```
{"weight_0":
{"weight_0":
{0.1: 0.22,
{0.1: 0.22,
0.2: 0.33
0.2: 0.33
},
},
...
@@ -239,7 +231,7 @@ startup_program = fluid.Program()
...
@@ -239,7 +231,7 @@ startup_program = fluid.Program()
image_shape = [1,28,28]
image_shape = [1,28,28]
with fluid.program_guard(main_program, startup_program):
with fluid.program_guard(main_program, startup_program):
image = fluid.data(name='image', shape=[None]+image_shape, dtype='float32')
image = fluid.data(name='image', shape=[None]+image_shape, dtype='float32')
label = fluid.data(name='label', shape=[None, 1], dtype='int64')
label = fluid.data(name='label', shape=[None, 1], dtype='int64')
conv1 = conv_bn_layer(image, 8, 3, "conv1")
conv1 = conv_bn_layer(image, 8, 3, "conv1")
conv2 = conv_bn_layer(conv1, 8, 3, "conv2")
conv2 = conv_bn_layer(conv1, 8, 3, "conv2")
sum1 = conv1 + conv2
sum1 = conv1 + conv2
...
@@ -253,8 +245,8 @@ with fluid.program_guard(main_program, startup_program):
...
@@ -253,8 +245,8 @@ with fluid.program_guard(main_program, startup_program):
# avg_cost = fluid.layers.mean(x=cost)
# avg_cost = fluid.layers.mean(x=cost)
acc_top1 = fluid.layers.accuracy(input=out, label=label, k=1)
acc_top1 = fluid.layers.accuracy(input=out, label=label, k=1)
# acc_top5 = fluid.layers.accuracy(input=out, label=label, k=5)
# acc_top5 = fluid.layers.accuracy(input=out, label=label, k=5)
place = fluid.CPUPlace()
place = fluid.CPUPlace()
exe = fluid.Executor(place)
exe = fluid.Executor(place)
exe.run(startup_program)
exe.run(startup_program)
...
@@ -287,21 +279,20 @@ print(sensitivities)
...
@@ -287,21 +279,20 @@ print(sensitivities)
```
```
## merge_sensitive
## merge_sensitive
paddleslim.prune.merge_sensitive(sensitivities)
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/prune/sensitive.py#L161
)
>merge_sensitive(sensitivities)
: 合并多个敏感度信息。
合并多个敏感度信息。
参数:
参数:
-
**sensitivities(list<dict> | list<str>)
:**
待合并的敏感度信息,可以是字典的列表,或者是存放敏感度信息的文件的路径列表。
-
**sensitivities(list<dict> | list<str>)
**
-
待合并的敏感度信息,可以是字典的列表,或者是存放敏感度信息的文件的路径列表。
返回:
返回:
-
**sensitivities(dict)
:**
合并后的敏感度信息。其格式为:
-
**sensitivities(dict)
**
-
合并后的敏感度信息。其格式为:
```
```
{"weight_0":
{"weight_0":
{0.1: 0.22,
{0.1: 0.22,
0.2: 0.33
0.2: 0.33
},
},
...
@@ -318,37 +309,32 @@ print(sensitivities)
...
@@ -318,37 +309,32 @@ print(sensitivities)
## load_sensitivities
## load_sensitivities
paddleslim.prune.load_sensitivities(sensitivities_file)
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/prune/sensitive.py#L184
)
>load_sensitivities(sensitivities_file)
: 从文件中加载敏感度信息。
从文件中加载敏感度信息。
参数:
参数:
-
**sensitivities_file(str)
:**
存放敏感度信息的本地文件.
-
**sensitivities_file(str)
**
-
存放敏感度信息的本地文件.
返回:
返回:
-
**sensitivities(dict)**
敏感度信息。
-
**sensitivities(dict)**
-
敏感度信息。
示例:
示例:
## get_ratios_by_loss(sensitivities, loss)
根据敏感度和精度损失阈值计算出一组剪切率。对于参数
`w`
, 其剪裁率为使精度损失低于
`loss`
的最大剪裁率。
## get_ratios_by_loss
paddleslim.prune.get_ratios_by_loss(sensitivities, loss)
[
源代码
](
https://github.com/PaddlePaddle/PaddleSlim/blob/develop/paddleslim/prune/sensitive.py#L206
)
: 根据敏感度和精度损失阈值计算出一组剪切率。对于参数
`w`
, 其剪裁率为使精度损失低于
`loss`
的最大剪裁率。
参数:
参数:
-
**sensitivities(dict)
:**
敏感度信息。
-
**sensitivities(dict)
**
-
敏感度信息。
-
**loss
:**
精度损失阈值。
-
**loss
**
-
精度损失阈值。
返回:
返回:
-
ratios(dict): 一组剪切率。
`key`
是待剪裁参数的名称。
`value`
是对应参数的剪裁率。
-
**ratios(dict)**
- 一组剪切率。
`key`
是待剪裁参数的名称。
`value`
是对应参数的剪裁率。
示例:
```
```
docs/mkdocs.yml
浏览文件 @
973efc15
...
@@ -9,11 +9,12 @@ nav:
...
@@ -9,11 +9,12 @@ nav:
-
SA搜索
:
tutorials/nas_demo.md
-
SA搜索
:
tutorials/nas_demo.md
-
API
:
-
API
:
-
量化
:
api/quantization_api.md
-
量化
:
api/quantization_api.md
-
剪枝
:
api/prune_api.md
-
剪枝
与敏感度
:
api/prune_api.md
-
敏感度
分析
:
api/analysis_api.md
-
模型
分析
:
api/analysis_api.md
-
蒸馏
:
api/single_distiller_api.md
-
蒸馏
:
api/single_distiller_api.md
-
SA搜索
:
api/nas_api.md
-
SA搜索
:
api/nas_api.md
-
搜索空间
:
api/search_space.md
-
搜索空间
:
api/search_space.md
-
硬件延时评估表
:
table_latency.md
-
算法原理
:
algo/algo.md
-
算法原理
:
algo/algo.md
theme
:
theme
:
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录