超参数 Acemyzoe

损失函数

损失函数用来评价模型的预测值真实值不一样的程度,损失函数越好,通常模型的性能越好。

tain loss & test loss

train loss 不断下降,test loss不断下降,说明网络仍在学习;(最好的) train loss 不断下降,test loss趋于不变,说明网络过拟合;(max pool或者正则化) train loss 趋于不变,test loss不断下降,说明数据集100%有问题;(检查dataset) train loss 趋于不变,test loss趋于不变,说明学习遇到瓶颈,需要减小学习率或批量数目;(减少学习率) train loss 不断上升,test loss不断上升,说明网络结构设计不当,训练超参数设置不当,数据集经过清洗等问题。(最不好的情况)

回归问题

平均损失函数(最小二乘法)

回归问题中常用的损失函数,在线性回归中,可以通过极大似然估计(MLE)推导。计算的是预测值与真实值之间距离的平方和。实际更常用的是均方误差(MSE)

平均值绝对误差(L1损失)——MAE

MAE是目标值和预测值之差的绝对值之和,可以用来衡量预测值和真实值的距离。

MAE(L1损失) VS MSE(L2损失)

MSE计算简便,但MAE对异常点有更好的鲁棒性:当数据中存在异常点时,用RMSE计算损失的模型以牺牲了其他样本的误差为代价,朝着减小异常点误差的方向更新,会降低模型的整体性能。

NN中MAE更新梯度始终相同,而MSE则不同: MSE损失的梯度随损失增大而增大,而损失趋于0时则会减小。

使用MAE训练神经网络最大的一个问题就是不变的大梯度,这可能导致在使用梯度下降快要结束时,错过了最小点,为了解决这个缺陷,我们可以使用变化的学习率,在损失接近最小值时降低学习率。而对于MSE,梯度会随着损失的减小而减小,这使得在训练结束时,使用MSE模型的结果会更精确。

Loss选择建议:

  • MSE: 如果异常点代表在商业中很重要的异常情况,并且需要被检测出来

  • MAE: 如果只把异常值当作受损数据

Huber损失

Huber损失是绝对误差,只是在误差很小时,就变为平方误差。

当δ很大时,等价为MSE曲线,当δ很小时,等价为MAE曲线。 \(L_\delta(y,f(x))=\{ { {1\over2}(y-f(x))^2 \qquad for|y-f(x)|<\delta \atop {\delta|y-f(x)|-{1\over2}\delta^2 \qquad otherwise} }\)

LogLoss

对数损失(Logarithmic Loss), 即对数似然损失(Log-likelihood Loss), 也称交叉熵损失(cross-entropy Loss)。

对数损失通过惩罚错误的分类,实现对分类器的准确度(Accuracy)的量化。 最小化对数损失基本等价于最大化分类器的准确度。

当使用sigmoid作为激活函数的时候,常用交叉熵损失函数而不用均方误差损失函数,因为它可以完美解决平方损失函数权重更新过慢的问题,具有“误差大的时候,权重更新快;误差小的时候,权重更新慢”的良好性质。

#!/usr/bin/env python
# -*- coding: utf8 -*-
# y_true: list, the true labels of input instances 
# y_pred: list, the probability when the predicted label of input instances equals to 1
def logloss(y_true, y_pred, eps=1e-15):
    import numpy as np

    # Prepare numpy array data
    y_true = np.array(y_true)
    y_pred = np.array(y_pred)
    assert (len(y_true) and len(y_true) == len(y_pred))

    # Clip y_pred between eps and 1-eps
    p = np.clip(y_pred, eps, 1-eps)
    loss = np.sum(- y_true * np.log(p) - (1 - y_true) * np.log(1-p))

    return loss / len(y_true)

def unitest():
    y_true = [0, 0, 1, 1]
    y_pred = [0.1, 0.2, 0.7, 0.99]

    print ("Use self-defined logloss() in binary classification, the result is {}".format(logloss(y_true, y_pred)))

    from sklearn.metrics import log_loss
    print ("Use log_loss() in scikit-learn, the result is {} ".format(log_loss(y_true, y_pred)))

if __name__ == '__main__':
    unitest()

exponential loss

指数损失函数,对离群点、噪声非常敏感。经常用在AdaBoost算法中。

评价指标

如何评估机器学习算法模型是任何项目中一个非常重要的环节。分类问题一般会选择准确率(Accuracy)或者AUC作为metric,回归问题使用MSE。上述损失函数大部分可以直接作为评价指标来使用。

回归问题

MSE

均方误差 (Mean Square Error) \(MSE={1\over n}{\sum^{n}_{i=1}(\hat{y_i} -{y_i})^2}\)

范围[0,+∞),当预测值与真实值完全吻合时等于0,即完美模型;误差越大,该值越大。

RMSE

均方根误差 (Root Mean Square Error) \(RMSE=\sqrt {MSE} = \sqrt {\frac{1}{n} \sum_{i=1}^{n} (\hat{y}_i - y_i)^2}\)

数量级上比较直观,比如RMSE=10,可以认为回归效果相比真实值平均相差10。

MAE

平均绝对误差(Mean Absolute Error) \(MAE=\frac{1}{n} \sum_{i=1}^{n} |\hat{y}_i - y_i|\)

MAPE

平方绝对百分比误差 (Mean Absolute Percentage Error) \(MAPE=\frac{100\%}{n}\sum_{i=1}^n |\frac{ \hat{y}_i - y_i }{ y_i }|\)

当真实值有数据等于0时,存在分母0除问题,该公式不可用。

SMAPE

对称平均绝对百分比误差 (Symmetric Mean Absolute Percentage Error) \(SMAPE=\frac{100\%}{n}\sum_{i=1}^n \frac{ |\hat{y}_i - y_i| }{ (|\hat{y}_i| + |y_i|)/2 }\)

R Squared

决定系数 (coefficient of determination) \(R^2=1-{\frac {\sum _i (\hat y_i-y_i)^2}{\sum _i (\overline y-y_i)^2}}\)

  1. 分母代表baseline(平均值)的误差,分子代表模型的预测结果产生的误差;
  2. 预测结果越大越好,R为1说明完美拟合, 为0说明和baseline一致;

分类问题

Confusion Matrix

混淆矩阵,后续多个指标的基础。

eg. 二类混淆矩阵(训练目的:减少FP、FN)

  预测正例 预测反例
真实正例 TP 真正例 FN 假反例
真实反例 FP 假反例 TN 真反例

Accuracy

准确率:当样本类别均衡时,Accuracy是一个很好的指标。但在样本不平衡的情况下,产生效果较差。 \(Acc=\frac {TP+TN}{TP+TN+FP+FN}\)

Precision

精准率:预测为正例的样本中有多少实际为正。 \(P=\frac {TP}{TP+FP}\)

Recall

召回率:实际为正例的样本有多少被预测为正。 \(R=\frac {TP}{TP+FN}\)

P-R曲线

通过选择不同的阈值,得到Recall和Precision,以Recall为横坐标,Precision为纵坐标得到的曲线图。

加权调和平均&调和平均

beta>1时召回率(Recall)影响更大。

beta<1时,精确率(Precision)影响更大。 \(F_\beta=\frac{(1+\beta^2)PR}{\beta^2P+R},(\beta=1时)F_1=\frac {2PR}{P+R}\)

ROC-AUC

Area Under Curve(AUC)二分类问题中使用非常广泛的一个评价指标。AUC的本质是,任取一个正样本和负样本,模型输出正样本的值大于负样本值的概率。构成AUC的两个基本指标是假正例率和真正例率。

  • 横轴-假正例率: 实际为负的样本多少被预测为正。FPR。
  • 纵轴-真正例率: 实际为正的样本多少被预测为正。TPR。

TPR和FPR的范围均是[0,1],通过选择不同的阈值得到TPR和FPR,然后绘制ROC曲线。ROC曲线下的面积为AUC值。

代码

# coding=utf-8
import numpy as np
from sklearn import metrics
y_true=np.array([1.1,3.3,5.5,7.7])
y_pred=np.array([1.0,3.0,5.0,7.0])

# MSE
def MSE(true, pred):
    return np.sum((true - pred)**2)
mse=metrics.mean_squared_error(y_true,y_pred)
# RMSE
rmse=np.sqrt(mse)
# MAE
def mae(true, pred):
    return np.sum(np.abs(true - pred))
mae=metrics.mean_absolute_error(y_true,y_pred)
# MAPE
mape=np.mean(np.abs(y_pred-y_true)/y_true)*100
#SMPAE
smape=np.mean(2*np.abs(y_pred-y_true)/(np.abs(y_pred)+np.abs(y_true)))*100
# R Squared
RS=metrics.r2_score(y_true,y_pred)
# huber loss
def huber(true, pred, delta):
    loss = np.where(np.abs(true-pred) < delta , 0.5*((true-pred)**2), delta*np.abs(true - pred) - 0.5*(delta**2))
    return np.sum(loss)

y_trues = [1,1,1,1,0,0,1,1,1,0,0]
y_preds = [1,1,1,0,1,1,0,1,1,1,0] 

# ACC准确率
acc=metrics.accuracy_score(y_trues,y_preds)
# Precision精准率
P=metrics.precision_score(y_trues,y_preds)
# Recall召回率
R=metrics.recall_score(y_trues,y_preds)
# F
F=metrics.fbeta_score(y_trues,y_preds,beta=1)

学习率

学习率 (learning rate),控制模型的 学习进度

  学习率 大 学习率 小
学习速度
使用时间点 刚开始训练时 一定轮数过后
副作用 1.易损失值爆炸;2.易振荡。 1.易过拟合;2.收敛速度慢。

学习率设置

在训练过程中,一般根据训练轮数设置动态变化的学习率

  • 刚开始训练时:学习率以 0.01 ~ 0.001 为宜。
  • 一定轮数过后:逐渐减缓。
  • 接近训练结束:学习速率的衰减应该在100倍以上。

Note: 如果是 迁移学习 ,由于模型已在原始数据上收敛,此时应设置较小学习率 (≤10−4≤10−4) 在新数据上进行 微调

目标函数损失值曲线

理想情况下曲线:滑梯式下降 曲线初始时上扬:初始 学习率过大 导致 振荡,应减小学习率,并 从头 开始训练 曲线初始时强势下降没多久归于水平:后期 学习率过大导致无法拟合,应减小学习率,并重新训练 后几轮 。 曲线全程缓慢:初始学习率过小导致 收敛慢,应增大学习率,并从头 开始训练。