PyTorTutorial de transferencia de aprendizaje con ejemplos
ยฟQuรฉ es el aprendizaje por transferencia?
Transferir aprendizaje es una tรฉcnica que utiliza un modelo entrenado para resolver otra tarea relacionada. Es un mรฉtodo de investigaciรณn de aprendizaje automรกtico que almacena el conocimiento adquirido al resolver un problema particular y utiliza el mismo conocimiento para resolver otro problema diferente pero relacionado. Esto mejora la eficiencia al reutilizar la informaciรณn recopilada de la tarea aprendida previamente.
Es popular utilizar otros pesos de modelo de red para reducir el tiempo de entrenamiento porque se necesitan muchos datos para entrenar un modelo de red. Para reducir el tiempo de entrenamiento, utiliza otras redes y su peso y modifica la รบltima capa para resolver nuestro problema. La ventaja es que puedes utilizar un pequeรฑo conjunto de datos para entrenar la รบltima capa.
A continuaciรณn, en este PyTorEn este tutorial sobre aprendizaje por transferencia, aprenderemos cรณmo usar el aprendizaje por transferencia con PyTorch.
Cargando conjunto de datos
Fuente: Alien vs Predator Kaggle
Antes de comenzar a usar Transfer Learning PyTorch, necesitas comprender el conjunto de datos que vas a utilizar. En este Transfer Learning PyTorPor ejemplo, clasificarรกs un Alien y un Predator a partir de casi 700 imรกgenes. Para esta tรฉcnica, realmente no necesitas una gran cantidad de datos para entrenar. Puedes descargar el conjunto de datos desde Kaggle: Alien contra depredador.
ยฟCรณmo utilizar el aprendizaje por transferencia?
Aquรญ tienes un proceso paso a paso sobre cรณmo usar el aprendizaje por transferencia para el aprendizaje profundo con PyTorcanal:
Paso 1) Cargar los datos
El primer paso es cargar nuestros datos y realizar algunas transformaciones en imรกgenes para que coincidan con los requisitos de la red.
Cargarรก los datos desde una carpeta con torchvision.dataset. El mรณdulo iterarรก en la carpeta para dividir los datos para el entrenamiento y la validaciรณn. El proceso de transformaciรณn recortarรก las imรกgenes desde el centro, realizarรก un giro horizontal, las normalizarรก y finalmente las convertirรก a tensor utilizando Deep Learning.
from __future__ import print_function, division
import os
import time
import torch
import torchvision
from torchvision import datasets, models, transforms
import torch.optim as optim
import numpy as np
import matplotlib.pyplot as plt
data_dir = "alien_pred"
input_shape = 224
mean = [0.5, 0.5, 0.5]
std = [0.5, 0.5, 0.5]
#data transformation
data_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'].classes
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
Visualicemos nuestro conjunto de datos para PyTorAprendizaje por transferencia. El proceso de visualizaciรณn obtendrรก el siguiente lote de imรกgenes de los cargadores de datos de entrenamiento y las etiquetas y las mostrarรก con matplotlib.
images, labels = next(iter(dataloaders['train'])) rows = 4 columns = 4 fig=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 + mean plt.imshow(img) plt.show()

Paso 2) Definir modelo
En esta Aprendizaje profundo En el proceso, utilizarรก ResNet18 del mรณdulo torchvision.
Utilizarรกs torchvision.models para cargar resnet18 con el peso preentrenado establecido en True. Despuรฉs, congelarรกs las capas para que no sean entrenables. Tambiรฉn modificarรกs la รบltima capa con una capa lineal para adaptarla a nuestras necesidades, que son 2 clases. Ademรกs, usarรกs CrossEntropyLoss como funciรณn de pรฉrdida multiclase y, para el optimizador, usarรกs SGD con una tasa de aprendizaje de 0.0001 y un momento de 0.9, como se muestra en el siguiente cรณdigo Py.TorEjemplo de aprendizaje por transferencia.
## Load the model based on VGG19 vgg_based = torchvision.models.vgg19(pretrained=True) ## freeze the layers for param in vgg_based.parameters(): param.requires_grad = False # Modify the last layer number_features = vgg_based.classifier[6].in_features features = list(vgg_based.classifier.children())[:-1] # Remove last layer features.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)
La estructura del modelo de salida.
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) ) )
Paso 3) Entrenar y probar el modelo
Usaremos algunas de las funciones de Transfer Learning PyTorTutorial para ayudarnos a entrenar y evaluar nuestro modelo.
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 = data
inputs = 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() - since
print('Training complete in {:.0f}m {:.0f}s'.format(
time_elapsed // 60, time_elapsed % 60))
return model
def visualize_model(model, num_images=6):
was_training = model.training
model.eval()
images_so_far = 0
fig = 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 += 1
ax = 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 + mean
ax.imshow(img)
if images_so_far == num_images:
model.train(mode=was_training)
return
model.train(mode=was_training)
Finalmente, en este aprendizaje por transferencia en PythonTorPor ejemplo, comencemos el entrenamiento con 25 รฉpocas y evaluemos los resultados. En cada paso, el modelo toma la entrada y predice la salida. A continuaciรณn, la salida predicha se pasa al criterio para calcular las pรฉrdidas. Luego, las pรฉrdidas realizan un cรกlculo de retropropagaciรณn para calcular el gradiente y, finalmente, se calculan los pesos y se optimizan los parรกmetros con autograd.
En el modelo de visualizaciรณn, la red entrenada se probarรก con un lote de imรกgenes para predecir las etiquetas. Luego se visualizarรก con la ayuda de matplotlib.
vgg_based = train_model(vgg_based, criterion, optimizer_ft, num_epochs=25) visualize_model(vgg_based) plt.show()
Paso 4) Resultados
El resultado final es que logrรณ una precisiรณn del 92%.
Epoch 23/24 ---------- train Loss: 0.0044 train Loss: 0.0078 train Loss: 0.0141 train Loss: 0.0221 train Loss: 0.0306 train Loss: 0.0336 train Loss: 0.0442 train Loss: 0.0482 train Loss: 0.0557 train Loss: 0.0643 train Loss: 0.0763 train Loss: 0.0779 train Loss: 0.0843 train Loss: 0.0910 train Loss: 0.0990 train Loss: 0.1063 train Loss: 0.1133 train Loss: 0.1220 train Loss: 0.1344 train Loss: 0.1382 train Loss: 0.1429 train Loss: 0.1500 Epoch 24/24 ---------- train Loss: 0.0076 train Loss: 0.0115 train Loss: 0.0185 train Loss: 0.0277 train Loss: 0.0345 train Loss: 0.0420 train Loss: 0.0450 train Loss: 0.0490 train Loss: 0.0644 train Loss: 0.0755 train Loss: 0.0813 train Loss: 0.0868 train Loss: 0.0916 train Loss: 0.0980 train Loss: 0.1008 train Loss: 0.1101 train Loss: 0.1176 train Loss: 0.1282 train Loss: 0.1323 train Loss: 0.1397 train Loss: 0.1436 train Loss: 0.1467 Training complete in 2m 47s
Finalice, el resultado de nuestro modelo se visualizarรก con el siguiente diagrama matplo:

Resumen
ยกResumamos todo! El primer factor es PyTorch es un marco de aprendizaje profundo en crecimiento para principiantes o para fines de investigaciรณn. Ofrece un alto tiempo de computaciรณn, grรกficos dinรกmicos, soporte para GPU y estรก totalmente escrito en PythonPuedes definir tu propio mรณdulo de red con facilidad y realizar el proceso de entrenamiento con una iteraciรณn sencilla. Estรก claro que PyTorch es ideal para principiantes que quieran aprender sobre aprendizaje profundo, y para investigadores profesionales es muy รบtil gracias a su tiempo de cรกlculo mรกs rรกpido y a la prรกctica funciรณn autograd que ayuda con los grรกficos dinรกmicos.

