PyTorch Transfer Learning pre hlboké učenie s príkladom

Obsah:

Anonim

Čo je to Transfer Learning?

Transfer Learning je technika využívania trénovaného modelu na riešenie ďalšej súvisiacej úlohy. Jedná sa o výskumnú metódu strojového učenia, ktorá ukladá vedomosti získané pri riešení konkrétneho problému a používa ich na vyriešenie iného, ​​zatiaľ súvisiaceho problému. To zvyšuje efektivitu opätovným použitím informácií zhromaždených z predtým naučenej úlohy.

Je populárne používať inú váhu sieťového modelu na skrátenie času potrebného na tréning, pretože na trénovanie sieťového modelu potrebujete veľa údajov. Na skrátenie času potrebného na trénovanie použijete iné siete a ich váhu a upravíte poslednú vrstvu, aby ste vyriešili náš problém. Výhodou je, že poslednú vrstvu môžete trénovať pomocou malého súboru údajov.

Ďalej v tomto výučbovom výučbe PyTorch Transfer sa dozvieme, ako používať Transfer Learning s PyTorch.

Načítava sa množina údajov

Zdroj: Alien vs. Predator Kaggle

Predtým, ako začnete používať Transfer Learning PyTorch, musíte porozumieť množine údajov, ktorú budete používať. V tomto príklade Transfer Learning PyTorch klasifikujete Mimozemšťana a Predátora z takmer 700 obrázkov. Pre túto techniku ​​nepotrebujete na trénovanie skutočne veľké množstvo dát. Dataset si môžete stiahnuť z Kaggle: Alien vs. Predator.

Ako používať Transfer Learning?

Tu je krok za krokom postup, ako používať Transfer Learning na Deep Learning s PyTorch:

Krok 1) Načítajte údaje

Prvým krokom je načítanie našich údajov a vykonanie určitej transformácie na obrázky tak, aby zodpovedali požiadavkám na sieť.

Dáta načítate z priečinka s torchvision.dataset. Modul bude v priečinku iterovať, aby rozdelil údaje pre vlak a validáciu. Proces transformácie orezá obrázky zo stredu, vykoná horizontálne prevrátenie, normalizuje sa a nakoniec ho pomocou funkcie Deep Learning prevedie na 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")

Poďme si vizualizovať náš dátový súbor pre PyTorch Transfer Learning. Proces vizualizácie získa ďalšiu várku obrázkov z nakladačov údajov a štítkov vlakov a zobrazí ich pomocou matplotu.

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

Krok 2) Definujte model

V tomto procese hlbokého učenia budete používať ResNet18 z modulu torchvision.

Použijete torchvision.models na načítanie resnet18 s vopred vyškolenou hmotnosťou nastavenou na True. Potom vrstvy zmrazíte, aby ich nebolo možné trénovať. Poslednú vrstvu tiež upravíte lineárnou vrstvou tak, aby vyhovovala našim potrebám, čo sú 2 triedy. CrossEntropyLoss tiež používate na funkciu straty viacerých tried a na optimalizáciu použijete SGD s rýchlosťou učenia 0,0001 a hybnosťou 0,9, ako je uvedené v príklade 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)

Štruktúra výstupného modelu

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

Krok 3) Trénujte a testujte model

Niektoré z funkcií z Transfer Learning PyTorch Tutorial použijeme, aby nám pomohli trénovať a hodnotiť náš model.

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)

Nakoniec v tomto príklade Transfer Learning in PyTorch začnime náš tréningový proces s počtom epoch nastaveným na 25 a po tréningovom procese vyhodnotíme. V každom tréningovom kroku model prevezme vstup a predpovedá výstup. Potom sa predpovedaný výstup prenesie do kritéria na výpočet strát. Potom straty vykonajú spätný výpočet na výpočet gradientu a nakoniec výpočet váh a optimalizáciu parametrov pomocou autogradu.

Na modeli vizualizácie bude trénovaná sieť testovaná s dávkou obrázkov na predpovedanie štítkov. Potom bude vizualizovaná pomocou matplotlib.

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

Krok 4) Výsledky

Konečným výsledkom je, že ste dosiahli presnosť 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

Nakoniec bude výstup nášho modelu vizualizovaný pomocou matplotu nižšie:

Zhrnutie

Poďme si teda všetko zhrnúť! Prvým faktorom je PyTorch, ktorý predstavuje rastúci rámec hlbokého učenia pre začiatočníkov alebo na účely výskumu. Ponúka vysoký výpočtový čas, dynamický graf, podporu GPU a je úplne napísaný v jazyku Python. Môžete ľahko definovať náš vlastný sieťový modul a vykonať tréningový proces s ľahkou iteráciou. Je zrejmé, že program PyTorch je ideálny pre začiatočníkov, ktorí chcú spoznať hlboké učenie, a pre profesionálnych výskumníkov je veľmi užitočný s rýchlejším výpočtovým časom a tiež s veľmi užitočnou funkciou autogradu na pomoc pri dynamickom grafe.