학습된 이미지 분류 모델을 활용해 이미지 분류 실습을 진행
이미지 분류란,
이미지의 대부분을 차지하는 객체의 종류를 예측하는 문제를 의미함

ResNet 이라는 모델을 사용할 예정.
딥러닝 모델을 학습하는 시간은 이전 머신러닝 모델 대비 상당히 오래 걸림
• 따라서 Pytorch 내부에서 이미 학습 된 모델을 가져다가 활용!
시작 전 GPU 연결하기
딥러닝은 리소스를 많이 사용하기 때문에 GPU로 연결해준다.

url = 'https://img.freepik.com/premium-photo/cute-puppy-of-maltipoo-dog-posing-running-isolated-over-white-studio-background-playful-animal_756748-85193.jpg'
url = 'https://cdn.newsquest.co.kr/news/photo/202305/206197_97856_1244.jpg'
import requests
from PIL import Image
import matplotlib.pyplot as plt
# 이미지를 웹에서 불러오는 함수
def load_image_from_web(url):
response = requests.get(url, stream=True).raw
img = Image.open(response).convert('RGB')
if img is None :
raise ValueError('url로부터 데이터를 가져오지 못했습니다. 다른 url을 사용해보세요!')
return img
# 이미지 시각화 코드
def imshow(img):
plt.imshow(img)
plt.axis('off')
image = load_image_from_web(url)
imshow(image)

이미지가 나오는 모습!
• 머신러닝 모델은 학습 과정과 똑같은 전처리를 진행한 뒤 추론을 진행해야 함
• ResNet 모델도 마찬가지
• ResNet 모델이 학습할 당시의 전처리 과정이 저장된 class가 존재
• ResNet 모델의 학습 결과물이 저장된 객체
• 만약 resnet18 모델을 사용한다면
• ResNet18_Weights 라는 이름의 클래스에 담겨있음

• 따라서 전처리 코드를 가져와 사용할 이미지에 적용해야 함
코드는 아래와 같이 사용한다.

weight_name = : 클래스를 사용할 때 ‘ResNet18_Weights’ 이런식으로 작성해 줘야 되기 때문에 숫자에 해당하는 부분을 찾아주는 코드 작성
• 옵션 : resnet18, resnet34, resnet50, resnet101, resnet152
import re
import torchvision.models as models
# 모델 선택 및 로드
def get_model_and_trans(model_name):
if model_name not in ['resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152']:
raise ValueError("model name을 확인해주세요. 옵션 : 'resnet18', 'resnet34', 'resnet50', 'resnet101', 'resnet152'")
weight_name = 'ResNet' + re.findall(r'\d+', model_name)[0] +'_Weights'
weights = getattr(models, weight_name).DEFAULT
transforms = weights.transforms()
model = getattr(models, model_name)(weights=weights)
model.eval()
meta_data = weights.meta
return model, transforms, meta_data
# 타깃 모델을 선택하고
model_name='resnet18'
# 모델과 그에 맞는 전처리 과정을 불러온다(파일토치에서 가져옴.)
myModel, transform, meta_data = get_model_and_trans(model_name)
가져온 데이터를 출력해보면 아래와 같이나온다.
myModel

transform에서는 사이즈 등이 변환된 모습을 볼 수 있다.
transform

import torch
# 이미지 전처리 진행
trans_image = transform(image)
trans_image = torch.unsqueeze(trans_image, 0)
def imshow_from_tensor(tensor):
image = tensor.cpu().clone() # 텐서 복제
image = image.squeeze(0) # 배치 차원 제거
image = image.permute(1, 2, 0) # 차원 재배열
image = image.numpy()
plt.imshow(image)
plt.axis('off')
plt.show()
# 전처리가 진행되면 원본 이미지의 형태가 많이 훼손됨
# 하지만 딥러닝 모델은 이런 형태를 더욱 잘 알아본다고!
imshow_from_tensor(trans_image)

그럼 이런식으로 이미지가 짤리고 색감도 바뀜.
색감이 변한 이유는
RGB 색깔의 분포가 컴퓨터가 더 잘 볼 수 있는 형태로 바뀌기 때문.
# 모델에 입력하고 결과를 출력
output = myModel(trans_image)
# 1000개의 결과값을 출력
# 이들 중 최고 값을 갖는 값이 출력의 결과값!
print(output)

각 클래스들의 점수가 나온다.
이제 각 부분의 MAX점수 부분을 확률 형태로 추출하면 확률이 가장 큰 부분이 나옴.
import torch.nn.functional as F
# 출력 결과로부터 출력 결과 도출하기
conf, predicted = F.softmax(output, dim=1).max(1)#F.softmax:점수를 확률의 형태로 변경.
total_class = meta_data["categories"]
cls = total_class[predicted.item()]
print(f'최종 결과 입력 이미지는 {conf.item()*100:.2f} % 의 확률로 {cls} 이라고 예측됩니다.')
출력결과:
최종 결과 입력 이미지는 99.99 % 의 확률로 Arabian camel 이라고 예측됩니다.