PyTorch Transfer Learning för Deep Learning med exempel

Innehållsförteckning:

Anonim

Vad är Transfer Learning?

Transfer Learning är en teknik för att använda en utbildad modell för att lösa en annan relaterad uppgift. Det är en maskininlärningsforskningsmetod som lagrar kunskapen som erhållits när man löser ett visst problem och använder samma kunskap för att lösa ett annat men ändå relaterat problem. Detta förbättrar effektiviteten genom att återanvända informationen som samlats in från den tidigare inlärda uppgiften.

Det är populärt att använda annan nätverksmodellvikt för att minska din träningstid eftersom du behöver mycket data för att träna en nätverksmodell. För att minska träningstiden använder du andra nätverk och dess vikt och ändrar det sista lagret för att lösa vårt problem. Fördelen är att du kan använda en liten dataset för att träna det sista lagret.

Nästa i denna PyTorch Transfer-inlärningshandledning lär vi oss hur man använder Transfer Learning med PyTorch.

Laddar datauppsättning

Källa: Alien vs. Predator Kaggle

Innan du börjar använda Transfer Learning PyTorch måste du förstå den dataset som du ska använda. I det här PyTorch-exemplet Transfer Learning klassificerar du en utomjording och en rovdjur från nästan 700 bilder. För den här tekniken behöver du inte riktigt mycket data för att träna. Du kan ladda ner dataset från Kaggle: Alien vs. Predator.

Hur använder jag Transfer Learning?

Här är en steg för steg-process om hur du använder Transfer Learning för Deep Learning med PyTorch:

Steg 1) Ladda data

Det första steget är att ladda vår data och göra en viss omvandling till bilder så att den matchar nätverkskraven.

Du laddar in data från en mapp med torchvision.dataset. Modulen upprepas i mappen för att dela upp data för tåg och validering. Transformationsprocessen kommer att beskära bilderna från mitten, utföra en horisontell vändning, normalisera och slutligen konvertera den till tensor med hjälp av Deep Learning.

from __future__ import print_function, divisionimport osimport timeimport torchimport torchvisionfrom torchvision import datasets, models, transformsimport torch.optim as optimimport numpy as npimport matplotlib.pyplot as pltdata_dir = "alien_pred"input_shape = 224mean = [0.5, 0.5, 0.5]std = [0.5, 0.5, 0.5]#data transformationdata_transforms = {'train': transforms.Compose([transforms.CenterCrop(input_shape),transforms.ToTensor(),transforms.Normalize(mean, std)]),'validation': transforms.Compose([transforms.CenterCrop(input_shape),transforms.ToTensor(),transforms.Normalize(mean, std)]),}image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),transform=data_transforms[x])for x in ['train', 'validation']}dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=32,shuffle=True, num_workers=4)for x in ['train', 'validation']}dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'validation']}print(dataset_sizes)class_names = image_datasets['train'].classesdevice = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

Låt oss visualisera vår dataset för PyTorch Transfer Learning. Visualiseringsprocessen kommer att hämta nästa sats bilder från tågdataladdare och etiketter och visa det med matplot.

images, labels = next(iter(dataloaders['train']))rows = 4columns = 4fig=plt.figure()for i in range(16):fig.add_subplot(rows, columns, i+1)plt.title(class_names[labels[i]])img = images[i].numpy().transpose((1, 2, 0))img = std * img + meanplt.imshow(img)plt.show()

Steg 2) Definiera modell

I denna Deep Learning-process kommer du att använda ResNet18 från torchvision-modulen.

Du använder torchvision.models för att ladda resnet18 med den förutbildade vikten inställd på True. Därefter fryser du lagren så att dessa lager inte kan tränas. Du ändrar också det sista lagret med ett linjärt lager för att passa våra behov som är två klasser. Du använder också CrossEntropyLoss för förlustfunktion i flera klasser och för optimeraren kommer du att använda SGD med inlärningshastigheten 0,0001 och en momentum på 0,9 som visas i PyTorch Transfer Learning-exemplet nedan.

## Load the model based on VGG19vgg_based = torchvision.models.vgg19(pretrained=True)## freeze the layersfor param in vgg_based.parameters():param.requires_grad = False# Modify the last layernumber_features = vgg_based.classifier[6].in_featuresfeatures = list(vgg_based.classifier.children())[:-1] # Remove last layerfeatures.extend([torch.nn.Linear(number_features, len(class_names))])vgg_based.classifier = torch.nn.Sequential(*features)vgg_based = vgg_based.to(device)print(vgg_based)criterion = torch.nn.CrossEntropyLoss()optimizer_ft = optim.SGD(vgg_based.parameters(), lr=0.001, momentum=0.9)

Produktionsmodellstrukturen

VGG((features): Sequential((0): Conv2d(3, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(1): ReLU(inplace)(2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(3): ReLU(inplace)(4): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(5): Conv2d(64, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(6): ReLU(inplace)(7): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(8): ReLU(inplace)(9): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(10): Conv2d(128, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(11): ReLU(inplace)(12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(13): ReLU(inplace)(14): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(15): ReLU(inplace)(16): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(17): ReLU(inplace)(18): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(19): Conv2d(256, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(20): ReLU(inplace)(21): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(22): ReLU(inplace)(23): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(24): ReLU(inplace)(25): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(26): ReLU(inplace)(27): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)(28): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(29): ReLU(inplace)(30): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(31): ReLU(inplace)(32): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(33): ReLU(inplace)(34): Conv2d(512, 512, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))(35): ReLU(inplace)(36): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))(classifier): Sequential((0): Linear(in_features=25088, out_features=4096, bias=True)(1): ReLU(inplace)(2): Dropout(p=0.5)(3): Linear(in_features=4096, out_features=4096, bias=True)(4): ReLU(inplace)(5): Dropout(p=0.5)(6): Linear(in_features=4096, out_features=2, bias=True)))

Steg 3) Träna och testa modellen

Vi kommer att använda en del av funktionen från Transfer Learning PyTorch Tutorial för att hjälpa oss att träna och utvärdera vår modell.

def train_model(model, criterion, optimizer, num_epochs=25):since = time.time()for epoch in range(num_epochs):print('Epoch {}/{}'.format(epoch, num_epochs - 1))print('-' * 10)#set model to trainable# model.train()train_loss = 0# Iterate over data.for i, data in enumerate(dataloaders['train']):inputs , labels = datainputs = inputs.to(device)labels = labels.to(device)optimizer.zero_grad()with torch.set_grad_enabled(True):outputs = model(inputs)loss = criterion(outputs, labels)loss.backward()optimizer.step()train_loss += loss.item() * inputs.size(0)print('{} Loss: {:.4f}'.format('train', train_loss / dataset_sizes['train']))time_elapsed = time.time() - sinceprint('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))return modeldef visualize_model(model, num_images=6):was_training = model.trainingmodel.eval()images_so_far = 0fig = plt.figure()with torch.no_grad():for i, (inputs, labels) in enumerate(dataloaders['validation']):inputs = inputs.to(device)labels = labels.to(device)outputs = model(inputs)_, preds = torch.max(outputs, 1)for j in range(inputs.size()[0]):images_so_far += 1ax = plt.subplot(num_images//2, 2, images_so_far)ax.axis('off')ax.set_title('predicted: {} truth: {}'.format(class_names[preds[j]], class_names[labels[j]]))img = inputs.cpu().data[j].numpy().transpose((1, 2, 0))img = std * img + meanax.imshow(img)if images_so_far == num_images:model.train(mode=was_training)returnmodel.train(mode=was_training)

Slutligen, i detta Transfer Learning in PyTorch-exempel, låt oss börja vår träningsprocess med antalet epoker inställda på 25 och utvärdera efter träningsprocessen. Vid varje träningssteg tar modellen inmatningen och förutsäger resultatet. Därefter kommer den förutsagda produktionen att överföras till kriteriet för att beräkna förlusterna. Då gör förlusterna en backprop-beräkning för att beräkna lutningen och slutligen beräkna vikterna och optimera parametrarna med autograd.

Vid visualiseringsmodellen testas det utbildade nätverket med ett antal bilder för att förutsäga etiketterna. Då kommer det att visualiseras med hjälp av matplotlib.

vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)visualize_model(vgg_based)plt.show()

Steg 4) Resultat

Det slutliga resultatet är att du uppnådde en noggrannhet på 92%.

Epoch 23/24----------train Loss: 0.0044train Loss: 0.0078train Loss: 0.0141train Loss: 0.0221train Loss: 0.0306train Loss: 0.0336train Loss: 0.0442train Loss: 0.0482train Loss: 0.0557train Loss: 0.0643train Loss: 0.0763train Loss: 0.0779train Loss: 0.0843train Loss: 0.0910train Loss: 0.0990train Loss: 0.1063train Loss: 0.1133train Loss: 0.1220train Loss: 0.1344train Loss: 0.1382train Loss: 0.1429train Loss: 0.1500Epoch 24/24----------train Loss: 0.0076train Loss: 0.0115train Loss: 0.0185train Loss: 0.0277train Loss: 0.0345train Loss: 0.0420train Loss: 0.0450train Loss: 0.0490train Loss: 0.0644train Loss: 0.0755train Loss: 0.0813train Loss: 0.0868train Loss: 0.0916train Loss: 0.0980train Loss: 0.1008train Loss: 0.1101train Loss: 0.1176train Loss: 0.1282train Loss: 0.1323train Loss: 0.1397train Loss: 0.1436train Loss: 0.1467Training complete in 2m 47s

Avsluta så kommer produktionen av vår modell att visualiseras med matplot nedan:

Sammanfattning

Så låt oss sammanfatta allt! Den första faktorn är att PyTorch är en växande ram för djupinlärning för nybörjare eller för forskningsändamål. Den erbjuder hög beräkningstid, dynamisk graf, GPU-stöd och den är helt skriven i Python. Du kan enkelt definiera vår egen nätverksmodul och göra träningsprocessen med en enkel iteration. Det är tydligt att PyTorch är perfekt för nybörjare att ta reda på djupinlärning och för professionella forskare är det mycket användbart med snabbare beräkningstid och också den mycket hjälpsamma autogradfunktionen för att hjälpa dynamisk graf.