Angel中的损失函数详解
在最优化,统计学,计量经济学,决策论,机器学习和计算神经科学的领域中,损失函数或成本函数是指一种将一个事件(在一个样本空间中的一个元素)映射到一个表达与其事件相关的经济成本或机会成本的实数上的一种函数,借此直观表示的一些"成本"与事件的关联。一个最佳化问题的目标是将损失函数最小化。一个目标函数通常为一个损失函数的本身或者为其负值。当一个目标函数为损失函数的负值时,目标函数的值寻求最大化。
在统计学中,损失函数的作用是估计参数。在机器学习中损失函数越小,就代表模型拟合的越好,当中也会有过拟合的问题。过拟合出现的原因通常是学习时模型包含的参数过多,从而导致训练误差较低,但测试误差较高。如果说造成过拟合的原因是学习能力太强,那么造成欠拟合的原因就是学习能力太弱,从训练数据中的基本性质多没能学到
下面介绍下Angel中有哪些损失函数。
1. Angel中的损失函数
Angel中有丰富的损失函数, 可分为两类
分类损失函数
回归损失函数
分类损失函数如下表所示:
用图形化表示如下:
回归损失函数如下表所示
用图形化表示如下:
2. Angel中Loss的实现
Angel中的损失函数都实现了LossFunc Trait, 如下:
trait LossFunc extends Serializable {
var lossLayer: LossLayer = _
def getLabels: Array[Float] = lossLayer.getLabel.asInstanceOf[BlasFloatMatrix].getData
def getAttachedArr: Array[String] = lossLayer.getAttached
def setLossLayer(layer: LossLayer): this.type = {
lossLayer = layer
this
}
def calLoss(modelOut: Matrix, graph: Graph): Double
def loss(pred: Double, label: Double): Double
def calGrad(modelOut: Matrix, graph: Graph): Matrix
def predict(modelOut: Matrix, graph: Graph): List[PredictResult]
private[mlcore] def toJson: JObject = {
JObject(JField(LossFuncKeys.typeKey, JString(s"${this.getClass.getSimpleName}")))
}
}
可见, angel中的loss的不仅有计算loss的功能, 还有计算梯度, 预测两项功能. 正是由于在Loss中实现了梯度计算, 才使反向传导有了起点. 在LossLayer中计算梯度就是直接调用lossFunc的calGrad, 如下:
override def calGradOutput(): Matrix = {
val start = System.currentTimeMillis()
status match {
gradOutput = lossFunc.calGrad(output, graph)
status = STATUS.Backward
case _ =>
}
val end = System.currentTimeMillis()
gradOutput
}
另外一项功能是预测, 在LossLayer中计算预测值就是直接调用lossFunc的predict, 如下:
override def predict(): Matrix = {
status match {
case STATUS.Null =>
calOutput()
case _ =>
}
lossFunc.predict(output)
}
Angel提供了很多的loss func实现, 如下图:
3. Loss Function的Json配置
无参数的损失函数
除了huberloss外, 其它的lossfunc匀为无参数的损失函数, 有两种表达方式, 如下
"lossfunc": "logloss"
"lossfunc": {
"type": "logloss"
}
参数的损失函数
只有huberloss, 具体如下:
"lossfunc": {
"type": "huberloss",
"delta": 0.1
}
完整的示例如下:
{
"data": {
"format": "dummy",
"indexrange": 148,
"validateratio": 0.1,
"numfield": 13,
"sampleratio": 0.2
},
"train": {
"epoch": 5,
"lr": 0.8,
"decay": 0.2
},
"model": {
"modeltype": "T_FLOAT_DENSE",
"modelsize": 148
},
"default_optimizer": {
"type": "momentum",
"reg2": 0.01
},
"layers": [
{
"name": "wide",
"type": "simpleinputlayer",
"outputdim": 1,
"transfunc": "identity"
},
{
"name": "embedding",
"type": "embedding",
"numfactors": 8,
"outputdim": 104
},
{
"name": "biinnersumcross",
"type": "BiInnerSumCross",
"inputlayer": "embedding",
"outputdim": 1
},
{
"name": "sumPooling",
"type": "SumPooling",
"outputdim": 1,
"inputlayers": [
"wide",
"biinnersumcross"
]
},
{
"name": "simplelosslayer",
"type": "losslayer",
"lossfunc": "logloss",
"inputlayer": "sumPooling"
}
]
}