modèle de pré-formation Resnet et réglage fin

Affinement :
l'entraînement conjoint du classificateur nouvellement ajouté et de certaines ou de toutes les couches convolutives nous permet d'affiner les représentations des caractéristiques d'ordre élevé dans le modèle de base car elles sont pertinentes pour la tâche spécifique.
Ce n'est que lorsque le classificateur est entraîné (c'est-à-dire la couche linéaire) que la base de convolution peut être affinée, sinon l'erreur d'apprentissage sera très importante au début et ce qui a été appris dans la couche de convolution avant le réglage fin sera détruit.
 
Étapes :
1. Ajoutez une couche personnalisée à la base de convolution pré-entraînée
2. Gelez la base de convolution
3. Entraînez la couche de classification ajoutée
4. Dégelez une partie ou la totalité de la base de convolution (dégelez généralement la base de convolution proche de la sortie partie)
5. Former conjointement l'ensemble du modèle

Étapes générales pour l'apprentissage par transfert :

 Code:

"""Utilisez le modèle Resnet pour pré-entraîner le modèle + réglage fin""" 


import torch.cuda 
import torchvision 
from torch import nn 
import os 
from torchvision import transforms 
# import matplotlib.pyplot as plt 


#Preprocess data 
base_dir = r'. /dataset/4weather ' 
train_dir = os.path.join(base_dir,'train') 
test_dir = os.path.join(base_dir,'test') 

train_transformer = torchvision.transforms.Compose( 
     [ transforms.Resize((224,224)) , 
     transforms.RandomCrop ((192,192)), 
     transforms.ColorJitter(luminosité=0,4), 
     transforms.RandomHorizontalFlip(0,2), 
     transforms.ColorJitter(contrast=4), 
     transforms.ToTensor(),
     transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5]) ] 
     ) 

test_transformer 

= torchvision.transforms.Compose([ 
                         transforms.Resize((192,192)), 
                          transforms.ToTensor(), 
                          transforms.Normalize(mean=[0.5,0.5,0.5],std=[0.5,0.5,0.5])]) 

#创建dataset 
train_ds = torchvision.datasets.ImageFolder( 
    train_dir, 
    transform = train_transformer 
) 

test_ds = torchvision.datasets.ImageFolder ( 
    test_dir, 
    transform =test_transformer 
) 

#创建dataloader 
batch = 8 
train_dl =torch .utils.data.DataLoader( 
    train_ds, batch_size = batch, 
    shuffle = True 
) 
test_dl = torch.utils.data .DataLoader ( 
    test_ds, 
    batch_size = lot)
 
imgs,labels =next(iter(train_dl)) 



#Charger le modèle de périphérique 
= 'cuda' si torch.cuda. is_available() else 'cpu' 
model = torchvision.models.resnet18().to(device) 


for param in model.parameters(): 
    param.requires_grad = False 

#Seul le nombre de catégories de classification dans la couche de liaison complète doit être modifié 
in_f= model .fc.in_features 
#Le remplacement de la couche entièrement liée est un 
model.fc = nn.Linear(in_f, 4) 

#L'optimiseur n'a besoin d'optimiser que la dernière couche 
optim =torch .optim.Adam(model.fc .parameters() ,lr =0.001) 
#Fonction de 
perte loss_fn = nn.CrossEntropyLoss()

#训练函数fit 必须要指定 model.train,model.eval Resnet中有BN层

def fit(epoch,model,trainloader,testloader) : 
    correct = 0 
    total = 0 
    epoch_loss = running_loss/len(trainloader.dataset) 
    running_loss =0 
    model.train() #Indiquez qu'il s'agit du mode train et qu'il nécessite bn et laisse tomber
    pour x,y dans le chargeur de train : 
        si 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() 
        avec 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() 
    model.eval() 
    avec torch.no_grad() :
    epoch_acc =correct/total 

    test_correct = 0 
    test_total = 0 
    test_running_loss =0 
    print('epoch',epoch,'loss',round(epoch_loss,3),

        pour x,y dans le chargeur de test : 
            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_tst_loss =test_running_loss /len(testloader.dataset) 
    epoch_tst_acc = test_correct/test_total 
    return epoch_loss ,époque_acc,époque_tst_loss,époque_tst_acc

          'acc:',round(epoch_acc,3), 
          'test_loss:',round(epoch_tst_loss,3), 
          'test_acc:',round(epoch_tst_acc,3)) 

# époques =5 
# train_loss =[] 
# train_acc =[] 
# test_loss =[] 
# test_acc=[] 
# 
# pour l'époque dans la plage (époques) : 
# epoch_loss,epoch_acc,epoch_tst_loss,epoch_tst_acc =fit(epoch,model,train_dl,test_dl) 
# train_loss.append(epoch_loss) 
# train_acc.append (epoch_acc) 
# test_loss.append(epoch_tst_loss) 
# test_acc.append(epoch_tst_acc) 


#绘制图像:
# plt.plot(range(1,epochs+1),train_loss,label='train_loss') 
# plt.plot(range( 1,époques+1),test_loss,étiquette = 'test_loss' )
# plt.legend() 
# plt.show() 
# #Réglage précis 
des paramètres dans model.parameters() : 
    param.requires_grad=True 

extend_epoch =8 
#Le taux d'apprentissage doit être plus faible lors du réglage fin 
optimiseur = torch.optim .Adam( model.parameters(),lr=0.00001) 
# 
# #Processus de formation 
train_loss =[]
train_acc =[] 
test_loss =[] 
test_acc=[] 

pour l'époque dans la plage (extend_epoch) : 
    epoch_loss,epoch_acc,epoch_tst_loss,epoch_tst_acc =fit(epoch,model,train_dl,test_dl) 
    train_loss.append(epoch_loss) 
    train_acc.append(epoch_acc) 
    test_loss.append(epoch_tst_loss) 
    test_acc.append(epoch_tst_acc)

Je suppose que tu aimes

Origine blog.csdn.net/qq_45675231/article/details/129911570
conseillé
Classement