计算机视觉模型预训练通用框架

一、前言

1、计算机视觉包含常用的四大任务:分类、识别、分割、检测等。

2、这些任务可以被称为下游任务,关键的上游任务是预训练模型的backbone。backbone是一个模型的特征提取层,也叫骨干网络。当涉及训练预模型时,有一个通用框架可以帮助我们快速构建和训练模型的backbone。这个框架可以适用于各种下游任务,并且易于定制和扩展。在本文中,我们将介绍这个通用框架的不同部分,并说明如何使用它来训练自己的模型。

二、具体步骤

接下来我将通过Resnet作为backbone来说明得到一个模型之后如何预训练来得到模型,包括数据加载和预处理、实例化模型并修改Fc(fully conneted layer)头、调整学习率策略、训练和验证函数等说明。

1、数据加载和预处理:通常我们可以加载一些官方的数据集或建立自己的数据集,这里有一些区别,比如官方的数据集往往经过预处理,可以直接加载函数,例如MNIST,ImageNet。而自己的数据集需要根据网络需求调整大小、channel等。无论是官方还是自己的数据集都需要适当的预处理,比如图像增强、归一化等等。下面是具体步骤:以官方的MNIST数据集为例

import torch
import torchvision
import torch.nn as nn
form torchvision import datasets


batch_size = 256 #批量大小

#预处理
transform = transforms.Compose(    
    [transforms.Resize((224,224)),
     transforms.ToTensor(),
     transforms.Normalize((0.1307,), (0.3081,))]
)
transform_test = transforms.Compose(
    [transforms.Resize((224,224)),
     transforms.ToTensor(),
     transforms.Normalize((0.1307,), (0.3081,))]
)

#下载训练集
datasets_train = datasets.MNIST(root='./data',train=True,download=True,transform=transform)
datasets_test = datasets.MNIST(root='./data',train=False,download=True,transform=transform_test)
#加载训练集
train_loader = torch.utils.data.Dataloader(datasets_train,batch_size= batch_size,shuffle=True)
test_loader = torch.utils.data.DataLoader(datasets_test,batch_size=batch_size,shuffle=False)

若是接受自己的数据集:

from dataset.dataset import SeedlingData

dataset_train = SeedlingData(root='./data/train',transforms=transform,trian=True)
dataset_test = SeedlingData(root='./test/test', transforms=transform_test, train=False)

2、实例化模型:下载好模型源码,或者是选用torchvision.models里面已有的模型(包含Alexnet、densenet、inception、resnet、squeezenet、vgg),根据自己的任务调整分类头,下面以Resnet50为例:

from torchvision.models import resnet50

modellr = 1e-4  #learning rate
BATCHSIZE = 8
EPOCHS = 100
DEVICE = torch.device('cuda'if torch.cuda.is_vailable() else 'cpu') #使用GPU
classes = 10  #自己的类别数
criterion = nn.CrossEntropyLoss()  #定义损失函数
model = Resnet50(Pretrained=True) #预训练的模型
print(model) #打印模型结构,方便修改全连接层
model.fc = nn.Linear(in_features=2048, out_features=classes, bias=True)  #修改全连接层
model.to(DEVICE)

optimizer = optim.Adam(model_ft.parameters(), lr=modellr)  #实例化Adam优化器,更新可学习参数
cosine_schedule = optim.lr_scheduler.CosineAnnealingLR(optimizer=optimizer,T_max=20,eta_min=1e-9)  #余弦退火调整学习率
'''
可以用别的学习率衰减方法代替,例如
def adjust_learning_rate(optimizer,epoch):
    modellrnew = modellr*(0.1**(epoch//50))
    for param_group in optimizer.param_groups:
        param_group['lr'] = modellrnew

'''

3、定义训练和验证函数:函数接受模型、周期、设备(GPU)、数据加载器、优化器等参数,多说无用,直接看代码:

def train(model,device,optimizer,epoch,train_loader):
    model.train()  #设置为训练模式,意味着模型中有BN层和Dropout会启用
    sum_loss = 0
    total_num = len(train_loader.dataset) 
    for batch_idx, (data, target) in enumerate(train_loader):
        data,target = Variable(data).to(device),Variable(target).to(device)
        output = model(data)
        loss = criterion(output,target)
        optimizer.zero_grad()
        loss_backward()
        optimizer.step()
        print_loss = loss.data.item()
        sum_loss += print_loss
        if (batch_idx + 1) % 10 == 0:  #每10个批次打印进度和损失
            print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
                epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),
                       100. * (batch_idx + 1) / len(train_loader), loss.item()))
    ave_loss = sum_loss / len(train_loader)  
    print('epoch:{},loss:{}'.format(epoch, ave_loss))       

def val(model,device,test_loader):
    model.eval() #测试模式,不启用BN层和Dropout
        test_loss = 0
    correct = 0  #预测正确的样本数
    total_num = len(test_loader.dataset) 
    print(total_num, len(test_loader))
    with torch.no_grad():
        for data, target in test_loader:
            data, target = Variable(data).to(device), Variable(target).to(device)
            output = model(data)
            loss = criterion(output, target)
            _, pred = torch.max(output.data, 1) #最优答案与标签是否相同
            correct += torch.sum(pred == target)
            print_loss = loss.data.item()
            test_loss += print_loss
        correct = correct.data.item()
        acc = correct / total_num
        avgloss = test_loss / len(test_loader)
        print('\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
            avgloss, correct, len(test_loader.dataset), 100 * acc))


        

开始训练:

# 训练
for epoch in range(1, EPOCHS + 1):
    adjust_learning_rate(optimizer, epoch)
    train(model_ft, DEVICE, train_loader, optimizer, epoch)
    val(model_ft, DEVICE, test_loader)
torch.save(model_ft, 'model.pth')  #保存权重

当然,如果你想只保留最好的权重,可以在验证函数那里修改,像这样:

ACC=0
# 验证过程
def val(model, device, test_loader):
    global ACC
    model.eval()
    test_loss = 0
    correct = 0
    total_num = len(test_loader.dataset)
    print(total_num, len(test_loader))
    with torch.no_grad():
        for data, target in test_loader:
            data, target = Variable(data).to(device), Variable(target).to(device)
            output = model(data)
            loss = criterion(output, target)
            _, pred = torch.max(output.data, 1)
            correct += torch.sum(pred == target)
            print_loss = loss.data.item()
            test_loss += print_loss
        correct = correct.data.item()
        acc = correct / total_num
        avgloss = test_loss / len(test_loader)
        print('\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
            avgloss, correct, len(test_loader.dataset), 100 * acc))
        if acc > ACC:
            torch.save(model_ft, 'model_' + str(epoch) + '_' + str(round(acc, 3)) + '.pth')
            ACC = acc

以上,基本包含了整个训练流程。注意,backbone是和整个模型一起训练的,当然,我们可以通过不断优化训练方法(数据增强、学习率调整等等)来提高模型效果。一旦得到一个满意的模型后(评价模型的指标之前有提),可以拿它进行下游工作。

1、对于分类任务,可以将训练好的backbone模型与全连接层相连,以输出每个类别的概率分布。通过将输入样本传递给backbone模型,然后使用分类器对提取的特征进行分类,您可以得到输入属于每个类别的概率。最终,您可以选择具有最高概率的类别作为预测结果。

2、在目标检测任务中,您可以使用训练好的backbone模型来提取图像特征,并将这些特征传递给一个目标检测网络,如Faster R-CNN、YOLO或SSD。这个目标检测网络会在图像中定位和识别目标。通过联合训练backbone和目标检测网络,可以实现对图像中多个目标的检测和分类。

3、对于语义分割任务,使用训练好的backbone模型来提取图像特征,并将这些特征传递给一个分割网络,如U-Net或DeepLab。这个分割网络将利用backbone提取的特征来生成每个像素的语义分割结果,将图像中的每个像素分配给不同的类别,通过联合训练backbone和分割网络。

4、在目标识别任务中,您可以使用训练好的backbone模型来提取图像特征,并将这些特征传递给一个特征匹配或特征提取算法,如SIFT或ORB。这些算法可以在图像中寻找和识别特定目标的位置和姿态。通过结合backbone的特征提取能力和识别算法,可以实现对特定目标的识别和定位。

三、总结

以上为全部内容,觉得有用的亲可以点赞收藏哦,完整的框架内容可以从我的主页下载。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值