由KHYATIMAHENDRU编译|CDADataAnalystLossfunctions其实就是我们经常使用的这些技术的核心。本文介绍了各种损失函数,它们的作用以及如何在Python中编码但是,此时你应该如何确定模型会给出最优结果呢?是否有一种指标或技术可以帮助您快速评估数据集中的模型?当然有——简单地说,这就是损失函数在机器学习中发挥作用的地方。损失函数是我们喜欢使用的机器学习算法的核心。但是可以看出,对于如何使用损失函数,在哪里使用损失函数,大部分初学者和爱好者都非常迷茫。损失函数并没有那么难理解,掌握了它会无限提升你对机器学习算法的理解。那么,什么是损失函数,又该如何把握损失函数的含义呢?在本文中,我们将讨论机器学习中使用的7种常见损失函数,并解释每个函数的使用位置。我们将在本文中介绍很多内容,所以让我们现在开始吧!什么是损失函数?假设你现在在山顶上,此时你需要下山。你应该如何决定你要去的方向?如果是我,我会这样做:首先环顾四周,查看所有可能的路径并拒绝上升的路径。这是因为这些路径实际上消耗了我更多的能量并使我的任务更加困难吗?最后走我认为最容易下坡的路。我只是根据我的直率来判断我的决定吗?当然不是,这些决定正是损失函数提供的。损失函数将决策映射到相关成本。决定上坡会浪费我们的精力和时间。决定下来对我们更好。因此,它具有负成本。在有监督的机器学习算法中,我们希望在学习过程中最小化每个训练示例的误差。这可以通过一些优化策略来完成,例如梯度下降。这个错误来自损失函数。损失函数和成本函数有什么区别?这里首先需要强调的是,成本函数和损失函数虽然是同义词,可以互换使用,但它们是不同的。损失函数仅用于单个训练示例。有时也称为误差函数。另一方面,成本函数是整个训练数据集的平均损失。优化策略的目标是最小化成本函数。回归损失函数此时,您应该对线性回归非常熟悉。它涉及对因变量Y和几个自变量X_i之间的线性关系建模。所以我们实际上在这些变量上拟合了一条空间线。我们将使用给定的数据点来查找系数a0、a1、...、an。我们将使用著名的波士顿住房数据集来理解这个概念。为简单起见,我们将仅使用一个特征——每套住宅的平均房间数(X)——来预测因变量,即1000美元房屋的中值(Y)。我们将使用“梯度下降”作为寻找回归线的优化策略。我不会深入“梯度下降”的复杂性,但这里有一个关于权重更新规则的提示:这里,theta_j是要更新的权重,alpha是学习率,J是成本函数。成本函数由thetaParameterization定义。我们的目标是找到产生最小总成本的theta值。我为每个损失函数定义了以下步骤:编写我们的预测函数f(X)的表达式,并确定我们需要找到的参数确定用于每个训练样本的损失函数找到成本函数的表达式——所有样本的平均损失找到成本函数相对于每个未知参数的梯度确定学习率并运行权重固定迭代次数的更新规则1.SquaretheerrorLoss每个训练样本的平方误差损失(也称为L2损失)是实际值与预测值之差的平方:对应的成本functionisthemeanofthesesquarederrors(MSE)我想在你参考下面这些代码之前,首先尝试自己找到梯度下降的梯度。defupdate_weights_MSE(m,b,X,Y,learning_rate):m_deriv=0b_deriv=0N=len(X)foriinrange(N):#计算偏导数#-2x(y-(mx+b))m_deriv+=-2*X[i]*(Y[i]-(m*X[i]+b))#-2(y-(mx+b))b_deriv+=-2*(Y[i]-(m*X[i]+b))#我们减去因为导数指向最陡上升的方向m-=(m_deriv/float(N))*learning_rateb-=(b_deriv/float(N))*learning_ratereturnm,b我用这段代码在波士顿数据上得到了500次迭代的不同学习率值:接下来你可以尝试再次运行代码500次迭代,学习率为0.1。让我们多谈谈MSE损失函数。这是一个二次函数,其中a>0),还记得它的样子吗?二次函数只有全局最小值。由于没有局部最小值,我们永远不会陷入局部最小值。因此,它始终可以确保“梯度下降”收敛(如果它完全收敛)到全局最小值。MSE损失函数通过对较大误差的误差进行平方来惩罚模型。对组件进行平方会使它变大,对吗?但这里有一个警告。此属性使MSE成本函数对异常值的鲁棒性较差。因此,如果我们的数据容易出现异常值,则不应使用此方法。2.绝对误差损失每个训练样本的绝对误差是预测值与实际值之间的距离,与符号无关。绝对误差也称为L1损失:正如我之前提到的,成本是这些绝对误差(MAE)的平均值。与MSE相比,MAE成本对异常值更加稳健。然而,处理数学方程式中的绝对运算或模运算并不容易。我相信你们中的许多人都会同意这一点!我们可以认为这是MAE的一个缺点。下面是具有MAE成本的update_weight函数的代码:defupdate_weights_MAE(m,b,X,Y,learning_rate):m_deriv=0b_deriv=0N=len(X)foriinrange(N):#Calculatepartialderivatives#-x(y-(mx+b))/|mx+b|m_deriv+=-X[i]*(Y[i]-(m*X[i]+b))/abs(Y[i]-(m*X[i]+b))#-(y-(mx+b))/|mx+b|b_deriv+=-(Y[i]-(m*X[i]+b))/abs(Y[i]-(m*X[i]+b))#我们减去因为导数指向最速上升m-=(m_deriv/float(N))*learning_rateb-=(b_deriv/float(N))*learning_ratereturnm,b在以不同的学习率运行代码500次迭代后,我们得到下图:3.HuberLossHuberloss结合了MSE和MAE的最佳性能。对于小错误,它是平方的;对于其他人,它是线性的(对于渐变也是如此)。由其_delta_参数标识:上部是小误差的平方,下部是其他误差的线性。defupdate_weights_Huber(m,b,X,Y,delta,learning_rate):m_deriv=0b_deriv=0N=len(X)foriinrange(N):#小值的二次导数和大值的线性导数值ifabs(Y[i]-m*X[i]-b)<=delta:m_deriv+=-X[i]*(Y[i]-(m*X[i]+b))b_deriv+=-(Y[i]-(m*X[i]+b))否则:m_deriv+=delta*X[i]*((m*X[i]+b)-Y[i])/abs((m*X[i]+b)-Y[i])b_deriv+=delta*((m*X[i]+b)-Y[i])/abs((m*X[i]+b)-Y[i])#我们减去因为导数指向最陡上升的方向m-=(m_deriv/float(N))*learning_rateb-=(b_deriv/float(N))*learning_ratereturnm,b为delta参数的不同取值,我们以0.0001的学习率进行500次权重更新迭代,得到如下图:【与MSE相比,Huberloss对离群值更加鲁棒。它与稳健回归、M估计和堆叠模型一起使用。HuberLoss的一个变体也用于分类。二元分类损失函数从名字上看应该是不言自明的。二元分类是指将对象分配给两个类别之一。这种分类基于应用于输入特征向量的规则。例如,根据电子邮件的主题将电子邮件分类为垃圾邮件或非垃圾邮件,这是一种二元分类。我将在乳腺癌数据集上说明这些二元损失函数。我们想根据平均半径、面积、周长等特征将肿瘤分类为“恶性”或“良性”。为简单起见,我们将仅使用两个输入特征(X_1和X_2),即“最差区域”和“平均对称性”进行分类。目标值Y可以是0(恶性)或1(良性)。这是我们数据的散点图:1.二元交叉熵损失让我们首先理解“熵”这个词。通常,我们使用熵来表示混乱或不确定性。对具有概率分布p(X)的随机变量X进行测量:负号用于使聚合为正。概率分布的熵值越大,分布的不确定性越大。同样,较小的值表示更确定的分布。这使得二元交叉熵适合作为损失函数——最小化它的值。我们对分类模型使用二元交叉熵损失,输出概率_p_。元素属于第1类(或正类)的概率=p那么,元素属于第0类(或负类)的概率=1-p然后,输出标签y的交叉熵(可以取值和1)预测概率pLoss定义为:这也称为对数损失。要计算概率p,我们可以使用Sigmoid函数。这里,z是我们输入特征的函数:sigmoid函数在[0,1]范围内,适合计算概率。尝试自己输入代码,然后查看下面_update_weight_函数的_code_。defupdate_weights_BCE(m1,m2,b,X1,X2,Y,learning_rate):m1_deriv=0m2_deriv=0b_deriv=0N=len(X1)foriinrange(N):s=1/(1/(1+math.exp(-m1*X1[i]-m2*X2[i]-b)))#计算偏导数m1_deriv+=-X1[i]*(s-Y[i])m2_deriv+=-X2[i]*(s-Y[i])b_deriv+=-(s-Y[i])#我们减去因为导数指向最陡上升的方向m1-=(m1_deriv/float(N))*learning_ratem2-=(m2_deriv/float(N))*learning_rateb-=(b_deriv/float(N))*learning_ratereturnm1,m2,b对于使用权重更新规则的1000次迭代(具有不同的alpha值),我得到以下内容图表:2.HingeLoss(铰链损失)铰链损失主要用于支持标签为-1和1的支持向量机(SVM)分类器。所以一定要将数据集中“Malignant”类的标签从0改成到-1。Hingeloss不仅惩罚错误的预测,也惩罚不确定的正确预测。输入输出对(x,y)的铰链损失为:defupdate_weights_Hinge(m1,m2,b,X1,X2,Y,learning_rate):m1_deriv=0m2_deriv=0b_deriv=0N=len(X1)foriinrange(N):#计算偏导数ifY[i]*(m1*X1[i]+m2*X2[i]+b)<=1:m1_deriv+=-X1[i]*Y[i]m2_deriv+=-X2[i]*Y[i]b_deriv+=-Y[i]#否则导数为零#我们减去因为导数指向最陡上升方向m1-=(m1_deriv/float(N))*learning_ratem2-=(m2_deriv/float(N))*learning_rateb-=(b_deriv/float(N))*learning_ratereturnm1,m2,b在使用三个不同的alpha值运行更新函数2000次迭代后,我们得到画了下图:Hingeloss简化了SVM的数学运算,同时最大化了loss(相对于logloss)。当我们想要做出实时决策并且准确性不是很重要时,可以使用它。多类分类损失函数现在,电子邮件不只是被分类为垃圾邮件或非垃圾邮件(现在已经不是90年代了!)。它们可以细分为其他各种类别——工作、家庭、社交、促销等。邮件分类现在是一个多类别用例。我们将使用iris数据集来了解其余两个损失函数。我们将使用2个特征X_1(萼片长度)和特征X_2(花瓣宽度)来预测鸢尾(Setosa、Versicolor或Virginica)的类别(Y)我们的任务是使用神经网络模型和Keras内置的Adam优化器来实现分类。这是因为随着参数数量的增加,数学和代码变得难以理解。这是我们数据的散点图:1.多类交叉熵损失多类交叉熵损失是二元交叉熵损失的推广。输入向量X_i和相应的单编码目标向量Y_i的损失是:作为输出层的节点数。”最后,我们的输出是给定输入的概率最大的类。我们用一个输入层和一个输出层构建模型,并用不同的学习率编译它。在model.compile()语句中将损失参数指定为“categorical_crossentropy”:#importingrequirementsfromkeras.layersimportDensefromkeras.modelsimportSequentialfromkeras.optimizersimportadam#alpha=0.001asgiveninthelrparameterinadam()optimizer#构建模型model_alpha1=Sequential()model_alpha1.add(Dense(50,input_dim=2,activation='relu'))model_alpha1.add(Dense(3,activation='softmax'))#编译模型opt_alpha1=adam(lr=0.001)model_alpha1。compile(loss='categorical_crossentropy',optimizer=opt_alpha1,metrics=['accuracy'])#fitthemodel#dummy_Yistheone-hotencoded#history_alpha1用于对绘图的验证和准确度分数进行评分history_alpha1=model_alpha1.fit(dataX,dummy_Y,validation_data=(dataX,dummy_Y),epochs=200,verbose=0)这是训练200个周期后的成本和准确率图:2.KLScatterKL-Divergence是衡量一个概率之间差异的指标分布和另一个。KL散度为零意味着分布相同。请注意,散度函数不是对称的。这就是为什么KL散度不能用作距离度量的原因。我将介绍使用KL散度作为损失函数的基础知识,而不涉及其数学。给定近似分布q,我们希望获得目标变量相对于输入特征的真实概率分布P的近似值。由于kl-divergence不是对称的,我们可以通过两种方式来实现:第一种方法用于监督学习,第二种方法用于强化学习。KL-divergence在功能上类似于多类交叉熵,也称为P相对于Q的相对熵:我们在compile()函数中添加'kullback_leibler_divergence',就像我们对多类交叉熵所做的那样指定为损失参数的值之前的熵损失。#从keras.layers导入需求从keras.models导入密集型从keras.optimizers导入序列导入亚当#alpha=0.001在adam()优化器中的lr参数中给出#构建模型model_alpha1=Sequential()model_alpha1.add((50,input_dim=2,activation='relu'))model_alpha1.add(Dense(3,activation='softmax'))#编译模型opt_alpha1=adam(lr=0.001)model_alpha1.compile(loss='kullback_leibler_divergence',optimizer=opt_alpha1,metrics=['accuracy'])#fitthemodel#dummy_Yistheone-hotencoded#history_alpha1用于对绘图的验证和准确度分数进行评分history_alpha1=model_alpha1.fit(dataX,dummy_Y,validation_data=(dataX,dummy_Y),epochs=200,verbose=0)KL-divergence比多类分类更常用于近似复杂函数。在使用变分自动编码器(VAE)等深度自动生成模型时,我们经常会遇到KL散度。结语哇!到目前为止我们已经谈了很多。继续看最后的你,给自己一点鼓励。这篇文章详细列出了我们通常在机器学习中使用的损失函数。在这里,建议大家在继续进行机器学习的过程中多看几遍。因为这不是一蹴而就的事情。需要一些阅读时间和经验才能理解这些损失函数的工作方式和位置。扫描二维码进入CDA官方小程序,解锁更多新鲜资讯和优质内容,更有海量免费试听课程,不要错过!
