人工智能(pytorch)搭建模型15-手把手搭建MnasNet模型,并实现模型的训练与预测

人工智能(pytorch)搭建模型15-手把手搭建MnasNet模型,并实现模型的训练与预测

大家好,我是微学AI,今天给大家介绍一下人工智能(pytorch)搭建模型15-手把手搭建MnasNet模型,并实现模型的训练与预测,本文将介绍MnasNet模型的原理,并使用PyTorch框架构建一个MnasNet模型用于图像分类任务,让大家充分了解该模型。

文章将分为以下几个部分:

  1. MnasNet模型简介
  2. MnasNet模型的实现
  3. 数据集准备
  4. 模型训练
  5. 模型测试
  6. 结论

1. MnasNet模型简介

MnasNet(Mobile Neural Architecture Search Network)是一种通过搜索得到的高效卷积神经网络,最早由Google于2018年提出。MnasNet的主要特点是在保证模型的高性能的同时,尽量降低计算复杂度和参数数量,适用于移动设备等资源有限的场景。

MnasNet的核心思想是利用神经结构搜索(Neural Architecture Search, NAS)技术来找到最优的模型结构。NAS的目标是在给定任务和硬件平台的约束下,自动搜索出性能最佳的神经网络结构。MnasNet采用的搜索空间主要包括卷积层、深度可分离卷积层以及倒残差结构等基本操作。

www.zeeklog.com  - 人工智能(pytorch)搭建模型15-手把手搭建MnasNet模型,并实现模型的训练与预测


MnasNet模型的数学原理可以用以下公式表示:

假设输入图像为 x ∈ R H × W × C x\in \mathbb{R}^{H\times W\times C} x∈RH×W×C,其中 H H H、 W W W、 C C C分别表示图像的高、宽和通道数。MnasNet模型可以看作一个函数 f ( x ; θ ) f(x;\theta) f(x;θ),其中 θ \theta θ表示模型的参数,包括卷积核、批量归一化参数、全连接层参数等。

MnasNet模型的核心是自动化神经架构搜索技术,可以自动搜索最佳的神经网络架构。假设搜索得到的最佳神经网络架构为 A A A,则模型的输出可以表示为:

f ( x ; θ A ) = f A ( x ; θ A ) f(x;\theta_A)=f_A(x;\theta_A) f(x;θA​)=fA​(x;θA​)

其中 f A ( x ; θ A ) f_A(x;\theta_A) fA​(x;θA​)表示使用神经网络架构 A A A搭建的模型, θ A \theta_A θA​表示模型 A A A的参数。模型 A A A的参数由两部分组成,即共享参数和非共享参数,可以表示为:

θ A = { w , α } \theta_A=\{w,\alpha\} θA​={w,α}

其中 w w w表示共享参数, α \alpha α表示非共享参数。共享参数在不同的神经网络架构之间是共享的,而非共享参数则是每个神经网络架构独立的。

由于自动化神经架构搜索技术的存在,MnasNet模型可以在保证准确率的前提下,显著减小模型的参数量和计算量,从而在移动设备上得到更好的应用。

2. MnasNet模型的实现

以下是用PyTorch实现MnasNet模型的代码:

import torch
import torch.nn as nn
import torch.optim as optim
import torchvision.transforms as transforms
import torchvision.datasets as datasets
from torch.utils.data import DataLoader

class _InvertedResidual(nn.Module):
    def __init__(self, in_ch, out_ch, kernel_size, stride, expansion_factor):
        super(_InvertedResidual, self).__init__()
        hidden_dim = round(in_ch * expansion_factor)
        self.use_residual = in_ch == out_ch and stride == 1
        
        layers = []
        if expansion_factor != 1:
            layers.append(nn.Conv2d(in_ch, hidden_dim, 1, 1, 0, bias=False))
            layers.append(nn.BatchNorm2d(hidden_dim))
            layers.append(nn.ReLU6(inplace=True))
        
        layers.extend([
            nn.Conv2d(hidden_dim, hidden_dim, kernel_size, stride, kernel_size//2, groups=hidden_dim, bias=False),
            nn.BatchNorm2d(hidden_dim),
            nn.ReLU6(inplace=True),
            nn.Conv2d(hidden_dim, out_ch, 1, 1, 0, bias=False),
            nn.BatchNorm2d(out_ch),
        ])

        self.layers = nn.Sequential(*layers)
    
    def forward(self, x):
        if self.use_residual:
            return x + self.layers(x)
        else:
            return self.layers(x)

class MnasNet(nn.Module):
    def __init__(self, num_classes=1000, alpha=1.0):
        super(MnasNet, self).__init__()
        self.alpha = alpha
        self.num_classes = num_classes

        def conv_dw(in_ch, out_ch, stride):
            return _InvertedResidual(in_ch, out_ch, 3, stride, 1)

        def conv_pw(in_ch, out_ch, stride):
            return _InvertedResidual(in_ch, out_ch, 1, stride, 6)

        def make_layer(in_ch, out_ch, num_blocks, stride):
            layers = [conv_pw(in_ch, out_ch, stride)]
            for _ in range(num_blocks - 1):
                layers.append(conv_pw(out_ch, out_ch, 1))
            return nn.Sequential(*layers)

        # 构建MnasNet模型
        self.model = nn.Sequential(
            nn.Conv2d(3, int(32 * alpha), 3, 2, 1, bias=False),
            nn.BatchNorm2d(int(32 * alpha)),
            nn.ReLU6(inplace=True),
            make_layer(int(32 * alpha), int(16 * alpha), 1, 1),
            make_layer(int(16 * alpha), int(24 * alpha), 2, 2),
            make_layer(int(24 * alpha), int(40 * alpha), 3, 2),
            make_layer(int(40 * alpha), int(80 * alpha), 4, 2),
            make_layer(int(80 * alpha), int(96 * alpha), 2, 1),
            make_layer(int(96 * alpha), int(192 * alpha), 4, 2),
            make_layer(int(192 * alpha), int(320 * alpha), 1, 1),
            nn.Conv2d(int(320 * alpha), 1280, 1, 1, 0, bias=False),
            nn.BatchNorm2d(1280),
            nn.ReLU6(inplace=True),
        )

        self.classifier = nn.Sequential(
            nn.AdaptiveAvgPool2d(1),
            nn.Flatten(),
            nn.Dropout(0.2),
            nn.Linear(1280, self.num_classes),
        )

    def forward(self, x):
        x = self.model(x)
        x = self.classifier(x)
        return x

3. 数据集准备

我们将在CIFAR-10数据集上训练和测试我们的MnasNet模型。CIFAR-10数据集包含10个类别的60000张32x32彩色图像,每个类别有6000张图像。其中50000张用于训练,10000张用于测试。

准备数据集的代码如下:

transform_train = transforms.Compose([
    transforms.RandomCrop(32, padding=4),
    transforms.RandomHorizontalFlip(),
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])

transform_test = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
])

trainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
trainloader = DataLoader(trainset, batch_size=100, shuffle=True, num_workers=2)

testset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)
testloader = DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)

4. 模型训练

接下来,我们将使用训练集对MnasNet模型进行训练,并在每个epoch后输出训练损失值和准确率。训练代码如下:

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
num_classes = 10
mnasnet = MnasNet(num_classes=num_classes, alpha=0.5)
mnasnet = mnasnet.to(device)

criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(mnasnet.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)

# 学习率调整策略
def adjust_learning_rate(optimizer, epoch):
    lr = 0.1
    if epoch >= 80:
        lr = 0.01
    if epoch >= 120:
        lr = 0.001
    for param_group in optimizer.param_groups:
        param_group['lr'] = lr

num_epochs = 150
for epoch in range(num_epochs):
    adjust_learning_rate(optimizer, epoch)
    mnasnet.train()
    train_loss = 0
    correct = 0
    total = 0

    for batch_idx, (inputs, targets) in enumerate(trainloader):
        inputs, targets = inputs.to(device), targets.to(device)
        optimizer.zero_grad()
        outputs = mnasnet(inputs)
        loss = criterion(outputs, targets)
        loss.backward()
        optimizer.step()

        train_loss += loss.item()
        _, predicted = outputs.max(1)
        total += targets.size(0)
        correct += predicted.eq(targets).sum().item()

    print(f'Epoch: {epoch+1}, Loss: {train_loss/(batch_idx+1)}, Acc: {100.*correct/total}')

5. 模型测试

训练完成后,我们使用测试集对模型进行测试,输出测试损失值和准确率。测试代码如下:

mnasnet.eval()
test_loss = 0
correct = 0
total = 0

with torch.no_grad():
    for batch_idx, (inputs, targets) in enumerate(testloader):
        inputs, targets = inputs.to(device), targets.to(device)
        outputs = mnasnet(inputs)
        loss = criterion(outputs, targets)

        test_loss += loss.item()
        _, predicted = outputs.max(1)
        total += targets.size(0)
        correct += predicted.eq(targets).sum().item()

print(f'Test Loss: {test_loss/(batch_idx+1)}, Acc: {100.*correct/total}')

6. 结论

本文主要介绍了MnasNet模型的搭建与训练,测试,MnasNet特点在于使用了自动化神经架构搜索技术,可以在保证准确率的前提下,显著减小模型的参数量和计算量,从而在移动设备上得到更好的应用。

MnasNet模型的搭建与训练的总结:

数据集准备:首先需要准备适当的数据集,包括训练集、验证集和测试集。可以使用公共数据集,如ImageNet,也可以使用自己收集的数据集。

模型架构搜索:MnasNet采用神经架构搜索技术,可以自动搜索最佳的神经网络架构。这个过程需要使用大量的计算资源和时间,可以在GPU或者云端进行。

模型搭建:在得到最佳的神经网络架构之后,需要将其搭建成一个可以训练的模型。这个过程可以使用深度学习框架来实现,如TensorFlow、PyTorch等。

模型训练:训练模型需要选择合适的优化算法和损失函数,同时设置合适的超参数,如学习率、批量大小等。训练过程中,可以使用一些技巧来提高模型的性能,如数据增强、学习率调整等。

模型评估:在训练完成后,需要使用验证集或测试集来评估模型的性能。可以使用一些指标来评估模型的准确率、召回率、F1值等。

Read more

Linux学习总结(51)——25个Linux服务器安全小贴士

Linux学习总结(51)——25个Linux服务器安全小贴士

前言 大家都认为 Linux 默认是安全的,我大体是认可的 (这是个有争议的话题)。Linux默认确实有内置的安全模型。你需要打开它并且对其进行定制,这样才能得到更安全的系统。Linux更难管理,不过相应也更灵活,有更多的配置选项。对于系统管理员,让产品的系统更安全,免于骇客和黑客的攻击,一直是一项挑战。这是我们关于“如何让Linux系统更安全” 或者 “加固Linux系统“之类话题的第一篇文章。本文将介绍 25个有用的技巧和窍门 ,帮助你让Linux系统更加安全。希望下面的这些技巧和窍门可以帮助你加强你的系统的安全。 1. 物理系统的安全性 配置BIOS,禁用从CD/DVD、外部设备、软驱启动。下一步,启用BIOS密码,同时启用GRUB的密码保护,这样可以限制对系统的物理访问。 2. 磁盘分区 使用不同的分区很重要,对于可能得灾难,这可以保证更高的数据安全性。通过划分不同的分区,数据可以进行分组并隔离开来。当意外发生时,只有出问题的分区的数据才会被破坏,其他分区的数据可以保留下来。你最好有以下的分区,并且第三方程序最好安装在单独的文件系统/opt下。 3.

By Ne0inhk
Springboot应用的信创适配-补充

Springboot应用的信创适配-补充

因为篇幅限制,这里补全Spring信创适配、数据库信创适配、Redis信创适配、消息队列信创适配等四个章节。 Springboot应用的信创适配         Springboot应用的信创适配,如上图所示需要适配的很多,从硬件、操作系统、中间件(消息队列、缓存)、web服务器、数据库,jdk等方面整理如下。 Spring信创适配         Spring 是一个开源应用框架,它本身不包含与信创有关的内容。信创是指使用自主可控的技术来替代原来依赖的技术。替换spring无异于替换java语言,在springboot应用中。 各行业中,金融行业数字化水平较高,数字化转型与信创实践均起步较早,使用的是比较新的应用架构,比如微服务架构,需要通过分布式技术进行应用开发等。因此,金融信创迁移实践中,需要基础软件匹配新技术变革带来的架构冲击,来进行迁移改造。与时俱进的普元应用服务器PAS,支持标准JakartaEE应用架构,也支持SpringBoot微服务架构、云端容器架构使用,能够支撑不同架构开发的应用或业务运行。 以微服务框架下的SpringBoot体系为例,微服务应

By Ne0inhk
科普文:外贸垃圾邮件判定

科普文:外贸垃圾邮件判定

国外垃圾邮件判定规则 很多时候,外贸的沟通多以邮件为主,他们作为专业的采购商,每天邮箱里都会塞满了邮件。因此,为了提高工作效率,很多国外客户喜欢使用垃圾邮件过滤器来过滤掉一部分垃圾邮件。 以下几种情况会触发垃圾邮件过滤器,外贸人在自己的邮件内一定要避免出现。在开发客户的过程中,让邮件出现在客户的收件箱里只是第一步,但仍有很多邮件被视为垃圾邮件,这是不可能收到回复的。所以,外贸人一定要避免此类错误。 1.出现敏感词 邮件中大量出现spam(垃圾邮件)敏感词,比如说110%、free、sell、sale、low price、quote、offer、discount、MOQ、advertisement、Order now、Make $等字眼,会引起垃圾邮件过滤器的警觉而被过滤掉,可能永远得不到回复。 2.非正常拼写 如果邮件上用其他字符代替字母,比如w0rds、L3tter等这种非正常拼写,或uPPer、CaSE这种颠倒大小写,是很容易被判定会垃圾邮件的。要知道,外国人是比较严肃认真的,特别是工作上。 2.

By Ne0inhk
Git学习总结(24)——彻底搞懂 Git-Rebase

Git学习总结(24)——彻底搞懂 Git-Rebase

使用 Git 已经好几年了,却始终只是熟悉一些常用的操作。对于 Git Rebase 却很少用到,直到这一次,不得不用。 一、起因 上线构建的过程中扫了一眼代码变更,突然发现,commit 提交竟然多达 62 次。我们来看看都提交了什么东西: 这里我们先不说 git ,就单纯这么多次无用的 commit 就很让人不舒服。可能很多人觉得无所谓,无非是多了一些提交纪录。 然而,并非如此,你可能听过破窗效应,编程也是如此! 二、导致问题 1.不利于代码 review 设想一下,你要做 code review ,结果一个很小的功能,提交了 60 多次,会不会有一些崩溃? 2.会造成分支污染 你的项目充满了无用的 commit 纪录,如果有一天线上出现了紧急问题,

By Ne0inhk