1. Alien vs predator 데이터셋
- Alien vs predator 데이터셋은 컴퓨터 비전과 이미지 분류 모델을 학습시키기 위해 제공되는 소규모 데이터셋입니다.
- 영화 속 캐릭터인 Alien(에일리언)과 Predator(프레데터)의 이미지로 구성되어 있습니다.
- 이데이터를 통해 두 클래스를 분류하는 이미지 분류 모델을 학습시킬 수 있습니다.
!kaggle datasets download pmigdal/alien-vs-predator-images
!unzip -q alien-vs-predator-images.zip
2. AlexNet을 활용한 Alien vs Predator 분류
import torch
import torch.nn as nn
import torch.optim as optim
import matplotlib.pyplot as plt
from torchvision import datasets, models, transforms
from torch.utils.data import DataLoader
모델 전처리
device = 'cuda' if torch.cuda.is_available() else 'cpu'
data_transforms = {
'train' : transforms.Compose([
transforms.Resize((224, 224)),
transforms.RandomAffine(0, shear=10, scale=(0.8, 1.2)),
transforms.RandomHorizontalFlip(),
transforms.ToTensor()
]),
'validation' : transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor()
])
}
def target_transforms(target) :
return torch.FloatTensor([target])
image_datasets = {
'train' : datasets.ImageFolder('data/train', data_transforms['train'], target_transform=target_transforms),
'validation' : datasets.ImageFolder('data/validation', data_transforms['validation'], target_transform=target_transforms)
}
dataloaders = {
'train' : DataLoader(
image_datasets['train'],
batch_size=32,
shuffle=True
),
'validation' : DataLoader(
image_datasets['validation'],
batch_size=32,
shuffle=False
)
}
imgs, labels = next(iter(dataloaders['train']))
fig, axes = plt.subplots(4, 8, figsize=(16, 8))
for ax, img, label in zip(axes.flatten(), imgs, labels):
ax.imshow(img.permute(1, 2, 0)) # (3, 224, 224) -> (224, 224, 3)
ax.set_title(label.item())
ax.axis('off')
3. 전이 학습
- 전이 학습(Transfer Learning)은 이미 학습된 모델(주로 대규모 데이터셋에서 사전 학습된 딥러닝 모델)을 새로운 문제에 적용하여 학습 시간을 단축하고 성능을 향상시키는 방법입니다.
- 기존 모델이 학습한 Feature를 활용해, 새로운 데이터셋에서 모델의 일부(주로 마지막 레이어)만 다시 학습하거나 추가 학습(Fine-Tuning)을 진행합니다.
- 특히 데이터가 적거나 학습 리소스가 제한된 상황에서 효과적이며, 이미지 분류(ex: ResNet, VGG), 자연어처리(ex: BERT, GPT) 등 다양한 분야에서 널리 사용됩니다.

※ ImageNet
- ImagNet은 대규모 이미지 데이터셋으로, 컴퓨터 비전 연구와 딥러닝 모델 학습에 널리 사용됩니다.
- 2009년 스탠포드 대학의 페이페이 리 교수팀이 구축했으며, 약 1,400만 장의 이미지와 22,000개 이상의 카테고리로 구성되어 있습니다.
- 이 중, 가장 널리 사용되는 ILSVRC 버전은 약 1,000개의 클래스와 120만 장의 이미지를 포함합니다.
- ImageNet은 모델이 객체를 분류하고 특징을 학습하는 데에 필요한 풍부한 데이터와 레이블을 제공하며, ResNet, VGG, Inception 등 여러 혁신적인 모델이 ImageNet 대회를 통해 개발되었습니다.
# 제공하는 alexnet의 가중치를 ImageNet의 가중치로 사용
model = models.alexnet(weights='IMAGENET1K_V1').to(device)
※ Model Freezing
- Model Freezing은 Transfer Learning에서 사전 학습된 모델의 일부 또는 전체 계층의 가중치를 고정하여 학습되지 않도록 설정하는 기법입니다.
- 주로 사전 학습된 모델의 초기 계층(Convolutional Layers 등)은 일반적인 특징(ex: 가장자리, 패턴)을 학습했으므로 고정하고, 새로운 데이터셋에 특화된 특징을 학습하기 위해 최상위 계층(분류 헤드 등)만 학습합니다.
- 이 방법은 학습할 가중치의 수를 줄여 계산 비용을 절감하고, Overfitting을 방지하며, 데이터가 부족한 상황에서 특히 유용합니다.
- 필요에 따라, 초기 학습이 끝난 후 일부 계층을 고정 해제(Fine-Tuning)하여 모델을 더 정교하게 조정할 수도 있습니다.
for param in model.parameters() :
# 파라미터를 갱신하지 않겠다. 수식 누적도 X
param.requires_grad = False
model.classifier = nn.Sequential(
nn.Linear(256 * 6 * 6, 128),
nn.ReLU(),
nn.Linear(128, 1),
nn.Sigmoid()
).to(device)
print(model)
모델 학습
# Output Layer(FC Layer 등)를 전이 학습 시키기 위해 classifier를 명시함
optimizer = optim.Adam(model.classifier.parameters(), lr=0.001)
epochs = 10
for epoch in range(epochs) :
for phase in ['train', 'validation'] :
if phase == 'train' :
model.train()
else :
model.eval()
sum_losses = 0
sum_accs = 0
for x_batch, y_batch in dataloaders[phase] :
x_batch = x_batch.to(device)
y_batch = y_batch.to(device)
y_pred = model(x_batch)
loss = nn.BCELoss()(y_pred, y_batch)
if phase == 'train' :
optimizer.zero_grad()
loss.backward()
optimizer.step()
sum_losses += loss
y_bool = (y_pred >= 0.5).float()
acc = (y_batch == y_bool).float().sum() / len(y_batch) * 100
sum_accs += acc
avg_loss = sum_losses / len(dataloaders[phase])
avg_acc = sum_accs / len(dataloaders[phase])
print(f'{phase:10s}: Epoch {epoch+1:4d}/{epochs} Loss: {avg_loss:.4f} Accuracy: {avg_acc:.2f}%')
Validation 폴더내에 있는 Alien, Predator 이미지를 학습된 모델에 넣어 예측해보기
from PIL import Image
img1 = Image.open('/content/data/validation/alien/55.jpg')
img2 = Image.open('/content/data/validation/predator/55.jpg')
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].imshow(img1)
axes[0].axis('off')
axes[1].imshow(img2)
axes[1].axis('off')
plt.show()
img1_input = data_transforms['validation'](img1)
img2_input = data_transforms['validation'](img2)
test_batch = torch.stack([img1_input, img2_input])
test_batch = test_batch.to(device)
test_batch.shape
y_pred = model(test_batch)
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].set_title(f'{(1-y_pred[0, 0])*100:.2f}% Alien, {(y_pred[0, 0])*100:.2f}% Prediator')
axes[0].imshow(img1)
axes[0].axis('off')
axes[1].set_title(f'{(1-y_pred[1, 0])*100:.2f}% Alien, {(y_pred[1, 0])*100:.2f}% Prediator')
axes[1].imshow(img2)
axes[1].axis('off')
외부 이미지 다운로드 후 예측하기
img1 = Image.open('/content/Alien_test.jpg')
img2 = Image.open('/content/predator_test.jpg')
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].imshow(img1)
axes[0].axis('off')
axes[1].imshow(img2)
axes[1].axis('off')
plt.show()
img1_input = data_transforms['validation'](img1)
img2_input = data_transforms['validation'](img2)
test_batch = torch.stack([img1_input, img2_input])
test_batch = test_batch.to(device)
test_batch.shape
y_pred = model(test_batch)
fig, axes = plt.subplots(1, 2, figsize=(12, 6))
axes[0].set_title(f'{(1-y_pred[0, 0])*100:.2f}% Alien, {(y_pred[0, 0])*100:.2f}% Prediator')
axes[0].imshow(img1)
axes[0].axis('off')
axes[1].set_title(f'{(1-y_pred[1, 0])*100:.2f}% Alien, {(y_pred[1, 0])*100:.2f}% Prediator')
axes[1].imshow(img2)
axes[1].axis('off')