Files
2026-07-13 12:37:18 +08:00

72 lines
2.6 KiB
Python

# -*- coding:utf-8 -*-
# Author: hankcs
# Date: 2019-12-05 02:12
import copy
from io import TextIOWrapper
from typing import List
import numpy as np
import tensorflow as tf
class StreamTableFormatter(object):
def __init__(self) -> None:
super().__init__()
self.col_widths = None
def format_row(self, cells) -> List[str]:
if not isinstance(cells, list):
cells = list(cells)
if not self.col_widths:
self.col_widths = [0] * len([_ for _ in cells])
for i, c in enumerate(cells):
self.col_widths[i] = max(self.col_widths[i], len(self.format_cell(c, self.col_widths[i])))
return list(self.format_cell(cell, width) for cell, width in zip(cells, self.col_widths))
def format_cell(self, cell: str, min_width) -> str:
if isinstance(cell, (np.float32, np.float)):
return '{:>{}.4f}'.format(cell, min_width)
return '{:>{}}'.format(cell, min_width)
class FineCSVLogger(tf.keras.callbacks.History):
def __init__(self, filename, separator=',', append=False):
super().__init__()
self.append = append
self.separator = separator
self.filename = filename
self.out: TextIOWrapper = None
self.keys = []
self.formatter = StreamTableFormatter()
def on_train_begin(self, logs=None):
super().on_train_begin(logs)
self.out = open(self.filename, 'a' if self.append else 'w')
def on_train_end(self, logs=None):
self.out.close()
def on_epoch_end(self, epoch, logs=None):
super().on_epoch_end(epoch, logs)
if not self.keys:
self.keys = sorted(logs.keys())
if getattr(self.model, 'stop_training', None):
# We set NA so that csv parsers do not fail for this last epoch.
logs = dict([(k, logs[k]) if k in logs else (k, 'NA') for k in self.keys])
# feed them twice to decide the actual width
values = self.formatter.format_row([epoch + 1] + [logs.get(k, 'NA') for k in self.keys])
headers = self.formatter.format_row(['epoch'] + self.keys)
# print headers and bars
self.out.write(self.separator.join(headers) + '\n')
# bars for markdown style
bars = [''.join(['-'] * width) for width in self.formatter.col_widths]
self.out.write(self.separator.join(bars) + '\n')
values = self.formatter.format_row([epoch + 1] + [logs.get(k, 'NA') for k in self.keys])
self.out.write(self.separator.join(values) + '\n')
self.out.flush()