最近正值秋招季,很多同学都在忙着温习深度学习相干的基础知识应答面试和口试。这段时间,正好发现自己基础知识也比拟单薄,想系统性的温习和整顿一下。基于这样一个出发点,最近筹备开始一个名为【CV 知识点扫盲】的专题文章,帮忙本人和更多人温习计算机视觉中的基础知识,也心愿可能对正在找工作的同学有帮忙。
1、机器学习中常见的损失函数及其利用场景?
用于分类问题:
0- 1 损失函数:
$$
L_{0-1}(f, y)=1_{f y \leq 0}
$$
0- 1 损失函数能够直观的刻画分类的错误率,然而因为其非凸,非润滑的特点,使得算法很难对其进行间接优化
Hinge 损失函数(SVM)
$$
L_{\text {hinge}}(f, y)=\max \{0,1-f y\}
$$
Hinge 损失函数是 0 - 1 损失函数的一个代理损失函数,也是其紧上界,当 $f y \geq 0$ 时,不对模型做惩办。能够看到,hinge 损失函数在 $f y=1$ 处不可导,因而不能用梯度降落法对其优化,只能用次梯度降落法。
Logistic 损失函数
$$
L_{\text {logistic}}(f, y)=\log _{2}(1+\exp (-f y))
$$
Logistic 损失函数是 0 - 1 损失函数的另一个代理损失函数,它也是 0 - 1 损失函数的凸上界,且该函数处处润滑。然而该损失函数对所有样本点都惩办,因而对异样值更加敏感。当预测值 $ f ∈ [− 1 , 1] $ 时,另一个罕用的代理损失函数是穿插熵损失函数
Cross-Entropy 损失函数
$$
L_{\text {cross entropy}}(f, y)=-\log _{2}\left(\frac{1+f y}{2}\right)
$$
穿插熵损失函数也是 0 - 1 损失函数的润滑凸上界
Exponential 损失函数(AdaBoost)
$$
L_{\text {exponential}}(f, y)=e^{-f y}
$$
指数损失函数是 AdaBoost 里应用的损失函数,同样地,它对异样点较为敏感,鲁棒性不够
Logistic 损失函数(LR)
$$
L_{\text {logloss}}(y, p(y \mid x))=-\log (p(y \mid x))
$$
逻辑回归 $ p (y ∣ x) $ 的表达式如下:
$$
P\left(Y=y^{(i)} \mid x^{(i)}, \theta\right)=\left\{\begin{array}{l}h_{\theta}\left(x^{(i)}\right)=\frac{1}{1+e^{\theta_{x}}}, y^{(i)}=1 \\ 1-h_{\theta}\left(x^{(i)}\right)=\frac{e^{\theta^{T_{x}}}}{1+e^{\theta_{x}}}, y^{(i)}=0,\end{array}\right.
$$
将下面两个式子合并,可得第 i 个样本被正确预测的概率:
$$
P\left(Y=y^{(i)} \mid x^{(i)}, \theta\right)=\left(h_{\theta}\left(x^{(i)}\right)\right)^{y^{(i)}}\left(1-h_{\theta}\left(x^{(i)}\right)\right)^{1-y^{(i)}}
$$
对于所有的样本,因为生成过程是独立的,因而
$$
P(Y \mid X, \theta)=\Pi_{i=1}^{N}\left(h_{\theta}\left(x^{(i)}\right)\right)^{y^{(i)}}\left(1-h_{\theta}\left(x^{(i)}\right)\right)^{1-y^{(i)}}
$$
最终的损失函数如下:
$$
\mathcal{J}(\theta)=-\sum_{i=1}^{N}\left[y^{(i)} \log \left(h_{\theta}\left(x^{(i)}\right)\right)+\left(1-y^{(i)}\right) \log \left(1-h_{\theta}\left(x^{(i)}\right)\right)\right]
$$
用于回归问题:
对于回归问题,$Y=\mathbb{R}$,咱们心愿 $f\left(x^{(i)}, \theta\right)=y^{(i)}$
平方损失函数(最小二乘法)
$$
L_{\text {square}}(f, y)=(f-y)^{2}
$$
平方损失函数是润滑的,能够用梯度降落法求解,然而,当预测值和实在值差别较大时,它的惩办力度较大,因而对异样点较为敏感。
相对损失函数
$$
L_{\text {absolute}}(f, y)=|f-y|
$$
相对损失函数对异样点不那么敏感,其鲁棒性比平方损失更强一些,然而它在 $f=y$ 处不可导
Huber 损失函数
$$
L_{H u b e r}(f, y)=\left\{\begin{array}{l}\frac{1}{2}(f-y)^{2},|f-y| \leq \delta \\ \delta|f-y|-\frac{1}{2} \delta^{2},|f-y|>\delta,\end{array}\right.
$$
Huber 损失函数在 ∣ f − y ∣较小时为平方损失,在 ∣ f − y ∣ 较大时为线性损失,且处处可导,对异样点鲁棒性较好。
Log-cosh 损失函数
$$
L_{\log -\cosh}(f, y)=\log (\cosh (f-y))
$$
其中 $\cosh (x)=\left(e^{x}+e^{-x}\right) / 2$,log-cosh 损失函数比均方损失函数更加润滑,具备 huber 损失函数的所有长处,且二阶可导。因而能够应用牛顿法来优化计算,然而在误差很大状况下,一阶梯度和 Hessian 会变成定值,导致牛顿法生效。
分位数损失函数
$$
L_{\gamma}(f, y)=\sum_{i: y_{i}<f_{i}}(1-\gamma)\left|y_{i}-f_{i}\right|+\sum_{i: y_{i} \geq f_{i}} \gamma\left|y_{i}-f_{i}\right|
$$
预测的是指标的取值范畴而不是值。γ 是所需的分位数,其值介于 0 和 1 之间,γ 等于 0.5 时,相当于 MAE。设置多个 γ 值,失去多个预测模型,而后绘制成图表,即可晓得预测范畴及对应概率(两个 γ 值相减)
用于检索问题
Triplet loss
$$
\sum_{i}^{N}\left[\left\|f\left(x_{i}^{a}\right)-f\left(x_{i}^{p}\right)\right\|_{2}^{2}-\left\|f\left(x_{i}^{a}\right)-f\left(x_{i}^{n}\right)\right\|_{2}^{2}+\alpha\right]_{+}
$$
[]\_+ 相当于一个 ReLU 函数。三元组的形成:从训练数据集中随机选一个样本,该样本称为 Anchor,而后再随机选取一个和 Anchor 属于同一类的样本和不同类的样本, 这两个样本对应的称为 Positive 和 Negative,由此形成一个三元组。
通过学习,让正样本特色表白之间的间隔尽可能小,而负样本的特色表白之间的间隔尽可能大,并且要让正样本之间的间隔和负样本之间的间隔之间有一个最小的距离(margin)。损失函数如下所示:
Sum Hinge Loss & Max Hinge Loss
Triplet loss 的输出是 (a, p, n),个别的做法是 b 个 $\left(a_{i}, p_{i}\right) i \in[0, b]$pair 对,咱们对 pi 旋转一下失去 $\left(p_{1}, p_{2}, \ldots, p_{b}, p_{0}\right)$ 作为负样本列表。最初失去一个一维的 loss 向量 $\left(l_{1}, l_{2} \ldots, l_{b}\right)$。
Triplet loss 实际上只思考了由 a 和 p 组成矩阵的局部状况产生的 loss,咱们实际上能够对 a、p 产生的类似度矩阵中所有非对角线的负样本进行计算损失,从而充分利用 batch 内的信息,通过这个思路咱们能够失去 Sum Hinge Loss 如下,Triplet loss 的计算中是用的 L2 间隔,这里改为了余弦类似度,所以之前的 ap – an + margin,改为了 an – ap + margin 了,指标是让 an 的类似度更小,ap 的类似度更大
Sum Hinge Loss:
$$
\ell_{S H}(i, c)=\sum_{\hat{c}}[\alpha-s(i, c)+s(i, \hat{c})]{+}+\sum{\hat{i}}[\alpha-s(i, c)+s(\hat{i}, c)]_{+}
$$
Max Hinge Loss:
VSE++ 提出了一个新的损失函数 max hinge loss,它主张在排序过程中应该更多地关注艰难负样例,艰难负样本是指与 anchor 靠得近的负样本,试验后果也显示 max hinge loss 性能比之前罕用的排序损失 sum hinge loss 好很多:
$$
\ell_{M H}(i, c)=\max {c^{\prime}}\left[\alpha+s\left(i, c^{\prime}\right)-s(i, c)\right]{+}+\max {i^{\prime}}\left[\alpha+s\left(i^{\prime}, c\right)-s(i, c)\right]{+}
$$
Max Hinge Loss pytorch 代码如下:
def cosine_sim(im, s):
"""Cosine similarity between all the image and sentence pairs"""
return im.mm(s.t())
class MaxHingLoss(nn.Module):
def __init__(self, margin=0.2, measure=False, max_violation=True):
super(MaxHingLoss, self).__init__()
self.margin = margin
self.sim = cosine_sim
self.max_violation = max_violation
def forward(self, im, s):
an = self.sim(im, s) # an
diagonal = scores.diag().view(im.size(0), 1)
ap1 = diagonal.expand_as(scores)
ap2 = diagonal.t().expand_as(scores)
# query2doc retrieval
cost_s = (self.margin + an - ap1).clamp(min=0)
# doc2query retrieval
cost_im = (self.margin + an - ap2).clamp(min=0)
# clear diagonals
mask = torch.eye(scores.size(0)) > .5
I = Variable(mask)
if torch.cuda.is_available():
I = I.cuda()
cost_s = cost_s.masked_fill_(I, 0)
cost_im = cost_im.masked_fill_(I, 0)
# keep the maximum violating negative for each query
if self.max_violation:
cost_s = cost_s.max(1)[0][:1]
cost_im = cost_im.max(0)[0][:1]
return cost_s.mean() + cost_im.mean()
# or # return cost_s.sum() + cost_im.sum()
Info NCE
Info NCE loss 是 NCE 的一个简略变体,它认为如果你只把问题看作是一个二分类,只有数据样本和噪声样本的话,可能对模型学习不敌对,因为很多噪声样本可能本就不是一个类,因而还是把它看成一个多分类问题比拟正当(但这里的多分类 k 指代的是负采样之后负样本的数量),于是就有了 InfoNCE loss 函数如下:
$$
L_{q}=-\log \frac{\exp \left(q \cdot k_{+} / \tau\right)}{\left.\sum_{i=0}^{k} \exp \left(q \cdot k_{i} / \tau\right)\right)}
$$
其中 $q \cdot k$ 相当于是 logits,$\tau$ 是温度系数,整体和 cross entropy 是十分相近的。
用于检测问题:
类别损失
Softmax+ 穿插熵
对于二分类而言,穿插熵损失函数模式如下:
$$
\mathrm{L}=-\mathrm{ylog} y^{\prime}-(1-y) \log \left(1-y^{\prime}\right)=\left\{\begin{array}{ll}-\log y^{\prime}, & y=1 \\ -\log \left(1-y^{\prime}\right), & y=0\end{array}\right.
$$
穿插熵损失函数通过一直放大两个散布的差别,使预测后果更牢靠。
Focal Loss
focal loss 出于论文 Focal Loss for Dense Object Detection,次要是为了解决 one-stage 指标检测算法中正负样本比例重大失衡的问题,升高了大量简略负样本在训练中所占的比重,可了解为是一种艰难样本开掘。focal loss 是在穿插熵损失函数上批改的。具体改良:
$$
\mathrm{L}_{f l}=\left\{\begin{array}{cc}-\alpha\left(1-y^{\prime}\right)^{\gamma} \log y^{\prime}, & y=1 \\ -(1-\alpha) y^{\prime \gamma} \log \left(1-y^{\prime}\right), & y=0\end{array}\right.
$$
其中 γ >0(文章中取 2)使得缩小易分类样本的损失,更关注艰难的、错分的样本。例如 γ 为 2,对于正类样本而言,预测后果为 0.95 必定是简略样本,所以(1-0.95)的 γ 次方就会很小,这时损失函数值就变得更小。而预测概率为 0.3 的样本其损失绝对很大。对于负类样本而言同样,预测 0.1 的后果该当远比预测 0.7 的样本损失值要小得多。对于预测概率为 0.5 时,损失只缩小了 0.25 倍,所以更加关注于这种难以辨别的样本。这样缩小了简略样本的影响,大量预测概率很小的样本叠加起来后的效应才可能比拟无效。
此外退出均衡因子 α,用来均衡正负样本自身的比例不均,文中取值为 0.25,即正样本比负样本占比小,这是因为负例易分
地位损失
L1(MAE),L2(MSE),smooth L1 损失函数
利用 L1,L2 或者 smooth L1 损失函数,来对 4 个坐标值进行回归。smooth L1 损失函数是在 Fast R-CNN 中提出的。三个损失函数,如下所示:
$$
L 1=|x|\\L 2=x^{2}\\smoothL1 =\left\{\begin{array}{cc}0.5 x^{2} & \text {if}|x|<1 \\ |x|-0.5 & \text {otherwise}\end{array}\right.
$$
从损失函数对 x 的导数可知:L1 损失函数对 x 的导数为常数,不会有梯度爆炸的问题,但其在 0 处不可导,在较小损失值时,失去的梯度也绝对较大,可能造成模型震荡不利于收敛。L2 损失函数处处可导,但因为采纳平方运算,当预测值和实在值的差值大于 1 时,会放大误差。尤其当函数的输出值间隔核心值较远的时候,应用梯度降落法求解的时候梯度很大,可能造成梯度爆炸。同时当有多个离群点时,这些点可能占据 Loss 的次要局部,须要就义很多无效的样本去弥补它,所以 L2 loss 受离群点的影响较大。smooth L1 完满的避开了 L1 和 L2 损失的毛病:
- 在 [-1,1] 之间就是 L2 损失,解决 L1 在 0 处有折点
- 在 [-1,1] 区间以外就是 L1 损失,解决离群点梯度爆炸问题
- 当预测值与实在值误差过大时,梯度值不至于过大
- 当预测值与实在值误差很小时,梯度值足够小
上述 3 个损失函数存在以下有余:
- 上述三个损失函数在计算 bounding box regression loss 时,是独立的求 4 个点的 loss,而后相加失去最终的损失值,这种做法的前提是四个点是互相独立的,而实际上是有肯定相关性的
- 理论评估检测后果好坏的指标是 IoU,这两者是不等价的,多个检测框可能有雷同的 loss,但 IoU 差别很大
IoU Loss
IoU loss 的定义如下:
$$
L_I= 1-\frac{P \cap G}{P \cup G}
$$
其中 P 代表预测框,G 代表实在框。
GIoU loss
IoU 反映了两个框的重叠水平,在两个框不重叠时,IoU 衡等于 0,此时 IoU loss 恒等于 1。而在指标检测的边界框回归中,这显然是不适合的。因而,GIoU loss 在 IoU loss 的根底上思考了两个框没有重叠区域时产生的损失。具体定义如下:
$$
L_{G}=1-I o U+R(P, G)=1-I o U+\frac{|C-P \cup G|}{|C|}
$$
其中,C 示意两个框的最小突围矩形框,R(P,G)是惩办项。从公式能够看出,当两个框没有重叠区域时,IoU 为 0,但 R 仍然会产生损失。极限状况下,当两个框间隔无穷远时,R→1
DIoU Loss
IoU loss 和 GIoU loss 都只思考了两个框的重叠水平,但在重叠水平雷同的状况下,咱们其实更心愿两个框能挨得足够近,即框的核心要尽量凑近。因而,DIoU 在 IoU loss 的根底上思考了两个框的中心点间隔,具体定义如下:
$$
L_{G}=1-I o U+R(P, G)=1-I o U+\frac{\rho^{2}(p, g)}{c^{2}}
$$
其中,ρ 示意预测框和标注框核心端的间隔,p 和 g 是两个框的中心点。c 示意两个框的最小突围矩形框的对角线长度。当两个框间隔有限远时,中心点间隔和外接矩形框对角线长度有限迫近,R→1。
CIoU Loss
DIoU loss 思考了两个框中心点的间隔,而 CIoU loss 在 DIoU loss 的根底上做了更具体的度量,具体包含:
- 重叠面积
- 中心点间隔
- 长宽比
具体定义如下:
$$
L_{G}=1-I o U+R(P, G)=1-I o U+\frac{\rho^{2}(p, g)}{c^{2}}+\alpha v
$$
$$
v=\frac{4}{\pi^{2}}\left(\arctan \frac{w^{g}}{h^{g}}-\arctan \frac{w^{p}}{h^{p}}\right)^{2}\\\alpha=\frac{v}{(1-I o U)+v}
$$
用于宰割问题
dice Loss
dice loss 源于 dice 系数,是用于度量汇合类似度的度量函数,通常用于计算两个样本之间的类似度,公式如下:
$$
Dice =\frac{2|\mathrm{X} \cap Y|}{|X|+|Y|}
$$
那么对应的 dice loss 的公式如下:
$$
Dice loss =1-\frac{2|\mathrm{X} \cap Y|}{|X|+|Y|}
$$
依据 dice loss 的定义能够看出,dice loss 是一种区域相干的 loss,也即意味着某像素点的 loss 以及梯度值不仅和该点的 label 和预测值相干,也与其余点的 label 及预测值相干。dice loss 可用于样本极度不平衡的状况,而在个别状况下应用 dice loss 会对反向流传有不利的影响,使得训练不稳固。
穿插熵
语义宰割工作中最罕用的损失函数是穿插熵,通过一一比照每个像素失去损失值。
每个像素对应的损失函数为:
$$
pixel – loss =-\sum_{\text {classes}}\left(y_{c} \log \left(p_{c}\right)\right)
$$
$y_{c}$ 为一个 one-hot 向量,取值只有[0, 1],$p_c$ 为网络预测值通过 softmax 或 sigmoid 函数之后的概率值。
整个图像的损失就是每个像素的损失求均匀。穿插熵损失函数实用于大多数语义宰割场景中,然而当前景像素的数量远小于背景像素的数量时,此时背景的损失占主导地位,导致网络性能不佳。
带权值的穿插熵
针对类别不均衡的问题,通过给每个类别增加一个权重系数来缓解。加上权重之后的公式如下:
$$
pixel – loss =-\sum_{c}^{\text {classes}}\left(w_{c} y_{c} \log \left(p_{c}\right)\right)
$$
其中 $w_{c}=\frac{N-N_{c}}{N}$,$N$ 示意总的像素个数,而 $N_c$ 示意 GT 类别为 c 的像素个数。
2、为什么不能将辨认精度作为指标?
以数字辨认工作为例,咱们想取得的是能进步辨认精度的参数,特意再导入一个损失函数不是有些重复劳动吗?也就是说,既然咱们的指标是取得使辨认精度尽可能高的神经网络,那不是应该把辨认精度作为指标吗?
在进行神经网络的学习时,不能将辨认精度作为指标,因为如果以辨认精度为指标,导数大多数状况下都为 0 。导数为 0 会导致权重参数的更新会停下来。
3、为什么 LogSoftmax 比 Softmax 更好?
log\_softmax 可能解决函数 overflow 和 underflow,放慢运算速度,进步数据稳定性。
因为 softmax 会进行指数操作,当上一层的输入,也就是 softmax 的输出比拟大的时候,可能就会产生 overflow。同理当输出为正数且绝对值也很大的时候,会分子、分母会变得极小,有可能四舍五入为 0,导致下溢出。
只管在数学示意式上是对 softmax 在取对数的状况。然而在实操中是通过:
$$
\log \left[f\left(x_{i}\right)\right]=\log \left(\frac{e^{x_{i}}}{e^{x_{1}}+e^{x_{2}}+\ldots+e^{x_{n}}}\right)\\=\log \left(\frac{\frac{e^{x_{i}}}{e^{M}}}{\frac{e^{x_{1}}}{e^{M}}+\frac{e^{2}}{e^{M}}+\ldots+\frac{e^{x_{n}}}{e^{M}}}\right)=\log \left(\frac{e^{\left(x_{i}-M\right)}}{\sum_{j}^{n} e^{\left(x_{j}-M\right)}}\right)\\=\log \left(e^{\left(x_{i}-M\right)}\right)-\log \left(\sum_{j}^{n} e^{\left(x_{j}-M\right)}\right)=\left(x_{i}-M\right)-\log \left(\sum_{j}^{n} e^{\left(x_{j}-M\right)}\right)
$$
来实现,其中 $M=\max \left(x_{i}\right), i=1,2, \cdots, n$,即 M 为所有 $x_{i}$ 中最大的值。能够解决这个问题,在放慢运算速度的同时,能够放弃数值的稳定性。
4、什么是 label smoothing?为什么要用 label smoothing?
label smoothing 是一种正则化的形式,全称为 Label Smoothing Regularization(LSR),即标签平滑正则化。
在传统的分类工作计算损失的过程中,是将实在的标签做成 one-hot 的模式,而后应用穿插熵来计算损失。而 label smoothing 是将实在的 one hot 标签做一个标签平滑解决,使得标签变成又概率值的 soft label. 其中,在实在 label 处的概率值最大,其余地位的概率值是个十分小的数。
在 label smoothing 中有个参数 epsilon,形容了将标签软化的水平,该值越大,通过 label smoothing 后的标签向量的标签概率值越小,标签越平滑,反之,标签越趋向于 hard label,在训练 ImageNet-1k 的试验里通常将该值设置为 0.1。
5、在用 sigmoid 或 softmax 作为激活函数的时候,为什么要用穿插熵损失函数,而不必均方误差损失函数?
1. 因为穿插熵损失函数能够完满解决平方损失函数权重更新过慢的问题,具备“误差大的时候,权重更新快;误差小的时候,权重更新慢”的良好性质。
2. sigmoid 作为激活函数的时候,如果采纳均方误差损失函数,那么这是一个非凸优化问题,不宜求解。而采纳穿插熵损失函数仍然是一个凸优化问题,更容易优化求解。
公式推导详解见:https://blog.csdn.net/weixin\_41888257/article/details/104894141
6、对于穿插熵损失函数(Cross-entropy)和 平方损失(MSE)的区别?
1. 概念区别
均方差损失函数(MSE):简略来说,均方误差(MSE)的含意是求一个 batch 中 n 个样本的 n 个输入与冀望输入的差的平方的平均值。
Cross-entropy(穿插熵损失函数):穿插熵是用来评估以后训练失去的概率分布与实在散布的差别状况。它刻画的是理论输入(概率)与冀望输入(概率)的间隔,也就是穿插熵的值越小,两个概率分布就越靠近。
2. 利用场景
MSE 更适宜 回归问题 ,穿插熵损失函数更适宜 分类问题。
7、什么是 KL 散度?
KL 散度定义
KL(Kullback-Leibler divergence)散度多利用于概率论或信息论中,又可称绝对熵(relative entropy)。它是用来形容两个概率分布 P 和 Q 的差别的一种办法。
KL 具备非对称性,即 D(P||Q) ≠ D(Q||P)。
在信息论中,D(P||Q) 示意用概率分布 Q 来拟合实在散布 P 时,产生的信息损耗,其中 P 示意实在散布,Q 示意 P 的拟合散布
KL 散度公式定义
对于离散型随机变量有:
$$
\mathrm{D}(\mathrm{P} \| \mathrm{Q})=\sum_{i \in X} P(i) *\left[\log \left(\frac{P(i)}{Q(i)}\right)\right]
$$
对于连续型随机变量有:
$$
\mathrm{D}(\mathrm{P} \| \mathrm{Q})=\int_{x} P(x) *\left[\log \left(\frac{P(i)}{Q(i)}\right)\right] d x
$$
KL 散度的物理定义
在信息论中,它是用来度量 应用基于 Q 散布的编码来编码来自 P 散布的样本均匀所需的额定的比特 (bit) 个数 。
在机器学习畛域,是用来度量 两个函数的类似水平或者相近水平。
8、手写 IOU、GIOU、DIOU、CIOU 的代码
IOU 代码及后果展现如下
import cv2
import numpy as np
def IOU_score(box1,box2):
"""
计算两个区域的 iou 的值
para: box1 区域 1 的两个角的坐标值 x1,y1,x2,y2
para: box2 区域 2 的两个角的坐标值 x1,y1,x2,y2
"""
# 两个框的交
iou_x1 = max(box1[0], box2[0])
iou_y1 = max(box1[1], box2[1])
iou_x2 = min(box1[2], box2[2])
iou_y2 = min(box1[3], box2[3])
# 下面求进去的为交加的两个角的坐标
area_inter = max(0,(iou_x2 - iou_x1)) * max(0 , (iou_y2 - iou_y1))
# 计算两个区域的并集
area_all = ((box1[2] - box1[0]) * (box1[3] - box1[1])) + ((box2[2] - box2[0]) * (box2[3] - box2[1])) - area_inter
center_x = int((iou_x1 + iou_x2) / 2)
center_y = int((iou_y2 + iou_y1) / 2)
return float(area_inter / area_all) , (center_x,center_y)
def main():
img = np.zeros((512,512,3), np.uint8)
img.fill(255)
box1 = [50,50,300,300]
box2 = [51,51,301,301]
cv2.rectangle(img, (box1[0],box1[1]), (box1[2],box1[3]), (0, 0, 255), 2)
cv2.rectangle(img, (box2[0],box2[1]), (box2[2],box2[3]), (255, 0, 0), 2)
IOU , center = IOU_score(box1,box2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,"IOU = %.2f"%IOU,center,font,0.8,(0,0,0),2)
cv2.imshow("image",img)
cv2.waitKey()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
GIOU 代码及后果展现如下
import cv2
import numpy as np
def GIOU_score(box1,box2):
"""
计算两个区域的 iou 的值
para: box1 区域 1 的两个角的坐标值 x1,y1,x2,y2
para: box2 区域 2 的两个角的坐标值 x1,y1,x2,y2
"""
# 两个框的交
iou_x1 = max(box1[0], box2[0])
iou_y1 = max(box1[1], box2[1])
iou_x2 = min(box1[2], box2[2])
iou_y2 = min(box1[3], box2[3])
g_iou_x1 = min(box1[0], box2[0])
g_iou_y1 = min(box1[1], box2[1])
g_iou_x2 = max(box1[2], box2[2])
g_iou_y2 = max(box1[3], box2[3])
# 下面求进去的为交加的两个角的坐标
area_inter = max(0,(iou_x2 - iou_x1)) * max(0 , (iou_y2 - iou_y1))
# 计算两个区域的并集
area_union = max(0,((box1[2] - box1[0]) * (box1[3] - box1[1])) + ((box2[2] - box2[0]) * (box2[3] - box2[1])) - area_inter)
# 计算最小外接矩形
area_all = max(0,(g_iou_x2 - g_iou_x1) * (g_iou_y2 - g_iou_y1))
g_iou = max(0,area_inter/area_union) - max(0,area_all - area_union) / area_all
return float(g_iou) , (iou_x1,iou_y1,iou_x2,iou_y2) , (g_iou_x1,g_iou_y1,g_iou_x2,g_iou_y2)
def main():
img = np.zeros((512,512,3), np.uint8)
img.fill(255)
box1 = [50,50,300,300]
box2 = [100,100,400,400]
IOU , area_inter , area_all = GIOU_score(box1,box2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,"GIOU = %.2f"%IOU,(area_inter[0]+30,area_inter[1]+30),font,0.8,(0,0,0),2)
cv2.rectangle(img, (box1[0],box1[1]), (box1[2],box1[3]), (255, 0, 0), thickness = 3)
cv2.rectangle(img, (box2[0],box2[1]), (box2[2],box2[3]), (0, 255, 0), thickness = 3)
cv2.rectangle(img, (area_all[0],area_all[1]), (area_all[2],area_all[3]), (0, 0, 255), thickness = 3)
cv2.imshow("image",img)
cv2.waitKey()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
DIOU 代码及后果展现如下
import cv2
import numpy as np
def DIOU_score(box1,box2):
"""
计算两个区域的 iou 的值
para: box1 区域 1 的两个角的坐标值 x1,y1,x2,y2
para: box2 区域 2 的两个角的坐标值 x1,y1,x2,y2
"""
# 两个框的交
iou_x1 = max(box1[0], box2[0])
iou_y1 = max(box1[1], box2[1])
iou_x2 = min(box1[2], box2[2])
iou_y2 = min(box1[3], box2[3])
d_x1 = max(0, (box1[2] + box1[0])/2)
d_y1 = max(0, (box1[3] + box1[1])/2)
d_x2 = max(0, (box2[2] + box2[0])/2)
d_y2 = max(0, (box2[3] + box2[1])/2)
c_x1 = min(box1[0], box2[0])
c_y1 = min(box1[1], box2[1])
c_x2 = max(box1[2], box2[2])
c_y2 = max(box1[3], box2[3])
# 下面求进去的为交加的两个角的坐标
area_inter = max(0,(iou_x2 - iou_x1)) * max(0 , (iou_y2 - iou_y1))
# 计算两个区域的并集
area_union = max(0,((box1[2] - box1[0]) * (box1[3] - box1[1])) + ((box2[2] - box2[0]) * (box2[3] - box2[1])) - area_inter)
# 计算最小外接矩形
c_2 = max(0,(c_x2 - c_x1))**2 + max(0,(c_y2 - c_y1))**2
d_2 = max(0,(d_x2 - d_x1))**2 + max(0,(d_y2 - d_y1))**2
g_iou = max(0,area_inter/area_union) - d_2/c_2
return float(g_iou) , (iou_x1,iou_y1,iou_x2,iou_y2) , (c_x1,c_y1,c_x2,c_y2), (int(d_x1),int(d_y1),int(d_x2),int(d_y2))
def main():
img = np.zeros((512,512,3), np.uint8)
img.fill(255)
box1 = [50,50,300,300]
box2 = [250,80,400,350]
IOU , area_inter , area_all , short_line = DIOU_score(box1,box2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,"GIOU = %.2f"%IOU,(area_inter[0]+30,area_inter[1]+30),font,0.8,(0,0,0),2)
cv2.rectangle(img, (box1[0],box1[1]), (box1[2],box1[3]), (255, 0, 0), thickness = 3)
cv2.rectangle(img, (box2[0],box2[1]), (box2[2],box2[3]), (0, 255, 0), thickness = 3)
cv2.rectangle(img, (area_all[0],area_all[1]), (area_all[2],area_all[3]), (0, 0, 255), thickness = 3)
cv2.line(img, (short_line[0],short_line[1]), (short_line[2],short_line[3]), (200,45,45),5)
cv2.line(img, (area_all[0],area_all[1]), (area_all[2],area_all[3]), (64,78,0),5)
cv2.imshow("image",img)
cv2.waitKey()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
CIOU 代码及后果展现如下
import cv2
import numpy as np
from math import pi,atan
def CIOU_score(box1,box2):
"""
计算两个区域的 iou 的值
para: box1 区域 1 的两个角的坐标值 x1,y1,x2,y2
para: box2 区域 2 的两个角的坐标值 x1,y1,x2,y2
"""
# 两个框的交
iou_x1 = max(box1[0], box2[0])
iou_y1 = max(box1[1], box2[1])
iou_x2 = min(box1[2], box2[2])
iou_y2 = min(box1[3], box2[3])
d_x1 = max(0, (box1[2] + box1[0])/2)
d_y1 = max(0, (box1[3] + box1[1])/2)
d_x2 = max(0, (box2[2] + box2[0])/2)
d_y2 = max(0, (box2[3] + box2[1])/2)
c_x1 = min(box1[0], box2[0])
c_y1 = min(box1[1], box2[1])
c_x2 = max(box1[2], box2[2])
c_y2 = max(box1[3], box2[3])
w_gt = max(0,box2[2] - box2[0])
h_gt = max(0,box2[3] - box2[1])
w = max(0,box1[2] - box1[0])
h = max(0,box1[3] - box1[1])
# 下面求进去的为交加的两个角的坐标
area_inter = max(0,(iou_x2 - iou_x1)) * max(0 , (iou_y2 - iou_y1))
# 计算两个区域的并集
area_union = max(0,((box1[2] - box1[0]) * (box1[3] - box1[1])) + ((box2[2] - box2[0]) * (box2[3] - box2[1])) - area_inter)
iou = max(0,area_inter/area_union)
c_2 = max(0,(c_x2 - c_x1))**2 + max(0,(c_y2 - c_y1))**2
d_2 = max(0,(d_x2 - d_x1))**2 + max(0,(d_y2 - d_y1))**2
v = 4/pi**2 * (atan(w_gt/h_gt) - atan(w/h))**2
alpha = v / (1-iou + v)
c_iou = iou - d_2/c_2 - alpha * v
return float(c_iou) , (iou_x1,iou_y1,iou_x2,iou_y2) , (c_x1,c_y1,c_x2,c_y2), (int(d_x1),int(d_y1),int(d_x2),int(d_y2))
def main():
img = np.zeros((512,512,3), np.uint8)
img.fill(255)
box1 = [50,50,300,300]
box2 = [100,80,200,260]
IOU , area_inter , area_all , short_line = CIOU_score(box1,box2)
font = cv2.FONT_HERSHEY_SIMPLEX
cv2.putText(img,"GIOU = %.2f"%IOU,(area_inter[0]+30,area_inter[1]+30),font,0.8,(0,0,0),2)
cv2.rectangle(img, (box1[0],box1[1]), (box1[2],box1[3]), (255, 0, 0), thickness = 3)
cv2.rectangle(img, (box2[0],box2[1]), (box2[2],box2[3]), (0, 255, 0), thickness = 3)
cv2.rectangle(img, (area_all[0],area_all[1]), (area_all[2],area_all[3]), (0, 0, 255), thickness = 3)
cv2.line(img, (short_line[0],short_line[1]), (short_line[2],short_line[3]), (200,45,45),5)
cv2.line(img, (area_all[0],area_all[1]), (area_all[2],area_all[3]), (64,78,0),5)
cv2.imshow("image",img)
cv2.waitKey()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
9、代价函数,损失函数、指标函数、危险函数的区别?
- 损失函数(Loss Function)是定义在单个样本上的,算的是一个样本的误差。
- 代价函数(Cost Function)是定义在整个训练集上的,是所有样本误差的均匀,也就是损失函数的均匀。
- 指标函数(Object Function)定义为:最终须要优化的函数。等于教训危险 + 构造危险(也就是代价函数 + 正则化项)。代价函数最小化,升高教训危险,正则化项最小化升高。
- 危险函数 (risk function),危险函数是损失函数的冀望,这是因为咱们输入输出的(X,Y) 遵循一个联结散布,然而这个联结散布是未知的,所以无奈计算。然而咱们是有历史数据的,就是咱们的训练集,f(x) 对于训练集的均匀损失称作教训危险(empirical risk),即,所以咱们的指标就是最小化 称为教训危险最小化。
10、噪声、偏差和方差的区别是啥?
- 噪声:形容了在当前任务上任何学习算法所能达到的 冀望泛化误差的下界,即刻画了学习问题自身的难度。说人话,就是数据中的有些标签不是真的标签,也是无限噪声的标签。
- 偏差:是指 预测后果与实在值之间的差别,排除噪声的影响,偏差更多的是针对某个模型输入的样本误差,偏差是模型无奈精确表白数据关系导致,比方模型过于简略,非线性的数据关系采纳线性模型建模,偏差较大的模型是错的模型。
- 方差:不是针对某一个模型输入样本进行断定,而是指多个 (次) 模型输入的后果之间的离散差别,留神这里写的是多个模型或者屡次模型,即不同模型或同一模型不同工夫的输入后果方差较大,方差是由训练集的数据不够导致,一方面量 (数据量) 不够,无限的数据集适度训练导致模型简单,另一方面质 (样本品质) 不行,测试集中的数据分布未在训练集中,导致每次抽样训练模型时,每次模型参数不同,输入的后果都无奈精确的预测出正确后果。
11、MSE 对于异样样本的鲁棒性差的问题怎么解决?
- 如果异样样本无意义,能够进行异样值的平滑或者间接删除。
- 如果异样样本有意义,须要模型把这些有意义的异样思考进来,则从模型侧思考应用表达能力更强的模型或复合模型或分群建模等;
- 在损失层面抉择更鲁棒的损失函数。
12、熵的相干知识点?
- 信息量 度量一个事件的不确定性水平,不确定性越高则信息量越大,个别通过事件产生的概率来定义不确定性,信息量则是基于概率密度函数的 log 运算,用以下式子定义:
$$
I(x)=-\log p(x)
$$
- 信息熵 掂量的是一个事件汇合的不确定性水平,就是事件汇合中所有事件的不确定性的冀望,公式定义如下:
$$
H(X)=-\sum_{x \in X}[p(x) \log p(x)]
$$
- 绝对熵(KL 散度) kl 散度,从概统角度登程,示意用于两个概率分布的差别的非对称掂量,kl 散度也能够从信息实践的角度登程,从这个角度登程的 kl 散度咱们也能够称之为绝对熵,实际上形容的是两个概率分布的信息熵的差值:
$$
K L(P \| Q)=\sum P(x) \log \frac{P(x)}{Q(x)}
$$
kl 散度和余弦间隔一样,不满足间隔的严格定义;非负且不对称。
- js 散度 公式如下:
$$
J S(P \| Q)=\frac{1}{2} K L(P(x))\left\|\frac{P(x)+Q(x)}{2}+\frac{1}{2} K L(Q(x))\right\| \frac{P(x)+Q(x)}{2}
$$
js 散度的范畴是[0,1], 雷同则是 0,相同为 1。相较于 KL,对类似度的判断更精确; 同时,js 散度满足对称性 JS(P||Q)=JS(Q||P)
- 穿插熵 公式如下:
$$
H(P, Q)=-\sum p \log q=H(P)+D_{k l}(P \| Q)
$$
可见, 穿插熵就是真值散布的信息熵与 KL 散度的和, 而真值的熵是确定的, 与模型的参数 θ 无关, 所以梯度降落求导时,优化穿插熵和优化 kl 散度(绝对熵)是一样的;
- 联结熵 公式如下:
$$
H(X, Y)=-\sum_{x, y} p(x, y) \log p(x, y)
$$
联结熵实际上掂量的是两个事件汇合,通过组合之后造成的新的大的事件汇合的信息熵;
- 条件熵 公式如下:
$$
H(Y \mid X)=H(X, Y)-H(X)
$$
事件汇合 Y 的条件熵 = 联结熵 - 事件汇合 X 的信息熵,用来掂量在事件汇合 X 已知的根底上,事件汇合 Y 的不确定性的缩小水平;
13、怎么掂量两个散布的差别?
应用 KL 散度或者 JS 散度
14、Huber Loss 有什么特点?
Huber Loss 联合了 MSE 和 MAE 损失,在误差靠近 0 时应用 MSE,使损失函数可导并且梯度更加稳固;在误差较大时应用 MAE 能够升高 outlier 的影响,使训练对 outlier 更加强壮。毛病是须要额定地设置一个超参数。
15、如何了解 Hinger Loss?
能够看到,当 x 大于某个值的时候,loss 为 0,当 x 小于某个值的时候,那就须要算 loss 了,阐明模型对小于阈值的样本进行了惩办,而且越大惩办的越厉害,对于大于阈值的样本不进行惩办,总的来说就是该损失函数寻找一个边界,对具备可信的样本不惩办,对不可信的样本或者超出决策边界的样本进行惩办。
已建设深度学习公众号——FightingCV,欢送大家关注!!!
面向小白的顶会论文外围代码学习:https://github.com/xmu-xiaoma…
退出交换群,请增加小助手 wx:FightngCV666,备注:地区 - 学校(公司)- 名称
参考:
https://blog.csdn.net/zuolixiangfisher/article/details/88649110
https://zhuanlan.zhihu.com/p/514859125
https://blog.csdn.net/weixin\_43750248/article/details/116656242
https://blog.csdn.net/hello\_dear\_you/article/details/121078919
https://blog.csdn.net/weixin\_41888257/article/details/104894141
https://blog.csdn.net/weixin\_37763870/article/details/103026505
https://blog.csdn.net/to\_be\_little/article/details/124674924
https://zhuanlan.zhihu.com/p/548782472
本文由 mdnice 多平台公布