python-损失函数作为几个点的最小值,自定义损失函数和梯度
作者:互联网
我正在尝试预测金属线圈的质量.我有宽度为10米,长度为1至6公里的金属线圈.作为训练数据,我每10米测量约600个参数,以及最终质量控制标记-好/坏(对于整个线圈).不良表示至少有1个地方有线圈不良,没有数据准确地存在.我有大约10000个线圈的数据.
让我们想象一下,我们想为该数据训练逻辑回归(有2个因素).
X = [[0, 0],
...
[0, 0],
[1, 1], # coil is actually broken here, but we don't know it yet.
[0, 0],
...
[0, 0]]
Y = ?????
我不能只将所有“坏”都放在Y中并运行分类器,因为我会对分类器感到困惑.我不能将所有“好”和一个“坏”都用Y表示,因为我不知道哪里是不好的位置.
我想到的解决方案如下,我可以将损失函数定义为sum((Y-min(F(x1,x2)))^ 2)(由属于一个线圈的所有F计算的最小值)而不是sum((YF (x1,x2))^ 2).在这种情况下,我可能正确地训练了F指向错误的地方.为此,我需要梯度,不可能在所有点上都可以计算出来,最小值在所有位置上都不是可微的,但是我可以改用弱梯度(在每个位置使用最小的线圈函数值).
我或多或少知道自己如何实现它,问题是用scikit-learn在python中实现它的最简单方法是什么.理想情况下,它应与几种学习方法(很多基于损失函数和梯度的方法)相同(或易于适应),是否有可能为这种方法工作的学习方法做一些包装?
更新:查看gradient_boosting.py-有内部抽象类LossFunction,具有计算损耗和梯度的能力,看上去很透视.似乎没有通用的解决方案.
解决方法:
您在此处考虑的内容在机器学习社区中被称为超集学习,这意味着,您不用{{{x_i,y_i)}形式的训练集而采用典型的监督设置,而是{{{x_1,…, x_N},y_1)},这样您就知道集合中至少有一个元素具有属性y_1.这不是一个很常见的设置,但是现有的Google(通过一些研究)可用于该领域的论文.
对于您自己的损失功能-scikit-learn是不行的. Scikit-learn是关于简单性的,它为您提供了少量可灵活使用的即用型工具.它不是研究工具,您的问题是研究性的.您可以使用什么呢?我建议您使用任何符号微分解决方案,例如autograd,它使您能够通过python代码进行区分,只需在其之上应用scipy.optimize.minimize,就可以完成!任何自定义损失功能都可以正常工作.
附带说明-最小运算符不可微,因此模型可能很难弄清发生了什么.相反,您可以尝试执行sum((Y-prod_x F(x_1,x_2))^ 2),因为乘法是可微分的,并且您仍会得到类似的效果-如果预测至少一个元素为0,它将删除其余任何“ 1”答案.您甚至可以进一步提高数值稳定性,并执行以下操作:
if Y==0 then loss = sum_x log(F(x_1, x_2 ) )
if Y==1 then loss = sum_x log(1-F(x_1, x_2))
转化为
Y * sum_x log(1-F(x_1, x_2)) + (1-Y) * sum_x log( F(x_1, x_2) )
您会发现交叉熵成本具有相似性,这很有意义,因为您的问题确实是分类.现在您有了完美的概率损失-您将每个段的概率附加为“坏”或“好”,因此整个对象变坏的概率要么很高(如果Y == 0),要么很低(如果Y = = 1).
标签:scikit-learn,machine-learning,gradient-descent,python 来源: https://codeday.me/bug/20191118/2025839.html