未验证 提交 41aacacb 编写于 作者: P Peter Pan 提交者: GitHub

fix: public path cannot be set to root path if not in api mode (#641)

* fix: public path cannot be set to root path if not in api mode

* fix: use position argument

* fix: support legacy call method

* doc: update document
上级 ec6479a2
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
<img src="https://raw.githubusercontent.com/PaddlePaddle/VisualDL/develop/frontend/packages/core/public/images/logo-visualdl.svg?sanitize=true" width="70%"/> <img src="https://raw.githubusercontent.com/PaddlePaddle/VisualDL/develop/frontend/packages/core/public/images/logo-visualdl.svg?sanitize=true" width="70%"/>
</p> </p>
[![Build Status](https://travis-ci.org/PaddlePaddle/VisualDL.svg?branch=develop)](https://travis-ci.org/PaddlePaddle/VisualDL) [![Build Status](https://img.shields.io/travis/PaddlePaddle/VisualDL/develop?style=flat-square)](https://travis-ci.org/PaddlePaddle/VisualDL)
[![Documentation Status](https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat)](https://github.com/PaddlePaddle/VisualDL/tree/develop/docs) [![Documentation Status](https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat-square)](https://github.com/PaddlePaddle/VisualDL/tree/develop/docs)
[![Release](https://img.shields.io/github/release/PaddlePaddle/VisualDL.svg)](https://github.com/PaddlePaddle/VisualDL/releases) [![Release](https://img.shields.io/github/release/PaddlePaddle/VisualDL.svg?style=flat-square)](https://github.com/PaddlePaddle/VisualDL/releases)
[![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](LICENSE) [![License](https://img.shields.io/badge/license-Apache%202-blue.svg?style=flat-square)](LICENSE)
## 介绍 ## 介绍
VisualDL是深度学习模型可视化分析工具,以丰富的图表呈现训练参数变化趋势、模型结构、数据样本、高维数据分布等。可帮助用户更清晰直观地理解深度学习模型训练过程及模型结构,进而实现高效的模型优化。 VisualDL是深度学习模型可视化分析工具,以丰富的图表呈现训练参数变化趋势、模型结构、数据样本、高维数据分布等。可帮助用户更清晰直观地理解深度学习模型训练过程及模型结构,进而实现高效的模型优化。
...@@ -123,16 +123,20 @@ with LogWriter(logdir="./log/scalar_test/train") as writer: ...@@ -123,16 +123,20 @@ with LogWriter(logdir="./log/scalar_test/train") as writer:
使用命令行启动VisualDL面板,命令格式如下: 使用命令行启动VisualDL面板,命令格式如下:
```python ```python
visualdl --logdir <dir_1, dir_2, ... , dir_n> --host <host> --port <port> visualdl --logdir <dir_1, dir_2, ... , dir_n> --host <host> --port <port> --cache-timeout <cache_timeout> --language <language> --public-path <public_path> --api-only
``` ```
参数详情: 参数详情:
| 参数 | 意义 | | 参数 | 意义 |
| -------- | ------------------------------------------------------------ | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --logdir | 设定日志所在目录,可以指定多个目录,VisualDL将遍历并且迭代寻找指定目录的子目录,将所有实验结果进行可视化 | | --logdir | 设定日志所在目录,可以指定多个目录,VisualDL将遍历并且迭代寻找指定目录的子目录,将所有实验结果进行可视化 |
| --host | 设定IP,默认为`127.0.0.1` | | --host | 设定IP,默认为`127.0.0.1` |
| --port | 设定端口,默认为`8040` | | --port | 设定端口,默认为`8040` |
| --cache-timeout | 后端缓存时间,在缓存时间内前端多次请求同一url,返回的数据从缓存中获取,默认为20秒 |
| --language | VisualDL面板语言,可指定为'en'或'zh',默认为浏览器使用语言 |
| --public-path | VisualDL面板URL路径,默认是'/app',即访问地址为'http://<host>:<port>/app' |
| --api-only | 是否只提供API,如果设置此参数,则VisualDL不提供页面展示,只提供API服务,此时API地址为'http://<host>:<port>/<public_path>/api';若没有设置public_path参数,则默认为'http://<host>:<port>/api' |
针对上一步生成的日志,启动命令为: 针对上一步生成的日志,启动命令为:
...@@ -150,19 +154,23 @@ visualdl.server.app.run(logdir, ...@@ -150,19 +154,23 @@ visualdl.server.app.run(logdir,
port=8080, port=8080,
cache_timeout=20, cache_timeout=20,
language=None, language=None,
public_path=None,
api_only=False,
open_browser=False) open_browser=False)
``` ```
接口参数: 接口参数:
| 参数 | 格式 | 含义 | | 参数 | 格式 | 含义 |
| ------------- | ------------------------------------------------ | ------------------------------------------------------------ | | ------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| logdir | string或list[string_1, string_2, ... , string_n] | 日志文件所在的路径,VisualDL将在此路径下递归搜索日志文件并进行可视化,可指定单个或多个路径 | | logdir | string或list[string_1, string_2, ... , string_n] | 日志文件所在的路径,VisualDL将在此路径下递归搜索日志文件并进行可视化,可指定单个或多个路径 |
| host | string | 指定启动服务的ip,默认为`127.0.0.1` | | host | string | 指定启动服务的ip,默认为`127.0.0.1` |
| port | int | 启动服务端口,默认为`8040` | | port | int | 启动服务端口,默认为`8040` |
| cache_timeout | int | 后端缓存时间,在缓存时间内前端多次请求同一url,返回的数据从缓存中获取,默认为20秒 | | cache_timeout | int | 后端缓存时间,在缓存时间内前端多次请求同一url,返回的数据从缓存中获取,默认为20秒 |
| language | string | VisualDL面板语言,可指定为'EN'或'CN',默认自动匹配操作系统使用语言 | | language | string | VisualDL面板语言,可指定为'en'或'zh',默认为浏览器使用语言 |
| open_browser | boolean | 是否打开浏览器,设置为True则在启动后自动打开浏览器并访问VisualDL面板 | | public_path | string | VisualDL面板URL路径,默认是'/app',即访问地址为'http://<host>:<port>/app' |
| api_only | boolean | 是否只提供API,如果设置此参数,则VisualDL不提供页面展示,只提供API服务,此时API地址为'http://<host>:<port>/<public_path>/api';若没有设置public_path参数,则默认为'http://<host>:<port>/api' |
| open_browser | boolean | 是否打开浏览器,设置为True则在启动后自动打开浏览器并访问VisualDL面板,若设置api_only,则忽略此参数 |
针对上一步生成的日志,我们的启动脚本为: 针对上一步生成的日志,我们的启动脚本为:
...@@ -175,7 +183,7 @@ app.run(logdir="./log") ...@@ -175,7 +183,7 @@ app.run(logdir="./log")
在使用任意一种方式启动VisualDL面板后,打开浏览器访问VisualDL面板,即可查看日志的可视化结果,如图: 在使用任意一种方式启动VisualDL面板后,打开浏览器访问VisualDL面板,即可查看日志的可视化结果,如图:
<p align="center"> <p align="center">
<img src="https://user-images.githubusercontent.com/48054808/82395889-1ca01a00-9a7f-11ea-8e80-4a81393d0234.png" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/3points_demo.png" width="60%"/>
</p> </p>
...@@ -190,7 +198,7 @@ app.run(logdir="./log") ...@@ -190,7 +198,7 @@ app.run(logdir="./log")
在启动VisualDL Board后,LogReader将不断增量的读取日志中数据并供前端调用展示,因此能够在训练中同步观测指标变化,如下图: 在启动VisualDL Board后,LogReader将不断增量的读取日志中数据并供前端调用展示,因此能够在训练中同步观测指标变化,如下图:
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/dynamic_display.gif" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/dynamic_display.gif" width="60%"/>
</p> </p>
...@@ -199,7 +207,7 @@ app.run(logdir="./log") ...@@ -199,7 +207,7 @@ app.run(logdir="./log")
只需在启动VisualDL Board的时将每个实验日志所在路径同时传入即可,每个实验中相同tag的指标将绘制在一张图中同步呈现,如下图: 只需在启动VisualDL Board的时将每个实验日志所在路径同时传入即可,每个实验中相同tag的指标将绘制在一张图中同步呈现,如下图:
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/multi_experiments.gif" width="100%"/> <img src="https://visualdl.bj.bcebos.com/images/multi_experiments.gif" width="100%"/>
</p> </p>
...@@ -207,7 +215,7 @@ app.run(logdir="./log") ...@@ -207,7 +215,7 @@ app.run(logdir="./log")
实时展示训练过程中的图像数据,用于观察不同训练阶段的图像变化,进而深入了解训练过程及效果。 实时展示训练过程中的图像数据,用于观察不同训练阶段的图像变化,进而深入了解训练过程及效果。
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/image-eye.gif" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/image-eye.gif" width="60%"/>
</p> </p>
...@@ -221,7 +229,7 @@ app.run(logdir="./log") ...@@ -221,7 +229,7 @@ app.run(logdir="./log")
## 开源贡献 ## 开源贡献
VisualDL 是由 [PaddlePaddle](http://www.paddlepaddle.org/)[ECharts](http://echarts.baidu.com/) 合作推出的开源项目。欢迎所有人使用,提意见以及贡献代码。 VisualDL 是由 [PaddlePaddle](https://www.paddlepaddle.org/)[ECharts](https://echarts.apache.org/) 合作推出的开源项目。欢迎所有人使用,提意见以及贡献代码。
## 更多细节 ## 更多细节
......
...@@ -8,10 +8,10 @@ VisualDL 是一个面向深度学习任务设计的可视化工具。VisualDL ...@@ -8,10 +8,10 @@ VisualDL 是一个面向深度学习任务设计的可视化工具。VisualDL
目前,VisualDL 支持 scalar, image, high dimensional 三个组件,项目正处于高速迭代中,敬请期待新组件的加入。 目前,VisualDL 支持 scalar, image, high dimensional 三个组件,项目正处于高速迭代中,敬请期待新组件的加入。
| 组件名称 | 展示图表 | 作用 | | 组件名称 | 展示图表 | 作用 |
| :----------------------------------------------------------: | :--------: | :----------------------------------------------------------- | | :------------------------------------------------------------------: | :--------: | :---------------------------------------------------------------- |
| <a href="#1">[Scalar](#Scalar--折线图组件)</a> | 折线图 | 动态展示损失函数值、准确率等标量数据 | | <a href="#1">[Scalar](#Scalar--折线图组件)</a> | 折线图 | 动态展示损失函数值、准确率等标量数据 |
| <a href="#3">[Image](#Image--图片可视化组件)</a> | 图片可视化 | 显示图片,可显示输入图片和处理后的结果,便于查看中间过程的变化 | | <a href="#3">[Image](#Image--图片可视化组件)</a> | 图片可视化 | 显示图片,可显示输入图片和处理后的结果,便于查看中间过程的变化 |
| <a href="#6">[High Dimensional](#High-Dimensional--数据降维组件)</a> | 数据降维 | 将高维数据映射到 2D/3D 空间来可视化嵌入,便于观察不同数据的相关性 | | <a href="#6">[High Dimensional](#High-Dimensional--数据降维组件)</a> | 数据降维 | 将高维数据映射到 2D/3D 空间来可视化嵌入,便于观察不同数据的相关性 |
...@@ -30,12 +30,12 @@ Scalar 组件的记录接口如下: ...@@ -30,12 +30,12 @@ Scalar 组件的记录接口如下:
add_scalar(tag, value, step, walltime=None) add_scalar(tag, value, step, walltime=None)
``` ```
接口参数说明如下: 接口参数说明如下:
|参数|格式|含义| | 参数 | 格式 | 含义 |
|-|-|-| | -------- | ------ | ------------------------------------------- |
|tag|string|记录指标的标志,如`train/loss`,不能含有`%`| | tag | string | 记录指标的标志,如`train/loss`,不能含有`%` |
|value|float|要记录的数据值| | value | float | 要记录的数据值 |
|step|int|记录的步数| | step | int | 记录的步数 |
|walltime|int|记录数据的时间戳,默认为当前时间戳| | walltime | int | 记录数据的时间戳,默认为当前时间戳 |
### Demo ### Demo
下面展示了使用 Scalar 组件记录数据的示例,代码见[Scalar组件](../../demo/components/scalar_test.py) 下面展示了使用 Scalar 组件记录数据的示例,代码见[Scalar组件](../../demo/components/scalar_test.py)
...@@ -70,7 +70,7 @@ visualdl --logdir ./log --port 8080 ...@@ -70,7 +70,7 @@ visualdl --logdir ./log --port 8080
* 支持数据卡片「最大化」、「还原」、「坐标系转化」(y轴对数坐标)、「下载」折线图 * 支持数据卡片「最大化」、「还原」、「坐标系转化」(y轴对数坐标)、「下载」折线图
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/scalar-icon.png" width="55%"/> <img src="https://visualdl.bj.bcebos.com/images/scalar-icon.png" width="55%"/>
</p> </p>
...@@ -78,7 +78,7 @@ visualdl --logdir ./log --port 8080 ...@@ -78,7 +78,7 @@ visualdl --logdir ./log --port 8080
* 数据点Hover展示详细信息 * 数据点Hover展示详细信息
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/scalar-tooltip.png" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/scalar-tooltip.png" width="60%"/>
</p> </p>
...@@ -86,7 +86,7 @@ visualdl --logdir ./log --port 8080 ...@@ -86,7 +86,7 @@ visualdl --logdir ./log --port 8080
* 可搜索卡片标签,展示目标图像 * 可搜索卡片标签,展示目标图像
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/scalar-searchlabel.png" width="90%"/> <img src="https://visualdl.bj.bcebos.com/images/scalar-searchlabel.png" width="90%"/>
</p> </p>
...@@ -94,7 +94,7 @@ visualdl --logdir ./log --port 8080 ...@@ -94,7 +94,7 @@ visualdl --logdir ./log --port 8080
* 可搜索打点数据标签,展示特定数据 * 可搜索打点数据标签,展示特定数据
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/scalar-searchstream.png" width="40%"/> <img src="https://visualdl.bj.bcebos.com/images/scalar-searchstream.png" width="40%"/>
</p> </p>
...@@ -105,12 +105,12 @@ visualdl --logdir ./log --port 8080 ...@@ -105,12 +105,12 @@ visualdl --logdir ./log --port 8080
3. Relative:训练时长 3. Relative:训练时长
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/x-axis.png" width="40%"/> <img src="https://visualdl.bj.bcebos.com/images/x-axis.png" width="40%"/>
</p> </p>
* 可调整曲线平滑度,以便更好的展现参数整体的变化趋势 * 可调整曲线平滑度,以便更好的展现参数整体的变化趋势
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/scalar-smooth.png" width="37%"/> <img src="https://visualdl.bj.bcebos.com/images/scalar-smooth.png" width="37%"/>
</p> </p>
...@@ -128,12 +128,12 @@ Image 组件的记录接口如下: ...@@ -128,12 +128,12 @@ Image 组件的记录接口如下:
add_image(tag, img, step, walltime=None) add_image(tag, img, step, walltime=None)
``` ```
接口参数说明如下: 接口参数说明如下:
|参数|格式|含义| | 参数 | 格式 | 含义 |
|-|-|-| | -------- | ------------- | ------------------------------------------- |
|tag|string|记录指标的标志,如`train/loss`,不能含有`%`| | tag | string | 记录指标的标志,如`train/loss`,不能含有`%` |
|img|numpy.ndarray|以ndarray格式表示的图片| | img | numpy.ndarray | 以ndarray格式表示的图片 |
|step|int|记录的步数| | step | int | 记录的步数 |
|walltime|int|记录数据的时间戳,默认为当前时间戳| | walltime | int | 记录数据的时间戳,默认为当前时间戳 |
### Demo ### Demo
下面展示了使用 Image 组件记录数据的示例,代码文件请见[Image组件](../../demo/components/image_test.py) 下面展示了使用 Image 组件记录数据的示例,代码文件请见[Image组件](../../demo/components/image_test.py)
...@@ -180,14 +180,14 @@ visualdl --logdir ./log --port 8080 ...@@ -180,14 +180,14 @@ visualdl --logdir ./log --port 8080
可搜索图片标签显示对应图片数据 可搜索图片标签显示对应图片数据
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/image-search.png" width="90%"/> <img src="https://visualdl.bj.bcebos.com/images/image-search.png" width="90%"/>
</p> </p>
支持滑动Step/迭代次数查看不同迭代次数下的图片数据 支持滑动Step/迭代次数查看不同迭代次数下的图片数据
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/image-eye.gif" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/image-eye.gif" width="60%"/>
</p> </p>
...@@ -208,12 +208,12 @@ High Dimensional 组件的记录接口如下: ...@@ -208,12 +208,12 @@ High Dimensional 组件的记录接口如下:
add_embeddings(tag, labels, hot_vectors, walltime=None) add_embeddings(tag, labels, hot_vectors, walltime=None)
``` ```
接口参数说明如下: 接口参数说明如下:
|参数|格式|含义| | 参数 | 格式 | 含义 |
|-|-|-| | ----------- | ------------------- | ---------------------------------------------------- |
|tag|string|记录指标的标志,如`default`,不能含有`%`| | tag | string | 记录指标的标志,如`default`,不能含有`%` |
|labels|numpy.array 或 list|一维数组表示的标签,每个元素是一个string类型的字符串| | labels | numpy.array 或 list | 一维数组表示的标签,每个元素是一个string类型的字符串 |
|hot_vectors|numpy.array or list|与labels一一对应,每个元素可以看作是某个标签的特征| | hot_vectors | numpy.array or list | 与labels一一对应,每个元素可以看作是某个标签的特征 |
|walltime|int|记录数据的时间戳,默认为当前时间戳| | walltime | int | 记录数据的时间戳,默认为当前时间戳 |
### Demo ### Demo
下面展示了使用 High Dimensional 组件记录数据的示例,代码见[High Dimensional组件](../../demo/components/high_dimensional_test.py) 下面展示了使用 High Dimensional 组件记录数据的示例,代码见[High Dimensional组件](../../demo/components/high_dimensional_test.py)
...@@ -245,5 +245,5 @@ visualdl --logdir ./log --port 8080 ...@@ -245,5 +245,5 @@ visualdl --logdir ./log --port 8080
接着在浏览器打开`http://127.0.0.1:8080`,即可查看降维后的可视化数据。 接着在浏览器打开`http://127.0.0.1:8080`,即可查看降维后的可视化数据。
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/dynamic_high_dimensional.gif" width="80%"/> <img src="https://visualdl.bj.bcebos.com/images/dynamic_high_dimensional.gif" width="80%"/>
</p> </p>
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/vdl-logo.png" width="70%"/> <img src="https://raw.githubusercontent.com/PaddlePaddle/VisualDL/develop/frontend/packages/core/public/images/logo-visualdl.svg?sanitize=true" width="70%"/>
</p> </p>
[![Build Status](https://travis-ci.org/PaddlePaddle/VisualDL.svg?branch=develop)](https://travis-ci.org/PaddlePaddle/VisualDL) [![Build Status](https://img.shields.io/travis/PaddlePaddle/VisualDL/develop?style=flat-square)](https://travis-ci.org/PaddlePaddle/VisualDL)
[![Documentation Status](https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat)](https://github.com/PaddlePaddle/VisualDL/tree/develop/docs) [![Documentation Status](https://img.shields.io/badge/docs-latest-brightgreen.svg?style=flat-square)](https://github.com/PaddlePaddle/VisualDL/tree/develop/docs)
[![Release](https://img.shields.io/github/release/PaddlePaddle/VisualDL.svg)](https://github.com/PaddlePaddle/VisualDL/releases) [![Release](https://img.shields.io/github/release/PaddlePaddle/VisualDL.svg?style=flat-square)](https://github.com/PaddlePaddle/VisualDL/releases)
[![License](https://img.shields.io/badge/license-Apache%202-blue.svg)](LICENSE) [![License](https://img.shields.io/badge/license-Apache%202-blue.svg?style=flat-square)](LICENSE)
## 介绍 ## 介绍
VisualDL是深度学习模型可视化分析工具,以丰富的图表呈现训练参数变化趋势、模型结构、数据样本、高维数据分布等。可帮助用户更清晰直观地理解深度学习模型训练过程及模型结构,进而实现高效的模型优化。 VisualDL是深度学习模型可视化分析工具,以丰富的图表呈现训练参数变化趋势、模型结构、数据样本、高维数据分布等。可帮助用户更清晰直观地理解深度学习模型训练过程及模型结构,进而实现高效的模型优化。
...@@ -56,7 +56,7 @@ API设计简洁易懂,使用简单。模型结构一键实现可视化。 ...@@ -56,7 +56,7 @@ API设计简洁易懂,使用简单。模型结构一键实现可视化。
使用pip安装 VisualDL 运行范例: 使用pip安装 VisualDL 运行范例:
```shell ```shell
pip install --upgrade visualdl==2.0.0a2 pip install --upgrade visualdl==2.0.0b4
``` ```
...@@ -81,14 +81,14 @@ class LogWriter(logdir=None, ...@@ -81,14 +81,14 @@ class LogWriter(logdir=None,
#### 接口参数 #### 接口参数
| 参数 | 格式 | 含义 | | 参数 | 格式 | 含义 |
| --------------- | ------- | ------------------------------------------------------------ | | --------------- | ------- | ------------------------------------------------------------------------------------------------------ |
| logdir | string | 日志文件所在的路径,VisualDL将在此路径下建立日志文件并进行记录,如果不填则默认为`runs/${CURRENT_TIME}` | | logdir | string | 日志文件所在的路径,VisualDL将在此路径下建立日志文件并进行记录,如果不填则默认为`runs/${CURRENT_TIME}` |
| comment | string | 为日志文件夹名添加后缀,如果制定了logdir则此项无效 | | comment | string | 为日志文件夹名添加后缀,如果制定了logdir则此项无效 |
| max_queue | int | 日志记录消息队列的最大容量,达到此容量则立即写入到日志文件 | | max_queue | int | 日志记录消息队列的最大容量,达到此容量则立即写入到日志文件 |
| flush_secs | int | 日志记录消息队列的最大缓存时间,达到此时间则立即写入到日志文件 | | flush_secs | int | 日志记录消息队列的最大缓存时间,达到此时间则立即写入到日志文件 |
| filename_suffix | string | 为默认的日志文件名添加后缀 | | filename_suffix | string | 为默认的日志文件名添加后缀 |
| write_to_disk | boolean | 是否写入到磁盘 | | write_to_disk | boolean | 是否写入到磁盘 |
#### 示例 #### 示例
...@@ -114,16 +114,20 @@ with LogWriter(logdir="./log/scalar_test/train") as writer: ...@@ -114,16 +114,20 @@ with LogWriter(logdir="./log/scalar_test/train") as writer:
使用命令行启动VisualDL面板,命令格式如下: 使用命令行启动VisualDL面板,命令格式如下:
```python ```python
visualdl --logdir <dir_1, dir_2, ... , dir_n> --host <host> --port <port> visualdl --logdir <dir_1, dir_2, ... , dir_n> --host <host> --port <port> --cache-timeout <cache_timeout> --language <language> --public-path <public_path> --api-only
``` ```
参数详情: 参数详情:
| 参数 | 意义 | | 参数 | 意义 |
| -------- | ------------------------------------------------------------ | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| --logdir | 设定日志所在目录,可以指定多个目录,VisualDL将遍历并且迭代寻找指定目录的子目录,将所有实验结果进行可视化 | | --logdir | 设定日志所在目录,可以指定多个目录,VisualDL将遍历并且迭代寻找指定目录的子目录,将所有实验结果进行可视化 |
| --host | 设定IP,默认为`127.0.0.1` | | --host | 设定IP,默认为`127.0.0.1` |
| --port | 设定端口,默认为`8040` | | --port | 设定端口,默认为`8040` |
| --cache-timeout | 后端缓存时间,在缓存时间内前端多次请求同一url,返回的数据从缓存中获取,默认为20秒 |
| --language | VisualDL面板语言,可指定为'en'或'zh',默认为浏览器使用语言 |
| --public-path | VisualDL面板URL路径,默认是'/app',即访问地址为'http://<host>:<port>/app' |
| --api-only | 是否只提供API,如果设置此参数,则VisualDL不提供页面展示,只提供API服务,此时API地址为'http://<host>:<port>/<public_path>/api';若没有设置public_path参数,则默认为'http://<host>:<port>/api' |
针对上一步生成的日志,启动命令为: 针对上一步生成的日志,启动命令为:
...@@ -141,32 +145,36 @@ visualdl.server.app.run(logdir, ...@@ -141,32 +145,36 @@ visualdl.server.app.run(logdir,
port=8080, port=8080,
cache_timeout=20, cache_timeout=20,
language=None, language=None,
public_path=None,
api_only=False,
open_browser=False) open_browser=False)
``` ```
接口参数: 接口参数:
| 参数 | 格式 | 含义 | | 参数 | 格式 | 含义 |
| ------------- | ------------------------------------------------ | ------------------------------------------------------------ | | ------------- | ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| logdir | string或list[string_1, string_2, ... , string_n] | 日志文件所在的路径,VisualDL将在此路径下递归搜索日志文件并进行可视化,可指定单个或多个路径 | | logdir | string或list[string_1, string_2, ... , string_n] | 日志文件所在的路径,VisualDL将在此路径下递归搜索日志文件并进行可视化,可指定单个或多个路径 |
| host | string | 指定启动服务的ip,默认为`127.0.0.1` | | host | string | 指定启动服务的ip,默认为`127.0.0.1` |
| port | int | 启动服务端口,默认为`8040` | | port | int | 启动服务端口,默认为`8040` |
| cache_timeout | int | 后端缓存时间,在缓存时间内前端多次请求同一url,返回的数据从缓存中获取,默认为20秒 | | cache_timeout | int | 后端缓存时间,在缓存时间内前端多次请求同一url,返回的数据从缓存中获取,默认为20秒 |
| language | string | VisualDL面板语言,可指定为'EN'或'CN',默认自动匹配操作系统使用语言 | | language | string | VisualDL面板语言,可指定为'en'或'zh',默认为浏览器使用语言 |
| open_browser | boolean | 是否打开浏览器,设置为True则在启动后自动打开浏览器并访问VisualDL面板 | | public_path | string | VisualDL面板URL路径,默认是'/app',即访问地址为'http://<host>:<port>/app' |
| api_only | boolean | 是否只提供API,如果设置此参数,则VisualDL不提供页面展示,只提供API服务,此时API地址为'http://<host>:<port>/<public_path>/api';若没有设置public_path参数,则默认为'http://<host>:<port>/api' |
| open_browser | boolean | 是否打开浏览器,设置为True则在启动后自动打开浏览器并访问VisualDL面板,若设置api_only,则忽略此参数 |
针对上一步生成的日志,我们的启动脚本为: 针对上一步生成的日志,我们的启动脚本为:
```python ```python
from visualdl.server import app from visualdl.server import app
app.run(logdir="./log") app.run("./log")
``` ```
在使用任意一种方式启动VisualDL面板后,打开浏览器访问VisualDL面板,即可查看日志的可视化结果,如图: 在使用任意一种方式启动VisualDL面板后,打开浏览器访问VisualDL面板,即可查看日志的可视化结果,如图:
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/3points_demo.png" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/3points_demo.png" width="60%"/>
</p> </p>
...@@ -181,7 +189,7 @@ app.run(logdir="./log") ...@@ -181,7 +189,7 @@ app.run(logdir="./log")
在启动VisualDL Board后,LogReader将不断增量的读取日志中数据并供前端调用展示,因此能够在训练中同步观测指标变化,如下图: 在启动VisualDL Board后,LogReader将不断增量的读取日志中数据并供前端调用展示,因此能够在训练中同步观测指标变化,如下图:
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/dynamic_display.gif" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/dynamic_display.gif" width="60%"/>
</p> </p>
...@@ -190,7 +198,7 @@ app.run(logdir="./log") ...@@ -190,7 +198,7 @@ app.run(logdir="./log")
只需在启动VisualDL Board的时将每个实验日志所在路径同时传入即可,每个实验中相同tag的指标将绘制在一张图中同步呈现,如下图: 只需在启动VisualDL Board的时将每个实验日志所在路径同时传入即可,每个实验中相同tag的指标将绘制在一张图中同步呈现,如下图:
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/multi_experiments.gif" width="100%"/> <img src="https://visualdl.bj.bcebos.com/images/multi_experiments.gif" width="100%"/>
</p> </p>
...@@ -198,7 +206,7 @@ app.run(logdir="./log") ...@@ -198,7 +206,7 @@ app.run(logdir="./log")
实时展示训练过程中的图像数据,用于观察不同训练阶段的图像变化,进而深入了解训练过程及效果。 实时展示训练过程中的图像数据,用于观察不同训练阶段的图像变化,进而深入了解训练过程及效果。
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/image-eye.gif" width="60%"/> <img src="https://visualdl.bj.bcebos.com/images/image-eye.gif" width="60%"/>
</p> </p>
...@@ -207,12 +215,12 @@ app.run(logdir="./log") ...@@ -207,12 +215,12 @@ app.run(logdir="./log")
将高维数据进行降维展示,目前支持T-SNE、PCA两种降维方式,用于深入分析高维数据间的关系,方便用户根据数据特征进行算法优化。 将高维数据进行降维展示,目前支持T-SNE、PCA两种降维方式,用于深入分析高维数据间的关系,方便用户根据数据特征进行算法优化。
<p align="center"> <p align="center">
<img src="http://visualdl.bj.bcebos.com/images/high_dimensional_test.png" width="100%"/> <img src="https://visualdl.bj.bcebos.com/images/high_dimensional_test.png" width="100%"/>
</p> </p>
## 开源贡献 ## 开源贡献
VisualDL 是由 [PaddlePaddle](http://www.paddlepaddle.org/)[ECharts](http://echarts.baidu.com/) 合作推出的开源项目。欢迎所有人使用,提意见以及贡献代码。 VisualDL 是由 [PaddlePaddle](https://www.paddlepaddle.org/)[ECharts](https://echarts.apache.org/) 合作推出的开源项目。欢迎所有人使用,提意见以及贡献代码。
## 更多细节 ## 更多细节
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<br /> <br />
<p align="center"> <p align="center">
<a href="https://travis-ci.org/PaddlePaddle/VisualDL"><img src="https://img.shields.io/travis/PaddlePaddle/VisualDL?style=flat-square" alt="Build Status" /></a> <a href="https://travis-ci.org/PaddlePaddle/VisualDL"><img src="https://img.shields.io/travis/PaddlePaddle/VisualDL/develop?style=flat-square" alt="Build Status" /></a>
<a href="https://github.com/PaddlePaddle/VisualDL"><img src="https://img.shields.io/github/languages/top/PaddlePaddle/VisualDL?style=flat-square" alt="GitHub top language" /></a> <a href="https://github.com/PaddlePaddle/VisualDL"><img src="https://img.shields.io/github/languages/top/PaddlePaddle/VisualDL?style=flat-square" alt="GitHub top language" /></a>
<a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square" alt="code style: prettier" /></a> <a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square" alt="code style: prettier" /></a>
<a href="https://lerna.js.org/"><img src="https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg?style=flat-square" alt="lerna"></a> <a href="https://lerna.js.org/"><img src="https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg?style=flat-square" alt="lerna"></a>
......
...@@ -25,7 +25,7 @@ import re ...@@ -25,7 +25,7 @@ import re
import webbrowser import webbrowser
import requests import requests
from visualdl.reader.reader import LogReader from visualdl.reader.reader import LogReader
from argparse import ArgumentParser
from visualdl.utils import update_util from visualdl.utils import update_util
from flask import (Flask, Response, redirect, request, send_file) from flask import (Flask, Response, redirect, request, send_file)
...@@ -33,6 +33,7 @@ from flask_babel import Babel ...@@ -33,6 +33,7 @@ from flask_babel import Babel
import visualdl.server import visualdl.server
from visualdl.server import lib from visualdl.server import lib
from visualdl.server.args import (ParseArgs, parse_args)
from visualdl.server.log import logger from visualdl.server.log import logger
from visualdl.server.template import Template from visualdl.server.template import Template
from visualdl.python.cache import MemCache from visualdl.python.cache import MemCache
...@@ -50,24 +51,6 @@ template_file_path = os.path.join(SERVER_DIR, "./dist") ...@@ -50,24 +51,6 @@ template_file_path = os.path.join(SERVER_DIR, "./dist")
mock_data_path = os.path.join(SERVER_DIR, "./mock_data/") mock_data_path = os.path.join(SERVER_DIR, "./mock_data/")
class ParseArgs(object):
def __init__(self,
logdir,
host="0.0.0.0",
port=8040,
cache_timeout=20,
language=None,
public_path=None,
api_only=False):
self.logdir = logdir
self.host = host
self.port = port
self.cache_timeout = cache_timeout
self.language = language
self.public_path = public_path
self.api_only = api_only
def try_call(function, *args, **kwargs): def try_call(function, *args, **kwargs):
res = lib.retry(error_retry_times, function, error_sleep_time, *args, res = lib.retry(error_retry_times, function, error_sleep_time, *args,
**kwargs) **kwargs)
...@@ -76,73 +59,12 @@ def try_call(function, *args, **kwargs): ...@@ -76,73 +59,12 @@ def try_call(function, *args, **kwargs):
return res return res
def parse_args():
"""
:return:
"""
parser = ArgumentParser(
description="VisualDL, a tool to visualize deep learning.")
parser.add_argument(
"-p",
"--port",
type=int,
default=8040,
action="store",
dest="port",
help="api service port")
parser.add_argument(
"-t",
"--host",
type=str,
default="0.0.0.0",
action="store",
help="api service ip")
parser.add_argument(
"--logdir",
required=True,
action="store",
dest="logdir",
nargs="+",
help="log file directory")
parser.add_argument(
"--cache_timeout",
action="store",
dest="cache_timeout",
type=float,
default=20,
help="memory cache timeout duration in seconds, default 20", )
parser.add_argument(
"-L",
"--language",
type=str,
action="store",
help="set the default language")
parser.add_argument(
"-P",
"--public-path",
type=str,
action="store",
default="/",
help="set public path"
)
parser.add_argument(
"--api-only",
action="store_true",
help="serve api only"
)
args = parser.parse_args()
if not args.logdir:
parser.print_help()
sys.exit(-1)
return args
# status, msg, data # status, msg, data
def gen_result(status, msg, data): def gen_result(status, msg, data):
""" """
:param status: :param status:
:param msg: :param msg:
:param data:
:return: :return:
""" """
result = dict() result = dict()
...@@ -153,7 +75,7 @@ def gen_result(status, msg, data): ...@@ -153,7 +75,7 @@ def gen_result(status, msg, data):
def create_app(args): def create_app(args):
app = Flask(__name__, static_url_path="") app = Flask('visualdl', static_folder=None)
# set static expires in a short time to reduce browser's memory usage. # set static expires in a short time to reduce browser's memory usage.
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 30 app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 30
...@@ -166,9 +88,12 @@ def create_app(args): ...@@ -166,9 +88,12 @@ def create_app(args):
cache_get = lib.cache_get(CACHE) cache_get = lib.cache_get(CACHE)
update_util.PbUpdater().start() update_util.PbUpdater().start()
public_path = args.public_path.rstrip('/') public_path = args.public_path
api_path = public_path + '/api' api_path = public_path + '/api'
if args.api_only:
logger.info('Running in API mode, only {}/* will be served.'.format(api_path))
@babel.localeselector @babel.localeselector
def get_locale(): def get_locale():
lang = args.language lang = args.language
...@@ -178,7 +103,7 @@ def create_app(args): ...@@ -178,7 +103,7 @@ def create_app(args):
if not args.api_only: if not args.api_only:
template = Template(os.path.join(server_path, template_file_path), PUBLIC_PATH=public_path.strip('/')) template = Template(os.path.join(server_path, template_file_path), PUBLIC_PATH=public_path.lstrip('/'))
@app.route("/") @app.route("/")
def base(): def base():
...@@ -191,7 +116,7 @@ def create_app(args): ...@@ -191,7 +116,7 @@ def create_app(args):
return send_file(icon) return send_file(icon)
return "file not found", 404 return "file not found", 404
@app.route(public_path + "/") @app.route(public_path + '/')
def index(): def index():
lang = get_locale() lang = get_locale()
if lang == default_language: if lang == default_language:
...@@ -340,52 +265,24 @@ def _open_browser(app, index_url): ...@@ -340,52 +265,24 @@ def _open_browser(app, index_url):
webbrowser.open(index_url) webbrowser.open(index_url)
def _run(logdir, def _run(**kwargs):
host="127.0.0.1", args = ParseArgs(**kwargs)
port=8080,
cache_timeout=20,
language=None,
public_path="/app",
api_only=False,
open_browser=False):
args = ParseArgs(
logdir=logdir,
host=host,
port=port,
cache_timeout=cache_timeout,
language=language,
public_path=public_path,
api_only=api_only)
logger.info(" port=" + str(args.port)) logger.info(" port=" + str(args.port))
app = create_app(args) app = create_app(args)
index_url = "http://" + host + ":" + str(port) + args.public_path if not args.api_only:
if open_browser: index_url = "http://" + args.host + ":" + str(args.port) + args.public_path
threading.Thread( if kwargs.get('open_browser', False):
target=_open_browser, kwargs={"app": app, threading.Thread(
"index_url": index_url}).start() target=_open_browser, kwargs={"app": app, "index_url": index_url}).start()
app.run(debug=False, host=args.host, port=args.port, threaded=False) app.run(debug=False, host=args.host, port=args.port, threaded=False)
def run(logdir, def run(logdir=None, **options):
host="127.0.0.1", kwargs = {
port=8040, 'logdir': logdir
cache_timeout=20,
language=None,
public_path="/app",
api_only=False,
open_browser=False):
kwarg = {
"logdir": logdir,
"host": host,
"port": port,
"cache_timeout": cache_timeout,
"language": language,
"public_path": public_path,
"api_only": api_only,
"open_browser": open_browser
} }
kwargs.update(options)
p = multiprocessing.Process(target=_run, kwargs=kwarg) p = multiprocessing.Process(target=_run, kwargs=kwargs)
p.start() p.start()
return p.pid return p.pid
......
# Copyright (c) 2017 VisualDL Authors. All Rights Reserve.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# =======================================================================
import sys
from argparse import ArgumentParser
from visualdl.server.log import logger
default_host = '127.0.0.1'
default_port = 8040
default_cache_timeout = 20
default_public_path = '/app'
class DefaultArgs(object):
def __init__(self, args):
self.logdir = args.get('logdir')
self.host = args.get('host', default_host)
self.port = args.get('port', default_port)
self.cache_timeout = args.get('cache_timeout', default_cache_timeout)
self.language = args.get('language')
self.public_path = args.get('public_path')
self.api_only = args.get('api_only', False)
self.open_browser = args.get('open_browser', False)
def validate_args(args):
# exit if no logdir specified
if not args.logdir or args.logdir is None:
logger.error('Log directory is not specified.')
sys.exit(-1)
# if not in API mode, public path cannot be set to root path
if not args.api_only and args.public_path == '/':
logger.error('Public path cannot be set to root path.')
sys.exit(-1)
# public path must start with `/`
if args.public_path is not None and not args.public_path.startswith('/'):
logger.error('Public path should always start with a `/`.')
sys.exit(-1)
def format_args(args):
validate_args(args)
# set default public path according to API mode option
if args.public_path is None:
args.public_path = '' if args.api_only else default_public_path
else:
args.public_path = args.public_path.rstrip('/')
# don't open browser in API mode
if args.api_only:
args.open_browser = False
return args
class ParseArgs(object):
def __init__(self, **kwargs):
args = format_args(DefaultArgs(kwargs))
self.logdir = args.logdir
self.host = args.host
self.port = args.port
self.cache_timeout = args.cache_timeout
self.language = args.language
self.public_path = args.public_path
self.api_only = args.api_only
self.open_browser = args.open_browser
def parse_args():
"""
:return:
"""
parser = ArgumentParser(description="VisualDL, a tool to visualize deep learning.")
parser.add_argument(
"--logdir",
required=True,
action="store",
dest="logdir",
nargs="+",
help="log file directory")
parser.add_argument(
"-p",
"--port",
type=int,
default=default_port,
action="store",
dest="port",
help="api service port")
parser.add_argument(
"-t",
"--host",
type=str,
default=default_host,
action="store",
help="api service ip")
parser.add_argument(
"--cache_timeout",
action="store",
dest="cache_timeout",
type=float,
default=default_cache_timeout,
help="memory cache timeout duration in seconds, default 20", )
parser.add_argument(
"-L",
"--language",
type=str,
action="store",
default=None,
help="set the default language")
parser.add_argument(
"-P",
"--public-path",
type=str,
action="store",
default=None,
help="set public path"
)
parser.add_argument(
"-A",
"--api-only",
action="store_true",
default=False,
help="serve api only"
)
args = parser.parse_args()
# print help if no logdir specified
if not args.logdir:
parser.print_help()
return format_args(args)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册