'딥러닝 파이토치 교과서'의 코드를 따라서 짜다 보면 이해가 가긴 하는데 완벽하게 내 것이 안 되는 것 같아서 이렇게 정리해봅니다... 화이팅
import torch
import torchvision
from torch.utils.data import DataLoader, Dataset
from torchvision.transforms import transforms
from torch import optim
import torch.nn as nn
import torch.nn.functional as F
import os
import cv2
from PIL import Image
from tqdm import tqdm_notebook as tqdm
import random
from matplotlib import pyplot as plt
torch
torchvision
from torch.utils.data import DataLoader, Dataset
optim
os
cv2
from PIL import Image
matplotlib.pyplot
class ImageTransform():
def __init__(self,resize,mean,std): #resize할 크기, 평균, 표준편차
self.data_transforms = {
'train': transforms.Compose([
transforms.RandomResizedCrop(resize,scale=(0.5,1.0)),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize(mean=mean,std=std)
]),
'val': transforms.Compose([
transforms.Resize(256),
transforms.CentorCrop(resize),
transforms.ToTensor(),
transforms.Normalize(mean=mean,std=std)
])
}
def __call__(self,img,phase):
self.data_transforms[phase](img)
RandomResizedCrop
: scale 범위 내에서 랜덤하게 자르고, 입력된 resize만큼 크기 조정RandomHorizontalFlip
: p(확률) 의 비율만큼 랜덤하게 좌우 전환 (default : p=0.5)ToTensor
: PIL Image나 numpy.ndarray 를 tensor로 변환해줌Normalize
: 각 채널마다 정규화해주는 것cat_directory = r'/content/drive/MyDrive/dogs-vs-cats/Cat'
dog_directory = r'/content/drive/MyDrive/dogs-vs-cats/Dog'
cat_images_filepaths = sorted([os.path.join(cat_directory, f) for f in os.listdir(cat_directory)])
dog_images_filepaths = sorted([os.path.join(dog_directory, f) for f in os.listdir(dog_directory)])
images_filepaths = [*cat_images_filepaths, *dog_images_filepaths]
correct_images_filepaths = [i for i in images_filepaths if cv2.imread(i) is not None)
random.seed(42)
random.shuffle(correct_images_filepaths)
train_images_filepaths = correct_images_filepaths[:400]
val_images_filepaths = correct_images_filepaths[400:-10]
test_images_filepaths = correct_images_filepaths[-10:]
len(train_images_filepaths), len(val_images_filepaths),len(test_images_filepaths)
def display_image_grid(images_filepaths, predicted_labels=(), cols=5):
rows = len(images_filepaths) // cols
figure, ax = plt.subplots(nrows=rows, ncols=cols, figsize=(12,6))
for i, image_filepath in enumerate(images_filepaths):
image = cv2.imread(image_filepath)
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
true_label = os.path.normpath(image_filepath).split(os.sep)[-2]
predicted_label = predicted_label[i] if predicted_labels else true_label
color = "green" if true_label==predicted_label else "red"
ax.ravel()[i].imshow(image)
ax.ravel()[i].set_title(predicted_label,color=color)
ax.ravel()[i].set_axis_off()
plt.tight_layout()
plt.show()
display_image_grid(test_images_filepaths)
출력 결과
plt.subplots
: (figure, axes) 튜플을 반환 / figure -> 전체, axes -> 그래프 각각cv2.imread
: 이미지 파일을 입력하면 이미지 반환cv2.cvtColor
: opencv는 BGR 순서로 색상이 되어있으므로 RGB로 바꿔줘야한다.os.path.normpath
: 파일 정규화. //나 / 로 되어 있는 것들을 모두 / 로 통일.split(input)
: input 기준으로 잘라서 list 반환os.sep
: '/'ravel()
: ax에 하나하나 접근 가능 ( 1차원으로 바꿔줌 )class DogvsCatDataset(Dataset):
def __init__(self, file_list, transform=None, phase = 'train'):
self.file_list = file_list
self.transform = transform
self.phase = phase
def __len__(self):
return len(self.file_list)
def __getitem__(self, idx):
img_path = self.file_list[idx]
img = Image.open(img_path)
img_transformed = self.transform(img,self.phase)
label = img_path.split('/')[-1].split('.')[0]
if label == 'dog':
label = 1
elif label == 'cat':
label = 0
return img_transformed, label
__init__
: file_list, transform, phase 입력 받음.__len__
: file_list의 길이 반환__getitem__
: idx번째 이미지와 라벨 반환train_dataset = DogvsCatDataset(
file_list = train_images_filepaths,
transform=ImageTransform(size,mean,std),
phase = 'train'
)
val_dataset = DogvsCatDataset(
file_list = val_images_filepaths,
transform=ImageTransform(size,mean,std),
phase = 'val'
)
train_loader = DataLoader(train_dataset, batch_size=batch_size,shuffle=True, num_workers=2)
val_loader = DataLoader(val_dataset, batch_size=batch_size,shuffle=True, num_workers=2)
dataloader_dict = {'train': train_loader, 'test': val_loader}