有什么方法可以显式测量 Python 中机器学习模型的复杂性

数据挖掘 机器学习 Python r 预测建模 模型选择
2021-10-12 16:53:13

我对模型调试很感兴趣,其中提到的一点是将您的模型与“不太复杂”的模型进行比较,以检查最复杂模型的性能是否比更简单的模型更好。

所以,它提出了我的问题:

假设您有一个用于分类任务 的集成模型线性模型“认为集成模型比线性模型更复杂似乎很自然”

  1. 为了能够在这样的术语中比较两个或多个模型,模型的不可知论方法是什么?用数值测量模型的复杂性?

  2. 是否有任何 python/R 实现可以帮助完成这样的任务?

4个回答

我还没有听说过任何与模型无关的方法来衡量模型复杂性。有几种策略,但它们取决于模型。

您可以使用不同的模型系列来解决问题。

  • 对于线性模型,您可以计算正在使用的非零参数的数量。用于预测的特征数。

  • 对于决策树,您可以计算树达到的最大深度。

  • 对于神经网络,您可以计算 NN 正在优化的参数数量。

  • 对于集成方法(随机森林、梯度提升),您可以使用模型中使用的不同弱学习器的聚合。

对于 python 实现,有几种实现取决于您要测量的模型。如果您注意到,其中一些非常容易测量。

直观上很难比较不同模型系列之间的复杂性。具有 4 个系数的线性回归或具有 max_depth=3 的决策树更复杂的是什么?

关于深度学习复杂性的话题,Hinton、Oriol、Jeff Dean 发表了一篇论文Distilling the knowledge of a Neural Network他们谈论简化神经网络的复杂性。

您可能知道,“复杂性”是计算机科学中的一个重要术语。通常,复杂性以“大 O 表示法”来衡量,并且与解决方案如何随着输入数量的增长而及时扩展有关。例如,这篇文章讨论了卷积层的计算复杂度。

然而,在深度学习中,相互竞争的神经网络架构通常将相同的算法(反向传播)应用于相同类型的问题(例如,ImageNet 分类)。唯一的区别是架构。此外,大多数架构使用类似的计算元素(例如,卷积层和线性层)。因此,使用参数的数量作为复杂性的替代是一种惯例。确实,这只是一个近似值:两个网络可能具有相同数量的参数,但需要不同数量的操作。但它通常是一个很好的近似值,因为不同的架构通常具有上述相似之处,但大小可能相差几个数量级。

作为参考,请考虑EfficientNet 论文中的图 1 。他们使用可训练参数的数量作为“模型大小”的替代,并注意到参数的数量与运行时间或多或少呈线性相关。

至于计算可训练参数数量的 Python 函数,这将取决于您使用的是 Keras、Tensorflow、PyTorch 等。在 Keras 中,这是一行:model.count_params(). 在 PyTorch 中,您可以按照此处model.parameters()讨论的方式计算它

这可能有点天真,但首先想到的想法是简单地计算在训练期间必须估计的参数数量:需要估计的值越多,模型越复杂,因为假设空间更大. 例如线性模型只需要n+1参数(与n特征的数量),而集成模型中需要的参数数量是每个学习器的参数数量之和,因此它可能会更高。可以改进这个想法以考虑参数值的范围。

作为一个非常粗略的近似,可以简单地计算在 python 中表示模型的对象的大小(假设模型的表示是节省空间的,但可能并非总是如此)。

正如此处其他答案所提到的,当我们谈论模型复杂性时,我们通常会考虑模型学习的参数数量。当有人谈论与不太复杂的模型进行比较时,他们通常是指与直观上不太复杂的模型进行比较(同一类中的模型,例如具有较少神经元的神经网络,或者来自更简单类的模型,例如线性模型而不是随机森林)。

考虑非常不同模型之间模型复杂性的一种方法是Kolmogorov Complexity,您可以通过查看保存的(例如腌制的)模型占用的空间量来近似这一点。在您给出的示例中,集合将比线性模型占用更多的磁盘空间,除非集合比线性模型更简单(例如,两个线性模型的集合,每个模型有 10 个学习系数,而线性模型有 200 个学习系数)。