pytorch 预训练模型

预训练模型

学习到的特征在不同问题之间是可移植的

pytorch库中的预训练模型:

VGG16、VGG19、densenet

ResNet、mobilenet

ImageNet是一个手动标注好类别的图片数据库 目前以有22000个类别

VGG

在所有层都选用了(3*3)的卷积核,卷积步长为1,输入为(224,224)的RGB图像

VGG的缺点:网络架构weight数量相当大,很消耗磁盘空间 占用GPU空间大

训练非常慢

根据自己的需要调整out_features

model.classifier[-1].out_features=4 #将最后的输出分成4分类

数据增强

torchvision pytorch为视觉算法开发的

transforms.Resize 随机缩放比例
transforms.RandomCrop 随机位置裁剪
transforms.CenterCrop 中心位置裁剪
transforms.RandomHorizaontalFlip(p=1) 随机水平翻转
transforms.RandomVerticalFilp(p=1) 随机上下翻转
transforms.ColorJitter(brightness=1) 明暗度

数据增强仅对train数据进行,test数据集不需要

train_transform = transforms.Compose([
    transforms.Resize((224)),
    transforms.RandomCrop(192),
    transforms.RandomHorizontalFlip(p=0.5),
    transforms.RandomRotation(0.2),
    transforms.ColorJitter(brightness=0.5,contrast=0.5), #明暗度和对比度
    transforms.ToTensor(),
    transforms.Normalize(mean=[.5,.5,.5],
                        std=[.5,.5,.5])
]) #统一写代码实现

学习速率衰减

from torch.optim import lr_scheduler
exp_lr_scheduler = lr_scheduler.StepLR(optim,step_size=5,gamma=0.1) #gamma为衰减系数  lr*=gamma step_size为步长(每隔几步衰减)
lr_scheduler.MultiStepLR(optim,[20,50,80],gamma=0.1) #在20,50,80步衰减
在fit函数中增加
ex_lr_scheduler.step() 


def fit(epoch, model, trainloader, testloader):
    correct = 0
    total = 0
    running_loss = 0
    model.train()
    for x, y in trainloader:
        if torch.cuda.is_available():
            x, y = x.to('cuda'), y.to('cuda')
        y_pred = model(x)
        loss = loss_fn(y_pred, y)
        optim.zero_grad()
        loss.backward()
        optim.step()
        with torch.no_grad():
            y_pred = torch.argmax(y_pred, dim=1)
            correct += (y_pred == y).sum().item()
            total += y.size(0)
            running_loss += loss.item()
    ex_lr_scheduler.step()   
    epoch_loss = running_loss / len(trainloader)
    epoch_acc = correct / total
        
        
    test_correct = 0
    test_total = 0
    test_running_loss = 0 
    
    model.eval()
    with torch.no_grad():
        for x, y in testloader:
            if torch.cuda.is_available():
                x, y = x.to('cuda'), y.to('cuda')
            y_pred = model(x)
            loss = loss_fn(y_pred, y)
            y_pred = torch.argmax(y_pred, dim=1)
            test_correct += (y_pred == y).sum().item()
            test_total += y.size(0)
            test_running_loss += loss.item()
    
    epoch_test_loss = test_running_loss / len(testloader)
    epoch_test_acc = test_correct / test_total
    
        
    print('epoch: ', epoch, 
          'loss: ', round(epoch_loss, 3),
          'accuracy:', round(epoch_acc, 3),
          'test_loss: ', round(epoch_test_loss, 3),
          'test_accuracy:', round(epoch_test_acc, 3)
             )
        
    return epoch_loss, epoch_acc, epoch_test_loss, epoch_test_acc

微调

先将分类器训练好,再微调卷积层的数据 (训练两遍,model不变)

for param in model.parameters:
    param.requires_grad = True
extend_epoch = 30
optim = torch.optim.Adam(model.parameters(),lr=0.001)

模型权重的保存

PATH='my_model.pth'
torch.save(model.state_dict(),PATH)  #进保存最后一个epoch的权重  model.state_dict() model的权重
new_model = model
new_model.load_state_dict(torch.load(PATH))

保存最好的权重,在训练过程中增加if循环保存best_acc下的model.state_dict() 利用深度copy将数据拷贝出来

best_model_wts = copy.deepcopy(model.state_dict())
train_loss = []
train_acc = []
test_loss = []
test_acc = []
best_acc = 0
for epoch in range(extend_epoch):
    epoch_loss,epoch_acc,epoch_test_loss,epoch_test_acc = fit(epoch,model,train_dl,test_dl)
    
    if epoch_test_acc>best_acc:
        best_model_wts = copy.deepcopy(model.state_dict())
        best_acc = epoch_test_acc
    
    train_loss.append(epoch_loss)
    train_acc.append(epoch_acc)
    test_loss.append(epoch_test_loss)
    test_acc.append(epoch_test_acc)
model.load_state_dict(best_model_wts)

你可能感兴趣的:(pytorch,深度学习,人工智能)