안녕하세요.
HuggingFace 10기 파트너 정정민입니다.
2 기수에 거쳐 진행된 “HuggingFace로 모델 학습시키기”의 마지막 시간이네요.
이전 모델 학습시키기 포스팅은 아래 링크로 걸어두겠습니다.
지금까지 뭘 했냐하면
학습할 데이터(인도 음식 데이터)를 가져왔고
학습할 모델(ResNet)을 가져왔으며
목적 데이터로 인해 변경될 모델의 세팅(TrainArguments)을 변경하고
학습(Trainer)을 진행했습니다!
결과적으로 학습된 모델이 잘 저장이 됩니다.
model.safetensors : 학습된 최고 성능의 모델이 담겨있습니다.
preprocesser_config.json : 이미지 전처리 과정의 세부 내용이 담겨있죠.
기타 json & bin : 학습 과정 초, 중, 후에 생긴 부산물입니다.
학습한 모델을 다시 불러오기
저는 results라는 폴더에 학습된 결과물을 저장했습니다.
즉, 저 폴더만있으면 학습된 모델을 들고올 수 있는거죠.
폴더의 위치를 찍어주고 손쉽게 불러옵니다.
from transformers import ResNetForImageClassification
target_folder = "results"
model = ResNetForImageClassification.from_pretrained(target_folder)
더불어, 모델이 이미지 전처리 과정을 위해 학습 과정에서 사용했던 이미지 전처리 과정도 불러옵니다.
AI 모델이 학습 했던 환경 그대로 데이터를 다시 넣어주기위해 필수로 들고와야합니다.
from transformers import AutoImageProcessor
target_folder = "results"
image_processor = AutoImageProcessor.from_pretrained(target_folder)
HuggingFace 에 올라와있는 모델을 ID 만으로 호출했었던 것처럼
원하는 폴더만 찍어주면 모델이 쉽게 불러와집니다.
이런 통일된 인터페이스를 제공하기 때문에
코드 몇 줄로 모델을 가져오고 할 수 있는거겠죠?? ㅎㅎ
사용할 데이터 선택
학습한 AI 모델은 인도 음식 이미지를 받아 무슨 음식인지 예측하는 모델입니다.
이번 데모에서 사용할 이미지는 아래와 같습니다.
인터넷에서 음식 찾고 저장하고 불러오기 귀찮으니
웹 상의 이미지 주소를 받아 불러오는 코드를 작성해봅니다.
from PIL import Image
import requests
url = 'https://i.namu.wiki/i/XQznKj51oCpN5HKkUBe6o2R_fRb4TSbU6JTZk52zYJbbjH_1B0BFHM5uYQMfsFzQOLRHG3mhR8xhqPG_UbeA0w.webp'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36'
}
image = Image.open(requests.get(url, headers=headers, stream=True).raw)
간혹 특정 이미지가 주소만을 이용해 접근할 수 없는 경우가 있어 header도 추가해줍니다.
이후, 모델에 넣어주기 위해 Pillow 패키지의 Image 객체로 불러옵니다.
불러온 이미지 넣어서 결과 보기
앞서 말씀드린대로
저 이미지 그대로를 AI 모델에게 넣어줄 수는 없습니다.
학습 과정에서처럼 변환이 필요합니다.
processed_img = image_processor(images=image.convert("RGB"), return_tensors="pt")
바로 넣어서 결과를 뽑아봅니다.
with torch.no_grad():
outputs = model(**processed_img)
logits = outputs.logits
AI 모델의 결과를 logits 이라고 합니다.
이걸 프린트해보면 아래와 같아요.
print(logits)
tensor([[ 9.1721, 22.3537, 0.6114, 19.3361, 6.9428, -9.9826, 4.2027,
9.3850, 4.6262, -6.8385, 11.5310, -20.4190, 3.5227, -4.2744,
2.4644, -4.1362, -4.1042, -0.9797, 9.8295, -5.8950]])
이 값은
입력으로 넣어준 음식 이미지가
총 20개의 각기 다른 음식일 점수 입니다.
해석이 어렵죠??
따라서 이걸 사람이 이해하기 쉽게 후처리 (Post-processing)를 해줘야 합니다.
(이미지 분류는 사실 후처리가 매우 간단합니다)
아래와 같은 과정으로
각 점수를 확률로 변경하고,
제일 높은 확률을 갖는 음식을 뽑아주면 됩니다.
prob = torch.nn.functional.softmax(logits, dim=-1)
topk_prob, topk_indices = torch.topk(prob, k=5)
for prob, index in zip(topk_prob[0], topk_indices[0]):
print(f"{model.config.id2label[index.item()]:<15} ({prob.item()*100:.2f} %)")
butter_naan (95.33 %)
chapati (4.66 %)
kaathi_rolls (0.00 %)
pizza (0.00 %)
fried_rice (0.00 %)
AI 모델이 “butter_naan” 이라고 하네요 ㅎㅎ
굳!!
캠프에서는 다른 예로 데모를 좀 더 진행해보도록 하겠습니다
학습시키기 시리즈 마무리
길어질거라 생각하지 못했던 “학습시키기” 시리즈가 끝이 났네요 ㅎㅎ
‘학습’은 ‘잘 활용하기’ 만큼이나 딥러닝에서 큰 비중을 차지합니다.
하지만 난이도가 있는것은 분명하죠 ㅠㅠ
HuggingFace의 모듈을 활요한 학습 코드 작업은 그 난이도를 조금 낮춰주는 유용한 도구였습니다.
“엄청 맛있는 할머니 청국장은 아니지만 마트에서 파는 풍성한 밀키트” 같은 느낌이랄까..
있는 그대로만 사용해도 평균 이상은 할 수 있고,
대파랑 두부를 좀 더 넣고, 이쁜 그릇에 담으면 매우 그럴듯한 요리가 될 수 있는 것처럼
HuggingFace의 학습 과정 그 자체만 이해해도 AI로 할 수 있는 부분이 훨씬 넓어질 것 같습니다.
물론 조금 더 공부해서 대파랑 두부를 첨가할 수 있다면 근사한 AI 결과물이 나올 수도 있을겁니다!
이후 포스팅에서는 학습하기 이후로
모델을 huggingface hub로 올리거나,
gradio를 사용하는 방법을 공부해볼까 합니다.
많관잘부!!
감사합니다.
#10기HuggingFace #10기 #HuggingFace
작성자 : 정정민
블로그 : 링크