PyTorch prenos učenja za poglobljeno učenje s primerom

Kazalo:

Anonim

Kaj je učenje s prenosom?

Transferno učenje je tehnika uporabe usposobljenega modela za reševanje druge povezane naloge. Gre za metodo raziskovanja strojnega učenja, ki shranjuje znanje, pridobljeno med reševanjem določenega problema, in uporablja isto znanje za reševanje drugega, a še povezanega problema. To izboljša učinkovitost z vnovično uporabo informacij, zbranih iz prej naučene naloge.

Za zmanjšanje časa treninga je priljubljena uporaba druge teže omrežnega modela, ker za usposabljanje mrežnega modela potrebujete veliko podatkov. Če želite skrajšati čas treninga, uporabite drugo mrežo in njeno težo ter spremenite zadnjo plast, da rešite naš problem. Prednost je, da lahko za treniranje zadnjega sloja uporabite majhen nabor podatkov.

V nadaljevanju te vadnice za učenje PyTorch Transfer bomo izvedeli, kako uporabljati učenje učenja s PyTorch.

Nalaganje nabora podatkov

Vir: Alien vs Predator Kaggle

Preden začnete uporabljati Transfer Learning PyTorch, morate razumeti nabor podatkov, ki ga boste uporabili. V tem primeru Transfer Learning PyTorch boste Tujec in Predator razvrstili med skoraj 700 slik. Za to tehniko v resnici ne potrebujete velike količine podatkov za trening. Podatkovni niz lahko prenesete iz Kaggle: Alien vs. Predator.

Kako uporabiti učenje s prenosom?

Tukaj je korak za korakom, kako uporabiti prenos učenja za poglobljeno učenje s PyTorch:

Korak 1) Naložite podatke

Prvi korak je naložiti naše podatke in nekaj preoblikovati v slike, tako da ustrezajo omrežnim zahtevam.

Podatke boste naložili iz mape z torchvision.dataset. Modul se bo ponovil v mapi, da bo razdelil podatke za vlak in preverjanje. Postopek preoblikovanja bo obrezal slike iz središča, izvedel vodoravni preklop, normaliziral in na koncu z globokim učenjem pretvoril v tenzor.

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")

Predstavljajmo si naš nabor podatkov za učenje učenja PyTorch. Postopek vizualizacije bo naslednjo serijo slik dobil iz vlačilcev podatkov in nalepk vlakov ter jih prikazal z matplotom.

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()

2. korak) Določite model

V tem postopku globokega učenja boste uporabili ResNet18 iz modula torchvision.

Za nalaganje resnet18 s predhodno usposobljeno težo, nastavljeno na True, boste uporabili modele torchvision.models. Po tem boste sloje zamrznili, tako da teh plasti ni mogoče izučiti. Zadnji sloj spremenite tudi z Linearnim slojem, da ustreza našim potrebam, to je 2 razreda. CrossEntropyLoss uporabljate tudi za večrazredno izgubo, za optimiziranje pa SGD s stopnjo učenja 0,0001 in zagonom 0,9, kot je prikazano na spodnjem primeru učenja PyTorch Transfer Learning.

## 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)

Struktura izhodnega modela

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)))

Korak 3) Treniraj in preizkusi model

Za usposabljanje in ocenjevanje našega modela bomo uporabili nekaj funkcij iz vadnice PyTorch za prenos učenja.

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)

Na koncu v tem primeru Transfer Learning in PyTorch začnimo svoj proces treninga s številom obdobij, nastavljenim na 25, in ocenimo po treningu. Na vsakem koraku treninga bo model vzel vhod in napovedal izhod. Po tem se predvideni izhod prenese na merilo za izračun izgub. Nato bodo izgube izvedle izračun povratne podlage za izračun naklona in na koncu izračun uteži ter optimizacijo parametrov z avtogradnjo.

Pri vizualiziranem modelu bo usposobljeno omrežje testirano s serijo slik za napovedovanje oznak. Nato bo vizualiziran s pomočjo matplotliba.

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

4. korak) Rezultati

Končni rezultat je, da ste dosegli natančnost 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

Konec, nato bo rezultat našega modela prikazan s spodnjim matplotom:

Povzetek

Torej, povzemimo vse! Prvi dejavnik je PyTorch, ki postaja vse bolj globok učni okvir za začetnike ali za raziskovalne namene. Ponuja velik čas izračuna, dinamični graf, podporo grafičnih procesorjev in je v celoti napisan v Pythonu. Z lahkoto lahko definirate naš lasten omrežni modul in opravite postopek usposabljanja z enostavno ponovitvijo. Jasno je, da je PyTorch idealen za začetnike, ki bodo izvedeli globoko učenje, za poklicne raziskovalce pa je zelo koristen s hitrejšim časom računanja in tudi zelo koristno funkcijo avtograda za pomoč pri dinamičnem grafu.