아래의 자료를 참고하였습니다
github.com/deeplearningzerotoall/PyTorch/blob/master/lab-10_4_2_ImageFolder_2.ipynb
실은 이번 챕터는 customize한 데이터를 가지고 이미지 분류를 하는 거였다.
있는 데이터 셋으로 하는 건 별로 재미가 없을 것 같아서 새로 만들어보았다.
혼자 여기저기 잘 놀러다니는 편이라, 이번주에는 어린이 대공원을 갔다왔다.
뮤지컬 극장 바로 옆이 어린이 대공원일줄 누가 알았겠는가.
하여간에, 그래서 어린이 대공원을 돌면서
호랑이랑 사자 사진을 좀 찍어볼까 싶었는데 에그머니!
늦게 가서 맹수 없는 맹수마을만 보고왔다. 동물들의 퇴근 시간이었지 뭔가.
그래서 하릴없이 꽃들 사진만 찍었다.
그런데 찍고 있자니 내가 굉장히 감수성이 짙은 할머니가 된 것만 같았다.
하여간에 그래서 이번 데이터 셋은 위 꽃들을 구분하는 거였다.
아직 내 딥러닝 친구는 똑똑하지 않고, 나도 그렇기 때문에 가능하면 비슷한 구도에서 찍었다.
그리고 또 웃긴 생각이 났는데, 바로 내 사진을 테스트 셋에 넣는거다.
킄킄...
## customizing data
import torchvision
from torchvision import transforms
from torch.utils.data import DataLoader
from matplotlib.pyplot import imshow
%matplotlib inline
사진이 워낙 고화질이다 보니, 그 사이즈를 줄여주는 과정
trans=transforms.Compose([transforms.Resize((64,128))])
train_data=torchvision.datasets.ImageFolder(root='./origin_data',transform=trans)
이 과정을 거치면 내 사진들이...
이런 똥퀄로 바뀐다! 내가 쭈그려 앉아서 열심히 찍었던 사진들이...
텐서로 바꾼 이미지를 띄우는 방법은 접은글로 넣겠다
img=train_data[0][0].squeeze()
print(train_data[0][1])
imshow(transforms.ToPILImage()(img), interpolation="bicubic")
###
img=train_data[15][0].squeeze()
print(train_data[15][1])
imshow(transforms.ToPILImage()(img), interpolation="bicubic")
그 다음엔 바꿔준 이미지들을 다시 저장해준다.
for num,value in enumerate(train_data):
data,label=value
print(num,data,label)
if label==0:
data.save('./train_data/purple/%d_%d.jpeg'%(num,label))
else:
data.save('./train_data/white/%d_%d.jpeg'%(num,label))
## learning
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import DataLoader
import torchvision
import torchvision.transforms as transforms
데이터 셋이 너무 작아서 배치 사이즈도 줄였다. 4정도로...
trans=transforms.Compose([transforms.ToTensor()])
train_data=torchvision.datasets.ImageFolder(root='./train_data',transform=trans)
data_loader = DataLoader(dataset = train_data, batch_size = 4, shuffle = True, num_workers=2)
CNN 모델 생성
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(3,6,5),
nn.ReLU(),
nn.MaxPool2d(2),
)
self.layer2 = nn.Sequential(
nn.Conv2d(6,16,5),
nn.ReLU(),
nn.MaxPool2d(2),
)
self.layer3 = nn.Sequential(
nn.Linear(16*13*29, 120),
nn.ReLU(),
nn.Linear(120,2)
)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = out.view(out.shape[0], -1)
out = self.layer3(out)
return out
기타 최적화, 비용 함수 생성
net=CNN()
optimizer=optim.Adam(net.parameters(),lr=0.00005)
loss_func=nn.CrossEntropyLoss()
아무 생각 말고 돌리기!
total_batch = len(data_loader)
epochs = 15
for epoch in range(epochs):
avg_cost = 0.0
for num, data in enumerate(data_loader):
imgs, labels = data
optimizer.zero_grad()
out = net(imgs)
loss = loss_func(out, labels)
loss.backward()
optimizer.step()
avg_cost += loss / total_batch
print('[Epoch:{}] cost = {}'.format(epoch+1, avg_cost))
print('Learning Finished!')
보통 epoch를 줄인다고 해서 비용함수가 막 줄진 않던데 이 경우는 잘 줄어서 기분이가 좋았다!
다음으로
테스트 셋도 이미지를 줄여준다.
그렇지만 실은 테스트 셋으로 트레인 셋을 이용했다.
사진을 찍을 사진이 모자랐다...
trans=torchvision.transforms.Compose([
transforms.Resize((64,128)),
transforms.ToTensor()
])
test_data = torchvision.datasets.ImageFolder(root='./train_data', transform=trans)
test_set = DataLoader(dataset = test_data, batch_size = len(test_data))
그 다음엔 예측해서 정확도를 비교한다
with torch.no_grad():
for num, data in enumerate(test_set):
imgs, label = data
prediction = net(imgs)
correct_prediction = torch.argmax(prediction, 1) == label
accuracy = correct_prediction.float().mean()
print('Accuracy:', accuracy.item())
정확도는 1이 나왔는데, 생각해보면 테스트 셋으로 트레인 셋을 썼으니 당연한 결과다
그래서 test data로 내 사진도 넣어보고 이 허접한 프로젝트는 잠시 마무리하려고 한다.
with torch.no_grad():
for num, data in enumerate(test_set):
imgs, label = data
prediction = net(imgs)
correct_prediction = torch.argmax(prediction, 1) == label
print(prediction)
print(torch.argmax(prediction, 1))
나는 보라색 꽃이라네!
근데 생각해보면 당연한 결과인게
이 사진에서 나는 분홍 꽃을 머리에 꽂고 있다.
아니면 첫번째 폴더에 있어서 그런가?
실은 ImageFolder를 잘 모르겠다.
왜냐하면 test_data도 이미지 폴더를 만들어줘야 하다보니, 그렇게 했는데.. 폴더가 나뉜 것도 딥러닝에 영향이 있는걸까?
그래서 한 폴더에 라벨과 내 사진을 섞었더니
이렇게 나왔다.
사진 자체는
폴더 속에선 혹시 몰라 파일명도 바꿨다... 물론 영향이 없을 것 같긴 했지만 만반의 준비는 해야지
사진을 더 찍게 된다면 테스트 셋을 바꿔서 리업로드 해볼까 한다..
그런데 문제가 생겼다
저렇게 압축된 사진 대신, train data에 있었던 원본을 넣었더니 예측을 제대로 못하는 사태가 일어났다.
그래서 점심시간에 급하게 나가서 꽃 사진을 찍었다..ㅋㅋ
대신 이번엔 좀 다양하게 찍어봤다.
기존에 찍었던 하얀색 철쭉도 다시 찍었고, 아예 데이터 셋에 없는 종류의 꽃도 찍어봤고, 마지막으로 빨간색 철쭉도 찍어봤다.
그런데 너무 처참하게도, 모두 class0(보라색 꽃, 꽃 이름을 모른다)로 예측하는 것이다
그래서 기분이 상한 나머지 좀 방황하다가
다시 돌아와 앉아서 합성곱 층의 채널 수를 달리 해봤다.
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.layer1 = nn.Sequential(
nn.Conv2d(3,16,5),
nn.ReLU(),
nn.MaxPool2d(2),
)
self.layer2 = nn.Sequential(
nn.Conv2d(16,64,5),
nn.ReLU(),
nn.MaxPool2d(2),
)
self.layer3 = nn.Sequential(
nn.Linear(64*13*29, 120),
nn.ReLU(),
nn.Linear(120,2)
)
def forward(self, x):
out = self.layer1(x)
out = self.layer2(out)
out = out.view(out.shape[0], -1)
out = self.layer3(out)
return out
그런데 사이즈를 계산하는게 어려워서 헤맸다. 그래서 코드의 도움을 받아서 해결했다.
out=net.layer1(train_data[0][0].unsqueeze(0))
print(out.shape)
out=net.layer2(out)
print(out.shape)
이렇게 생긴 테스트 셋을
이렇게 예측했다. 아무래도 색이 중요한 영향인걸까?
나도 갑자기 하얀색 꽃으로 예측됐다. 신기방기 컴퓨터의 생각을 알고 싶다.
'딥러닝 > 프로젝트' 카테고리의 다른 글
[Kaggle] CT Medical Image - (0) 서론, 액션 플랜 (0) | 2021.09.25 |
---|---|
[개인]R-CNN 을 이용한 BCCD type 분류 -(3)linear svm, (4)결론 (0) | 2021.06.29 |
[개인]R-CNN 을 이용한 BCCD type 구분 -(2) fine tuning (0) | 2021.06.29 |
[개인]R-CNN 을 이용한 BCCD type 구분 -(1) selective search (0) | 2021.06.23 |
[개인]R-CNN 을 이용한 BCCD type 구분 -(0) 서론, 데이터 셋 소개 (0) | 2021.06.22 |
댓글