【深度学习】损失函数(平均绝对误差,均方误差,平滑损失,交叉熵,带权值的交叉熵,骰子损失,FocalLoss)

目录

1.回归损失

平均绝对误差( Mean Absolute Error,MAE )

均方误差

Smooth L1 Loss

2.分类损失

交叉熵

带权重的交叉熵

Dice Loss

Focal Loss


损失函数是用于衡量模型所作出的预测离真实值(Ground Truth)之间的偏离程度。 通常,我们都会最小化目标函数,最常用的算法便是“梯度下降法”(Gradient Descent)。俗话说,任何事情必然有它的两面性,因此,并没有一种万能的损失函数能够适用于所有的机器学习任务,所以在这里我们需要知道每一种损失函数的优点和局限性,才能更好的利用它们去解决实际的问题。损失函数大致可分为两种:回归损失(针对连续型变量)和分类损失(针对离散型变量)。

1.回归损失

 

平均绝对误差( Mean Absolute Error,MAE )

如上图L1曲线

 

概念:也称为Mean Absolute Error,即平均绝对误差(MAE),它衡量的是预测值与真实值之间距离的平均误差幅度,作用范围为0到正无穷。

优点: 收敛速度快,能够对梯度给予合适的惩罚权重,而不是“一视同仁”,使梯度更新的方向可以更加精确。

缺点: 对异常值十分敏感,梯度更新的方向很容易受离群点所主导,不具备鲁棒性。

均方误差

如上图L2曲线

MSE=\frac{1}{n}\sum_{i=1}^{n}[f(x_{i})-y_{i}]^{2}

概念:也称为Mean Squred Error,即均方差(MSE),它衡量的是预测值与真实1值之间距离的平方和,作用范围同为0到正无穷。

优点: 对离群点(Outliers)或者异常值更具有鲁棒性。

缺点: 在0点处的导数不连续,使得求解效率低下,导致收敛速度慢;而对于较小的损失值,其梯度也同其他区间损失值的梯度一样大,所以不利于网络的学习。

Smooth L1 Loss

如上图红色曲线

即平滑的L1损失(SLL),出自Fast RCNN [7]。SLL通过综合L1和L2损失的优点,在0点处附近采用了L2损失中的平方函数,解决了L1损失在0点处梯度不可导的问题,使其更加平滑易于收敛。此外,在|x|>1的区间上,它又采用了L1损失中的线性函数,使得梯度能够快速下降。

Smooth_{L1}(x)=\begin{cases} 0.5x^{2} & \text{ if } |x|<1\\ |x|-0.5& \text{ otherwise} \end{cases}

通过对这三个损失函数进行求导可以发现,L1损失的导数为常数,如果不及时调整学习率,那么当值过小时,会导致模型很难收敛到一个较高的精度,而是趋向于一个固定值附近波动。反过来,对于L2损失来说,由于在训练初期值较大时,其导数值也会相应较大,导致训练不稳定。最后,可以发现Smooth L1在训练初期输入数值较大时能够较为稳定在某一个数值,而在后期趋向于收敛时也能够加速梯度的回传,很好的解决了前面两者所存在的问题。

2.分类损失

交叉熵

交叉熵损失函数可以衡量p与q的相似性,p表示真实标记的分布,其值要么是0,要么是1,q则为训练后的模型的预测标记分布,

H(p,q)=-\sum_{i=1}^{n}p(x_{i})log(q(x_{i}))

交叉熵的局限性: 当使用交叉熵损失时,标签的统计分布在训练准确性中起着重要作用。标签分布越不平衡,训练就越困难。在交叉熵损失中,将损失计算为每个像素损失的平均值,并离散计算每个像素损失,而无需知道其相邻像素是否为边界。结果,交叉熵损失仅在微观意义上考虑损失,而不是全局考虑,这不足以进行图像水平预测。每个样本是没有权重的,但是针对不同的类别,有相应的权重

带权重的交叉熵

 

p是经softmax处理后的输出值;

l(x)表示每个像素的真实标签

pl(x)(x):点x在对应的标签给出的那个类别的输出的激活值

w:在训练过程中给每个像素点的权重

Dice Loss

骰子损失是一种损失函数,可以防止普通交叉熵损失中存在的某些限制。

当使用交叉熵损失时,标签的统计分布在训练准确性中起着重要作用。标签分布越不平衡,训练就越困难。尽管加权交叉熵损失可以减轻困难,但是改进并不明显,也没有解决交叉熵损失的内在问题。

Dice Loss即骰子损失,出自V-Net [3],是一种用于评估两个样本之间相似性度量的函数,取值范围为0~1,值越大表示两个值的相似度越高,其基本定义(二分类)如下:

 

其中,|X∩Y|表示X和Y之间的交集,|X|和|Y|分别表示集合X和Y中像素点的个数,分子乘于2保证域值范围在0~1之间,因为分母相加时会计算多一次重叠区间,如下图:

 

从右边公式也可以看出,其实Dice系数是等价于F1分数的,优化Dice等价于优化F1值。此外,为了防止分母项为0,一般我们会在分子和分母处同时加入一个很小的数作为平滑系数,也称为拉普拉斯平滑项。Dice损失由以下两个主要特性:

有益于正负样本不均衡的情况,侧重于对前景的挖掘;训练过程中,在有较多小目标的情况下容易出现振荡; 极端情况下会出现梯度饱和的情况。所以一般来说,我们都会结合交叉熵损失或者其他分类损失一同进行优化。

Focal Loss

焦点损失,出自何凯明的《Focal Loss for Dense Object Detection》[4],出发点是解决目标检测领域中one-stage算法如YOLO系列算法准确率不高的问题。作者认为样本的类别不均衡(比如前景和背景)是导致这个问题的主要原因。比如在很多输入图片中,我们利用网格去划分小窗口,大多数的窗口是不包含目标的。如此一来,如果我们直接运用原始的交叉熵损失,那么负样本所占比例会非常大,主导梯度的优化方向,即网络会偏向于将前景预测为背景。即使我们可以使用OHEM(在线困难样本挖掘)算法来处理不均衡的问题,虽然其增加了误分类样本的权重,但也容易忽略掉易分类样本。而Focal loss则是聚焦于训练一个困难样本的稀疏集,通过直接在标准的交叉熵损失基础上做改进,引进了两个惩罚因子,来减少易分类样本的权重,使得模型在训练过程中更专注于困难样本。其基本定义如下:

 其中:

参数 α 和 (1-α) 分别用于控制正/负样本的比例,其取值范围为[0, 1]。α的取值一般可通过交叉验证来选择合适的值。 参数 γ 称为聚焦参数,其取值范围为[0, +∞),目的是通过减少易分类样本的权重,从而使模型在训练时更专注于困难样本。 当 γ = 0 时,Focal Loss就退化为交叉熵损失,γ 越大,对易分类样本的惩罚力度就越大。

实验中,作者取(α=0.25,γ=0.2)的效果最好,具体还需要根据任务的情况调整。由此可见,应用Focal-loss也会引入多了两个超参数需要调整,而一般来说很需要经验才能调好。

  • 2
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,我们需要导入必要的库和数据集。假设我们已经有了名为`ieee30.mat`的数据集。 ```python import numpy as np import scipy.io as sio import tensorflow as tf import random data = sio.loadmat('ieee30.mat') ``` 数据集中包含了节点的电气参数,我们需要将其转化为一个特征矩阵,并将其输入到DQN模型中。 ```python # 获取节点特征 features = data['features'] # 将特征矩阵转化为numpy数组 features = np.array(features) # 定义模型输入和输出的维度 num_features = features.shape[1] num_actions = len(features) # 定义DQN模型 class DQN: def __init__(self, num_features, num_actions): # 定义输入占位符 self.states = tf.placeholder(shape=[None, num_features], dtype=tf.float32) # 定义隐藏层 self.hidden_layer = tf.layers.dense(inputs=self.states, units=64, activation=tf.nn.relu) # 定义输出层 self.output_layer = tf.layers.dense(inputs=self.hidden_layer, units=num_actions, activation=None) # 定义动作占位符和Q值占位符 self.actions = tf.placeholder(shape=[None], dtype=tf.int32) self.Q_values = tf.placeholder(shape=[None], dtype=tf.float32) # 通过索引获取Q值 Q = tf.reduce_sum(tf.multiply(self.output_layer, tf.one_hot(self.actions, num_actions)), axis=1) # 定义损失函数 self.loss = tf.reduce_mean(tf.square(self.Q_values - Q)) # 定义优化器 self.optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(self.loss) # 初始化模型 dqn = DQN(num_features, num_actions) ``` 接下来,我们需要定义一些DQN算法的重要参数,例如学习率、批次大小、折扣因子等。 ```python # 定义重要参数 learning_rate = 0.001 batch_size = 32 gamma = 0.95 epsilon = 1.0 epsilon_min = 0.01 epsilon_decay = 0.995 num_episodes = 1000 ``` 然后,我们可以开始训练模型。 ```python # 创建TensorFlow会话 with tf.Session() as sess: # 初始化全局变量 sess.run(tf.global_variables_initializer()) # 训练模型 for episode in range(num_episodes): # 重置环境 state = features # 记录总奖励 total_reward = 0 # 记录步数 step = 0 while True: # 选择动作 if random.uniform(0, 1) < epsilon: action = random.randint(0, num_actions - 1) else: Q_values = sess.run(dqn.output_layer, feed_dict={dqn.states: np.expand_dims(state, axis=0)}) action = np.argmax(Q_values) # 执行动作 next_state = features reward = 0 # 更新Q值 Q_values_next_state = sess.run(dqn.output_layer, feed_dict={dqn.states: np.expand_dims(next_state, axis=0)}) Q_value = reward + gamma * np.max(Q_values_next_state) # 记录总奖励 total_reward += reward # 将Q值添加到记忆库中 replay_memory.append((state, action, Q_value, next_state)) # 从记忆库中随机抽取一批样本 batch = random.sample(replay_memory, batch_size) # 计算损失函数并优化模型 states, actions, Q_values, next_states = zip(*batch) states = np.array(states) actions = np.array(actions) Q_values = np.array(Q_values) next_states = np.array(next_states) sess.run(dqn.optimizer, feed_dict={dqn.states: states, dqn.actions: actions, dqn.Q_values: Q_values}) # 更新状态 state = next_state # 更新步数 step += 1 # 如果到达终止状态,则跳出循环 if done: break # 更新epsilon epsilon = max(epsilon_min, epsilon * epsilon_decay) # 打印每一轮的总奖励 print('Episode {}: Total reward = {}'.format(episode, total_reward)) ``` 最后,我们可以使用训练好的模型对节点进行重要度排序。 ```python # 获得每个节点的Q值 Q_values = sess.run(dqn.output_layer, feed_dict={dqn.states: features}) # 对Q值进行排序 ranked_nodes = np.argsort(Q_values)[::-1] # 打印排名前十的节点 print('Ranked nodes:', ranked_nodes[:10]) ``` 这就是使用DQN算法对IEEE30节点系统进行节点重要度排序的Python代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无咎.lsy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值