Skip to content

Commit

Permalink
Merge branch 'dygraph' into v3_rec_introduc
Browse files Browse the repository at this point in the history
  • Loading branch information
tink2123 authored May 6, 2022
2 parents 12b6e57 + 29f5ef4 commit 8cc0e8b
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 25 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ PaddleOCR aims to create multilingual, awesome, leading, and practical OCR tools

PaddleOCR support a variety of cutting-edge algorithms related to OCR, and developed industrial featured models/solution [PP-OCR](./doc/doc_en/ppocr_introduction_en.md) and [PP-Structure](./ppstructure/README.md) on this basis, and get through the whole process of data production, model training, compression, inference and deployment.

PaddleOCR also supports metric and model logging during training to [VisualDL](https://www.paddlepaddle.org.cn/documentation/docs/en/guides/03_VisualDL/visualdl_usage_en.html) and [Weights & Biases](https://docs.wandb.ai/).

![](./doc/features_en.png)

> It is recommended to start with the “quick experience” in the document tutorial
Expand Down
2 changes: 1 addition & 1 deletion configs/rec/PP-OCRv3/ch_PP-OCRv3_rec_distillation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ Loss:
key: head_out
multi_head: True
- DistillationSARLoss:
weight: 0.5
weight: 1.0
model_name_list: ["Student", "Teacher"]
key: head_out
multi_head: True
Expand Down
1 change: 1 addition & 0 deletions doc/doc_ch/models_list.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ PaddleOCR提供的可下载模型包括`推理模型`、`训练模型`、`预训
| devanagari_PP-OCRv3_rec | ppocr/utils/dict/devanagari_dict.txt |梵文字母 | [devanagari_PP-OCRv3_rec.yml](../../configs/rec/PP-OCRv3/multi_language/devanagari_PP-OCRv3_rec.yml) |9.6M|[推理模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/multilingual/devanagari_PP-OCRv3_rec_infer.tar) / [训练模型](https://paddleocr.bj.bcebos.com/dygraph_v2.0/multilingual/devanagari_PP-OCRv3_rec_train.tar) |



更多支持语种请参考: [多语言模型](./multi_languages.md)


Expand Down
16 changes: 14 additions & 2 deletions doc/doc_en/config_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Take rec_chinese_lite_train_v2.0.yml as an example
| pretrained_model | Set the path of the pre-trained model | ./pretrain_models/CRNN/best_accuracy | \ |
| checkpoints | set model parameter path | None | Used to load parameters after interruption to continue training|
| use_visualdl | Set whether to enable visualdl for visual log display | False | [Tutorial](https://www.paddlepaddle.org.cn/paddle/visualdl) |
| use_wandb | Set whether to enable W&B for visual log display | False | [Documentation](https://docs.wandb.ai/)
| infer_img | Set inference image path or folder path | ./infer_img | \||
| character_dict_path | Set dictionary path | ./ppocr/utils/ppocr_keys_v1.txt | If the character_dict_path is None, model can only recognize number and lower letters |
| max_text_length | Set the maximum length of text | 25 | \ |
Expand Down Expand Up @@ -66,7 +67,7 @@ In PaddleOCR, the network is divided into four stages: Transform, Backbone, Neck
| :---------------------: | :---------------------: | :--------------: | :--------------------: |
| model_type | Network Type | rec | Currently support`rec`,`det`,`cls` |
| algorithm | Model name | CRNN | See [algorithm_overview](./algorithm_overview_en.md) for the support list |
| **Transform** | Set the transformation method | - | Currently only recognition algorithms are supported, see [ppocr/modeling/transforms](../../ppocr/modeling/transforms) for details |
| **Transform** | Set the transformation method | - | Currently only recognition algorithms are supported, see [ppocr/modeling/transform](../../ppocr/modeling/transforms) for details |
| name | Transformation class name | TPS | Currently supports `TPS` |
| num_fiducial | Number of TPS control points | 20 | Ten on the top and bottom |
| loc_lr | Localization network learning rate | 0.1 | \ |
Expand Down Expand Up @@ -130,6 +131,17 @@ In PaddleOCR, the network is divided into four stages: Transform, Backbone, Neck
| drop_last | Whether to discard the last incomplete mini-batch because the number of samples in the data set cannot be divisible by batch_size | True | \ |
| num_workers | The number of sub-processes used to load data, if it is 0, the sub-process is not started, and the data is loaded in the main process | 8 | \ |

### Weights & Biases ([W&B](../../ppocr/utils/loggers/wandb_logger.py))
| Parameter | Use | Defaults | Note |
| :---------------------: | :---------------------: | :--------------: | :--------------------: |
| project | Project to which the run is to be logged | uncategorized | \
| name | Alias/Name of the run | Randomly generated by wandb | \
| id | ID of the run | Randomly generated by wandb | \
| entity | User or team to which the run is being logged | The logged in user | \
| save_dir | local directory in which all the models and other data is saved | wandb | \
| config | model configuration | None | \


<a name="3-multilingual-config-file-generation"></a>

## 3. Multilingual Config File Generation
Expand Down Expand Up @@ -233,4 +245,4 @@ For more supported languages, please refer to : [Multi-language model](https://g
The multi-language model training method is the same as the Chinese model. The training data set is 100w synthetic data. A small amount of fonts and test data can be downloaded using the following two methods.
* [Baidu Netdisk](https://pan.baidu.com/s/1bS_u207Rm7YbY33wOECKDA),Extraction code:frgi.
* [Google drive](https://drive.google.com/file/d/18cSWX7wXSy4G0tbKJ0d9PuIaiwRLHpjA/view)
* [Google drive](https://drive.google.com/file/d/18cSWX7wXSy4G0tbKJ0d9PuIaiwRLHpjA/view)
61 changes: 61 additions & 0 deletions doc/doc_en/logging_en.md
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.
Binary file added doc/imgs_en/wandb_metrics.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/imgs_en/wandb_models.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions ppocr/utils/loggers/__init__.py
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
15 changes: 15 additions & 0 deletions ppocr/utils/loggers/base_logger.py
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
18 changes: 18 additions & 0 deletions ppocr/utils/loggers/loggers.py
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()
21 changes: 21 additions & 0 deletions ppocr/utils/loggers/vdl_logger.py
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()
78 changes: 78 additions & 0 deletions ppocr/utils/loggers/wandb_logger.py
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()
Loading

0 comments on commit 8cc0e8b

Please sign in to comment.