PyTorch 之 基于经典网络架构训练图像分类模型

本文涉及的产品
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
交互式建模 PAI-DSW,5000CU*H 3个月
模型训练 PAI-DLC,5000CU*H 3个月
简介: 本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052

文章目录


一、 模块简单介绍

1. 数据预处理部分

2. 网络模块设置

3. 网络模型保存与测试

二、数据读取与预处理操作

1. 制作数据源

2. 读取标签对应的实际名字

3. 展示数据

三、模型构建与实现

1. 加载 models 中提供的模型,并且直接用训练的好权重当做初始化参数

2. 参考 pytorch 官网例子

3. 设置哪些层需要训练

4. 优化器设置

5. 训练模块

6. 测试模型效果


本文参加新星计划人工智能(Pytorch)赛道:https://bbs.csdn.net/topics/613989052

4a647097fcdc46b5bfc6e76bbba2425f.png


一、 模块简单介绍

  • 我们可以进入 pytorch 的官方网站,对模型的基本架构和训练好的参数进行直接调用,具体链接如下 https://pytorch.org/


1. 数据预处理部分

(1) 数据增强通过 torchvision 中 transforms 模块的自带功能实现,比较实用。

(2) 数据预处理通过 torchvision 中 transforms 也帮我们实现好了,直接调用即可。

(3) DataLoader 模块可以直接读取 batch 数据。


2. 网络模块设置

(1) 加载预训练模型,torchvision 中有很多经典网络架构,调用起来十分方便,并且可以用人家训练好的权重参数来继续训练,也就是所谓的迁移学习。

(2) 需要注意的是别人训练好的任务跟咱们的可不是完全一样,需要把最后的 head 层改一改,一般也就是最后的全连接层,改成咱们自己的任务。

(3) 训练时可以全部重头训练,也可以只训练最后咱们任务的层,因为前几层都是做特征提取的,本质任务目标是一致的。


3. 网络模型保存与测试

  • (1) 模型保存的时候可以带有选择性,例如在验证集中如果当前效果好则保存。
  • (2) 读取模型进行实际测试。
  • 5b66a833cae04710b3ab3ea94ec3d5c5.png
import os
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
import torch
from torch import nn
import torch.optim as optim
import torchvision
#pip install torchvision
from torchvision import transforms, models, datasets
#https://pytorch.org/docs/stable/torchvision/index.html
import imageio
import time
import warnings
import random
import sys
import copy
import json
from PIL import Image

二、数据读取与预处理操作

  • 在最开始,我们先进行训练集和测试集的数据读取。
data_dir = './flower_data/'
train_dir = data_dir + '/train'
valid_dir = data_dir + '/valid'

1. 制作数据源


  • 由于整体数据集较少,因此,我们通过 data_transforms 进行数据增强,指定所有图像预处理操作,包括旋转,裁剪,水平翻转、垂直翻转等等。
  • 需要注意的是,这里分为训练集和数据集两部分。
data_transforms = {
    'train': transforms.Compose([transforms.RandomRotation(45),#随机旋转,-45到45度之间随机选
        transforms.CenterCrop(224),#从中心开始裁剪
        transforms.RandomHorizontalFlip(p=0.5),#随机水平翻转 选择一个概率概率
        transforms.RandomVerticalFlip(p=0.5),#随机垂直翻转
        transforms.ColorJitter(brightness=0.2, contrast=0.1, saturation=0.1, hue=0.1),#参数1为亮度,参数2为对比度,参数3为饱和度,参数4为色相
        transforms.RandomGrayscale(p=0.025),#概率转换成灰度率,3通道就是R=G=B
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])#均值,标准差
    ]),
    'valid': transforms.Compose([transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}


  • 在数据加强完后,我们将单次传递给程序用以训练的数据也就是样本的个数设置为 8。
  • 在传入数据集的时候,第一个参数是我们原始数据的路径,第二个参数是我们的数据增强方法。
batch_size = 8
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x), data_transforms[x]) for x in ['train', 'valid']}
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=batch_size, shuffle=True) for x in ['train', 'valid']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'valid']}
class_names = image_datasets['train'].classes
  • 接下来,我们读取数据集的基本信息,包括训练集中的数据个数,存储路径等等信息,测试集也是相同的。
image_datasets
#{'train': Dataset ImageFolder
#     Number of datapoints: 6552
#     Root location: ./flower_data/train
#     StandardTransform
# Transform: Compose(
#                RandomRotation(degrees=(-45, 45), resample=False, expand=False)
#                CenterCrop(size=(224, 224))
#                RandomHorizontalFlip(p=0.5)
#                RandomVerticalFlip(p=0.5)
#                ColorJitter(brightness=[0.8, 1.2], contrast=[0.9, 1.1], saturation=[0.9, 1.1], #hue=[-0.1, 0.1])
#                RandomGrayscale(p=0.025)
#                ToTensor()
#                Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
#            ), 'valid': Dataset ImageFolder
#     Number of datapoints: 818
#     Root location: ./flower_data/valid
#     StandardTransform
# Transform: Compose(
#                Resize(size=256, interpolation=PIL.Image.BILINEAR)
#                CenterCrop(size=(224, 224))
#                ToTensor()
#                Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
#            )}
  • 我们也可以打印 dataloaders 中的信息,包含训练集和测试集两个。
dataloaders
#{'train': <torch.utils.data.dataloader.DataLoader at 0x21c5388b2b0>,
# 'valid': <torch.utils.data.dataloader.DataLoader at 0x21c539a80b8>}
  • 查看 dataset 中的数据数量,其中训练集包含 6552 个样本,测试集中包含 818 个样本。
dataset_sizes
#{'train': 6552, 'valid': 818}


2. 读取标签对应的实际名字

  • 在我们的文件当中,包含一个 json 文件,这中间包含了基本的标签信息,每个数字对应一种花的种类,在此,我们对这些信息进行读取。
  • fddec3c7e07e4fefa94dff2af05d4aad.png


with open('cat_to_name.json', 'r') as f:
    cat_to_name = json.load(f)
cat_to_name

66d96ae403b2481280b19a1f81e0138f.png


3. 展示数据


  • 在展示数据时,需要注意 tensor 的数据需要转换成 numpy 的格式,而且还需要还原回标准化的结果。
  • 由于现在的数据都是已经处理完成后的数据,因此,如果我们想要展示的话需要对这些数据进行还原。
def im_convert(tensor):
    """ 展示数据"""
    image = tensor.to("cpu").clone().detach()
    image = image.numpy().squeeze()
    image = image.transpose(1,2,0)
    image = image * np.array((0.229, 0.224, 0.225)) + np.array((0.485, 0.456, 0.406))
    image = image.clip(0, 1)
    return image

  • 在还原完成后,我们只需要对其中的数据进行读取即可,这里展示 8 个数据为例。
fig=plt.figure(figsize=(20, 12))
columns = 4
rows = 2
dataiter = iter(dataloaders['valid'])
inputs, classes = dataiter.next()
for idx in range (columns*rows):
    ax = fig.add_subplot(rows, columns, idx+1, xticks=[], yticks=[])
    ax.set_title(cat_to_name[str(int(class_names[classes[idx]]))])
    plt.imshow(im_convert(inputs[idx]))
plt.show()

c5152c4ce73544e6a6ec48d49a1ff522.png

三、模型构建与实现

1. 加载 models 中提供的模型,并且直接用训练的好权重当做初始化参数

  • 第一次执行需要下载,可能会比较慢,大家不必担心。
model_name = 'resnet'  #可选的比较多 ['resnet', 'alexnet', 'vgg', 'squeezenet', 'densenet', 'inception']
  • 在下载完成后,通过设置 feature_extract 为 True 或 False,决定是否用人家训练好的特征来做,这里直接使用人家训练好的特征,也就是设置为 True。
feature_extract = True


  • 之后,我们决定是否用 GPU 进行训练。
train_on_gpu = torch.cuda.is_available()
if not train_on_gpu:
    print('CUDA is not available.  Training on CPU ...')
else:
    print('CUDA is available!  Training on GPU ...')
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
#CUDA is available!  Training on GPU ...
  • 进行模型架构的打印。
def set_parameter_requires_grad(model, feature_extracting):
    if feature_extracting:
        for param in model.parameters():
            param.requires_grad = False
model_ft = models.resnet152()
model_ft


4239533061af4205b6498524d0dd1214.png

2. 参考 pytorch 官网例子

  • 选择合适的模型,不同模型的初始化方法稍微有点区别,具体的代码如下所示。
def initialize_model(model_name, num_classes, feature_extract, use_pretrained=True):
    model_ft = None
    input_size = 0
    if model_name == "resnet":
        """ Resnet152
        """
        model_ft = models.resnet152(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        num_ftrs = model_ft.fc.in_features
        model_ft.fc = nn.Sequential(nn.Linear(num_ftrs, 102),
                                   nn.LogSoftmax(dim=1))
        input_size = 224
    elif model_name == "alexnet":
        """ Alexnet
        """
        model_ft = models.alexnet(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        num_ftrs = model_ft.classifier[6].in_features
        model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes)
        input_size = 224
    elif model_name == "vgg":
        """ VGG11_bn
        """
        model_ft = models.vgg16(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        num_ftrs = model_ft.classifier[6].in_features
        model_ft.classifier[6] = nn.Linear(num_ftrs,num_classes)
        input_size = 224
    elif model_name == "squeezenet":
        """ Squeezenet
        """
        model_ft = models.squeezenet1_0(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        model_ft.classifier[1] = nn.Conv2d(512, num_classes, kernel_size=(1,1), stride=(1,1))
        model_ft.num_classes = num_classes
        input_size = 224
    elif model_name == "densenet":
        """ Densenet
        """
        model_ft = models.densenet121(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        num_ftrs = model_ft.classifier.in_features
        model_ft.classifier = nn.Linear(num_ftrs, num_classes)
        input_size = 224
    elif model_name == "inception":
        """ Inception v3
        Be careful, expects (299,299) sized images and has auxiliary output
        """
        model_ft = models.inception_v3(pretrained=use_pretrained)
        set_parameter_requires_grad(model_ft, feature_extract)
        # Handle the auxilary net
        num_ftrs = model_ft.AuxLogits.fc.in_features
        model_ft.AuxLogits.fc = nn.Linear(num_ftrs, num_classes)
        # Handle the primary net
        num_ftrs = model_ft.fc.in_features
        model_ft.fc = nn.Linear(num_ftrs,num_classes)
        input_size = 299
    else:
        print("Invalid model name, exiting...")
        exit()
    return model_ft, input_size


3. 设置哪些层需要训练

  • 在关于哪些层需要训练,首先导入模型的名字,把最终的输出结果 102 导入进去,然后选择是否动那些层,是否使用人家的模型参数。
model_ft, input_size = initialize_model(model_name, 102, feature_extract, use_pretrained=True)
  • 使用 GPU 进行计算。
model_ft = model_ft.to(device)


  • 将我们训练完成后的模型保存到指定路径之下。
filename='checkpoint.pth'

  • 否训练所有层。
params_to_updateparams_to_update = model_ft.parameters()
print("Params to learn:")
if feature_extract:
    params_to_update = []
    for name,param in model_ft.named_parameters():
        if param.requires_grad == True:
            params_to_update.append(param)
            print("\t",name)
else:
    for name,param in model_ft.named_parameters():
        if param.requires_grad == True:
            print("\t",name)
#Params to learn:
#  fc.0.weight
#  fc.0.bias
#model_ft

3417f92a18374636b2a5b2e02518ac45.png


4. 优化器设置

  • 进行学习率衰减。
optimizer_ft = optim.Adam(params_to_update, lr=1e-2)
scheduler = optim.lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)#学习率每7个epoch衰减成原来的1/10
#最后一层已经LogSoftmax()了,所以不能nn.CrossEntropyLoss()来计算了,nn.CrossEntropyLoss()相当于logSoftmax()和nn.NLLLoss()整合
criterion = nn.NLLLoss()

5. 训练模块

def train_model(model, dataloaders, criterion, optimizer, num_epochs=25, is_inception=False,filename=filename):
    since = time.time()
    best_acc = 0
    """
    checkpoint = torch.load(filename)
    best_acc = checkpoint['best_acc']
    model.load_state_dict(checkpoint['state_dict'])
    optimizer.load_state_dict(checkpoint['optimizer'])
    model.class_to_idx = checkpoint['mapping']
    """
    model.to(device)
    val_acc_history = []
    train_acc_history = []
    train_losses = []
    valid_losses = []
    LRs = [optimizer.param_groups[0]['lr']]
    best_model_wts = copy.deepcopy(model.state_dict())
    for epoch in range(num_epochs):
        print('Epoch {}/{}'.format(epoch, num_epochs - 1))
        print('-' * 10)
        # 训练和验证
        for phase in ['train', 'valid']:
            if phase == 'train':
                model.train()  # 训练
            else:
                model.eval()   # 验证
            running_loss = 0.0
            running_corrects = 0
            # 把数据都取个遍
            for inputs, labels in dataloaders[phase]:
                inputs = inputs.to(device)
                labels = labels.to(device)
                # 清零
                optimizer.zero_grad()
                # 只有训练的时候计算和更新梯度
                with torch.set_grad_enabled(phase == 'train'):
                    if is_inception and phase == 'train':
                        outputs, aux_outputs = model(inputs)
                        loss1 = criterion(outputs, labels)
                        loss2 = criterion(aux_outputs, labels)
                        loss = loss1 + 0.4*loss2
                    else:#resnet执行的是这里
                        outputs = model(inputs)
                        loss = criterion(outputs, labels)
                    _, preds = torch.max(outputs, 1)
                    # 训练阶段更新权重
                    if phase == 'train':
                        loss.backward()
                        optimizer.step()
                # 计算损失
                running_loss += loss.item() * inputs.size(0)
                running_corrects += torch.sum(preds == labels.data)
            epoch_loss = running_loss / len(dataloaders[phase].dataset)
            epoch_acc = running_corrects.double() / len(dataloaders[phase].dataset)
            time_elapsed = time.time() - since
            print('Time elapsed {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))
            print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))
            # 得到最好那次的模型
            if phase == 'valid' and epoch_acc > best_acc:
                best_acc = epoch_acc
                best_model_wts = copy.deepcopy(model.state_dict())
                state = {
                  'state_dict': model.state_dict(),
                  'best_acc': best_acc,
                  'optimizer' : optimizer.state_dict(),
                }
                torch.save(state, filename)
            if phase == 'valid':
                val_acc_history.append(epoch_acc)
                valid_losses.append(epoch_loss)
                scheduler.step(epoch_loss)
            if phase == 'train':
                train_acc_history.append(epoch_acc)
                train_losses.append(epoch_loss)
        print('Optimizer learning rate : {:.7f}'.format(optimizer.param_groups[0]['lr']))
        LRs.append(optimizer.param_groups[0]['lr'])
        print()
    time_elapsed = time.time() - since
    print('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))
    print('Best val Acc: {:4f}'.format(best_acc))
    # 训练完后用最好的一次当做模型最终的结果
    model.load_state_dict(best_model_wts)
    return model, val_acc_history, train_acc_history, valid_losses, train_losses, LRs 
model_ft, val_acc_history, train_acc_history, valid_losses, train_losses, LRs  = train_model(model_ft, dataloaders, criterion, optimizer_ft, num_epochs=20, is_inception=(model_name=="inception"))

48c728e25faf4e5d9932d2100546971b.png


for param in model_ft.parameters():
    param.requires_grad = True
#再继续训练所有的参数,学习率调小一点
optimizer = optim.Adam(params_to_update, lr=1e-4)
scheduler = optim.lr_scheduler.StepLR(optimizer_ft, step_size=7, gamma=0.1)
#损失函数
criterion = nn.NLLLoss()
#Load the checkpoint​
checkpoint = torch.load(filename)
best_acc = checkpoint['best_acc']
model_ft.load_state_dict(checkpoint['state_dict'])
optimizer.load_state_dict(checkpoint['optimizer'])
#model_ft.class_to_idx = checkpoint['mapping']
model_ft, val_acc_history, train_acc_history, valid_losses, train_losses, LRs  = train_model(model_ft, dataloaders, criterion, optimizer, num_epochs=10, is_inception=(model_name=="inception"))

194c60b420f64d6181efb03d1ad7c544.png


6. 测试模型效果

  • 输入一张测试图像,看看网络的返回结果:
probs, classes = predict(image_path, model)
print(probs)
print(classes)
#[ 0.01558163  0.01541934  0.01452626  0.01443549  0.01407339]
#['70', '3', '45', '62', '55']
  • 这里需要注意的是,预处理方法需相同。
  • 然后,我们加载训练好的模型。
model_ft, input_size = initialize_model(model_name, 102, feature_extract, use_pretrained=True)
#GPU模式
model_ft = model_ft.to(device)
#保存文件的名字
filename='seriouscheckpoint.pth'
#加载模型
checkpoint = torch.load(filename)
best_acc = checkpoint['best_acc']
model_ft.load_state_dict(checkpoint['state_dict'])

测试数据处理方法需要跟训练时一直才可以。

crop 操作的目的是保证输入的大小是一致的。

标准化操作也是必须的,用跟训练数据相同的 mean 和 std,但是需要注意一点训练数据是在 0-1 上进行标准化,所以测试数据也需要先归一化。

PyTorch 中颜色通道是第一个维度,跟很多工具包都不一样,需要转换。

def process_image(image_path):
    # 读取测试数据
    img = Image.open(image_path)
    # Resize,thumbnail方法只能进行缩小,所以进行了判断
    if img.size[0] > img.size[1]:
        img.thumbnail((10000, 256))
    else:
        img.thumbnail((256, 10000))
    # Crop操作
    left_margin = (img.width-224)/2
    bottom_margin = (img.height-224)/2
    right_margin = left_margin + 224
    top_margin = bottom_margin + 224
    img = img.crop((left_margin, bottom_margin, right_margin,   
                      top_margin))
    # 相同的预处理方法
    img = np.array(img)/255
    mean = np.array([0.485, 0.456, 0.406]) #provided mean
    std = np.array([0.229, 0.224, 0.225]) #provided std
    img = (img - mean)/std
    # 注意颜色通道应该放在第一个位置
    img = img.transpose((2, 0, 1))
    return img
  • 在数据测试完成后,我们需要对测试数据进行展示,也就是需要进行还原操作。
def imshow(image, ax=None, title=None):
    """展示数据"""
    if ax is None:
        fig, ax = plt.subplots()
    # 颜色通道还原
    image = np.array(image).transpose((1, 2, 0))
    # 预处理还原
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    image = std * image + mean
    image = np.clip(image, 0, 1)
    ax.imshow(image)
    ax.set_title(title)
    return ax
image_path = 'image_06621.jpg'
img = process_image(image_path)
imshow(img)

2536fb98d4394cc3b6069d3188e48aa9.png

之后进行预测结果的展示。

fig=plt.figure(figsize=(20, 20))
columns =4
rows = 2
for idx in range (columns*rows):
    ax = fig.add_subplot(rows, columns, idx+1, xticks=[], yticks=[])
    plt.imshow(im_convert(images[idx]))
    ax.set_title("{} ({})".format(cat_to_name[str(preds[idx])], cat_to_name[str(labels[idx].item())]),
                 color=("green" if cat_to_name[str(preds[idx])]==cat_to_name[str(labels[idx].item())] else "red"))
plt.show()


b53e7b380d2d40cdaaf86f49dd7792a0.png



相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
6天前
|
存储 边缘计算 Cloud Native
“论模型驱动架构设计方法及其应用”写作框架,软考高级,系统架构设计师
模型驱动架构设计是一种用于应用系统开发的软件设计方法,以模型构造、模型转换和精化为核心,提供了一套软件设计的指导规范。在模型驱动架构环境下,通过创建出机器可读和高度抽象的模型实现对不同问题域的描述,这些模型独立于实现技术,以标准化的方式储存,利用模型转换策略来驱动包括分析、设计和实现等在内的整个软件开发过程。
|
11天前
|
机器学习/深度学习 算法 PyTorch
Pytorch实现线性回归模型
在机器学习和深度学习领域,线性回归是一种基本且广泛应用的算法,它简单易懂但功能强大,常作为更复杂模型的基础。使用PyTorch实现线性回归,不仅帮助初学者理解模型概念,还为探索高级模型奠定了基础。代码示例中,`creat_data()` 函数生成线性回归数据,包括噪声,`linear_regression()` 定义了线性模型,`square_loss()` 计算损失,而 `sgd()` 实现了梯度下降优化。
|
5天前
|
机器学习/深度学习 算法
**反向传播算法**在多层神经网络训练中至关重要,它包括**前向传播**、**计算损失**、**反向传播误差**和**权重更新**。
【6月更文挑战第28天】**反向传播算法**在多层神经网络训练中至关重要,它包括**前向传播**、**计算损失**、**反向传播误差**和**权重更新**。数据从输入层流经隐藏层到输出层,计算预测值。接着,比较预测与真实值计算损失。然后,从输出层开始,利用链式法则反向计算误差和梯度,更新权重以减小损失。此过程迭代进行,直到损失收敛或达到训练次数,优化模型性能。反向传播实现了自动微分,使模型能适应训练数据并泛化到新数据。
16 2
|
11天前
|
机器学习/深度学习 PyTorch 算法框架/工具
PyTorch中的模型创建(一)
最全最详细的PyTorch神经网络创建
|
9天前
|
机器学习/深度学习 计算机视觉 网络架构
是VGG网络的主要特点和架构描述
是VGG网络的主要特点和架构描述:
15 1
|
11天前
|
机器学习/深度学习 PyTorch 算法框架/工具
|
12天前
|
机器学习/深度学习 人工智能 自然语言处理
深度揭秘:深度学习框架下的神经网络架构进化
从感知机到深度学习的革命,神经网络经历了从简单到复杂的演变。反向传播使多层网络实用化,深度信念网络(DBN)和卷积神经网络(CNN)的兴起,尤其是AlexNet在ImageNet竞赛中的胜利,开启了深度学习黄金时代。ResNet的残差学习解决了深度梯度消失问题。循环神经网络(RNN)、LSTM和GRU改进了序列处理,Transformer模型(如BERT和GPT)引领了自然语言处理的变革。超大规模模型如GPT-3和通义千问展示惊人能力,影响医疗、自动驾驶等多个领域。未来,平衡模型复杂度、计算成本与应用需求将是关键。
56 2
|
13天前
|
机器学习/深度学习 自然语言处理 算法
用神经架构搜索给LLM瘦身,模型变小,准确度有时反而更高
【6月更文挑战第20天】研究人员运用神经架构搜索(NAS)压缩LLM,如LLaMA2-7B,找到小而精准的子网,降低内存与计算成本,保持甚至提升性能。实验显示在多个任务上,模型大小减半,速度加快,精度不变或提升。NAS虽需大量计算资源,但结合量化技术,能有效优化大型语言模型。[论文链接](https://arxiv.org/pdf/2405.18377)**
22 2
|
13天前
|
机器学习/深度学习 算法框架/工具 计算机视觉
ViT模型的出现标志着Transformer架构在计算机视觉中的成功应用
ViT模型的出现标志着Transformer架构在计算机视觉中的成功应用
32 2
|
15天前
|
机器学习/深度学习 网络架构 计算机视觉
VGG深度卷积神经网络架构
VGG深度卷积神经网络架构