1. 에일리언 VS 프레데터 데이터셋
- 작업 데이터 가져오기
* 캐글: https://www.kaggle.com/datasets/pmigdal/alien-vs-predator-images
더보기
- 직접 다운로드 하기
- 캐글 api 가져오기
: 케글 로그인 -> 계정 클릭 -> Your Profile -> Account -> API항목에 Create New Token -> kaggle.json 다운로드
- Kaggle API를 위한 환경변수 설정
import os os.environ['KAGGLE_USERNAME'] = 'username'
os.environ['KAGGLE_KEY'] = 'key'
|
- 에일리언 데이터셋을 다운로드하고 압축을 해제
!kaggle datasets download -d pmigdal/alien-vs-predator-images
!unzip -q alien-vs-predator-images.zip
|
Dataset URL: https://www.kaggle.com/datasets/pmigdal/alien-vs-predator-images License(s): ODbL-1.0 Downloading alien-vs-predator-images.zip to /content 35% 5.00M/14.1M [00:00<00:00, 28.3MB/s] 100% 14.1M/14.1M [00:00<00:00, 66.3MB/s] |
- import / GPU
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 = torch.device ('cuda' if torch.cuda.is_available() else 'cpu')
print(device)
|
cpu [런타임 유형 변경] [런타임 다시 실행] cuda |
2. 이미지 증강 기법( image Augmentation)
* 원본 이미지 (데이터)를 조작하여 원본과는 크고 작은 변화를 가진 이미지를 생성
-일반적으로 모델 성능이 좋아짐
- over fitting 방지
- 이미지 데이터를 전처리하고 이미지 로드
data_transforms ={
'train': transforms.Compose([
transforms.Resize((224,224)), # 이미지를 224x224 크기로 조정
transforms.RandomAffine(0, shear=10 , scale =(0.8,12)),
# 랜덤으로 각도, 찌그러뜨림, 크기 변환
transforms.RandomHorizontalFlip(), # 랜덤으로 좌우반전
transforms.ToTensor(),# 이미지를 PyTorch 텐서로 변환
]),
'validation':transforms.Compose([
transforms.Resize((224,224)),
transforms.ToTensor()
])
}
# 목표 값 변환: target ---> PyTorch의 FloatTensor로 변환
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
)
}
print(len(image_datasets['train']), len(image_datasets['validation']))
|
데이터 전처리data_transforms 딕셔너리는 학습 데이터(train)와 검증 데이터(validation)에 대해 서로 다른 전처리 과정을 정의합니다.transforms.Compose는 여러 전처리 과정을 순차적으로 적용할 수 있도록 합니다.
목표 값도 적절한 형식으로 변환할 수 있습니다. 데이터셋 로드
|
694 200 |
- DataLoader를 사용하여 학습 데이터의 배치를 가져와서, 일부 이미지를 시각화
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)
ax.set_title(label.item())
ax.axis('off')
|
|
|
3. 전이 학습 (Transfer Learning)
* 하나의 작업을 위해 훈련된 모델을 유사 작업 수행 모델의 시작점으로 활용하는 딥러닝 접근법
* 신경망은 처음부터 새로 학습하는 것보다 전이학습을 통해 업데이트하고 재학습하는 편이 더 빠르고 간편함
* 전이 학습은 여러 응용 분야 중에서도 특히 검출, 영상 인식, 음성 인식, 검색분야에 많이 사용
1. 전이학습의 고려할 점
- 크기 : 모델 크기의 중요성은 모델을 배포할 위치와 방법에 따라 달라짐
- 정확도: 재훈련 전의 모델 성능은 어느 정도인지 확인이 필요
- 예측 속도: 하드웨어 및 배치 크기와 같은 다른 딥러닝 요소는 물론 선택된 모델의 아키텍쳐와 모델 크기에 따라서도 달라짐
2. 사전 학습된 ResNet50 모델
- https://pytorch.org/vision/stable/models.html
4. 이미지넷(ImageNet)
* 이미지 데이터베이스
* 1000개의 동물과 사물 이미지를 포함
- ResNet-50 모델을 불러와서 사용하기
# model = models.resnet50(pretrained=True).to (device)
model = models. resnet50(weights='IMAGENET1K_V1').to(device)
print(model)
|
출력된 모델 구조:ResNet-50 모델은 다양한 계층(layer)으로 구성되어 있으며, 기본적으로는 합성곱(convolutional), 풀링(pooling), 완전 연결(fully connected) 레이어 등으로 구성됩니다.
|
5. Freeze Layers
* 특징을 뽑아내는 CNN의 앞쪽 컨볼루션 레이어들은 학습을 하지 않도록 설정
* 출력 부분의 레이어(fc)를 다시 설정하여 분류에 맞게 설정
- ResNet-50 모델의 파라미터를 동결하고, 모델의 마지막 fully connected 레이어를 변경
for param in model. parameters():
param.requires_grad = False # 가져온 파라미터(W,b)를 업데이트하지 않음
model.fc= nn.Sequential(
nn.Linear(2048,128),
nn.ReLU(),
nn.Linear(128,1),
nn.Sigmoid()
). to (device)
print(model)
|
- ResNet-50 모델의 마지막 fully connected 레이어만을 학습하면서 이진 분류 작업을 수행
# 학습: fc 부분만 학습하므로 속도가 빠름
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}%')
|
요약이 코드는 ResNet-50 모델의 마지막 fully connected 레이어만을 학습하면서 이진 분류를 수행하는 과정을 보여줍니다. 학습과 검증 과정에서 손실과 정확도를 계산하고, Adam 옵티마이저를 사용하여 모델 파라미터를 업데이트합니다. 이를 통해 모델을 효율적으로 학습시키고 학습 진행 상황을 모니터링할 수 있습니다. |
- 테스트용 이미지 두 개를 불러와서 시각화
# 테스트
from PIL import Image
img1 =Image.open('data/validation/alien/21.jpg')
img2 =Image.open('data/validation/predator/30.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()
|
- 이미지 데이터에 대해 정의된 데이터 변환을 적용
변환된 이미지의 모양(shape)을 출력
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])
|
torch.Size([3, 224, 224]) torch.Size([3, 224, 224]) torch.Size([3, 224, 224]) |
- test_batch는 img1_input과 img2_input을 스택하여 하나의 텐서로 결합한 결과
test_batch = torch.stack([img1_input,img2_input])
test_batch = test_batch.to(device)
test_batch.shape
|
torch.Size([2, 3, 224, 224]) torch.stack([img1_input, img2_input]): img1_input과 img2_input을 차원 0에 대해 스택하여 하나의 텐서로 결합합니다. 따라서 결과적으로 형상이 [2, 3, 224, 224]인 텐서가 생성됩니다.
|
- test_batch를 입력으로 받아 모델이 예측한 출력값인 y_pred
y_pred = model(test_batch)
y_pred
|
tensor([[0.1966], [0.9433]], device='cuda:0', grad_fn=<SigmoidBackward0>)
|
- 두 개의 이미지(img1과 img2)에 대해 모델이 예측한 결과를 시각화
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}% 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()
|
|
'AI > 딥러닝' 카테고리의 다른 글
10. 포켓몬 분류 (0) | 2024.06.21 |
---|---|
08. 간단한 CNN 모델 만들기 (0) | 2024.06.20 |
07. CNN 기초 (0) | 2024.06.20 |
06. 비선형 활성화 함수 (0) | 2024.06.20 |
05. 딥러닝 (0) | 2024.06.20 |