* Constructor of LoggingCallback.
()
| 49 | * Constructor of LoggingCallback. |
| 50 | */ |
| 51 | constructor() { |
| 52 | super({ |
| 53 | onTrainBegin: async (logs?: Logs) => { |
| 54 | const samples = this.params.samples as number; |
| 55 | const batchSize = this.params.batchSize as number; |
| 56 | const steps = this.params.steps as number; |
| 57 | if (samples != null || steps != null) { |
| 58 | this.numTrainBatchesPerEpoch = |
| 59 | samples != null ? Math.ceil(samples / batchSize) : steps; |
| 60 | } else { |
| 61 | // Undetermined number of batches per epoch, e.g., due to |
| 62 | // `fitDataset()` without `batchesPerEpoch`. |
| 63 | this.numTrainBatchesPerEpoch = 0; |
| 64 | } |
| 65 | }, |
| 66 | onEpochBegin: async (epoch: number, logs?: Logs) => { |
| 67 | progressBarHelper.log(`Epoch ${epoch + 1} / ${this.params.epochs}`); |
| 68 | this.currentEpochBegin = util.now(); |
| 69 | this.epochDurationMillis = null; |
| 70 | this.usPerStep = null; |
| 71 | this.batchesInLatestEpoch = 0; |
| 72 | this.terminalWidth = process.stderr.columns; |
| 73 | }, |
| 74 | onBatchEnd: async (batch: number, logs?: Logs) => { |
| 75 | this.batchesInLatestEpoch++; |
| 76 | if (batch === 0) { |
| 77 | this.progressBar = new progressBarHelper.ProgressBar( |
| 78 | 'eta=:eta :bar :placeholderForLossesAndMetrics', { |
| 79 | width: Math.floor(0.5 * this.terminalWidth), |
| 80 | total: this.numTrainBatchesPerEpoch + 1, |
| 81 | head: `>`, |
| 82 | renderThrottle: this.RENDER_THROTTLE_MS |
| 83 | }); |
| 84 | } |
| 85 | const maxMetricsStringLength = |
| 86 | Math.floor(this.terminalWidth * 0.5 - 12); |
| 87 | const tickTokens = { |
| 88 | placeholderForLossesAndMetrics: |
| 89 | this.formatLogsAsMetricsContent(logs, maxMetricsStringLength) |
| 90 | }; |
| 91 | if (this.numTrainBatchesPerEpoch === 0) { |
| 92 | // Undetermined number of batches per epoch. |
| 93 | this.progressBar.tick(0, tickTokens); |
| 94 | } else { |
| 95 | this.progressBar.tick(tickTokens); |
| 96 | } |
| 97 | await nextFrame(); |
| 98 | if (batch === this.numTrainBatchesPerEpoch - 1) { |
| 99 | this.epochDurationMillis = util.now() - this.currentEpochBegin; |
| 100 | this.usPerStep = this.params.samples != null ? |
| 101 | this.epochDurationMillis / (this.params.samples as number) * 1e3 : |
| 102 | this.epochDurationMillis / this.batchesInLatestEpoch * 1e3; |
| 103 | } |
| 104 | }, |
| 105 | onEpochEnd: async (epoch: number, logs?: Logs) => { |
| 106 | if (this.epochDurationMillis == null) { |
| 107 | // In cases where the number of batches per epoch is not determined, |
| 108 | // the calculation of the per-step duration is done at the end of the |