MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比

P粉084495128
发布: 2025-07-23 15:47:07
原创
245人浏览过
本文介绍MobileNet v1和v2。v1用深度可分离卷积替代标准卷积,含深度和逐点卷积,参数和计算量大幅减少。v2引入倒残差结构和线性激活函数,性能更优。通过代码实现并测试,两者在速度和精度上表现良好,v2拟合与泛化能力更佳,优于部分传统网络。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R1 模型☜☜☜

mobilenet_v1_v2论文复现,附带与resnet,vgg网络对比 - php中文网

1.导入必要库

In [1]
import timeimport paddleimport paddle.nn as nnimport paddle.nn.functional as F 
from paddle.vision.transforms import Compose, Resizefrom PIL import Imageimport matplotlib.pyplot as pltfrom collections import OrderedDictimport copyimport numpy as npimport paddle.fluid as fluidfrom paddle.vision import transforms as transformsfrom paddle.vision.datasets import Cifar10from paddle.vision.transforms import Normalizefrom time import strftimefrom time import gmtimeimport paddle.vision.models as modelsfrom paddle.vision.models import resnet50from paddle.vision.models import resnet152
登录后复制
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/__init__.py:107: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  from collections import MutableMapping
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/rcsetup.py:20: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  from collections import Iterable, Mapping
/opt/conda/envs/python35-paddle120-env/lib/python3.7/site-packages/matplotlib/colors.py:53: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working
  from collections import Sized
登录后复制

2.MobileNet v1

2.1必要知识介绍

其实介绍MobileNetV1(以下简称V1)只有一句话,MobileNetV1就是把VGG中的标准卷积层换成深度可分离卷积就可以了。

可分离卷积主要有两种类型:空间可分离卷积和深度可分离卷积。

空间可分离卷积

顾名思义,空间可分离就是将一个大的卷积核变成两个小的卷积核,比如将一个3×3的核分成一个3×1和一个1×3的核:

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

由于空间可分离卷积不在MobileNet的范围内,就不说了。

深度可分离卷积

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

深度可分离卷积就是将普通卷积拆分成为一个深度卷积和一个逐点卷积。

标准的卷积操作

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

输入一个12×12×3的一个输入特征图,经过5×5×3的卷积核卷积得到一个8×8×1的输出特征图。如果此时我们有256个特征图,我们将会得到一个8×8×256的输出特征图。

以上就是标准卷积做干的活。那深度卷积和逐点卷积呢?

深度卷积

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

与标准卷积网络不一样的是,我们将卷积核拆分成为但单通道形式,在不改变输入特征图像的深度的情况下,对每一通道进行卷积操作,这样就得到了和输入特征图通道数一致的输出特征图。如上图:输入12×12×3的特征图,经过5×5×1×3的深度卷积之后,得到了8×8×3的输出特征图。输入个输出的维度是不变的3。这样就会有一个问题,通道数太少,特征图的维度太少,能获取到足够的有效信息吗?

逐点卷积

逐点卷积就是1×1卷积。主要作用就是对特征图进行升维和降维,如下图:

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

在深度卷积的过程中,我们得到了8×8×3的输出特征图,我们用256个1×1×3的卷积核对输入特征图进行卷积操作,输出的特征图和标准的卷积操作一样都是8×8×256了。

标准卷积与深度可分离卷积的过程对比如下:

应该为12x13x3---(5x5x1x3)--(1x1x3x256)-->12x12x256。

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

参数量计算

这个问题很好回答,如果有一个方法能让你用更少的参数,更少的运算,但是能达到差的不是很多的结果,你会使用吗?

深度可分离卷积就是这样的一个方法。

深度可分离卷积的参数量由深度卷积和逐点卷积两部分组成:

这一层,MobileNetV1所采用的深度可分离卷积计算量与标准卷积计算量的比值为:

109985792 /924844032 = 0.1189

与我们所计算的九分之一到八分之一一致。

深度可分离卷积层详解

V1卷积层

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

上图左边是标准卷积层,右边是V1的卷积层,虚线处是不相同点。V1的卷积层,首先使用3×3的深度卷积提取特征,接着是一个BN层,随后是一个ReLU层,在之后就会逐点卷积,最后就是BN和ReLU了。这也很符合深度可分离卷积,将左边的标准卷积拆分成右边的一个深度卷积和一个逐点卷积。

等等,我们发现有什么东西混了进来???ReLU6是什么?

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

上图左边是普通的ReLU,对于大于0的值不进行处理,右边是ReLU6,当输入的值大于6的时候,返回6,relu6“具有一个边界”。作者认为ReLU6作为非线性激活函数,在低精度计算下具有更强的鲁棒性。(这里所说的“低精度”,我看到有人说不是指的float16,而是指的定点运算(fixed-point arithmetic))

可以看到使用深度可分离卷积与标准卷积,参数和计算量能下降为后者的九分之一到八分之一左右。但是准确率只有下降极小的1%。

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

MobileNet的网络结构如上图所示。首先是一个3x3的标准卷积,s2进行下采样。然后就是堆积深度可分离卷积,并且其中的部分深度卷积会利用s2进行下采样。然后采用平均池化层将feature变成1x1,根据预测类别大小加上全连接层,最后是一个softmax层。整个网络有28层,其中深度卷积层有13层。

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

可以发现,作为轻量级网络的V1在计算量小于GoogleNet,参数量差不多是在一个数量级的基础上,在分类效果上比GoogleNet还要好,这就是要得益于深度可分离卷积了。VGG16的计算量参数量比V1大了30倍,但是结果也仅仅只高了1%不到。

对了,作者还在论文中分析整个了网络的参数和计算量分布,如下图所示。可以看到整个计算量基本集中在1x1卷积上。对于参数也主要集中在1x1卷积,除此之外还有就是全连接层占了一部分参数。

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

torch.nn.Conv2d:对输入的二维图像进行卷积运算

以2 x 3 x 4 x 5 input为例

此时卷积核shape为 6 x 3 x 3 x 3 [out_channels x in_channels x kernel_size x kernel_size] 此时groups参数为1,表示将in_channels所有通道作为一组,与每一个3x3x3卷积核卷积,一共6个3x3x3卷积核,共输出6个通道特征

先大概总结一下groups参数的含义:假设卷积操作的输入通道数是in_channels,输出通道数是out_channles,分组数是groups,分组卷积就是把原本的整体卷积操作分成groups个小组来分别处理,其中每个分组的输入通道数是in_channles / groups,输出通道数是out_channles / groups,最后将所有分组的输出通道数concat,得到最终的输出通道数out_channles,所以在做分组卷积的时候,in_channels和out_channels需要被groups整除

2.2代码实现部分

In [ ]
class MobileNet_v1(nn.Layer):
    def __init__(self):
        super(MobileNet_v1,self).__init__()        
        #标准卷积
        def conv_bn(inp,oup,stride):
            return nn.Sequential(                    # stride==1 尺寸不变
                    # stride==2 尺寸减半
                    nn.Conv2D(inp,oup,3,stride,1,bias_attr = False),
                    nn.BatchNorm2D(oup),
                    nn.ReLU())        
        #深度卷积
        def conv_dw(inp,oup,stride):
            return nn.Sequential(                    # groups!=1时为深度卷积
                    nn.Conv2D(inp,inp,3,stride,1,groups = inp,bias_attr = False),
                    nn.BatchNorm2D(inp),
                    nn.ReLU(),                    # 1*1卷积
                    nn.Conv2D(inp,oup,1,1,0,bias_attr = False),
                    nn.BatchNorm2D(oup),
                    nn.ReLU())            
        #网络模型声明
        self.model = nn.Sequential(            #标准卷积
            conv_bn(3,32,2),            #深度卷积
            conv_dw(32,64,1),
            conv_dw(64,128,2),
            conv_dw(128,128,1),
            conv_dw(128,256,2),
            conv_dw(256,256,1),
            conv_dw(256,512,2),
            conv_dw(512,512,1),
            conv_dw(512,512,1),
            conv_dw(512,512,1),
            conv_dw(512,512,1),
            conv_dw(512,512,1),
            conv_dw(512,1024,2),
            conv_dw(1024,1024,1),
            nn.AvgPool2D(7),
        )        # 全连接层
        self.fc = nn.Linear(1024,10)    
    #网络的前向过程    
    def forward(self,x):
        x = self.model(x)
        x=paddle.reshape(x,[-1, 1024])
        x = self.fc(x)        return x
登录后复制

3.MobileNet v2

3.1必要知识介绍

在MobileNet v1的网络结构表中能够发现,网络的结构就像VGG一样是个直筒型的,不像ResNet网络有shorcut之类的连接方式。而且有人反映说MobileNet v1网络中的DW卷积很容易训练废掉,效果并没有那么理想。所以我们接着看下MobileNet v2网络。

MobileNet v2网络是由google团队在2018年提出的,相比MobileNet V1网络,准确率更高,模型更小。

标书对比王
标书对比王

标书对比王是一款标书查重工具,支持多份投标文件两两相互比对,重复内容高亮标记,可快速定位重复内容原文所在位置,并可导出比对报告。

标书对比王 58
查看详情 标书对比王

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

倒残差结构

刚刚说了MobileNet v1网络中的亮点是DW卷积,那么在MobileNet v2中的亮点就是Inverted residual block(倒残差结构),同时分析了v1的几个缺点并针对性的做了改进

线性激活函数

在进行完卷积操作之后往往会接一层激活函数来增加特征的非线性性,一个最常见的激活函数便是ReLU。根据我们在残差网络中介绍的数据处理不等式(DPI),ReLU一定会带来信息损耗,而且这种损耗是没有办法恢复的,ReLU的信息损耗是当通道数非常少的时候更为明显。

  • 既然是ReLU导致的信息损耗,那么我们就将ReLU替换成线性激活函数;
  • 如果比较多的通道数能减少信息损耗,那么我们就使用更多的通道。

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

在残差结构中是1x1卷积降维->3x3卷积->1x1卷积升维,在倒残差结构中正好相反,是1x1卷积升维->3x3DW卷积->1x1卷积降维。为什么要这样做,原文的解释是高维信息通过ReLU激活函数后丢失的信息更少(注意倒残差结构中基本使用的都是ReLU6激活函数,但是最后一个1x1的卷积层使用的是线性激活函数)。

在使用倒残差结构时需要注意下,并不是所有的倒残差结构都有shortcut连接,只有当stride=1且输入特征矩阵与输出特征矩阵shape相同时才有shortcut连接(只有当shape相同时,两个矩阵才能做加法运算,当stride=1时并不能保证输入特征矩阵的channel与输出特征矩阵的channel相同)。

MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比 - php中文网

MobileNet v2相关问题

下图是MobileNet v2网络的结构表,其中t代表的是扩展因子(倒残差结构中第一个1x1卷积的扩展因子),c代表输出特征矩阵的channel,n代表倒残差结构重复的次数,s代表步距(注意:这里的步距只是针对重复n次的第一层倒残差结构,后面的都默认为1)。

  1. MobileNet V2中的bottleneck为什么先扩张通道数在压缩通道数呢?

因为MobileNet 网络结构的核心就是Depth-wise,此卷积方式可以减少计算量和参数量。而为了引入shortcut结构,若参照Resnet中先压缩特征图的方式,将使输入给Depth-wise的特征图大小太小,接下来可提取的特征信息少,所以在MobileNet V2中采用先扩张后压缩的策略。

  1. MobileNet V2中的bottleneck为什么在1*1卷积之后使用Linear激活函数?

因为在激活函数之前,已经使用1*1卷积对特征图进行了压缩,而ReLu激活函数对于负的输入值,输出为0,会进一步造成信息的损失,所以使用Linear激活函数。

MobileNet v1 v2 对比

MobileNet v1最主要的贡献是使用了Depthwise Separable Convolution,它又可以拆分成Depthwise卷积和Pointwise卷积。MobileNet v2主要是将残差网络和Depthwise Separable卷积进行了结合。通过分析单通道的流形特征对残差块进行了改进,包括对中间层的扩展(d)以及bottleneck层的线性激活(c)。Depthwise Separable Convolution的分离式设计直接将模型压缩了8倍左右,但是精度并没有损失非常严重,这一点还是非常震撼的。

Depthwise Separable卷积的设计非常精彩但遗憾的是目前cudnn对其的支持并不好,导致在使用GPU训练网络过程中我们无法从算法中获益,但是使用串行CPU并没有这个问题,这也就给了MobileNet很大的市场空间,尤其是在嵌入式平台。

3.2代码实现部分

In [ ]
# 带倒残差的深度可分离卷积class Bottleneck(nn.Layer):
    def __init__(self, in_channels, out_channels, multiple, stride):
        super(Bottleneck, self).__init__()
        self.stride = stride        # 1*1卷积升维
        self.conv1 = nn.Conv2D(
            in_channels=in_channels,
            out_channels=in_channels*multiple,
            kernel_size=1,
            stride=1,
            padding=0
        )
        self.bn1 = nn.BatchNorm2D(in_channels*multiple)        # 深度卷积
        self.conv2 = nn.Conv2D(
            in_channels=in_channels*multiple,
            out_channels=in_channels*multiple,
            kernel_size=3,
            stride=stride,
            padding=1,
            groups=in_channels*multiple,
        )
        self.bn2 = nn.BatchNorm2D(in_channels*multiple)        # 1*1卷积降维度
        self.conv3 = nn.Conv2D(
            in_channels=in_channels*multiple,
            out_channels=out_channels,
            kernel_size=1,
            stride=1,
            padding=0
        )
        self.bn3 = nn.BatchNorm2D(out_channels)
        self.shortcut = nn.Sequential()        if  in_channels!=out_channels and stride==1:            # 由于stride==1,shape一致,可以做残差连接 即总体上为倒残差结构
            self.shortcut = nn.Sequential(                # 1*1调整shortcut部分通道数
                nn.Conv2D(
                    in_channels=in_channels,
                    out_channels=out_channels,
                    kernel_size=1,
                    stride=1,
                    padding=0
                ),
                nn.BatchNorm2D(out_channels),
            )    def forward(self, x):
        out = F.relu6(self.bn1(self.conv1(x)))
        out = F.relu6(self.bn2(self.conv2(out)))        # 最后一层采用线性激活函数
        out = self.bn3(self.conv3(out))        # 如果stride==1,故shape一致,可以做残差连接 即总体上为倒残差结构
        if self.stride==1:
            out = out + self.shortcut(x)        return outclass MobileNet_v2(nn.Layer):
    parameters = [
        (1,16,1,1),
        (6,24,2,2),
        (6,32,3,2),
        (6,64,4,2),
        (6,96,3,1),
        (6,160,3,2),
        (6,320,1,1)]    def __init__(self,num_classes=10):
        super(MobileNet_v2,self).__init__()
        self.conv1 = nn.Conv2D(
            in_channels=3,
            out_channels=32,
            kernel_size=3,
            stride=1,
            padding=1
        )
        self.bn1 = nn.BatchNorm2D(32)
        self.bottleneck = self.Make_Bottleneck()
        self.conv2 = nn.Conv2D(
            in_channels=320,
            out_channels=1280,
            kernel_size=1,
            stride=1,
            padding=0
        )
        self.bn2 = nn.BatchNorm2D(1280)
        self.linear = nn.Linear(1280,num_classes)    def Make_Bottleneck(self):
        layers = []
        in_channels = 32
        for parameter in self.parameters:
            strides = [parameter[3]] + [1]*(parameter[2]-1)            for stride in strides:
                layer = Bottleneck(in_channels, parameter[1], parameter[0], stride)
                layers.append(layer)
                in_channels = parameter[1]        return nn.Sequential(*layers)    def forward(self, x):
        out = F.relu6(self.bn1(self.conv1(x)))
        out = self.bottleneck(out)
        out = F.relu6(self.bn2(self.conv2(out)))
        out = F.avg_pool2d(out, 4)
        out = F.avg_pool2d(out, 3)
        out=paddle.reshape(out,[out.shape[0], -1])
        out = self.linear(out)        return out
登录后复制
In [ ]
#速度评估def speed(model,name):
    t0 = time.time()    input = paddle.rand([1,3,224,224])
    t1 = time.time()
    model(input)
    t2 = time.time()
    model(input)
    t3 = time.time()    
    print('%10s : %fs'%(name,t3 - t2))
登录后复制

4.速度测评

resnet50

resnet152

vgg16

vgg19

mobilenet_v1

mobilenet_v2

In [ ]
resnet50 = models.resnet50()
resnet152 = models.resnet152()
vgg16 = models.vgg16()
vgg19 = models.vgg19()
mobilenet_v1 = MobileNet_v1()
mobilenet_v2 = MobileNet_v2()

speed(resnet50,'resnet50')
speed(resnet152,'resnet152')
speed(vgg16,'vgg16')
speed(vgg19,'vgg19')
speed(mobilenet_v1,'mobilenet_v1')
speed(mobilenet_v2,'mobilenet_v2')
登录后复制

5.结果展示与分析

resnet50 : 0.019720s

resnet152 : 0.058257s

vgg16 : 0.004025s

vgg19 : 0.004707s

mobilenet_v1 : 0.008120s

mobilenet_v2 : 0.020288s

可能是因为参数量的不同,导致速度有些差异,也与硬件环境有关,在本地运行时,无论是mobilenet_v1,还是mobilenet_v2,均要比vgg网络快

6.精度分析(以分类任务为例

使用Cifar10数据集测试MobileNet_v1,MobileNet_v2的精度

In [4]
transform_train = Compose([
    transforms.Resize([224, 224]),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])

transform_test = Compose([
    transforms.Resize([224, 224]),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]),
])

LR = 0.001EPOCHES = 3BATCHSIZE = 100trainset=Cifar10(data_file=None, mode='train', transform=transform_train, download=True)
testset=Cifar10(data_file=None, mode='test', transform=transform_test, download=True)

trainloader = paddle.io.DataLoader(trainset, batch_size=BATCHSIZE, shuffle=True, num_workers=2)
testloader = paddle.io.DataLoader(testset, batch_size=BATCHSIZE, shuffle=False, num_workers=2)
登录后复制

6.1训练mobilenet_v1

In [ ]
mobilenet_v1 = MobileNet_v1()
optimizer = paddle.optimizer.Adam(learning_rate=LR,parameters=mobilenet_v1.parameters())
loss_function = nn.CrossEntropyLoss()for ep in range(EPOCHES):
    train_correct = 0
    train_sum=0
    epoch_used_time=0
    epoch_ave_time=0
    time_start=time.time()    for i,(img, label) in enumerate(trainloader):

        optimizer.clear_grad()
        mobilenet_v1.train()
        out = mobilenet_v1(img)

        prediction = paddle.argmax(out, 1)
        pre_num = prediction.cpu().numpy()
        train_correct += (pre_num == label.cpu().numpy()).sum()
        train_sum+=BATCHSIZE

        loss = loss_function(out, label)
        loss.backward()
        optimizer.step()

        epoch_used_time+=(time.time()-time_start)
        time_start=time.time()
        
        used_t=strftime("%H:%M:%S", gmtime(epoch_used_time))
        total_t=strftime("%H:%M:%S", gmtime((epoch_used_time/(i+1))*len(trainloader)))        print(f"\rEpoch:{str(ep)} Iter {train_sum}/{len(trainloader)*BATCHSIZE} Train ACC: {(train_correct/train_sum):.5}\
    Used_Time:{used_t} / Total_Time:{total_t}",end="")    
    print('')

    vote_correct = 0
    test_sum=0
    for img, label in testloader:
        mobilenet_v1.eval()
        out = mobilenet_v1(img)
        prediction = paddle.argmax(out, 1)
        pre_num = prediction.cpu().numpy()
        vote_correct += (pre_num == label.cpu().numpy()).sum()
        test_sum+=BATCHSIZE    
        print(f"\rEpoch:{str(ep)} Iter {test_sum}/{len(testloader)*BATCHSIZE} Test ACC: {(vote_correct/test_sum):.5}",end="")    print('')
登录后复制

mobilenet_v1 3 Epoch 效果

Epoch:0 Iter 50000/50000 Train ACC: 0.47304 Used_Time:00:01:37 / Total_Time:00:01:37

Epoch:0 Iter 10000/10000 Test ACC: 0.5915

Epoch:1 Iter 50000/50000 Train ACC: 0.65172 Used_Time:00:01:39 / Total_Time:00:01:39

Epoch:1 Iter 10000/10000 Test ACC: 0.6733

Epoch:2 Iter 50000/50000 Train ACC: 0.73912 Used_Time:00:01:40 / Total_Time:00:01:40

Epoch:2 Iter 10000/10000 Test ACC: 0.7497

6.2训练mobilenet_v2

In [ ]
from paddle.vision.models import mobilenet_v2

mobilenet_v2 = mobilenet_v2(pretrained=False)
optimizer_v2 = paddle.optimizer.Adam(learning_rate=LR,parameters=mobilenet_v2.parameters())
loss_function = nn.CrossEntropyLoss()for ep in range(EPOCHES):
    train_correct = 0
    train_sum=0
    epoch_used_time=0
    epoch_ave_time=0
    time_start=time.time()    for i,(img, label) in enumerate(trainloader):

        optimizer_v2.clear_grad()
        mobilenet_v2.train()
        out = mobilenet_v2(img)

        prediction = paddle.argmax(out, 1)
        pre_num = prediction.cpu().numpy()
        train_correct += (pre_num == label.cpu().numpy()).sum()
        train_sum+=BATCHSIZE

        loss = loss_function(out, label)
        loss.backward()
        optimizer_v2.step()

        epoch_used_time+=(time.time()-time_start)
        time_start=time.time()
        
        used_t=strftime("%H:%M:%S", gmtime(epoch_used_time))
        total_t=strftime("%H:%M:%S", gmtime((epoch_used_time/(i+1))*len(trainloader)))        print(f"\rEpoch:{str(ep)} Iter {train_sum}/{len(trainloader)*BATCHSIZE} Train ACC: {(train_correct/train_sum):.5}\
    Used_Time:{used_t} / Total_Time:{total_t}",end="")    
    print('')

    vote_correct = 0
    test_sum=0
    for img, label in testloader:
        mobilenet_v2.eval()
        out = mobilenet_v2(img)
        prediction = paddle.argmax(out, 1)
        pre_num = prediction.cpu().numpy()
        vote_correct += (pre_num == label.cpu().numpy()).sum()
        test_sum+=BATCHSIZE    
        print(f"\rEpoch:{str(ep)} Iter {test_sum}/{len(testloader)*BATCHSIZE} Test ACC: {(vote_correct/test_sum):.5}",end="")    print('')
登录后复制

mobilenet_v2 3 Epoch 效果

Epoch:0 Iter 50000/50000 Train ACC: 0.50066 Used_Time:00:01:43 / Total_Time:00:01:43

Epoch:0 Iter 10000/10000 Test ACC: 0.5784

Epoch:1 Iter 50000/50000 Train ACC: 0.6868 Used_Time:00:01:43 / Total_Time:00:01:433

Epoch:1 Iter 10000/10000 Test ACC: 0.7133

Epoch:2 Iter 50000/50000 Train ACC: 0.76648 Used_Time:00:01:43 / Total_Time:00:01:43

Epoch:2 Iter 10000/10000 Test ACC: 0.7486

6.3训练其他网络以对比效果

In [5]
net = models.resnet50(pretrained=False)
optimizer = paddle.optimizer.Adam(learning_rate=LR,parameters=net.parameters())
loss_function = nn.CrossEntropyLoss()for ep in range(EPOCHES):
    train_correct = 0
    train_sum=0
    epoch_used_time=0
    epoch_ave_time=0
    time_start=time.time()    for i,(img, label) in enumerate(trainloader):

        optimizer.clear_grad()
        net.train()
        out = net(img)

        prediction = paddle.argmax(out, 1)
        pre_num = prediction.cpu().numpy()
        train_correct += (pre_num == label.cpu().numpy()).sum()
        train_sum+=BATCHSIZE

        loss = loss_function(out, label)
        loss.backward()
        optimizer.step()

        epoch_used_time+=(time.time()-time_start)
        time_start=time.time()
        
        used_t=strftime("%H:%M:%S", gmtime(epoch_used_time))
        total_t=strftime("%H:%M:%S", gmtime((epoch_used_time/(i+1))*len(trainloader)))        print(f"\rEpoch:{str(ep)} Iter {train_sum}/{len(trainloader)*BATCHSIZE} Train ACC: {(train_correct/train_sum):.5}\
    Used_Time:{used_t} / Total_Time:{total_t}",end="")    
    print(' ')    print(' ')

    vote_correct = 0
    test_sum=0
    for img, label in testloader:
        net.eval()
        out = net(img)
        prediction = paddle.argmax(out, 1)
        pre_num = prediction.cpu().numpy()
        vote_correct += (pre_num == label.cpu().numpy()).sum()
        test_sum+=BATCHSIZE    
        print(f"\rEpoch:{str(ep)} Iter {test_sum}/{len(testloader)*BATCHSIZE} Test ACC: {(vote_correct/test_sum):.5}",end="")    print(' ')    print(' ')
登录后复制

mobilenet_v1 mobilenet_v2 vgg16 vgg19 resnet50 resnet152
训练集精度 0.73912 0.76648 0.67516 0.69153 0.74648 0.68296
测试集精度 0.7497 0.7486 0.7027 0.71897 0.72132 0.67154
1个epoch训练时间 1:40min 1:43min 5:10min 6:30min 2.13min 5.47min

可见mobilenet_v2与mobilenet_v1训练所用时间差不多,但是mobilenet_v2的拟合能力更强,且最终的泛化表现也较好

In [ ]
<br/>
登录后复制

以上就是MobileNet_v1_v2论文复现,附带与ResNet,VGG网络对比的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门推荐
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号