Mis on ülekandeõpe?
Transfer Learning on koolitatud mudeli kasutamise tehnika teise seotud ülesande lahendamiseks. See on masinõppe uurimismeetod, mis salvestab konkreetse probleemi lahendamisel saadud teadmised ja kasutab samu teadmisi teise erineva, kuid sellega seotud probleemi lahendamiseks. See parandab tõhusust, kasutades varem õpitud ülesandest kogutud teavet uuesti.
Treeninguaja vähendamiseks on populaarne kasutada muud võrgumudeli kaalu, kuna võrgumudeli koolitamiseks on vaja palju andmeid. Treeningu aja vähendamiseks kasutage muid probleeme ja selle kaalu ning muudate meie probleemi lahendamiseks viimast kihti. Eeliseks on see, et saate viimase kihi treenimiseks kasutada väikest andmekogumit.
Järgmisena selles PyTorch Transferi õppeõpetuses õpime, kuidas Transfer Transferit PyTorchiga kasutada.
Andmekogumi laadimine
Allikas: Tulnukas vs Kiskja Kaggle
Enne Transfer Learning PyTorchi kasutamise alustamist peate mõistma andmekogumit, mida kavatsete kasutada. Selles Transfer Learning PyTorchi näites klassifitseerite tulnuka ja kiskja ligi 700 pildi hulgast. Selle tehnika jaoks ei vaja te treenimiseks tegelikult suurt hulka andmeid. Andmekogumi saate alla laadida saidilt Kaggle: Alien vs. Predator.
Kuidas Transfer Transferi kasutada?
Siit leiate samm-sammulise protsessi, kuidas Transfer Transferit PyTorchiga süvitsi õppimiseks kasutada:
1. samm. Laadige andmed
Esimene samm on meie andmete laadimine ja piltide teisendamine, et need vastaksid võrgunõuetele.
Laadite andmed kaustast torchvision.dataset. Moodul kordab kaustas rongi ja valideerimise andmete jagamiseks. Ümberkujundamisprotsess lõikab pildid keskelt, horisontaalse klapi, normaliseerib ja teisendab need lõpuks Deep Learning'i abil tensoriks.
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")
Visualiseerime oma andmekogumi PyTorch Transfer Learning jaoks. Visualiseerimise protsess saab rongi andmete laadijatelt ja siltidelt järgmise pildipartii ning kuvab selle koos matplotiga.
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. samm. Määratlege mudel
Selles süvaõppeprotsessis kasutate ResNet18 from torchvision moodulit.
Resnet18 laadimiseks kasutate torchvision.models, mille eelnevalt koolitatud kaal on tõene. Pärast seda külmutate kihid nii, et neid kihte pole võimalik treenida. Samuti muudate viimast kihti lineaarse kihiga, et see vastaks meie vajadustele, see on 2 klassi. Samuti kasutate CrossEntropyLossi mitme klassi kaotamise funktsiooni jaoks ja optimeerija jaoks kasutate SGD-d õppemääraga 0,0001 ja hoogu 0,9, nagu on näidatud allpool esitatud PyTorch Transfer Learning näites.
## 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)
Väljundi mudeli struktuur
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)))
3. samm. Treenige ja katsetage mudelit
Kasutame mõnda funktsiooni Transfer Learning PyTorchi õpetusest, et aidata meil oma mudelit koolitada ja hinnata.
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)
Lõpuks selles PyTorchi Transfer Learning näites alustame oma koolitusprotsessi ajastatud ajastute arvuga 25 ja hindame pärast koolitusprotsessi. Igal koolitusetapil võtab mudel sisendi ja ennustab väljundi. Pärast seda edastatakse prognoositud väljund kahjude arvutamiseks kriteeriumile. Seejärel arvutatakse kahjudega backprop arvutamine gradiendi arvutamiseks ja lõpuks kaalude arvutamiseks ning parameetrite optimeerimiseks autogradiga.
Visualiseerimismudelil testitakse koolitatud võrku siltide ennustamiseks koos pildipartiiga. Siis visualiseeritakse see matplotlibi abil.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)visualize_model(vgg_based)plt.show()
4. samm. Tulemused
Lõpptulemus on see, et saavutasite täpsuse 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
Lõpuks visualiseeritakse meie mudeli väljund allpool oleva matplotiga:
Kokkuvõte
Niisiis, võtame kõik kokku! Esimene tegur on see, et PyTorch on kasvav sügava õppe raamistik algajatele või teadusuuringute eesmärgil. See pakub suurt arvutusaega, dünaamilist graafikut, GPU-de tuge ja on täielikult Pythonis kirjutatud. Saate hõlpsasti määratleda meie enda võrgumooduli ja teha treeningprotsessi lihtsa iteratsiooniga. On selge, et PyTorch on ideaalne algajatele sügava õppimise väljaselgitamiseks ja professionaalsetele teadlastele on see kasulik kiirema arvutusaja ja ka väga kasuliku dünaamilise graafiku abistamise autogradi funktsiooniga.