简体   繁体   English

使用 tensorflow,我如何找到拟合期间一个时期所花费的时间?

[英]Using tensorflow, how do I find the time taken for an epoch during fitting?

I am following along this tutorial,https://www.tensorflow.org/tutorials/keras/basic_classification我正在关注本教程,https://www.tensorflow.org/tutorials/keras/basic_classification

When I fit the model using model.fit(train_images, train_labels, epochs=5, verbose =1) , the times are displayed in the python console.当我使用model.fit(train_images, train_labels, epochs=5, verbose =1)拟合模型时,时间会显示在 python 控制台中。 I want to get the wall time of each epoch by using time.clock() .我想通过使用time.clock()来获取每个时代的墙上时间。

I am assuming that when more epochs are added the fitting time increases linearly, but I want to graph this to be sure.我假设当添加更多时期时,拟合时间会线性增加,但我想确定这一点。

Besides fitting with 1 epoch, then 2 epochs, then 3 epochs, etc, how can I work out the training time (fitting time) for an increasing number of epochs?除了拟合 1 个 epoch,然后 2 个 epoch,然后 3 个 epoch 等等,我如何计算出越来越多的 epoch 的训练时间(拟合时间)?

Using a custom callback you can plot the total time taken to fit certain epochs.使用自定义回调,您可以绘制适合某些时期所需的总时间。

class timecallback(tf.keras.callbacks.Callback):
    def __init__(self):
        self.times = []
        # use this value as reference to calculate cummulative time taken
        self.timetaken = time.clock()
    def on_epoch_end(self,epoch,logs = {}):
        self.times.append((epoch,time.clock() - self.timetaken))
    def on_train_end(self,logs = {}):
        plt.xlabel('Epoch')
        plt.ylabel('Total time taken until an epoch in seconds')
        plt.plot(*zip(*self.times))
        plt.show()

And then pass this as a callback to the model.fit function like this然后像这样将它作为回调传递给 model.fit 函数

timetaken = timecallback()
model.fit(train_images, train_labels, epochs=5,callbacks = [timetaken])

This plots a graph at the end of training which shows the total time taken for the model to train upto a certain epoch from the start.这会在训练结束时绘制一个图表,显示模型从开始训练到某个时期所花费的总时间。

And if you want to plot the per epoch time.如果你想绘制每个纪元的时间。 You can replace the on_train_end method with on_epoch_end.您可以将 on_train_end 方法替换为 on_epoch_end。

def on_epoch_end(self,epoch,logs= {}):
    # same as the on_train_end function

Good practice to use callbacks.使用回调的好习惯。 How do we record the durations in the history?我们如何记录历史中的持续时间?

Say we're using history = model.fit( ..., callbacks=[my_training_callback])假设我们正在使用history = model.fit( ..., callbacks=[my_training_callback])

What should I write into the definition of my_training_callback ?我应该在my_training_callback的定义中写什么? I'm tryin to do:我正在尝试做:

def my_training_callback(Callback):
    def __init__(self):
        mark = 0
        duration = 0
    def on_epoch_begin(self, epoch, logs=None):
        self.mark = time()
    def on_epoch_end(self, epoch, logs=None):
        self.duration = time() - self.mark

It works ok, but I'm having trouble adding the duration value to the history.它工作正常,但我无法将duration值添加到历史记录中。 Thanks谢谢

Using a custom callback definitely works but you must be careful of how you generate a timestamp.使用自定义回调肯定有效,但您必须注意如何生成时间戳。 The recommended time.clock() works differently on Windows vs UNIX systems and may not generate the behavior that you want.推荐的time.clock() 在 Windows 和 UNIX 系统上的工作方式不同,可能不会产生您想要的行为。 Therefore, I recommend a tweak to the code others have recommended, using the built in tensorflow.timestamp() method ( documentation ).因此,我建议使用内置的 tensorflow.timestamp() 方法(文档)对其他人推荐的代码进行调整。 Note that this is a tensor object so if you'd like to plot the time as text, as I did, you'll need to extract the float value.请注意,这是一个张量对象,因此如果您想像我一样将时间绘制为文本,则需要提取浮点值。 I did so using .numpy() as this is an EagerTensor .我使用.numpy()这样做,因为这是一个EagerTensor

import tensorflow as tf
import matplotlib.pyplot as plt
from datetime import datetime

class timecallback(tf.keras.callbacks.Callback):
    def __init__(self):
        self.times = []
        self.epochs = []
        # use this value as reference to calculate cummulative time taken
        self.timetaken = tf.timestamp()
    def on_epoch_end(self,epoch,logs = {}):
        self.times.append(tf.timestamp() - self.timetaken)
        self.epochs.append(epoch)
    def on_train_end(self,logs = {}):
        plt.xlabel('Epoch')
        plt.ylabel('Total time taken until an epoch in seconds')
        plt.plot(self.epochs, self.times, 'ro')
        for i in range(len(self.epochs)):
          j = self.times[i].numpy()
          if i == 0:
            plt.text(i, j, str(round(j, 3)))
          else:
            j_prev = self.times[i-1].numpy()
            plt.text(i, j, str(round(j-j_prev, 3)))
        plt.savefig(datetime.now().strftime("%Y%m%d%H%M%S") + ".png")

Then, when calling model fit:然后,在调用模型拟合时:

model.fit(train_images, train_labels, epochs=5,callbacks = [timecallback()])

I have managed to add the duration to the history.我设法将持续时间添加到历史记录中。

The trick comes from the fact that the logs object passed to the methods of Callback is mutable, and is the same one that is passed to each callback... including the History object returned by model.fit .诀窍在于传递给Callback方法的logs对象是可变的,并且与传递给每个回调的对象相同......包括model.fit返回的History对象。

So if you want the duration of each epoch in the history (as opposed to displayed on the screen or saved to a file as in the other answers), you have to add it to the logs object in your custom callback.因此,如果您想要历史记录中每个时期的持续时间(而不是像其他答案那样显示在屏幕上或保存到文件中),则必须将其添加到自定义回调中的logs对象中。

Example:例子:

import datetime
import tensorflow as tf
class TimestampCallback(tf.keras.callbacks.Callback):
    def __init__(self, metric_name = "duration"):
        self.__epoch_start = None
        self.__metric_name = metric_name

    def on_epoch_begin(self, epoch, logs=None):
        self.__epoch_start = datetime.datetime.utcnow()

    def on_epoch_end(self, epoch, logs=None):
        logs[self.__metric_name] = datetime.datetime.utcnow() - self.__epoch_start

You don't have to use datetime obviously.显然,您不必使用datetime And if you have a callback that consumes the duration, make sure to put it after this callback in the callback list.如果您有一个消耗持续时间的回调,请确保将其放在回调列表中此回调之后 Because History is called after every callback, it will always receive the duration.因为每次回调后都会调用History ,所以它总是会收到持续时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在训练期间如何在每个 epoch 结束时调用测试集? 我正在使用张量流 - How can I call a test set at the end of each epoch during the training? I am using tensorflow 如何在 tensorflow 上的第一个纪元后修复错误? - How do I fix the error after first epoch on tensorflow? 如何在Python中将时间列表转换为Unix纪元时间? - How do I convert a list of times into Unix epoch time in Python? 如何在Python中找到未来时间的纪元时间 - How to find epoch time of future time in Python 如何使用 Python 和用户定义的 function 进行非线性曲线拟合并找到拟合参数? - How to do Non-Linar Curve fitting and find fitting parameter using Python with user defined function? 我怎么知道任务花费了很多时间? - How do I know much time taken by task? 如何找到乘坐次数最多的小时数? - How do I find the hour with most rides taken? 如何在拟合期间将权重添加到曲线而不是数据点? 我使用什么导入/功能? - How do I add weighting to a curve not the data points during fitting? What import/func do I use? 如何解决执行 LOC 期间发生的错误,如何在编写代码时使用 nb_epoch - how do I resolve an error occured during execution of LOC, how to use nb_epoch in writing code 我如何将 time.monotonic 更改为纪元时间或正常时间 - How do i change time.monotonic to epoch time or normal time
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM