Skip to content

Commit 1cfb186

Browse files
manangoel99KiddoZhu
andcommitted
add documentation for W&B logger (#74)
Co-authored-by: Zhaocheng Zhu <healmysoul@163.com>
1 parent eeee191 commit 1cfb186

File tree

5 files changed

+74
-20
lines changed

5 files changed

+74
-20
lines changed

README.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ Quick Start
7878

7979
TorchDrug is designed for humans and focused on graph structured data.
8080
It enables easy implementation of graph operations in machine learning models.
81-
All the operations in TorchDrug are backed by [PyTorch] framework, and support GPU acceleration and auto differentiation.
81+
All the operations in TorchDrug are backed by [PyTorch] framework, and support GPU
82+
acceleration and auto differentiation.
8283

8384
```python
8485
from torchdrug import data
@@ -90,7 +91,8 @@ graph = graph.cuda()
9091
subgraph = graph.subgraph([2, 3, 4])
9192
```
9293

93-
Molecules are also supported in TorchDrug. You can get the desired molecule properties without any domain knowledge.
94+
Molecules are also supported in TorchDrug. You can get the desired molecule
95+
properties without any domain knowledge.
9496

9597
```python
9698
mol = data.Molecule.from_smiles("CCOC(=O)N", node_feature="default", edge_feature="default")
@@ -99,7 +101,8 @@ print(mol.atom_type)
99101
print(mol.to_scaffold())
100102
```
101103

102-
You may also register custom node, edge or graph attributes. They will be automatically processed during indexing operations.
104+
You may also register custom node, edge or graph attributes. They will be
105+
automatically processed during indexing operations.
103106

104107
```python
105108
with mol.edge():
@@ -108,8 +111,9 @@ sub_mol = mol.subgraph(mol.atom_type != td.NITROGEN)
108111
print(sub_mol.is_CC_bond)
109112
```
110113

111-
TorchDrug provides a wide range of common datasets and building blocks for drug discovery.
112-
With minimal code, you can apply standard models to solve your own problem.
114+
TorchDrug provides a wide range of common datasets and building blocks for drug
115+
discovery. With minimal code, you can apply standard models to solve your own
116+
problem.
113117

114118
```python
115119
import torch
@@ -144,6 +148,13 @@ solver = core.Engine(task, train_set, valid_set, test_set, optimizer, gpus=[0, 1
144148
solver = core.Engine(task, train_set, valid_set, test_set, optimizer, gpus=[0, 1, 2, 3, 0, 1, 2, 3])
145149
```
146150

151+
Experiments can be easily tracked and managed through [Weights & Biases platform].
152+
```python
153+
solver = core.Engine(task, train_set, valid_set, test_set, optimizer, logger="wandb")
154+
```
155+
156+
[Weights & Biases platform]: https://wandb.ai/
157+
147158
Contributing
148159
------------
149160

doc/source/quick_start.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ the script using ``python -m torch.distributed.launch --nproc_per_node=4``.
177177
solver = core.Engine(task, train_set, valid_set, test_set, optimizer,
178178
batch_size=256, gpus=[0, 1, 2, 3])
179179
180+
We may log the training and evaluation metrics to Weights & Biases platform for
181+
better experiment tracking in the browser.
182+
183+
.. code:: python
184+
185+
solver = core.Engine(task, train_set, valid_set, test_set, optimizer,
186+
batch_size=1024, logger="wandb")
187+
180188
Test the Model
181189
^^^^^^^^^^^^^^
182190

torchdrug/core/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
from .core import _MetaContainer, Registry, Configurable, make_configurable
22
from .engine import Engine
33
from .meter import Meter
4-
from .logger import LoggerBase, ConsoleLogger, WandbLogger
4+
from .logger import LoggerBase, LoggingLogger, WandbLogger
55

66
__all__ = [
77
"_MetaContainer", "Registry", "Configurable",
8-
"Engine", "Meter", "LoggerBase", "ConsoleLogger", "WandbLogger",
8+
"Engine", "Meter", "LoggerBase", "LoggingLogger", "WandbLogger",
99
]

torchdrug/core/engine.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,13 @@ class Engine(core.Configurable):
5353
gradient_interval (int, optional): perform a gradient update every n batches.
5454
This creates an equivalent batch size of ``batch_size * gradient_interval`` for optimization.
5555
num_worker (int, optional): number of CPU workers per GPU
56-
logger (str or core.LoggerBase, optional): logger type. Avaiable types are ``console`` and ``wandb``.
56+
logger (str or core.LoggerBase, optional): logger type or logger instance.
57+
Available types are ``logging`` and ``wandb``.
5758
log_interval (int, optional): log every n gradient updates
5859
"""
5960

6061
def __init__(self, task, train_set, valid_set, test_set, optimizer, scheduler=None, gpus=None, batch_size=1,
61-
gradient_interval=1, num_worker=0, logger="console", log_interval=100):
62+
gradient_interval=1, num_worker=0, logger="logging", log_interval=100):
6263
self.rank = comm.get_rank()
6364
self.world_size = comm.get_world_size()
6465
self.gpus = gpus
@@ -107,10 +108,12 @@ def __init__(self, task, train_set, valid_set, test_set, optimizer, scheduler=No
107108
self.scheduler = scheduler
108109

109110
if isinstance(logger, str):
110-
if logger == "console":
111-
logger = core.ConsoleLogger()
111+
if logger == "logging":
112+
logger = core.LoggingLogger()
112113
elif logger == "wandb":
113114
logger = core.WandbLogger(project=task.__class__.__name__)
115+
else:
116+
raise ValueError("Unknown logger `%s`" % logger)
114117
self.meter = core.Meter(log_interval=log_interval, silent=self.rank > 0, logger=logger)
115118
self.meter.log_config(self.config_dict())
116119

torchdrug/core/logger.py

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import pprint
22
import logging
3+
import warnings
34

45
from torchdrug.core import Registry as R
56
from torchdrug.utils import pretty
@@ -34,10 +35,23 @@ def log_config(self, config):
3435
raise NotImplementedError
3536

3637

37-
@R.register("core.ConsoleLogger")
38-
class ConsoleLogger(LoggerBase):
38+
@R.register("core.LoggingLogger")
39+
class LoggingLogger(LoggerBase):
3940
"""
40-
Logger for console output.
41+
Log outputs with the builtin logging module of Python.
42+
43+
By default, the logs will be printed to the console. To additionally log outputs to a file,
44+
add the following lines in the beginning of your code.
45+
46+
.. code-block: python
47+
48+
import logging
49+
50+
format = logging.Formatter("%(asctime)-10s %(message)s", "%H:%M:%S")
51+
handler = logging.FileHandler("log.txt")
52+
handler.setFormatter(format)
53+
logger = logging.getLogger("")
54+
logger.addHandler(handler)
4155
"""
4256

4357
def __init__(self):
@@ -60,14 +74,25 @@ def log_config(self, config):
6074

6175

6276
@R.register("core.WandbLogger")
63-
class WandbLogger(ConsoleLogger):
77+
class WandbLogger(LoggingLogger):
6478
"""
65-
Logger for wandb and console outputs.
79+
Log outputs with `Weights and Biases`_ and track the experiment progress.
80+
81+
Note this class also output logs with the builtin logging module.
82+
83+
See `wandb.init`_ for more details.
84+
85+
.. _Weights and Biases:
86+
https://docs.wandb.ai
87+
88+
.. _wandb.init:
89+
https://docs.wandb.ai/ref/python/init
6690
6791
Parameters:
68-
project (str, optional): name of the project in wandb
69-
name (str, optional): name for this run in wandb
70-
dir (str, optional): path to save wandb outputs. By default, outputs are stored in ``./wandb``.
92+
project (str, optional): name of the project
93+
name (str, optional): name of this run
94+
dir (str, optional): path to store meta data. Default is `./wandb`.
95+
kwargs: keyword arguments for `wandb.init`_
7196
"""
7297

7398
def __init__(self, project=None, name=None, dir=None, **kwargs):
@@ -77,7 +102,14 @@ def __init__(self, project=None, name=None, dir=None, **kwargs):
77102
except ModuleNotFoundError:
78103
raise ModuleNotFoundError("Wandb is not found. Please install it with `pip install wandb`")
79104

80-
self.run = wandb.init(project=project, name=name, dir=dir, reinit=True, **kwargs)
105+
if wandb.run is not None:
106+
warnings.warn(
107+
"There is a wandb run already in progress and newly created instances of `WandbLogger` will reuse"
108+
" this run. If this is not desired, call `wandb.finish()` or `WandbLogger.finish()` before instantiating `WandbLogger`."
109+
)
110+
self.run = wandb.run
111+
else:
112+
self.run = wandb.init(project=project, name=name, dir=dir, **kwargs)
81113

82114
self.run.define_metric("train/batch/*", step_metric="batch", summary="none")
83115
for split in ["train", "valid", "test"]:

0 commit comments

Comments
 (0)