Kas ir pārejas mācīšanās?
Transfer Transfer ir apmācīta modeļa izmantošanas paņēmiens, lai atrisinātu citu saistītu uzdevumu. Tā ir mašīnmācīšanās pētījumu metode, kurā tiek glabātas zināšanas, kas iegūtas, risinot konkrētu problēmu, un tās pašas zināšanas tiek izmantotas, lai atrisinātu citu atšķirīgu, tomēr saistītu problēmu. Tas uzlabo efektivitāti, atkārtoti izmantojot informāciju, kas iegūta no iepriekš apgūtā uzdevuma.
Lai samazinātu apmācības laiku, ir populāri izmantot citu tīkla modeļa svaru, jo tīkla modeļa apmācībai ir nepieciešams daudz datu. Lai samazinātu apmācības laiku, jūs izmantojat citus tīklus un to svaru un modificējat pēdējo slāni, lai atrisinātu mūsu problēmu. Priekšrocība ir tā, ka pēdējā slāņa apmācībai varat izmantot nelielu datu kopu.
Tālāk šajā PyTorch Transfer mācību apmācībā mēs uzzināsim, kā izmantot Transfer Learning ar PyTorch.
Notiek datu kopas ielāde
Avots: Alien vs Predator Kaggle
Pirms sākat lietot Transfer Learning PyTorch, jums ir jāsaprot datu kopa, kuru izmantosit. Šajā Transfer Learning PyTorch piemērā jūs klasificēsit ārvalstnieku un plēsēju no gandrīz 700 attēliem. Lai izmantotu šo tehniku, apmācībai patiesībā nav nepieciešams liels datu apjoms. Datu kopu varat lejupielādēt vietnē Kaggle: Alien vs Predator.
Kā izmantot Transfer Learning?
Šis ir soli pa solim process, kā izmantot Transfer Learning padziļinātai mācīšanai ar PyTorch:
1. solis. Ielādējiet datus
Vispirms ir jāielādē mūsu dati un jāpārveido attēli, lai tie atbilstu tīkla prasībām.
Dati tiks ielādēti no mapes ar torchvision.dataset. Modulis atkārtosies mapē, lai sadalītu datus vilcienam un validācijai. Pārveidošanas procesā attēli tiek apgriezti no centra, tiek veikts horizontāls pagrieziens, normalizēts un visbeidzot pārveidots par tenzoru, izmantojot programmu 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")
Vizualizēsim mūsu datu kopu PyTorch Transfer Learning. Vizualizācijas process iegūs nākamo attēlu partiju no vilciena datu iekrāvējiem un etiķetēm un parādīs to ar 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()
2. solis. Definējiet modeli
Šajā dziļā mācību procesā jūs izmantosiet ResNet18 no torchvision moduļa.
Jūs izmantosiet torchvision.models, lai ielādētu resnet18 ar iepriekš apmācītu svaru kā patiesu. Pēc tam jūs iesaldēsit slāņus, lai šie slāņi nebūtu apmācāmi. Jūs arī modificējat pēdējo slāni ar lineāro slāni, lai tas atbilstu mūsu vajadzībām, tas ir, 2 klases. Jūs arī izmantojat CrossEntropyLoss vairāku klašu zaudēšanas funkcijai un optimizētājam izmantosiet SGD ar mācīšanās ātrumu 0,0001 un impulsu 0,9, kā parādīts zemāk redzamajā PyTorch Transfer Learning piemērā.
## 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)
Rezultāta modeļa struktūra
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. solis. Vilciena un testa modelis
Mēs izmantosim daļu no Transfer Learning PyTorch apmācības funkcijas, lai palīdzētu mums apmācīt un novērtēt mūsu modeli.
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)
Visbeidzot šajā piemērā Transfer Learning PyTorch sāksim apmācības procesu ar laikmetu skaitu, kas iestatīts uz 25, un novērtēsim pēc apmācības procesa. Katrā apmācības posmā modelis ņems ievadu un prognozēs rezultātu. Pēc tam prognozētā produkcija tiks nodota kritērijam, lai aprēķinātu zaudējumus. Tad zaudējumi veiks backprop aprēķinu, lai aprēķinātu gradientu un, visbeidzot, aprēķinātu svarus un optimizētu parametrus ar autograd.
Vizualizācijas modelī apmācītais tīkls tiks pārbaudīts ar attēlu sēriju, lai paredzētu etiķetes. Tad tas tiks vizualizēts ar matplotlib palīdzību.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)visualize_model(vgg_based)plt.show()
4. solis) Rezultāti
Gala rezultāts ir tāds, ka jūs sasniedzāt 92% precizitāti.
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
Beigās, tad mūsu modeļa rezultāts tiks vizualizēts ar zemāk esošo matplot:
Kopsavilkums
Tātad, apkoposim visu! Pirmais faktors ir tas, ka PyTorch ir augoša dziļo mācību sistēma iesācējiem vai pētniecības vajadzībām. Tas piedāvā lielu skaitļošanas laiku, Dynamic Graph, GPU atbalstu, un tas ir pilnībā rakstīts Python. Jūs varat viegli noteikt mūsu pašu tīkla moduli un veikt apmācības procesu ar vieglu atkārtojumu. Ir skaidrs, ka PyTorch ir ideāli piemērots iesācējiem, lai uzzinātu dziļu mācīšanos, un profesionāliem pētniekiem tas ir ļoti noderīgs ar ātrāku aprēķināšanas laiku un arī ļoti noderīgu automātiskās pakāpes funkciju, kas palīdz dinamiskam grafikam.