Yolo v3调优记录
1.使用专门针对背景的Focal Loss
def focal_loss(out_put,y_true):
# loss = ((torch.sigmoid(out_put))**2*(1-y_true)+ (1-torch.sigmoid(out_put))**2*y_true)\
# *F.binary_cross_entropy_with_logits((out_put), y_true, reduction='none')
loss = 0.8*(torch.sigmoid(out_put)) ** 2 * F.binary_cross_entropy_with_logits(1-out_put, 1-y_true, reduction='none')+F.binary_cross_entropy_with_logits((out_put), y_true, reduction='none')
return loss
针对一阶段网络前背景分类不平衡问题,使用只对背景加入loss调节因子的focal loss(实验中直接使用原版的focal loss导致ar下降,和yolo作者在论文中讲述一样),使得ar提升。
γ = 2,求导:
修改 yolo_layer.c 中的 l.output[obj_index] 即可
2.使用Senet通道加权层
class SELayer(nn.Module):
def __init__(self, channel, reduction=16):
super(SELayer, self).__init__()
self.avg_pool = nn.AdaptiveAvgPool2d(1)
self.fc = nn.Sequential(
nn.Linear(channel, channel // reduction, bias=False),
nn.ReLU(inplace=True),
nn.Linear(channel // reduction, channel, bias=False),
nn.Sigmoid()
)
def forward(self, x):
b, c, _, _ = x.size()
y = self.avg_pool(x).view(b, c)
y = self.fc(y).view(b, c, 1, 1)
return x * y.expand_as(x)
3.使用Giou Loss
pxmin = px_y[..., 0, :, :] - pw_h[..., 0, :, :] / 2
pxmax = px_y[..., 0, :, :] + pw_h[..., 0, :, :] / 2
pymin = px_y[..., 1, :, :] - pw_h[..., 1, :, :] / 2
pymax = px_y[..., 1, :, :] + pw_h[..., 1, :, :] / 2
pxmin = torch.min(pxmin,pxmax)
pxmax = torch.max(pxmin, pxmax)
pymin = torch.min(pymin, pymax)
pymax = torch.max(pymin, pymax)
gxmin =Y[..., 0, :, :]
gxmax = Y[..., 2, :, :]
gymin = Y[..., 1, :, :]
gymax = Y[..., 3, :, :]
AG=(gxmax-gxmin)*(gymax-gymin)
AP=(pxmax-pxmin)*(pymax-pymin)
AC=torch.max(torch.max(pxmax,gxmax)-torch.min(pxmin,gxmin), torch.zeros_like(pymin))*torch.max(torch.max(pymax,gymax)-torch.min(pymin,gymin),torch.zeros_like(pymin))
I = torch.max((torch.min(pymin, gymin) - torch.max(pymax, gymax)), torch.zeros_like(pymin)) * torch.max((torch.min(pxmin, gxmin) - torch.max(pxmax, gxmax)), torch.zeros_like(pymin))
area=AP+AG-I
GIOU=I/area-torch.div(AC-area, AC+0.000001)
objs= torch.nonzero(object_mask)
GIOU_loss+=((1-GIOU)*obj_mask.squeeze(2)).sum()
遇到的nan的问题,AC+0.000001后解决
GHMC Loss
def GHMC_loss(out_put,y_true):
bins = 10
edges = [float(x) / bins for x in range(bins + 1)]
edges[-1] += 1e-6
weights = torch.zeros_like(out_put)
g = torch.abs(torch.sigmoid(out_put) - y_true)
tot = 1
for k in out_put.size():
tot *= k
for i in range(bins):
inds = (g >= edges[i]) & (g < edges[i + 1])
num_in_bin = inds.sum().item()
if num_in_bin > 0:
weights[inds] = tot / num_in_bin
weights /= 10
loss = F.binary_cross_entropy_with_logits(out_put,y_true,weight=weights,reduction='none')
return loss