ПиТорцх трансфер учења за дубоко учење на примеру

Преглед садржаја:

Anonim

Шта је трансфер учење?

Трансфер учење је техника коришћења обученог модела за решавање другог повезаног задатка. То је метода истраживања машинског учења која чува знање стечено решавањем одређеног проблема и користи исто знање за решавање другог различитог, али повезаног проблема. Ово побољшава ефикасност поновном употребом информација прикупљених из претходно наученог задатка.

Популарно је користити другу тежину мрежног модела да бисте смањили време тренинга, јер вам је потребно много података да бисте обучили мрежни модел. Да бисте смањили време тренинга, користите друге мреже и њихову тежину и модификујете последњи слој да бисте решили наш проблем. Предност је што можете да користите мали скуп података за обуку последњег слоја.

Следеће у овом водичу за учење ПиТорцх Трансфера научићемо како се користи Трансфер Леарнинг са ПиТорцх.

Учитавање скупа података

Извор: Алиен вс. Предатор Каггле

Пре него што почнете да користите Трансфер Леарнинг ПиТорцх, морате да разумете скуп података који ћете користити. У овом примеру преноса учења ПиТорцх-а класификоваћете Ванземаљца и Предатора из скоро 700 слика. За ову технику вам није потребна велика количина података за обуку. Скуп података можете преузети са Каггле: Алиен вс. Предатор.

Како се користи учење трансфера?

Ево корак по корак процеса коришћења Трансфер Леарнинга за дубинско учење са ПиТорцх-ом:

Корак 1) Учитајте податке

Први корак је учитавање података и извршавање неке трансформације слика тако да одговарају мрежним захтевима.

Учитаћете податке из директоријума са торцхвисион.датасет. Модул ће се поновити у фасцикли како би поделио податке за воз и проверу ваљаности. Процес трансформације ће обрезати слике из центра, извршити хоризонтално окретање, нормализовати и на крају га претворити у тензор помоћу дубоког учења.

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

Визуелизујмо наш скуп података за ПиТорцх Трансфер Леарнинг. Процес визуализације ће добити следећу серију слика из уређаја за учитавање и ознаке возова и приказати их матплотом.

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) Дефинисање модела

У овом процесу дубоког учења користићете РесНет18 из модула торцхвисион.

Користићете торцхвисион.моделс за учитавање реснет18 са унапред обученом тежином постављеном на Тачно. Након тога ћете замрзнути слојеве тако да се ови слојеви не могу обучити. Такође последњи слој модификујете Линеарним слојем како би одговарао нашим потребама, а то су 2 класе. Такође користите ЦроссЕнтропиЛосс за функцију губитка у више класа, а за оптимизатор ћете користити СГД са стопом учења од 0,0001 и импулсом од 0,9, као што је приказано у доњем примеру ПиТорцх Трансфер Леарнинг учења.

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

Структура излазног модела

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) Модел обуке и тестирања

Користићемо неке од функција из Трансфер Леарнинг ПиТорцх водича како би нам помогли да обучимо и проценимо наш модел.

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)

На крају, у овом примеру Трансфер Леарнинг-а у ПиТорцх-у, започнимо наш процес обуке бројем епоха подешених на 25 и проценимо након процеса обуке. У сваком кораку тренинга, модел ће узимати улаз и предвиђати излаз. Након тога, предвиђени излаз ће се проследити критеријуму за израчунавање губитака. Тада ће губици извршити прорачун повратног материјала за израчунавање градијента и коначно израчунавање тежине и оптимизацију параметара помоћу аутоградње.

На моделу за визуелизацију, обучена мрежа ће бити тестирана са низом слика да би предвидела етикете. Тада ће се визуализовати уз помоћ матплотлиба.

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

Корак 4) Резултати

Коначни резултат је да сте постигли тачност од 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

На крају ће излаз нашег модела бити приказан матплотом испод:

Резиме

Дакле, да резимирамо све! Први фактор је ПиТорцх, све дубљи оквир за учење за почетнике или у истраживачке сврхе. Нуди дуго рачунање, динамички граф, подршку за графичке процесоре и у потпуности је написан на Питхону. Можете лако да дефинишете наш сопствени мрежни модул и одрадите процес обуке са лаганом итерацијом. Јасно је да је ПиТорцх идеалан за почетнике како би сазнали како дубоко учити, а за професионалне истраживаче врло је користан са бржим временом рачунања и такође врло корисном функцијом аутоград за помоћ динамичком графикону.