forked from PaddlePaddle/PaddleOCR
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'dygraph' into v3_rec_introduc
- Loading branch information
Showing
13 changed files
with
259 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
## Logging metrics and models | ||
|
||
PaddleOCR comes with two metric logging tools integrated directly into the training API: [VisualDL](https://readthedocs.org/projects/visualdl/) and [Weights & Biases](https://docs.wandb.ai/). | ||
|
||
### VisualDL | ||
VisualDL is a visualization analysis tool of PaddlePaddle. The integration allows all training metrics to be logged to a VisualDL dashboard. To use it, add the following line to the `Global` section of the config yaml file - | ||
|
||
``` | ||
Global: | ||
use_visualdl: True | ||
``` | ||
|
||
To see the visualizations run the following command in your terminal | ||
|
||
```shell | ||
visualdl --logdir <save_model_dir> | ||
``` | ||
|
||
Now open `localhost:8040` in your browser of choice! | ||
|
||
### Weights & Biases | ||
W&B is a MLOps tool that can be used for experiment tracking, dataset/model versioning, visualizing results and collaborating with colleagues. A W&B logger is integrated directly into PaddleOCR and to use it, first you need to install the `wandb` sdk and login to your wandb account. | ||
|
||
```shell | ||
pip install wandb | ||
wandb login | ||
``` | ||
|
||
If you do not have a wandb account, you can make one [here](https://wandb.ai/site). | ||
|
||
To visualize and track your model training add the following flag to your config yaml file under the `Global` section - | ||
|
||
``` | ||
Global: | ||
use_wandb: True | ||
``` | ||
|
||
To add more arguments to the `WandbLogger` listed [here](./config_en.md) add the header `wandb` to the yaml file and add the arguments under it - | ||
|
||
``` | ||
wandb: | ||
project: my_project | ||
entity: my_team | ||
``` | ||
|
||
These config variables from the yaml file are used to instantiate the `WandbLogger` object with the project name, entity name (the logged in user by default), directory to store metadata (`./wandb` by default) and more. During the training process, the `log_metrics` function is called to log training and evaluation metrics at the training and evaluation steps respectively from the rank 0 process only. | ||
|
||
At every model saving step, the WandbLogger, logs the model using the `log_model` function along with relavant metadata and tags showing the epoch in which the model is saved, the model is best or not and so on. | ||
|
||
All the logging mentioned above is integrated into the `program.train` function and will generate dashboards like this - | ||
|
||
![W&B Dashboard](../imgs_en/wandb_metrics.png) | ||
|
||
![W&B Models](../imgs_en/wandb_models.png) | ||
|
||
For more advanced usage to log images, audios, videos or any other form of data, you can use `WandbLogger().run.log`. More examples on how to log different kinds of data are available [here](https://docs.wandb.ai/examples). | ||
|
||
To view the dashboard, the link to the dashboard is printed to the console at the beginning and end of every training job and you can also access it by logging into your W&B account on your browser. | ||
|
||
### Using Multiple Loggers | ||
Both VisualDL and W&B can also be used simultaneously by just setting both the aforementioned flags to True. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
from .vdl_logger import VDLLogger | ||
from .wandb_logger import WandbLogger | ||
from .loggers import Loggers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import os | ||
from abc import ABC, abstractmethod | ||
|
||
class BaseLogger(ABC): | ||
def __init__(self, save_dir): | ||
self.save_dir = save_dir | ||
os.makedirs(self.save_dir, exist_ok=True) | ||
|
||
@abstractmethod | ||
def log_metrics(self, metrics, prefix=None): | ||
pass | ||
|
||
@abstractmethod | ||
def close(self): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
from .wandb_logger import WandbLogger | ||
|
||
class Loggers(object): | ||
def __init__(self, loggers): | ||
super().__init__() | ||
self.loggers = loggers | ||
|
||
def log_metrics(self, metrics, prefix=None, step=None): | ||
for logger in self.loggers: | ||
logger.log_metrics(metrics, prefix=prefix, step=step) | ||
|
||
def log_model(self, is_best, prefix, metadata=None): | ||
for logger in self.loggers: | ||
logger.log_model(is_best=is_best, prefix=prefix, metadata=metadata) | ||
|
||
def close(self): | ||
for logger in self.loggers: | ||
logger.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
from .base_logger import BaseLogger | ||
from visualdl import LogWriter | ||
|
||
class VDLLogger(BaseLogger): | ||
def __init__(self, save_dir): | ||
super().__init__(save_dir) | ||
self.vdl_writer = LogWriter(logdir=save_dir) | ||
|
||
def log_metrics(self, metrics, prefix=None, step=None): | ||
if not prefix: | ||
prefix = "" | ||
updated_metrics = {prefix + "/" + k: v for k, v in metrics.items()} | ||
|
||
for k, v in updated_metrics.items(): | ||
self.vdl_writer.add_scalar(k, v, step) | ||
|
||
def log_model(self, is_best, prefix, metadata=None): | ||
pass | ||
|
||
def close(self): | ||
self.vdl_writer.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import os | ||
from .base_logger import BaseLogger | ||
|
||
class WandbLogger(BaseLogger): | ||
def __init__(self, | ||
project=None, | ||
name=None, | ||
id=None, | ||
entity=None, | ||
save_dir=None, | ||
config=None, | ||
**kwargs): | ||
try: | ||
import wandb | ||
self.wandb = wandb | ||
except ModuleNotFoundError: | ||
raise ModuleNotFoundError( | ||
"Please install wandb using `pip install wandb`" | ||
) | ||
|
||
self.project = project | ||
self.name = name | ||
self.id = id | ||
self.save_dir = save_dir | ||
self.config = config | ||
self.kwargs = kwargs | ||
self.entity = entity | ||
self._run = None | ||
self._wandb_init = dict( | ||
project=self.project, | ||
name=self.name, | ||
id=self.id, | ||
entity=self.entity, | ||
dir=self.save_dir, | ||
resume="allow" | ||
) | ||
self._wandb_init.update(**kwargs) | ||
|
||
_ = self.run | ||
|
||
if self.config: | ||
self.run.config.update(self.config) | ||
|
||
@property | ||
def run(self): | ||
if self._run is None: | ||
if self.wandb.run is not None: | ||
logger.info( | ||
"There is a wandb run already in progress " | ||
"and newly created instances of `WandbLogger` will reuse" | ||
" this run. If this is not desired, call `wandb.finish()`" | ||
"before instantiating `WandbLogger`." | ||
) | ||
self._run = self.wandb.run | ||
else: | ||
self._run = self.wandb.init(**self._wandb_init) | ||
return self._run | ||
|
||
def log_metrics(self, metrics, prefix=None, step=None): | ||
if not prefix: | ||
prefix = "" | ||
updated_metrics = {prefix.lower() + "/" + k: v for k, v in metrics.items()} | ||
|
||
self.run.log(updated_metrics, step=step) | ||
|
||
def log_model(self, is_best, prefix, metadata=None): | ||
model_path = os.path.join(self.save_dir, prefix + '.pdparams') | ||
artifact = self.wandb.Artifact('model-{}'.format(self.run.id), type='model', metadata=metadata) | ||
artifact.add_file(model_path, name="model_ckpt.pdparams") | ||
|
||
aliases = [prefix] | ||
if is_best: | ||
aliases.append("best") | ||
|
||
self.run.log_artifact(artifact, aliases=aliases) | ||
|
||
def close(self): | ||
self.run.finish() |
Oops, something went wrong.