Repository: speechbrain/speechbrain

Issue:
Logging the number of parameters
Hey @pplantinga @Gastron , @mravanelli ,

It will be nice to have the information about the size of the model.

I will make a PR for it.


Discussion:

Resolving patch:
diff --git a/speechbrain/core.py b/speechbrain/core.py
--- a/speechbrain/core.py
+++ b/speechbrain/core.py
@@ -17,6 +17,7 @@
 from datetime import date
 from tqdm.contrib import tqdm
 from speechbrain.utils.logger import setup_logging
+from speechbrain.utils.logger import format_order_of_magnitude
 from speechbrain.utils.data_utils import recursive_update
 
 logger = logging.getLogger(__name__)
@@ -228,6 +229,13 @@ def __init__(self, modules=None, optimizer=None, first_inputs=None):
             if self.optimizer is not None:
                 self.optimizer.init_params(self.modules)
 
+        total_params = sum(
+            p.numel() for p in self.modules.parameters() if p.requires_grad
+        )
+        clsname = self.__class__.__name__
+        fmt_num = format_order_of_magnitude(total_params)
+        logger.info(f"Initialized {fmt_num} trainable parameters in {clsname}")
+
     def compute_forward(self, x, stage="train", init_params=False):
         """Forward pass, to be overridden by sub-classes.
 
diff --git a/speechbrain/utils/logger.py b/speechbrain/utils/logger.py
--- a/speechbrain/utils/logger.py
+++ b/speechbrain/utils/logger.py
@@ -1,13 +1,61 @@
 """
 Managing the logger.
+
+Author
+    Fang-Pen Lin 2012 and Peter Plantinga 2020
+    https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/
+    Aku Rouhe
 """
 
 import os
 import yaml
 import logging
 import logging.config
+import math
 from speechbrain.utils.data_utils import recursive_update
 
+ORDERS_ABBREV = {
+    -24: "y",
+    -21: "z",
+    -18: "a",
+    -15: "f",
+    -12: "p",
+    -9: "n",
+    -6: "µ",
+    -3: "m",
+    0: "",
+    3: "k",
+    6: "M",
+    9: "G",
+    12: "T",
+    15: "P",
+    18: "E",
+    21: "Z",
+    24: "Y",
+}
+
+# Short scale
+# Negative powers of ten in lowercase, positive in uppercase
+ORDERS_WORDS = {
+    -24: "septillionths",
+    -21: "sextillionths",
+    -18: "quintillionths",
+    -15: "quadrillionths",
+    -12: "trillionths",
+    -9: "billionths",
+    -6: "millionths",
+    -3: "thousandths",
+    0: "",
+    3: "Thousand",
+    6: "Million",
+    9: "Billion",
+    12: "Trillion",
+    15: "Quadrillion",
+    18: "Quintillion",
+    21: "Sextillion",
+    24: "Septillion",
+}
+
 
 def setup_logging(
     config_path="log-config.yaml", overrides={}, default_level=logging.INFO,
@@ -23,11 +71,6 @@ def setup_logging(
     overrides : dict
         a dictionary of the same structure as the config dict
         with any updated values that need to be applied
-
-    Author
-    ------
-    Fang-Pen Lin 2012 and Peter Plantinga 2020
-    https://fangpenlin.com/posts/2012/08/26/good-logging-practice-in-python/
     """
     if os.path.exists(config_path):
         with open(config_path, "rt") as f:
@@ -36,3 +79,50 @@ def setup_logging(
         logging.config.dictConfig(config)
     else:
         logging.basicConfig(level=default_level)
+
+
+def format_order_of_magnitude(number, abbreviate=True):
+    """
+    Formats number to appropriate order of magnitude for printing
+
+    Arguments
+    ---------
+    number : int, float
+        The number to format
+    abbreviate : bool
+        Whether to use abbreviations (k,M,G) or words (Thousand, Million,
+        Billion). Numbers will be either like: "123.5k" or "123.5 Thousand"
+
+    Returns
+    -------
+    str
+        The formatted number. Note that the order of magnitude token is part
+        of the string.
+
+    Example
+    -------
+    >>> print(format_order_of_magnitude(123456))
+    123.5k
+    >>> print(format_order_of_magnitude(0.00000123, abbreviate=False))
+    1.2 millionths
+    >>> print(format_order_of_magnitude(5, abbreviate=False))
+    5
+    """
+    style = ORDERS_ABBREV if abbreviate else ORDERS_WORDS
+    precision = "{num:3.1f}"
+    order = 3 * math.floor(math.log(math.fabs(number), 1000))
+    # Fallback for very large numbers:
+    while order not in style and order != 0:
+        order = order - math.copysign(3, order)  # Bring 3 units towards 0
+    order_token = style[order]
+    if order != 0:
+        formatted_number = precision.format(num=number / 10 ** order)
+    else:
+        if isinstance(number, int):
+            formatted_number = str(number)
+        else:
+            formatted_number = precision.format(num=number)
+    if abbreviate or not order_token:
+        return formatted_number + order_token
+    else:
+        return formatted_number + " " + order_token


Test patch: