1. 에일리언 VS 프레데터 데이터셋
https://www.kaggle.com/datasets/pmigdal/alien-vs-predator-images
- 캐글 로그인 -> 우측 상단 계정 클릭 -> Your Profile -> 중앙Account 클릭 -> API 항목에 Create New API Token 클릭 -> kaggle.json이 자동으로 다운로드 됩니다.
실습 시작
1. 필요 모듈 임포트
import os
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
2. datasets 다운로드 및 압축풀기
os.environ['KAGGLE_USERNAME'] = 'username'
os.environ['KAGGLE_KEY'] = '토큰키값'
▶ 다운로드 된 kaggle.json파일을 열어보시면 해당 값들이 적혀 있습니다. 값을 넣어서 다운로드 받으면 됩니다.
2-1. 다운로드
!kaggle datasets download -d pmigdal/alien-vs-predator-images
2-2. 압축풀기
!unzip -q alien-vs-predator-images.zip
3. gpu 변경
device = 'cuda' if torch.cuda.is_available() else 'cpu'
print(device)
# 결과값 => cuda
2. 이미지 증강 기법을 이용하여 예측하기
- 원본 이미지(데이터)를 조작하여 워본과는 크고 작은 변화를 가진 이미지를 생성
- 일반적으로 모델 성능이 좋아짐
- 오버피팅을 방지함
https://pytorch.org/vision/master/transforms.html
4. data_tranforms 생성
data_transforms = {
'train': transforms.Compose([
# 크기 재조정
transforms.Resize((224, 224)),
# 각도, 찌그러뜨림, 크기,
transforms.RandomAffine(0, shear = 10, scale = (0.8, 1.2)),
# RandomHorizontalFlip: 수평으로 뒤집기
transforms.RandomHorizontalFlip(),
# tensor로 전환
transforms.ToTensor()
]),
'validation': transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor()
])
}
- transforms.Resize() = 이미지의 크기를 조절 (224 * 224)
- transforms.RandomAffine() = 무작위로 이미지에 아핀 변환을 적용
- 0 : 회전각도를 설정
- shear = 10 : 이미지를 최대 10도까지 기울여 변형(shear)
- scale = (0.8, 1.2) : 이미지의 크기를 0.8배 ~ 1.2배 사이로 무작위로 조정
- transforms.RandomHorizontalFlip() : 이미지를 수평 방향으로 무작위로 뒤집습니다.
- 이미지의 좌우 대칭성을 활용하여 데이터의 다양성을 증가시키기 위함.
- transforms.ToTensor() : PIL 이미지 또는 NumPy ndarray를 PyTorch 텐서로 변환하며 픽셀의 강도 값을 0 ~ 1 범위로 정규화
5. target_transforms의 함수 생성
def target_transforms(target):
return torch.FloatTensor([target])
6. image 데이터셋 준비
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)
}
7. 데이터로드 준비
dataloaders = {
'train': DataLoader(
image_datasets['train'],
batch_size = 32,
shuffle = True
),
'validation': DataLoader(
image_datasets['validation'],
batch_size = 32,
shuffle = True
)
}
print(len(image_datasets['train']), len(image_datasets['validation']))
# 결과값 => 694, 200
8. 학습
imgs, labels = next(iter(dataloaders['train']))
_, 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))
ax.set_title(label.item())
ax.axis('off')
3. 전이 학습(Transform Learning)
- 하나의 작업을 위해 훈련된 모델을 유사 작업 수행 모델의 시작점으로 활용하는 딥러닝 접근법
- 신경망은 처음부터 새로 학습하는 것 보다 전이학습을 통해 업데이트하고 재학습 하는 편이 더 빠르고 간편함
- 전이 학습은 여러 응용 분야(검출, 영상, 인식, 음성인식, 검색 분야)에서 많이 사용됨
3-1. 전이 학습의 고려할 점
- 크기
- 모델 크기는 배포할 위치와 방법에 따라 달라짐
- 속도 및 정확도
- 하드웨어, 배치 크기와 같은 요소를 고려
4. 사전 학습된 RestNet50 모델 사용하기
- 파이토치에서 제공하는 사전 학습 모델들
https://pytorch.org/vision/stable/models.html
5. 이미지넷(ImageNet)
- 이미지 데이터베이스
- 1000개의 클래스로 동물과 사물 이미지를 포함함
RestNet50 모델 사용하기
9. 모델 생성하기
model = models.resnet50(weights = 'IMAGENET1K_V1').to(device)
print(model)
10. Freeze Layers 사용하기
for param in model.parameters():
# 가져온 파라미터(W, b)를 업데이트 하지 않음
param.requires_grad = False
model.fc = nn.Sequential(
nn.Linear(2048, 128),
nn.ReLU(),
nn.Linear(128, 1),
nn.Sigmoid()
).to(device)
11. 학습하기
# 학습
optimizer = optim.Adam(model.fc.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 = sum_losses + loss
y_bool = (y_pred >= 0.5).float()
acc = (y_batch == y_bool).float().sum() / len(y_batch) * 100
sum_accs = 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}%')
12. 학습 후 이미지 테스트
from PIL import Image
img1 = Image.open('./data/validation/alien/19.jpg)
img2 = Image.open('./data/validaition/predator/20.jpg')
_, 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()
13. 이미지를 텐서형으로 바꾸기
# 이미지를 텐서형으로 바꾸기
img1_input = data_transforms['validation'](img1)
img2_input = data_transforms['validation'](img2)
print(img1_input.shape)
print(img2_input.shape)
# 결과값 =>
# torch.Size([3, 224, 224])
# torch.Size([3, 224, 224])
14. 2개를 batch로 묶어서 넣기
test_batch = torch.stack([img1_input, img2_input])
test_batch = test_batch.to(device)
test_batch.shape
# 결과값 => torch.Size([2, 3, 224, 224])
※ stack() : 차원을 쌓아줌
15. 예측하기
y_pred = model(test_batch)
_, 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}% Predator')
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}% Predator')
axes[1].imshow(img2)
axes[1].axis('off')
plt.show()
'Study > 머신러닝과 딥러닝' 카테고리의 다른 글
[머신러닝과 딥러닝] 22. 포켓몬 분류 (0) | 2024.01.12 |
---|---|
[머신러닝과 딥러닝] 20. 간단한 CNN 모델 만들기 + MNIST 분류하기 (1) | 2024.01.10 |
[머신러닝과 딥러닝] 19. CNN 기초 (0) | 2024.01.10 |
[머신러닝과 딥러닝] 18. 비선형 활성화 함수 (0) | 2024.01.10 |
[머신러닝과 딥러닝] 17. 딥러닝(AND, OR, XOR 게이트) (1) | 2024.01.10 |