在 Tensorflow 中格式化 .fit() 日志

问题描述 投票:0回答:1

拟合我的张量流(2.15)模型时,我得到以下日志:

Epoch 2/10
32/32 - 0s - loss: 17.3287 - 99ms/epoch - 3ms/step
Epoch 3/10
32/32 - 0s - loss: 16.9345 - 123ms/epoch - 4ms/step

等等...我想在“日志记录”消息中添加时间戳(我不认为这是日志记录,因为更改记录器格式并没有改变消息中的任何内容)。不管怎样,我想我可以使用

on_epoch_end
回调并创建我自己的日志消息。但这样我就无法访问运行时信息,例如毫秒/步指标。 我要问的是:我可以在适合的消息中添加时间吗?如果没有,我在哪里可以在
on_epoch_end
回调中找到每个时期的训练时间?

import logging
import sys

import keras
import numpy as np
import tensorflow as tf

# logging setup
logger = tf.get_logger()
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)


class LoggerTensorflow(keras.callbacks.Callback):
    def on_epoch_end(self, epoch, logs=None):
        epoch_string = f"Epoch {epoch + 1} / {self.params['epochs']}"
        logs_formatted = " - ".join([f"{k}: {v:.4f}" for k, v in logs.items()])
        logger.info(f"{epoch_string} - {logs_formatted}")
        return super().on_epoch_end(epoch, logs)


# Generate some fake data: 1000 samples with 1 feature.
np.random.seed(42)  # for reproducible results
x_data = np.random.rand(1000, 1)  # features
y_data = 3 * x_data + 2 + np.random.normal(0, 0.05, (1000, 1))  # targets with noise


# Build a simple linear regression model
model = tf.keras.Sequential([tf.keras.layers.Dense(1, input_shape=(1,))])

# Compile the model specifying the optimizer, loss function, and metrics to track
model.compile(loss="mse")

# Train the model
model.fit(x_data, y_data, epochs=10, verbose=2)
python tensorflow keras logging
1个回答
0
投票

我找不到更改 .fit() 日志的方法,这些日志似乎是打印消息而不是日志消息。获取的方式可能是自己的回调。这就是我所实施的(如果它对任何人有帮助的话):


class LoggerTensorflow(keras.callbacks.Callback):
    def __init__(self, verbose: Literal[0, 1, 2] = 1):
        """Logging the training progress of a tensorflow model.

        Args:
            verbose (Literal[0, 1, 2], optional): 0 is no logging, 1 logs to the console and 2 uses the root logger settings. Defaults to 1.
        """
        super().__init__()

        self.start_time = None  # time at the beginning of the epoch

        # setup logger
        self.logger = logging.getLogger("tenforflow-fit")
        self.logger.setLevel(logging.INFO)
        if verbose == 0:  # no logging
            self.logger.setLevel(logging.WARNING)
        elif verbose == 1:  # logging but not using the root logger
            self.logger.propagate = False
            # Create and add console handler
            console_handler = logging.StreamHandler()
            # add formatter
            formatter = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s: %(message)s")
            console_handler.setFormatter(formatter)

            self.logger.addHandler(console_handler)

    def on_epoch_begin(self, epoch, logs=None):
        # set time
        self.start_time = time.time()
        return super().on_epoch_begin(epoch, logs)

    def on_epoch_end(self, epoch, logs=None):
        # compute duration
        duration = time.time() - self.start_time
        general_info = f"Epoch {epoch + 1}/{self.params['epochs']} - {duration:.3f}s"  # epoch number and time
        loss = ""  # string to hold the losses
        for k, v in logs.items():
            k = k.replace("output_", "")
            if k != "val_loss":
                k = k.replace("_loss", "")

            # add to string
            loss += f"{k} {v:.4f} - "

        self.logger.info(general_info + ": " + loss)
        return super().on_epoch_end(epoch, logs)
© www.soinside.com 2019 - 2024. All rights reserved.