Mi az a transzfertanulás?
A Transzfertanulás egy képzett modell alkalmazásának technikája egy másik kapcsolódó feladat megoldására. Ez egy Gépi tanulás kutatási módszer, amely tárolja az adott probléma megoldása során megszerzett tudást, és ugyanazon ismereteket felhasználja egy másik, mégis kapcsolódó probléma megoldására. Ez javítja a hatékonyságot azáltal, hogy újból felhasználja a korábban megtanult feladatból összegyűjtött információkat.
Népszerű más hálózati modell súlyát használni az edzésidő csökkentése érdekében, mert a hálózati modell kiképzéséhez sok adatra van szükség. Az edzésidő csökkentése érdekében használjon más hálózatokat és azok súlyát, és módosítsa az utolsó réteget a probléma megoldásához. Előnye, hogy egy kis adatkészlettel edzheti az utolsó réteget.
A következő lépés ebben a PyTorch Transfer oktatóanyagban megtanuljuk, hogyan kell használni a Transfer Learning alkalmazást a PyTorch programmal.
Adatkészlet betöltése
Forrás: Alien vs. Predator Kaggle
A Transfer Learning PyTorch használatának megkezdése előtt meg kell értenie a használni kívánt adatkészletet. Ebben a Transfer Learning PyTorch példában közel 700 képből osztályoz egy idegent és egy ragadozót. Ehhez a technikához valójában nem kell nagy mennyiségű adat az edzéshez. Az adatkészlet letölthető a Kaggle: Alien vs. Predator oldalról.
Hogyan használjuk a transzfertanulást?
Itt van egy lépésenkénti folyamat arról, hogyan használhatja a Transfer Learning-et a mély tanuláshoz a PyTorch segítségével:
1. lépés: Töltse be az adatokat
Az első lépés az adataink betöltése és a képek átalakítása, hogy azok megfeleljenek a hálózati követelményeknek.
Az adatokat egy torchvision.dataset mappából tölti be. A modul iterálni fog a mappában, hogy felossza az adatokat a vonathoz és az érvényesítéshez. Az átalakítási folyamat a képeket középen levágja, vízszintes elfordítást hajt végre, normalizál, és végül a Deep Learning segítségével tenzorrá alakítja.
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áljuk a PyTorch Transfer Learning adatkészletünket. A vizualizációs folyamat megkapja a következő képcsomagot a vonat adatbetöltőitől és a címkéktől, és matplot-nal megjeleníti.
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. lépés: Definiálja a modellt
Ebben a mély tanulási folyamatban a ResNet18 from torchvision modult használja.
A torchvision.models segítségével töltheti be a resnet18-at úgy, hogy az előre kiképzett súly igaz legyen. Ezt követően lefagyasztja a rétegeket, hogy ezek a rétegek ne legyenek kiképezhetők. Az utolsó réteget egy Lineáris réteggel is módosíthatja, hogy megfeleljen az igényeinknek, vagyis 2 osztályt. A CrossEntropyLoss-ot is használja a többosztályos veszteségfüggvényhez, az optimalizálóhoz pedig az SGD-t fogja használni 0,0001 tanulási sebességgel és 0,9 impulzusral, amint az az alábbi PyTorch Transfer Learning példában látható.
## 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)
A kimeneti modell felépítése
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. lépés) Vonat és tesztmodell
A Transfer Learning PyTorch Tutorial néhány funkcióját felhasználjuk a modellünk képzéséhez és értékeléséhez.
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)
Végül ebben a Transfer Learning PyTorch-ban példában kezdjük a képzési folyamatunkat a 25-re beállított korszakok számával, és értékeljük a képzési folyamat után. Minden egyes képzési lépésnél a modell beveszi és megjósolja a kimenetet. Ezt követően az előrejelzett kimenetet átadják a kritériumnak a veszteségek kiszámításához. Ezután a veszteségek egy backprop számítást hajtanak végre a gradiens kiszámításához, végül a súlyok kiszámításához és a paraméterek optimalizálásához autograd segítségével.
A vizualizációs modellnél a képzett hálózatot egy képcsomaggal tesztelik a címkék megjóslásához. Ezután a matplotlib segítségével láthatóvá válik.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25)visualize_model(vgg_based)plt.show()
4. lépés) Eredmények
A végeredmény az, hogy 92% -os pontosságot ért el.
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
Végül a modellünk kimenetét az alábbi matplot segítségével jelenítjük meg:
Összegzés
Tehát, foglaljunk össze mindent! Az első tényező a PyTorch egy egyre növekvő mély tanulási keretrendszer kezdőknek vagy kutatási célokra. Magas számítási időt, dinamikus grafikont, GPU-támogatást kínál, és teljesen Pythonban van megírva. Könnyedén meg tudja határozni a saját hálózati modulunkat, és az edzés folyamatát könnyen elvégezheti. Nyilvánvaló, hogy a PyTorch ideális a kezdők számára, hogy megismerje a mély tanulást, és a professzionális kutatók számára nagyon hasznos a gyorsabb számítási idő, valamint a dinamikus grafikont segítő, nagyon hasznos autograd funkció.