YOLO目标检测创新改进与实战案例专栏
专栏目录: YOLO有效改进系列及项目实战目录 包含卷积,主干 注意力,检测头等创新机制 以及 各种目标检测分割项目实战案例
专栏链接: YOLO基础解析+创新改进+实战案例
介绍
摘要
我们提出了一种基于MKLDNN加速策略的轻量级CPU网络,命名为PP-LCNet,它在多项任务中提高了轻量级模型的性能。本文列出了在延迟几乎不变的情况下能够提高网络准确性的技术。通过这些改进,PP-LCNet在相同推理时间内的分类准确性可以大大超过之前的网络结构。如图1所示,它的性能优于最先进的模型。在计算机视觉的下游任务中,如目标检测、语义分割等,它也表现得非常出色。我们所有的实验都是基于PaddlePaddle1进行的。代码和预训练模型可在PaddleClas2中找到。
文章链接
论文地址:论文地址
代码地址:代码地址
代码地址:代码地址
基本原理
PP-LCNet是一种基于MKLDNN加速策略的轻量级CPU卷积神经网络,旨在提高轻量级模型在多个任务上的性能。该网络通过一系列技术原理和改进,实现了在保持低延迟的同时提高准确性和效率。
网络架构:PP-LCNet采用了一种轻量级的卷积神经网络架构,结合了MKLDNN加速策略,使其在CPU上能够高效运行。网络结构经过精心设计,旨在在保持高性能的同时减少计算和内存消耗。
技术原理:
- H-Swish和大核卷积:PP-LCNet利用H-Swish激活函数和大核卷积技术来提高模型性能,同时几乎不增加推理时间。
- SE模块:通过添加少量SE模块可以进一步提升模型性能。
- 全局平均池化后的大型全连接层:在全局平均池化层后增加一个较大的全连接层可以显著提高准确性。
- Dropout策略:在涉及相对较大矩阵的情况下,使用Dropout策略可以进一步提高模型的准确性。
性能提升:PP-LCNet在保持低延迟的情况下,通过上述技术原理和改进,取得了显著的性能提升。不仅在图像分类任务中表现优异,还在计算机视觉的其他领域,如目标检测、语义分割等方面表现出色。
模型参数和性能:PP-LCNet根据不同的缩放比例(如0.25x、0.35x、0.5x等),具有不同的模型参数、FLOPs、Top-1准确率、Top-5准确率和推理延迟。通过这些指标可以评估不同规模的PP-LCNet在不同任务上的性能表现。
核心代码
class PPLCNet(nn.Module):
def __init__(self, scale=1.0, num_classes=1000, dropout_prob=0.2):
super(PPLCNet, self).__init__()
self.cfgs = [
# k, c, s, SE
[3, 32, 1, 0],
[3, 64, 2, 0],
[3, 64, 1, 0],
[3, 128, 2, 0],
[3, 128, 1, 0],
[5, 256, 2, 0],
[5, 256, 1, 0],
[5, 256, 1, 0],
[5, 256, 1, 0],
[5, 256, 1, 0],
[5, 256, 1, 0],
[5, 512, 2, 1],
[5, 512, 1, 1],
]
self.scale = scale
input_channel = _make_divisible(16 * scale)
layers = [nn.Conv2d(3, input_channel, 3, 2, 1, bias=False), HardSwish()]
block = DepSepConv
for k, c, s, use_se in self.cfgs:
output_channel = _make_divisible(c * scale)
layers.append(block(input_channel, output_channel, k, s, use_se))
input_channel = output_channel
self.features = nn.Sequential(*layers)
# # building last several layers
self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
self.fc = nn.Conv2d(input_channel, 1280, 1, 1, 0)
self.hwish = HardSwish()
self.dropout = nn.Dropout(p=dropout_prob)
self.classifier = nn.Linear(1280, num_classes)
self._initialize_weights()
def forward(self, x):
x = self.features(x)
x = self.avgpool(x)
x = self.fc(x)
x = self.hwish(x)
x = self.dropout(x)
x = x.view(x.size(0), -1)
x = self.classifier(x)
return x
def _initialize_weights(self):
for m in self.modules():
if isinstance(m, nn.Conv2d):
n = m.kernel_size[0] * m.kernel_size[1] * m.out_channels
m.weight.data.normal_(0, math.sqrt(2. / n))
if m.bias is not None:
m.bias.data.zero_()
elif isinstance(m, nn.BatchNorm2d):
m.weight.data.fill_(1)
m.bias.data.zero_()
elif isinstance(m, nn.Linear):
m.weight.data.normal_(0, 0.001)
m.bias.data.zero_()
task与yaml配置
详见: https://blog.csdn.net/shangyanaf/article/details/140450841