From 8bbedc2371a88ba445f18fcd424d05215a381fd8 Mon Sep 17 00:00:00 2001 From: qingqing01 Date: Wed, 25 Nov 2020 21:06:06 +0800 Subject: [PATCH] Fix doc format for callbacks, metrics and Model (#28638) * Fix doc format for callbacks, metrics and Model * Fix code sample and doc --- .../paddle/fluid/dataloader/batch_sampler.py | 4 +- python/paddle/hapi/callbacks.py | 36 +- python/paddle/hapi/model.py | 110 +++--- python/paddle/metric/metrics.py | 362 +++++++++--------- 4 files changed, 261 insertions(+), 251 deletions(-) diff --git a/python/paddle/fluid/dataloader/batch_sampler.py b/python/paddle/fluid/dataloader/batch_sampler.py index 085dcf6592..3debeecfe4 100644 --- a/python/paddle/fluid/dataloader/batch_sampler.py +++ b/python/paddle/fluid/dataloader/batch_sampler.py @@ -180,11 +180,11 @@ class DistributedBatchSampler(BatchSampler): batch_size(int): sample indice number in a mini-batch indices. num_replicas(int, optional): porcess number in distributed training. If :attr:`num_replicas` is None, :attr:`num_replicas` will be - retrieved from :code:`paddle.fluid.dygraph.parallel.ParallenEnv`. + retrieved from :code:`paddle.distributed.ParallenEnv`. Default None. rank(int, optional): the rank of the current process among :attr:`num_replicas` processes. If :attr:`rank` is None, :attr:`rank` is retrieved from - :code:`paddle.fluid.dygraph.parallel.ParallenEnv`. Default None. + :code:`paddle.distributed.ParallenEnv`. Default None. shuffle(bool): whther to shuffle indices order before genrating batch indices. Default False. drop_last(bool): whether drop the last incomplete batch dataset size diff --git a/python/paddle/hapi/callbacks.py b/python/paddle/hapi/callbacks.py index ca94b4e3ef..fe7d96a84a 100644 --- a/python/paddle/hapi/callbacks.py +++ b/python/paddle/hapi/callbacks.py @@ -161,10 +161,8 @@ class Callback(object): - 'batch_size': an integer. Number of samples per batch. - 'epochs': an integer. Number of epochs. - 'steps': an integer. Number of steps of one epoch. - - 'verbose': an integer. Verbose mode is 0, 1 or 2. - 0 = silent, 1 = progress bar, 2 = one line per epoch. - - 'metrics': a list of str. Names of metrics, including 'loss' - and the names of paddle.metric.Metric. + - 'verbose': an integer. Verbose mode is 0, 1 or 2. 0 = silent, 1 = progress bar, 2 = one line per epoch. + - 'metrics': a list of str. Names of metrics, including 'loss' and the names of paddle.metric.Metric. """ self.params = params @@ -298,18 +296,21 @@ class Callback(object): class ProgBarLogger(Callback): - """Logger callback function + """ + Logger callback function. + Args: - log_freq (int): The frequency, in number of steps, the logs such as `loss`, - `metrics` are printed. Default: 1. + log_freq (int): The frequency, in number of steps, + the logs such as loss, metrics are printed. Default: 1. verbose (int): The verbosity mode, should be 0, 1, or 2. - 0 = silent, 1 = progress bar, 2 = one line per epoch. Default: 2. + 0 = silent, 1 = progress bar, 2 = one line per epoch. Default: 2. Examples: .. code-block:: python import paddle import paddle.vision.transforms as T + from paddle.vision.datasets import MNIST from paddle.static import InputSpec inputs = [InputSpec([-1, 1, 28, 28], 'float32', 'image')] @@ -319,7 +320,7 @@ class ProgBarLogger(Callback): T.Transpose(), T.Normalize([127.5], [127.5]) ]) - train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform) + train_dataset = MNIST(mode='train', transform=transform) lenet = paddle.vision.LeNet() model = paddle.Model(lenet, @@ -439,18 +440,21 @@ class ProgBarLogger(Callback): class ModelCheckpoint(Callback): - """Model checkpoint callback function + """ + Model checkpoint callback function. + Args: - save_freq(int): The frequency, in number of epochs, the model checkpoint - are saved. Default: 1. + save_freq(int): The frequency, in number of epochs, the model checkpoint + are saved. Default: 1. save_dir(str|None): The directory to save checkpoint during training. - If None, will not save checkpoint. Default: None. + If None, will not save checkpoint. Default: None. Examples: .. code-block:: python import paddle import paddle.vision.transforms as T + from paddle.vision.datasets import MNIST from paddle.static import InputSpec inputs = [InputSpec([-1, 1, 28, 28], 'float32', 'image')] @@ -460,7 +464,7 @@ class ModelCheckpoint(Callback): T.Transpose(), T.Normalize([127.5], [127.5]) ]) - train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform) + train_dataset = MNIST(mode='train', transform=transform) lenet = paddle.vision.LeNet() model = paddle.Model(lenet, @@ -740,7 +744,9 @@ class EarlyStopping(Callback): class VisualDL(Callback): - """VisualDL callback function + """ + VisualDL callback function. + Args: log_dir (str): The directory to save visualdl log file. diff --git a/python/paddle/hapi/model.py b/python/paddle/hapi/model.py index ea9dac09e5..2ebdbe64b5 100644 --- a/python/paddle/hapi/model.py +++ b/python/paddle/hapi/model.py @@ -808,7 +808,7 @@ class Model(object): """ An Model object is network with training and inference features. Dynamic graph and static graph are supported at the same time, - switched by `paddle.disable_static()`. The usage is as follows. + switched by `paddle.enable_static()`. The usage is as follows. But note, the switching between dynamic and static should be before instantiating a Model. The input description, i.e, paddle.static.InputSpec, must be required for static graph. @@ -829,36 +829,36 @@ class Model(object): Examples: .. code-block:: python - import paddle - import paddle.nn as nn - import paddle.vision.transforms as T - from paddle.static import InputSpec - - device = paddle.set_device('cpu') # or 'gpu' - - net = nn.Sequential( - nn.Flatten(1), - nn.Linear(784, 200), - nn.Tanh(), - nn.Linear(200, 10)) - - # inputs and labels are not required for dynamic graph. - input = InputSpec([None, 784], 'float32', 'x') - label = InputSpec([None, 1], 'int64', 'label') - - model = paddle.Model(net, input, label) - optim = paddle.optimizer.SGD(learning_rate=1e-3, - parameters=model.parameters()) - model.prepare(optim, - paddle.nn.CrossEntropyLoss(), - paddle.metric.Accuracy()) - - transform = T.Compose([ - T.Transpose(), - T.Normalize([127.5], [127.5]) - ]) - data = paddle.vision.datasets.MNIST(mode='train', transform=transform) - model.fit(data, epochs=2, batch_size=32, verbose=1) + import paddle + import paddle.nn as nn + import paddle.vision.transforms as T + from paddle.static import InputSpec + + device = paddle.set_device('cpu') # or 'gpu' + + net = nn.Sequential( + nn.Flatten(1), + nn.Linear(784, 200), + nn.Tanh(), + nn.Linear(200, 10)) + + # inputs and labels are not required for dynamic graph. + input = InputSpec([None, 784], 'float32', 'x') + label = InputSpec([None, 1], 'int64', 'label') + + model = paddle.Model(net, input, label) + optim = paddle.optimizer.SGD(learning_rate=1e-3, + parameters=model.parameters()) + model.prepare(optim, + paddle.nn.CrossEntropyLoss(), + paddle.metric.Accuracy()) + + transform = T.Compose([ + T.Transpose(), + T.Normalize([127.5], [127.5]) + ]) + data = paddle.vision.datasets.MNIST(mode='train', transform=transform) + model.fit(data, epochs=2, batch_size=32, verbose=1) """ def __init__(self, network, inputs=None, labels=None): @@ -1052,9 +1052,9 @@ class Model(object): If `training` is set to False, only inference model will be saved. Args: - path (str): The file prefix to save model. The format is - 'dirname/file_prefix' or 'file_prefix'. if empty str. A exception - will be raised. + path (str): The file prefix to save model. The format + is 'dirname/file_prefix' or 'file_prefix'. if empty str. + A exception will be raised. training (bool, optional): Whether to save for training. If not, save for inference only. Default: True. @@ -1084,9 +1084,9 @@ class Model(object): return self.net(x) dynamic = True # False - device = paddle.set_device('cpu') # if use static graph, do not set - paddle.disable_static(device) if dynamic else None + if not dynamic: + paddle.enable_static() input = InputSpec([None, 784], 'float32', 'x') label = InputSpec([None, 1], 'int64', 'label') @@ -1361,18 +1361,19 @@ class Model(object): import paddle import paddle.vision.transforms as T + from paddle.vision.datasets import MNIST from paddle.static import InputSpec dynamic = True - device = paddle.set_device('cpu') # or 'gpu' - paddle.disable_static(device) if dynamic else None - + if not dynamic: + paddle.enable_static() + transform = T.Compose([ T.Transpose(), T.Normalize([127.5], [127.5]) ]) - train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform) - val_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform) + train_dataset = MNIST(mode='train', transform=transform) + val_dataset = MNIST(mode='test', transform=transform) input = InputSpec([None, 1, 28, 28], 'float32', 'image') label = InputSpec([None, 1], 'int64', 'label') @@ -1399,22 +1400,23 @@ class Model(object): import paddle import paddle.vision.transforms as T + from paddle.vision.datasets import MNIST from paddle.static import InputSpec dynamic = True - device = paddle.set_device('cpu') # or 'gpu' - paddle.disable_static(device) if dynamic else None + if not dynamic: + paddle.enable_static() transform = T.Compose([ T.Transpose(), T.Normalize([127.5], [127.5]) ]) - train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=transform) + train_dataset = MNIST(mode='train', transform=transform) train_loader = paddle.io.DataLoader(train_dataset, - places=device, batch_size=64) - val_dataset = paddle.vision.datasets.MNIST(mode='test', transform=transform) + batch_size=64) + val_dataset = MNIST(mode='test', transform=transform) val_loader = paddle.io.DataLoader(val_dataset, - places=device, batch_size=64) + batch_size=64) input = InputSpec([None, 1, 28, 28], 'float32', 'image') label = InputSpec([None, 1], 'int64', 'label') @@ -1540,7 +1542,8 @@ class Model(object): value is a scalar or numpy.array. Examples: - .. code-block:: python + + .. code-block:: python import paddle import paddle.vision.transforms as T @@ -1559,14 +1562,6 @@ class Model(object): model.prepare(metrics=paddle.metric.Accuracy()) result = model.evaluate(val_dataset, batch_size=64) print(result) - - # imperative mode - paddle.disable_static() - model = paddle.Model(paddle.vision.models.LeNet(), input, label) - model.prepare(metrics=paddle.metric.Accuracy()) - result = model.evaluate(val_dataset, batch_size=64) - print(result) - """ if eval_data is not None and isinstance(eval_data, Dataset): @@ -1637,7 +1632,8 @@ class Model(object): list: output of models. Examples: - .. code-block:: python + + .. code-block:: python import numpy as np import paddle diff --git a/python/paddle/metric/metrics.py b/python/paddle/metric/metrics.py index f1808efe86..ac9f048bab 100644 --- a/python/paddle/metric/metrics.py +++ b/python/paddle/metric/metrics.py @@ -38,11 +38,13 @@ class Metric(object): r""" Base class for metric, encapsulates metric logic and APIs Usage: - - m = SomeMetric() - for prediction, label in ...: - m.update(prediction, label) - m.accumulate() + + .. code-block:: text + + m = SomeMetric() + for prediction, label in ...: + m.update(prediction, label) + m.accumulate() Advanced usage for :code:`compute`: @@ -52,6 +54,9 @@ class Metric(object): call :code:`update` with states in NumPy format. Metric calculated as follows (operations in Model and Metric are indicated with curly brackets, while data nodes not): + + .. code-block:: text + inputs & labels || ------------------ | || {model} || @@ -67,8 +72,9 @@ class Metric(object): metric states(numpy) || numpy data | || {Metric.update} \/ ------------------ + Examples: - + For :code:`Accuracy` metric, which takes :code:`pred` and :code:`label` as inputs, we can calculate the correct prediction matrix between :code:`pred` and :code:`label` in :code:`compute`. @@ -79,29 +85,31 @@ class Metric(object): prediction of each sample like follows, while the correct prediction matrix shape is [N, 5]. - .. code-block:: python - def compute(pred, label): - # sort prediction and slice the top-5 scores - pred = paddle.argsort(pred, descending=True)[:, :5] - # calculate whether the predictions are correct - correct = pred == label - return paddle.cast(correct, dtype='float32') + .. code-block:: text + + def compute(pred, label): + # sort prediction and slice the top-5 scores + pred = paddle.argsort(pred, descending=True)[:, :5] + # calculate whether the predictions are correct + correct = pred == label + return paddle.cast(correct, dtype='float32') With the :code:`compute`, we split some calculations to OPs (which may run on GPU devices, will be faster), and only fetch 1 tensor with shape as [N, 5] instead of 2 tensors with shapes as [N, 10] and [N, 1]. :code:`update` can be define as follows: - .. code-block:: python - def update(self, correct): - accs = [] - for i, k in enumerate(self.topk): - num_corrects = correct[:, :k].sum() - num_samples = len(correct) - accs.append(float(num_corrects) / num_samples) - self.total[i] += num_corrects - self.count[i] += num_samples - return accs + .. code-block:: text + + def update(self, correct): + accs = [] + for i, k in enumerate(self.topk): + num_corrects = correct[:, :k].sum() + num_samples = len(correct) + accs.append(float(num_corrects) / num_samples) + self.total[i] += num_corrects + self.count[i] += num_samples + return accs """ def __init__(self): @@ -183,43 +191,46 @@ class Accuracy(Metric): .. code-block:: python - import numpy as np - import paddle + import numpy as np + import paddle - x = paddle.to_tensor(np.array([ - [0.1, 0.2, 0.3, 0.4], - [0.1, 0.4, 0.3, 0.2], - [0.1, 0.2, 0.4, 0.3], - [0.1, 0.2, 0.3, 0.4]])) - y = paddle.to_tensor(np.array([[0], [1], [2], [3]])) + x = paddle.to_tensor(np.array([ + [0.1, 0.2, 0.3, 0.4], + [0.1, 0.4, 0.3, 0.2], + [0.1, 0.2, 0.4, 0.3], + [0.1, 0.2, 0.3, 0.4]])) + y = paddle.to_tensor(np.array([[0], [1], [2], [3]])) - m = paddle.metric.Accuracy() - correct = m.compute(x, y) - m.update(correct) - res = m.accumulate() - print(res) # 0.75 + m = paddle.metric.Accuracy() + correct = m.compute(x, y) + m.update(correct) + res = m.accumulate() + print(res) # 0.75 Example with Model API: .. code-block:: python - import paddle - from paddle.static import InputSpec - - input = InputSpec([None, 1, 28, 28], 'float32', 'image') - label = InputSpec([None, 1], 'int64', 'label') - train_dataset = paddle.vision.datasets.MNIST(mode='train') - - model = paddle.Model(paddle.vision.LeNet(), input, label) - optim = paddle.optimizer.Adam( - learning_rate=0.001, parameters=model.parameters()) - model.prepare( - optim, - loss=paddle.nn.CrossEntropyLoss(), - metrics=paddle.metric.Accuracy()) - - model.fit(train_dataset, batch_size=64) + import paddle + from paddle.static import InputSpec + import paddle.vision.transforms as T + from paddle.vision.datasets import MNIST + + input = InputSpec([None, 1, 28, 28], 'float32', 'image') + label = InputSpec([None, 1], 'int64', 'label') + transform = T.Compose([T.Transpose(), T.Normalize([127.5], [127.5])]) + train_dataset = MNIST(mode='train', transform=transform) + + model = paddle.Model(paddle.vision.LeNet(), input, label) + optim = paddle.optimizer.Adam( + learning_rate=0.001, parameters=model.parameters()) + model.prepare( + optim, + loss=paddle.nn.CrossEntropyLoss(), + metrics=paddle.metric.Accuracy()) + + model.fit(train_dataset, batch_size=64) """ @@ -321,54 +332,53 @@ class Precision(Metric): .. code-block:: python - import numpy as np - import paddle + import numpy as np + import paddle - x = np.array([0.1, 0.5, 0.6, 0.7]) - y = np.array([0, 1, 1, 1]) + x = np.array([0.1, 0.5, 0.6, 0.7]) + y = np.array([0, 1, 1, 1]) - m = paddle.metric.Precision() - m.update(x, y) - res = m.accumulate() - print(res) # 1.0 + m = paddle.metric.Precision() + m.update(x, y) + res = m.accumulate() + print(res) # 1.0 Example with Model API: .. code-block:: python - import numpy as np - - import paddle - import paddle.nn as nn - - class Data(paddle.io.Dataset): - def __init__(self): - super(Data, self).__init__() - self.n = 1024 - self.x = np.random.randn(self.n, 10).astype('float32') - self.y = np.random.randint(2, size=(self.n, 1)).astype('float32') - - def __getitem__(self, idx): - return self.x[idx], self.y[idx] - - def __len__(self): - return self.n + import numpy as np + + import paddle + import paddle.nn as nn + + class Data(paddle.io.Dataset): + def __init__(self): + super(Data, self).__init__() + self.n = 1024 + self.x = np.random.randn(self.n, 10).astype('float32') + self.y = np.random.randint(2, size=(self.n, 1)).astype('float32') + + def __getitem__(self, idx): + return self.x[idx], self.y[idx] + + def __len__(self): + return self.n - paddle.disable_static() - model = paddle.Model(nn.Sequential( - nn.Linear(10, 1), - nn.Sigmoid() - )) - optim = paddle.optimizer.Adam( - learning_rate=0.001, parameters=model.parameters()) - model.prepare( - optim, - loss=nn.BCELoss(), - metrics=paddle.metric.Precision()) - - data = Data() - model.fit(data, batch_size=16) + model = paddle.Model(nn.Sequential( + nn.Linear(10, 1), + nn.Sigmoid() + )) + optim = paddle.optimizer.Adam( + learning_rate=0.001, parameters=model.parameters()) + model.prepare( + optim, + loss=nn.BCELoss(), + metrics=paddle.metric.Precision()) + + data = Data() + model.fit(data, batch_size=16) """ def __init__(self, name='precision', *args, **kwargs): @@ -455,54 +465,53 @@ class Recall(Metric): .. code-block:: python - import numpy as np - import paddle + import numpy as np + import paddle - x = np.array([0.1, 0.5, 0.6, 0.7]) - y = np.array([1, 0, 1, 1]) + x = np.array([0.1, 0.5, 0.6, 0.7]) + y = np.array([1, 0, 1, 1]) - m = paddle.metric.Recall() - m.update(x, y) - res = m.accumulate() - print(res) # 2.0 / 3.0 + m = paddle.metric.Recall() + m.update(x, y) + res = m.accumulate() + print(res) # 2.0 / 3.0 Example with Model API: .. code-block:: python - import numpy as np - - import paddle - import paddle.nn as nn - - class Data(paddle.io.Dataset): - def __init__(self): - super(Data, self).__init__() - self.n = 1024 - self.x = np.random.randn(self.n, 10).astype('float32') - self.y = np.random.randint(2, size=(self.n, 1)).astype('float32') - - def __getitem__(self, idx): - return self.x[idx], self.y[idx] - - def __len__(self): - return self.n - - paddle.disable_static() - model = paddle.Model(nn.Sequential( - nn.Linear(10, 1), - nn.Sigmoid() - )) - optim = paddle.optimizer.Adam( - learning_rate=0.001, parameters=model.parameters()) - model.prepare( - optim, - loss=nn.BCELoss(), - metrics=[paddle.metric.Precision(), paddle.metric.Recall()]) - - data = Data() - model.fit(data, batch_size=16) + import numpy as np + + import paddle + import paddle.nn as nn + + class Data(paddle.io.Dataset): + def __init__(self): + super(Data, self).__init__() + self.n = 1024 + self.x = np.random.randn(self.n, 10).astype('float32') + self.y = np.random.randint(2, size=(self.n, 1)).astype('float32') + + def __getitem__(self, idx): + return self.x[idx], self.y[idx] + + def __len__(self): + return self.n + + model = paddle.Model(nn.Sequential( + nn.Linear(10, 1), + nn.Sigmoid() + )) + optim = paddle.optimizer.Adam( + learning_rate=0.001, parameters=model.parameters()) + model.prepare( + optim, + loss=nn.BCELoss(), + metrics=[paddle.metric.Precision(), paddle.metric.Recall()]) + + data = Data() + model.fit(data, batch_size=16) """ def __init__(self, name='recall', *args, **kwargs): @@ -597,59 +606,58 @@ class Auc(Metric): Example by standalone: .. code-block:: python - import numpy as np - import paddle + import numpy as np + import paddle - m = paddle.metric.Auc() - - n = 8 - class0_preds = np.random.random(size = (n, 1)) - class1_preds = 1 - class0_preds - - preds = np.concatenate((class0_preds, class1_preds), axis=1) - labels = np.random.randint(2, size = (n, 1)) - - m.update(preds=preds, labels=labels) - res = m.accumulate() + m = paddle.metric.Auc() + + n = 8 + class0_preds = np.random.random(size = (n, 1)) + class1_preds = 1 - class0_preds + + preds = np.concatenate((class0_preds, class1_preds), axis=1) + labels = np.random.randint(2, size = (n, 1)) + + m.update(preds=preds, labels=labels) + res = m.accumulate() Example with Model API: .. code-block:: python - import numpy as np - import paddle - import paddle.nn as nn - - class Data(paddle.io.Dataset): - def __init__(self): - super(Data, self).__init__() - self.n = 1024 - self.x = np.random.randn(self.n, 10).astype('float32') - self.y = np.random.randint(2, size=(self.n, 1)).astype('int64') - - def __getitem__(self, idx): - return self.x[idx], self.y[idx] - - def __len__(self): - return self.n - - paddle.disable_static() - model = paddle.Model(nn.Sequential( - nn.Linear(10, 2), nn.Softmax()) - ) - optim = paddle.optimizer.Adam( - learning_rate=0.001, parameters=model.parameters()) - - def loss(x, y): - return nn.functional.nll_loss(paddle.log(x), y) - - model.prepare( - optim, - loss=loss, - metrics=paddle.metric.Auc()) - data = Data() - model.fit(data, batch_size=16) + import numpy as np + import paddle + import paddle.nn as nn + + class Data(paddle.io.Dataset): + def __init__(self): + super(Data, self).__init__() + self.n = 1024 + self.x = np.random.randn(self.n, 10).astype('float32') + self.y = np.random.randint(2, size=(self.n, 1)).astype('int64') + + def __getitem__(self, idx): + return self.x[idx], self.y[idx] + + def __len__(self): + return self.n + + model = paddle.Model(nn.Sequential( + nn.Linear(10, 2), nn.Softmax()) + ) + optim = paddle.optimizer.Adam( + learning_rate=0.001, parameters=model.parameters()) + + def loss(x, y): + return nn.functional.nll_loss(paddle.log(x), y) + + model.prepare( + optim, + loss=loss, + metrics=paddle.metric.Auc()) + data = Data() + model.fit(data, batch_size=16) """ def __init__(self, -- GitLab