【目标检测】损失函数:不同损失函数概念及其代码实现

本篇文章介绍目标检测中不同的损失函数概念及其代码实现。目标检测主要任务为实现目标的分类定位,其损失组成如下:

  • 类别/置信度损失(分类任务):BCE,FL,QFL,VFL
  • 位置损失(回归任务):IoU,GIoU,DIoU,CIoU,DFL(分类)

本文目录

  • 类别/置信度损失
    • BCE
    • Focal Loss
    • Quality Focal Loss
    • VariFocal Loss
  • 位置损失
    • IoU Loss
    • GIoU Loss
    • DIoU Loss
    • CIOU Loss
    • Distribution Focal Loss

类别/置信度损失

BCE

  二值交叉熵(Binary Cross-Entropy, BCE)是一种应用于二分类任务中的损失函数,用于衡量目标类别预测值实际值之间的差距,其计算公式如下:
B C E ( y , p ) = − y log ⁡ ( p ) − ( 1 − y ) log ⁡ ( 1 − p ) {BCE}(y,p) = - y\log (p) - (1 - y)\log (1 - p) BCE(y,p)=ylog(p)(1y)log(1p)
其中 y y y表示目标的实际类别,值为0或1, p p p为目标的预测类别,值为[0,1],进一步地,BCE Loss可表示为以下形式:
B C E ( p t ) = − l o g ( p t ) {BCE}(p_t) = - log (p_t) BCE(pt)=log(pt)
p t = { p , y = 1 1 − p , o t h e r w i s e   p_t= \begin{cases} p,y=1 \\ 1-p,otherwise\ \end{cases} pt={py=11potherwise 
针对多类别任务,可通过独热编码将其分解为多个二分类任务的组合再使用BCE Loss。
  BCE在PyTorch中的实现如下所示:

'''
函数实现:
	binary_cross_entropy_with_logits:Sigmoid + BCE
	binary_cross_entropy: BCE
'''
torch.nn.functional.binary_cross_entropy_with_logits(
						input=None,  # 预测值
						target=None,  # 实际标签
						weight=None,  # 对每个样本的损失进行加权
						size_average=None,  # 已弃用
						reduce=None,       # 不使用
						pos_weight=None,  # 正样本的损失加权(长度等于类数)
						reduction='mean'  # 所有样本的损失求平均(mean)或求和(sum)
						)
'''
类实现(调用上面的函数实现损失计算)
'''
torch.nn.BCEWithLogitsLoss(weight,pos_weight,reduction)

Focal Loss

  Focal Loss(FL)由文章Focal Loss for Dense Object Detection提出。Focal Loss在BCE Loss的基础上,通过权重系数实现以下两点目的:

  • 解决正负样本不平衡问题:目标检测任务中存在大量的背景(负样本),实际目标(正样本)占比减少
    B C E ( p t ) = − α t l o g ( p t ) {BCE}(p_t) = - α_tlog (p_t) BCE(pt)=αtlog(pt)
    α t = { α , y = 1 1 − α , o t h e r w i s e   α_t= \begin{cases} α,y=1 \\ 1-α,otherwise\ \end{cases} αt={αy=11αotherwise 
    其中 α α α用于控制正负样本的权重。
  • 降低易分类样本的权重:使模型训练更加关注于困难样本
    F L ( p t ) = − ( 1 − p t ) γ l o g ( p t ) {FL}(p_t) = -(1-p_t)^γlog (p_t) FL(pt)=(1pt)γlog(pt)
    其中 γ γ γ用于控制难易分类样本的权重, p t p_t pt越大,则该样本越易分类,则对损失的贡献越小。
      结合以上两点,得到最终的Focal Loss公式如下:
    F L ( p t ) = − α t ( 1 − p t ) γ l o g ( p t ) {FL}(p_t) = -α_t(1-p_t)^γlog (p_t) FL(pt)=αt(1pt)γlog(pt)

F L ( y , p ) = − α ( 1 − p ) γ y log ⁡ ( p ) − ( 1 − α ) p γ ( 1 − y ) log ⁡ ( 1 − p ) {FL}(y,p) = - α(1-p)^γy\log (p) -(1-α) p^γ(1 - y)\log (1 - p) FL(y,p)=α(1p)γylog(p)(1α)pγ(1y)log(1p)

  Focal Loss的实现方法如下:

class FocalLoss(nn.Module):
    '''
    用在代替原来的BCEcls(分类损失)和BCEobj(置信度损失)
    优点:
        1.解决了单阶段目标检测中图片正负样本(前景和背景)不均衡的问题;
        2.降低简单样本的权重, 使损失函数更关注困难样本
    '''
    def __init__(self, loss_fcn, gamma=1.5, alpha=0.25):
        super(FocalLoss, self).__init__()
        self.loss_fcn = loss_fcn  # 必须为nn.BCEWithLogitsLoss = sigmoid + BCELoss
        self.gamma = gamma  # 参数γ用于削弱简单样本对loss的贡献程度
        self.alpha = alpha  # 参数α用于平衡正负样本个数不均衡的问题
        self.reduction = loss_fcn.reduction
        self.loss_fcn.reduction = 'none'  # focalloss中的BCE函数的reduction='none', 需要将focal loss应用到每个样本中

    def forward(self, pred, true):
        loss = self.loss_fcn(pred, true)  # BCE(p_t) = -log(p_t)
        pred_prob = torch.sigmoid(pred)
        p_t = true * pred_prob + (1 - true) * (1 - pred_prob)  # p_t
        alpha_factor = true * self.alpha + (1 - true) * (1 - self.alpha)  # α_t
        modulating_factor = (1.0 - p_t) ** self.gamma  # (1-p_t)^γ
        
        loss *= alpha_factor * modulating_factor  # 损失乘上系数

        # 最后选择focalloss返回的类型 默认是mean
        if self.reduction == 'mean':
            return loss.mean()
        elif self.reduction == 'sum':
            return loss.sum()
        else:  # 'none'
            return loss

Quality Focal Loss

  Quality Focal Loss(QFL)由文章Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Detection提出,其与Focal Loss的主要不同为:

  • 将分类分数与检测框IoU结合,提出一种与IoU关联的软标签,将目标实际标签变为连续值
    • soft ont-hot label(iou label):IoU值表示该类别,0表示其他类别
    • ont-hot label(catgory label):1表示该类别,0表示其他类别
  • 修改了Focal Loss中的难易样本分类权重,用实际标签与预测标签的距离表征样本的分类难易度

  Quality Focal Loss公式如下:
Q F L ( y , p ) = − ∣ y − p ∣ γ ( α y log ⁡ ( p ) − ( 1 − α ) ( 1 − y ) log ⁡ ( 1 − p ) ) {QFL}(y,p) = - |y-p|^γ(αy\log (p) -(1-α)(1 - y)\log (1 - p)) QFL(y,p)=ypγ(αylog(p)(1α)(1y)log(1p))
其中p表示目标的soft ont-hot label(iou label),超参数 γ 、 α γ、α γα与Focal Loss中概念一致, y y y p p p越接近,则该样本越易分类,对损失的贡献则越小。
  Quality Focal Loss实现方法如下:

class QualityFocalLoss(nn.Module):
	'''
	相比Focal Loss的变化:
		1.以目标与预测结果的IoU作为实际标签(软标签)
		2.修改了难易样本的权重计算方法
	'''
    def __init__(self, loss_fcn, gamma=1.5, alpha=0.25):
        super(QFocalLoss, self).__init__()
        self.loss_fcn = loss_fcn  # 必须为 nn.BCEWithLogitsLoss() = BCE + Sigmoid
        self.gamma = gamma  # 参数γ用于削弱简单样本对loss的贡献程度
        self.alpha = alpha  # 参数α用于平衡正负样本个数不均衡的问题
        self.reduction = loss_fcn.reduction
        self.loss_fcn.reduction = 'none'

    def forward(self, pred, true):
        loss = self.loss_fcn(pred, true)  # loss = -log(p_t)

        pred_prob = torch.sigmoid(pred)
        alpha_factor = true * self.alpha + (1 - true) * (1 - self.alpha)  # α_t
        modulating_factor = torch.abs(true - pred_prob) ** self.gamma  # |y-p|^γ
        loss *= alpha_factor * modulating_factor  # 损失乘上系数

        if self.reduction == 'mean':
            return loss.mean()
        elif self.reduction == 'sum':
            return loss.sum()
        else:  # 'none'
            return loss

VariFocal Loss

  VariFocal Loss(VFL)由文章VarifocalNet: An IoU-aware Dense Object Detector提出,其与Focal Loss的主要不同为:

  • Focal Loss针对正样本和负样本均进行难易分类样本抑制,降低了正样本质量;VariFocal Loss仅针对负样本进行难易分类样本抑制
  • 使用Quality Focal Loss中的软标签以及难易样本分类权重

  VariFocal Loss公式如下:

V F L ( y , p ) = { − y ( y l o g ( p ) + ( 1 − y ) l o g ( 1 − p ) ) , y > 0 α p γ l o g ( 1 − p ) , y = 0   VFL(y,p)= \begin{cases} -y(ylog(p)+(1-y)log(1-p)),y>0 \\ αp^γlog(1-p),y=0\ \end{cases} VFL(y,p)={y(ylog(p)+(1y)log(1p))y>0αpγlog(1p)y=0 
其中 γ γ γ用于减少易分类负样本对损失的贡献, α α α用于防止过度抑制。
  VariFocal Loss的实现代码如下:

class VariFocalLoss(nn.Module):
    '''
    相比Focal Loss的变化:
        仅针对负样本进行难易分类度抑制
    '''
    def __init__(self, loss_fcn, gamma=1.5, alpha=0.75):
        super(VariFocalLoss, self).__init__()
        self.loss_fcn = loss_fcn  # 必须为 nn.BCEWithLogitsLoss()=BCE+sigmoid
        self.gamma = gamma  # 参数gamma 用于负样本中削弱简单样本对loss的贡献程度
        self.alpha = alpha  # 参数alpha 用于防止对负样本的过度抑制
        self.reduction = loss_fcn.reduction
        self.loss_fcn.reduction = 'none'

    def forward(self, pred, true):
        loss = self.loss_fcn(pred, true)  # loss = -log(p_t)

        pred_prob = torch.sigmoid(pred)
        focal_weight = self.alpha * torch.abs(pred_prob - true) ** self.gamma  # 负样本系数αp^γ
        indics = torch.where(true > 0.0)  # 正样本索引
        for i in range(len(indics[0])):  # 正样本系数替换为y
            focal_weight[indics[0][i], indics[1][i]] = true[indics[0][i], indics[1][i]]
        loss *= focal_weight  # 损失乘上系数

        # 最后选择focalloss返回的类型 默认是mean
        if self.reduction == 'mean':
            return loss.mean()
        elif self.reduction == 'sum':
            return loss.sum()
        else:  # 'none'
            return loss

位置损失

IoU Loss

  IoU即交并比,用于衡量预测边框与实际边框之间的差距,其计算公式如下:
I o U = ∣ A ∩ B ∣ ∣ A ∪ B ∣ [ 0 , 1 ] IoU = {{|A \cap B|} \over {|A \cup B|}} [0,1] IoU=ABAB[0,1]
其中 A ∩ B A \cap B AB表示边框A和B的交集面积, A ∩ B A \cap B AB表示边框A和B的并集面积。
  进一步地,IoU Loss表示为:
L I o U = 1 − I o U L_{IoU} = 1 - IoU LIoU=1IoU
  IoU计算方法如下:

def bbox_iou(box1,box2,xywh=True):
    # 将xywh坐标形式转换成xyxy(左上角右下角)坐标形式
    if xywh:  # transform from xywh to xyxy
        (x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
        w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
        b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_
        b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_
     
    # 计算交集面积
    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \
            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)
    # 计算并集面积
    union = w1 * h1 + w2 * h2 - inter + eps
    # 计算IoU
    iou = inter / union
	return iou

GIoU Loss

  GIoU由文章Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression提出,其计算公式如下:
G I o U = I o U − ∣ C − A ∩ B ∣ ∣ C ∣ [ − 1 , 1 ] GIoU = IoU-{{|C - A \cap B|} \over {|C|}} [-1,1] GIoU=IoUCCAB[1,1]
其中C表示A和B的最小包围矩形框。
  相比于IoU,GIoU不仅考虑重叠区域,也考虑非重叠区域,能更好的反映两者的重合度
  进一步地,IoU Loss表示为:
L G I o U = 1 − G I o U L_{GIoU} = 1 - GIoU LGIoU=1GIoU
  GIoU计算方法如下:

def bbox_giou(box1,box2,xywh=True):
    # 将xywh坐标形式转换成xyxy(左上角右下角)坐标形式
    if xywh:  # transform from xywh to xyxy
        (x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
        w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
        b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_
        b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_


    # 计算交集面积
    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \
            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)

    # 计算并集面积
    union = w1 * h1 + w2 * h2 - inter + eps

    # 计算IoU
    iou = inter / union
    cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # 最小包围矩形框宽度
    ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # 最小包围矩形框高度
    c_area = cw * ch + eps  # 最小包围矩形框面积
    giou = iou - (c_area - union) / c_area
    return giou

DIoU Loss

  DIoU由文章Distance-IoU Loss: Faster and Better Learning for Bounding Box Regression提出,其计算公式如下:
D I o U = I o U − ρ 2 ( b , b g t ) c 2 DIoU = IoU - {{{\rho ^2}(b,{b^{gt}})} \over {{c^2}}} DIoU=IoUc2ρ2(b,bgt)
其中 b b b, b g t b^{gt} bgt分别表示预测框和实际框的中心点坐标, ρ ρ ρ表示两者的欧式距离, c c c表示最小包围矩形框的对角线长度。
  相比于IoU和GIoU,DIoU不仅考虑两者之间的重合度,还考虑两者之间的距离
  进一步地,DIoU Loss表示为:
L D I o U = 1 − D I o U L_{DIoU} = 1 - DIoU LDIoU=1DIoU
  DIoU计算方法如下:

def bbox_diou(box1, box2, xywh=True):
    '''
    计算Iou/GIou/DIou/CIou
    '''
    # Returns Intersection over Union (IoU) of box1(1,4) to box2(n,4)

    # 将xywh坐标形式转换成xyxy(左上角右下角)坐标形式
    if xywh:  # transform from xywh to xyxy
        (x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
        w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
        b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_
        b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_


    # 计算交集面积
    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \
            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)

    # 计算并集面积
    union = w1 * h1 + w2 * h2 - inter + eps
    # 计算IoU
    iou = inter / union	
    
    cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # 最小包围矩形框宽度
    ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # 最小包围矩形框高度
    c2 = cw ** 2 + ch ** 2  # 最小包围矩形框对角线长度的平方
    rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4  # 矩形框中心点距离的平方
    diou = iou - rho2 / c2

    return diou

CIOU Loss

  CIOU也由DIOU作者在同一篇论文中提出,在DIOU基础上,CIOU考虑矩形框之间的高宽比,其计算公式如下:
D I o U = I o U − ( ρ 2 ( b , b g t ) c 2 + α v ) DIoU = IoU - ({{{\rho ^2}(b,{b^{gt}})} \over {{c^2}}}+αv) DIoU=IoU(c2ρ2(b,bgt)+αv)

v = 4 π 2 ( arctan ⁡ w g t h g t − arctan ⁡ w h ) 2 {v = {4 \over {{\pi ^2}}}{{(\arctan {{{w^{gt}}} \over {{h^{gt}}}} - \arctan {w \over h})}^2}} v=π24(arctanhgtwgtarctanhw)2

α = v ( 1 − I o U ) + v {\alpha = {v \over {(1 - IoU) + v}}} α=(1IoU)+vv

其中 ( w g t , h g t ) (w^{gt},h^{gt}) (wgt,hgt) ( w , h ) (w,h) (w,h)分别表示实际边框与预测边框的宽和高。
  进一步地,CIoU Loss表示为:
L D I o U = 1 − C I o U L_{DIoU} = 1 - CIoU LDIoU=1CIoU
  CIoU计算方法如下:

def bbox_ciou(box1, box2, xywh=True):
    '''
    计算Iou/GIou/DIou/CIou
    '''
    # Returns Intersection over Union (IoU) of box1(1,4) to box2(n,4)

    # 将xywh坐标形式转换成xyxy(左上角右下角)坐标形式
    if xywh:  # transform from xywh to xyxy
        (x1, y1, w1, h1), (x2, y2, w2, h2) = box1.chunk(4, -1), box2.chunk(4, -1)
        w1_, h1_, w2_, h2_ = w1 / 2, h1 / 2, w2 / 2, h2 / 2
        b1_x1, b1_x2, b1_y1, b1_y2 = x1 - w1_, x1 + w1_, y1 - h1_, y1 + h1_
        b2_x1, b2_x2, b2_y1, b2_y2 = x2 - w2_, x2 + w2_, y2 - h2_, y2 + h2_


    # 计算交集面积
    inter = (torch.min(b1_x2, b2_x2) - torch.max(b1_x1, b2_x1)).clamp(0) * \
            (torch.min(b1_y2, b2_y2) - torch.max(b1_y1, b2_y1)).clamp(0)

    # 计算并集面积
    union = w1 * h1 + w2 * h2 - inter + eps
    # 计算IoU
    iou = inter / union	
    
    cw = torch.max(b1_x2, b2_x2) - torch.min(b1_x1, b2_x1)  # 最小包围矩形框宽度
    ch = torch.max(b1_y2, b2_y2) - torch.min(b1_y1, b2_y1)  # 最小包围矩形框高度
    c2 = cw ** 2 + ch ** 2  # 最小包围矩形框对角线长度的平方
    rho2 = ((b2_x1 + b2_x2 - b1_x1 - b1_x2) ** 2 + (b2_y1 + b2_y2 - b1_y1 - b1_y2) ** 2) / 4  # 矩形框中心点距离的平方
    v = (4 / math.pi ** 2) * torch.pow(torch.atan(w2 / h2) - torch.atan(w1 / h1), 2)
	alpha = v / (v - iou + (1 + 1e-7))
	ciou - (rho2 / c2 + v * alpha)
    return ciou

Distribution Focal Loss

  Distribution Focal Loss(DFL)QFL作者在同一篇文章Generalized Focal Loss: Learning Qualified and Distributed Bounding Boxes for Dense Object Detection中提出,针对目标受遮挡时边界模糊问题,其将目标检测中边框回归任务 ( l e f t , t o p , r i g h t , b o t t o m ) (left, top, right, bottom) (left,top,right,bottom)转换为分类任务,将标签预测转换为序列预测,预测信息变化如图1所示(图来源于DFL论文),序列面积之和即为所需结果。假设某目标 l e f t left left预测结果为序列 { y 0 , y 1 , y 2 , . . . , y n − 1 } , y i ⊆ [ 0 , 1.0 ] \{y_0,y_1,y_2,...,y_{n-1}\},y_i\subseteq [0,1.0] {y0,y1,y2,...,yn1},yi[0,1.0],则转换为:
l e f t = ∑ i = 0 n − 1 i y i left = \sum\limits_{i = 0}^{n-1} {i{y_i}} left=i=0n1iyi
在这里插入图片描述

a 标签预测

在这里插入图片描述

b 序列预测
图1 边框信息分布预测
  不同的序列分布可能得到相同的预测结果,如图2(图来源于DFL论文)所示,希望得到中(3)的分布序列,中间值尽可能靠近实际标签,为实现该序列的预测,作者提出DFL损失。

在这里插入图片描述

图2 不同的分布情况

  Distribution Focal Loss公式如下:
D F L ( y i , y i + 1 ) = − ( i + 1 − y ) log ⁡ ( y i ) − ( y − i ) log ⁡ ( y i + 1 ) DFL({y_i},{y_{i + 1}}) = - (i + 1- y)\log ({y_i}) - (y - i)\log ({y_{i + 1}}) DFL(yi,yi+1)=(i+1y)log(yi)(yi)log(yi+1)
其中 y y y为实际标签,且式中变量满足 i ≤ y ≤ i + 1 ( i ⊆ N + ) i≤y≤i+1(i\subseteq N^+) iyi+1(iN+) y i , y i + 1 ⊆ [ 0 , 1.0 ] y_i,y_{i+1}\subseteq [0,1.0] yi,yi+1[0,1.0]

  Distribution Focal Loss的实现方法如下:

class DistributionFocalLoss(nn.Module):
    '''
	将目标边框回归预测转换为序列分类任务
    '''
    def __init__(self, reg_max):
        super(DistributionFocalLoss, self).__init__()
		self.reg_max = reg_max # 预测序列点数

    def forward(self, pred, true):
    	'''
    	pred: [num_points, reg_max]
    	true: [num_gt, 4] 4->(ltrb)(输入图像绝对坐标)
    	'''
  		tl = true.long()  # target left(i)
  		tr = tl + 1  # target right (i+1)
  		wl = tr - true  # i+1-y
  		wr = 1 - wl # y-i
  		# -(i+1-y)log(y_i) - (y-i)log(y_i+1)
  		dfl = (F.cross_entropy(pred, tl.view(-1), reduction='none').view(tl.shape) * wl  + 
  			   F.cross_entropy(pred, tr.view(-1), reduction='none').view(tl.shape) * wr).mean(-1,keepdim=True)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/339222.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring第七天(AOP)

简介 AOP(Aspect Oriented Programing)面向切面编程,一种编程范式,指导开发者如何组织程序结构 作用 在不惊动原始设计的基础上为其进行功能增强 Spring理念:无入侵式/无侵入式 基本概念 连接点(JoinPoint) : 程序执行过程中的任意位置&a…

云盘后端分析

1.验证码 用的是外面找的 2.发送邮箱验证码 配置邮箱的授权码 我们在发送邮箱的时候,需要把那个值传到数据库中,数据库中有它的状态,我们需要根据状态判断它是注册还是找回密码 我们在发送邮箱之前,先从session里面得到我们验证…

wayland(xdg_wm_base) + egl + opengles 最简实例

文章目录 前言一、ubuntu 下相关环境准备1. 获取 xdg_wm_base 依赖的相关文件2. 查看 ubuntu 上安装的opengles 版本3. 查看 weston 所支持的 窗口shell 接口种类二、xdg_wm_base 介绍三、egl_wayland_demo1.egl_wayland_demo2_0.c2.egl_wayland_demo3_0.c3. xdg-shell-protoco…

Node开发基础

1. 概述 1.1 为什么要学习服务器端开发基础 能够和后端程序员更加紧密的配合 网站业务逻辑前置,学习前端技术需要后端技术支撑 扩宽知识视野,能够站在更高的角度审视整个项目 1.2 服务器端开发要做的事情 实现网站的业务逻辑 ---网站登录部分&#…

[pytorch入门] 2. tensorboard

tensorboard简介 TensorBoard 是一组用于数据可视化的工具。它包含在流行的开源机器学习库 Tensorflow 中.但是也可以独立安装&#xff0c;服务Pytorch等其他的框架 可以常常用来观察训练过程中每一阶段如何输出的 安装pip install tensorboard启动tensorboard --logdir<d…

LeetCode面试题05.06

美好的一天&#xff0c;从力扣开始 王子公主请看题 整数转换。编写一个函数&#xff0c;确定需要改变几个位才能将整数A转成整数B。 示例1: 输入&#xff1a;A 29 &#xff08;或者0b11101&#xff09;, B 15&#xff08;或者0b01111&#xff09;输出&#xff1a;2示例2: 输…

深度求索开源国内首个 MoE 大模型 | DeepSeekMoE:在专家混合语言模型中实现终极专家专业化

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 在大语言模型时代&#xff0c;混合专家模型&#xff08;MoE&#xff09;是一种很有前途的架构&#xff0c;用于在扩展模型参数时管理计算成本。然而&a…

【算法专栏学习】成贤学院,程序员的福利站到了,判断子序列,经典算法实战。

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

使用宝塔面板安装wiki.js详细教程

因为在安装过程中遇到了一些问题&#xff0c;花费了很长时间在解决问题上。根据这篇教程可以少踩很多坑。点赞加关注吧。 准备运行环境 Nodejs 在宝塔面板的软件商店中找到nodejs版本管理器并安装。 点击设置&#xff0c;选择一个稳定版安装。 PostgreSQL 官方推荐的数据库是…

Nginx之负载均衡、静态代理与动态代理配置

Nginx之负载均衡配置 文章目录 Nginx之负载均衡配置1. 负载均衡基本配置1. 配置upstream2. 配置location3. 访问 2. Nginx常用负载均衡策略1. 轮询(默认)2. 权重3. ip_hash策略4. 最少连接策略5. 负载均衡其他几个配置 3. 静态代理1. 基于静态在一文件后缀的匹配2. 基于静态资源…

Python - 深夜数据结构与算法之 高级字符串

目录 一.引言 二.经典算法实战 1.Longest-Common-Sub-Seq [1143] 2.Edit-Distance [72] 3.Longest-Palindromic-Str [5] 4.Distinct-Sub-Seq [115] 5.Regular-Exp-Match [10] 三.总结 一.引言 上一节介绍了字符串的基本操作&#xff0c;本文介绍字符串更复杂的一些操作…

YOLOv8改进 | 主干篇 | 低照度图像增强网络SCINet改进黑暗目标检测(全网独家首发)

一、本文介绍 本文给大家带来的改进机制是低照度图像增强网络SCINet,SCINet(自校正照明网络)是一种专为低光照图像增强设计的框架。它通过级联照明学习过程和权重共享机制来处理图像,优化了照明部分以提升图像质量。我将该网络集成在YOLOv8的主干上针对于图像的输入进行增…

BurpSuite Pro 2023.12.1.2下载与破解-最新版BurpSuite Pro

本文在我的博客地址是&#xff1a;https://h4cker.zip/post/f05ae2e66da503f6383dffe48cdf5bac 上一次BurpSuite的分享还是在2020年 由于CSDN有防盗链&#xff0c;我自己的博客都无法访问这篇博文的图片了 至于为什么再写一次&#xff0c;是因为我看到群里这张图&#xff1a;…

高效能方法 - 任务清单优先级

任务清单是有优先级的&#xff0c;首先要尽所能保证A级别的事项完成&#xff0c;或许不能估计B级或者C级&#xff0c;那这结果也是不错的。 博恩崔西在《吃掉那只青蛙》一书中指出&#xff1a;在你决定要做什么&#xff0c;并对其进行排序的时候&#xff0c;你首要解决那些最难…

腾讯云服务器价格查询,2024更新

腾讯云服务器租用优惠价格表&#xff1a;轻量应用服务器2核2G3M价格62元一年、2核2G4M价格118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;2核4G5M带宽756元三年、轻量4核8G12M服务器646元15个月&#xff1b;云服务器CVM S5实例2核2G配置280.8元一年、2核4G…

x-cmd pkg | yq - 命令行 YAML处理工具

目录 简介首次用户支持格式转换友好的显示和操作语法与 jq 类似竞品和相关作品进一步阅读 简介 yq (YAML Query) 是一个轻量级的 YAML、JSON、XML 处理器&#xff0c;主要用于查询和提取 YAML 数据。 本 yq 的包来自 mikefarah/yq 项目&#xff0c;语法类似于 jq 。相比 kisly…

《WebKit 技术内幕》之八(2):硬件加速机制

2 Chromium的硬件加速机制 2.1 GraphicsLayer的支持 GraphicsLayer对象是对一个渲染后端存储中某一层的抽象&#xff0c;同众多其他WebKit所定义的抽象类一样&#xff0c;在WebKit移植中&#xff0c;它还需要具体的实现类来支持该类所要提供的功能。为了完成这一功能&#x…

python if条件判断的基础及应用

当前版本&#xff1a; Python 3.8.4 简介 if 语句是一种用于根据一个或多个条件的结果来执行不同代码块的控制流结构&#xff0c;它会检查给定的条件是否为真。如果条件为真&#xff0c;则执行与之关联的代码块&#xff1b;如果条件为假&#xff0c;则执行与之关联的其他代码块…

工作小计- RGB相关算子实现

项目中的模型一直都是直接操作NV12的yuv格式数据&#xff0c;这次的模型只支持RGB格式的输入&#xff0c;正好来自己实现对应的算子。 这里记录一下对应算子的实现过程&#xff0c;主要涉及到NV12到RGB的变换&#xff0c;RGB的crop/resize操作&#xff0c;对于数据的Norm/ToFlo…

python 正则表达式学习(1)

正则表达式是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与某种模式匹配。 1. 特殊符号 1.1 符号含义 模式描述^匹配字符串的开头$匹配字符串的末尾.匹配任意字符&#xff0c;除了换行符&#xff0c;当re.DOTALL标记被指定时&#xff0c;则可以匹配包…