当使用keras fit_generator时,如何让Bokeh更新显示某些度量与时代的图表?

时间:2017-03-30 15:20:41

标签: python deep-learning keras bokeh

我曾经在演示文稿中简要地看过一次,有人在密谋:

  • loss / validation_loss vs epoch
  • 准确性/ validation_accuracy vs epoch

特别之处在于,这个人正在使用一个在每个时代之后都可以使用的散景图。这样的壮举是如何完成的?

2 个答案:

答案 0 :(得分:2)

Piotr Migdal使用回调的例子看起来非常不错。您可以像我在家中的一些小型监控应用程序一样重新运行绘图仪,将其集成到回调函数中。假设您在绘制数据时有一些数据框,我会快速提取相关代码:

import bokeh.plotting as bplt

data = pd.read_csv(...)

bplt.output_file('myplots.html', title='Myplots')

p = bplt.figure(title='Keras Live Loss')
p.line(data['epoch'], data['loss'], line_color='blue', line_width=1)
p.line(data['epoch'], data['val_loss'], line_color='red', line_width=1, line_dash='dotted')

bplt.show(p)

你可以尝试的另一件事是一个看起来很有前途的蒸汽应用程序,但我从来没有尝试过,说实话。也许这有助于: https://www.continuum.io/content/painless-streaming-plots-bokeh

答案 1 :(得分:1)

您可以使用Bokeh的Jupyter集成在笔记本中实时完成此操作。我制作了一个示例笔记本here,尽管只是带有虚拟数据。

要与Keras一起使用,我将使用on_batch_endon_epoch_end回调从笔记本中调用update函数。

简而言之,相关代码为:

from bokeh.io import push_notebook, show, output_notebook
from bokeh.plotting import figure
import numpy as np
output_notebook()

p = figure()
r = p.line([], [], legend='loss')
show(p, notebook_handle=True)

def update(losses):
    x = np.arange(len(losses))
    r.data_source.data.update(x=x, y=losses)
    push_notebook()

# Train here, and periodically call `update(losses)`.

为此,您可能希望添加

  • 如果自上次通话以来没有花费太多时间,请从update提前退出。
  • 绘制训练损失和验证损失。
  • 使用例如scipy.ndimage.filters.uniform_filter1d并绘制透明度较低的不平滑数据。
  • 对数据进行二次采样,然后再将其传递到r.data_source.data.update。在我的损失历史记录为N =〜200,000点的实验中,我发现如果我对整个图进行绘制,则调用update的时间会增加一秒钟以上,但是如果我使用indices = np.floor(np.linspace(0, len(y)-1, 1000)).astype(int) if len(y) > 10000 else slice(0, None)来生成一个{缩小索引集后,我总是可以将时间保持在60毫秒左右(包括平滑时间,而N并不能真正有效地扩展该时间)。
  • 在单独的线程或进程中运行它。我尚未执行此操作,因为如果我考虑每批运行一次update,而实际上仅每秒运行一次,那么在进行.06 s / call进行更新时,我只会增加6%的培训时间。

当然,您可以交替使用Tensorboard,但如果您不需要其所有其他功能,则与Bokeh的几十行代码相比,它可能会过大,您需要开始一个单独的过程并考虑日志目录和捕获正确的摘要,就可以了。