Python sklearn在训练期间显示损失值

时间:2017-06-08 18:50:56

标签: python machine-learning scikit-learn

我想在训练期间检查我的损失值,这样我就可以观察每次迭代时的损失。到目前为止,我还没有找到一个简单的方法让scikit学会给我一个损失值的历史,我也没有找到一个功能已经在scikit中为我绘制损失。

如果没有办法对此进行绘制,那么如果我可以简单地在classifier.fit的末尾获取最终的损失值,那就太棒了。

注意:我知道某些解决方案是封闭的形式。我使用了几个没有分析解决方案的分类器,例如逻辑回归和svm。

有没有人有任何建议?

3 个答案:

答案 0 :(得分:4)

所以我无法找到关于每次迭代直接获取损失值的非常好的文档,但我希望这将有助于未来的人:

old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()
clf = SGDClassifier(**kwargs, verbose=1)
clf.fit(X_tr, y_tr)
sys.stdout = old_stdout
loss_history = mystdout.getvalue()
loss_list = []
for line in loss_history.split('\n'):
    if(len(line.split("loss: ")) == 1):
        continue
    loss_list.append(float(line.split("loss: ")[-1]))
plt.figure()
plt.plot(np.arange(len(loss_list)), loss_list)
plt.savefig("warmstart_plots/pure_SGD:"+str(kwargs)+".png")
plt.xlabel("Time in epochs")
plt.ylabel("Loss")
plt.close()

此代码将采用普通的SGDClassifier(几乎任何线性分类器),并拦截verbose=1标志,然后将其拆分以从详细打印中获取损失。显然这个速度较慢,但​​会给我们带来损失并打印出来。

答案 1 :(得分:1)

我刚刚改编并更新了@OneRaynyDay 的答案。使用 context manager 更优雅。

定义上下文管理器:

import sys
import io
import matplotlib.pyplot as plt

class DisplayLossCurve(object):
  def __init__(self, print_loss=False):
    self.print_loss = print_loss

  """Make sure the model verbose is set to 1"""
  def __enter__(self):
    self.old_stdout = sys.stdout
    sys.stdout = self.mystdout = io.StringIO()
  
  def __exit__(self, *args, **kwargs):
    sys.stdout = self.old_stdout
    loss_history = self.mystdout.getvalue()
    loss_list = []
    for line in loss_history.split('\n'):
      if(len(line.split("loss: ")) == 1):
        continue
      loss_list.append(float(line.split("loss: ")[-1]))
    plt.figure()
    plt.plot(np.arange(len(loss_list)), loss_list)
    plt.xlabel("Epoch")
    plt.ylabel("Loss")

    if self.print_loss:
      print("=============== Loss Array ===============")
      print(np.array(loss_list))
      
    return True

用法:

from sklearn.linear_model import SGDRegressor

model = SGDRegressor(verbose=1)

with DisplayLossCurve():
  model.fit(X, Y)

# OR

with DisplayLossCurve(print_loss=True):
  model.fit(X, Y)

答案 2 :(得分:0)

使用model.loss_curve_

您可以使用verbose选项在每次迭代中打印值,但是如果需要实际值,这不是最佳的处理方法,因为您将需要做一些棘手的工作来解析它们。

是的,文档没有提到任何有关此属性的信息,但是如果您签入源代码,您可能会注意到MLPClassifier个基类(BaseMultilayerPerceptron)中的一个实际上是{{3 }}在每个迭代中存储值。

当您获得列表中的所有值时,使用任何库进行绘制都将是微不足道的。

请注意,此属性仅在使用随机求解器(即sgdadam)时存在。