1. 포켓몬 분류
Pokemon Generation One
Gotta train 'em all!
www.kaggle.com
Complete Pokemon Image Dataset
2,500+ clean labeled images, all official art, for Generations 1 through 8.
www.kaggle.com
import os
os.environ['KAGGLE_USERNAME'] = 'sakongmyoungheun'
os.environ['KAGGLE_KEY'] = 'eebb8c6baa890a589e08e51889cc3832'
!kaggle datasets download -d thedagger/pokemon-generation-one
!unzip -q pokemon-generation-one.zip
!kaggle datasets download -d hlrhegemony/pokemon-image-dataset
!unzip -q pokemon-image-dataset.zip
!mv dataset train
!rm -rf train/dataset # 데이터가 중복되어 있기 때문에 삭제하는 과정, -rf 명령어는 없어도 에러나지 말라는 뜻
!mv images validation
# train : 149, validation : 898
# validation 에서 train 에 있는 디렉토리를 확인하여 없는 디렉토리를 모두 제거
import shutil
# train과 val에 동일한 폴더(label)이 없으면 제거하는 과정
for val_label in validation_labels:
if val_label not in train_labels:
shutil.rmtree(os.path.join('validation', val_label))
# train과 val에 없는 폴더가 있으면 생성하는 과정
for train_label in train_labels:
if train_label not in val_label:
print(train_label)
os.makedirs(os.path.join('validation', train_label),exist_ok=True)
# os.makedirs 함수는 하위 디렉토리도 생성
# exist_ok=True 옵션은 이미 디렉토리가 존재해도 에러를 발생시키지 않고 계속 진행
val_label = os.listdir('validation')
- 케글에 있는 포켓몬 데이터를 가지고 학습을 하여 분류 예측을 하는 과정을 진행해 보겠습니다
- 사이트에 있는 데이터를 가지고 와서 압축을 풀어줍니다
- 두 데이터셋의 구성이 다르므로 동일한 구성으로 만들어줍니다
# 필요한 모듈
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
# GPU 사용 확인
device = 'cuda' if torch.cuda.is_available() else 'cpu'
# 이미지 증강기법 사용
# data_transforms 증강
# train / validation 텐서 및 사이즈 변경
data_transforms = {
'train': transforms.Compose([
# 크기 재조정
transforms.Resize((224, 224)),
# 각도, 찌그러뜨림, 크기,
transforms.RandomAffine(0, shear = 10, scale = (0.8, 1.2)),
transforms.RandomHorizontalFlip(),
# tensor로 전환
transforms.ToTensor()
]),
'validation': transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor()
])
}
- 이제 학습할 train, validation 데이터가 준비되었다면 필요한 모듈(?)을 import 해주고 동일한 크기, 스케일로 transforms 해줄 딕셔너리를 만들어 줍니다
# 데이터셋 객체 생성
# image_datasets
# train / validation
image_datasets = {
'train': datasets.ImageFolder('train', data_transforms['train']),
'validation': datasets.ImageFolder('validation', data_transforms['validation'])
}
# 데이터로더 생성
# dataloaders
# batch_size = 32
# suffle = True
dataloaders = {
'train':DataLoader(
image_datasets['train'],
batch_size=32,
shuffle=True
),
'validation':DataLoader(
image_datasets['validation'],
batch_size=32,
shuffle=True
)
}
- 이후 만들어진 데이터셋을 가지고 transforms 딕셔너리에 적용하여 정제된 train, validation 데이터셋 객체를 만들어 줍니다
- 그리고 학습할 때 적용할 Dataloader에 넣고 dataloader 딕셔너리를 만들어줍니다
- 이전에 했던 과정들과 동일하게 32개씩 학습을 시키기 위해 batch_size를 32로 주었습니다
# 사전 학습된 EfficientNetB4 모델
from torchvision.models import efficientnet_b4, EfficientNet_B4_Weights
from torchvision.models._api import WeightsEnum
from torch.hub import load_state_dict_from_url
def get_state_dict(self, *args, **kwargs):
kwargs.pop("check_hash")
return load_state_dict_from_url(self.url, *args, **kwargs)
WeightsEnum.get_state_dict = get_state_dict
efficientnet_b4(weights=EfficientNet_B4_Weights.IMAGENET1K_V1)
efficientnet_b4(weights="DEFAULT")
model = efficientnet_b4(weights=EfficientNet_B4_Weights.IMAGENET1K_V1)
model = efficientnet_b4(weights="DEFAULT").to(device)
# cl Layer 수정
# print(model)
model.classifier = nn.Sequential(
nn.Linear(1792, 512),
nn.ReLU(),
nn.Linear(512, 149),
).to(device)
- 이번에 사용해볼 모델은 EfficientNetB4 입니다
- 구글에서 2019년에 개발한 이 모델은 이미지 인식 및 객체 감지, 세그멘테이션 등의 작업에서 좋은 성능을 보입니다
- 그리고 모델을 불러와서 출력 Layer를 수정해서 모델을 완성해 줍니다
# 학습
# optimizer: Adam
# epochs : 10
optimizer = optim.Adam(model.classifier.parameters(), lr=0.001)
epochs = 10
for epoch in range(epochs + 1):
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, y_batch = x_batch.to(device), y_batch.to(device)
y_pred = model(x_batch)
loss = nn.CrossEntropyLoss()(y_pred, y_batch)
if phase == 'train':
optimizer.zero_grad()
loss.backward()
optimizer.step()
sum_losses = sum_losses + loss
y_prob = nn.Softmax(1)(y_pred)
y_pred_index = torch.argmax(y_prob, axis=1)
acc = (y_batch == y_pred_index).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])
- 이제 데이터 구성과 모델 수정이 끝났으면 학습을 진행합니다
- 이번에는 train 데이터셋과 validation 데이터셋을 동시에 학습해보겠습니다
- 먼저 데이터셋 종류에 따라 모델을 그에 맞게 설정해주고 반복문을 돌립니다
- 이때 validaion 데이터는 학습된 후에 결과를 보는 데이터셋이기 때문에 train 데이터셋인 경우에만 optimizer 파라미터를 바꿔주는 코드를 추가해 줍니다
'수업 복습 > 머신러닝과 딥러닝' 카테고리의 다른 글
전이 학습 (0) | 2024.03.26 |
---|---|
간단한 CNN 모델 만들기 실습 (2) | 2024.01.23 |
CNN 기초 (0) | 2024.01.23 |
비선형 활성화 함수 (0) | 2024.01.17 |
딥러닝 (0) | 2024.01.16 |