22.10.20(목) Today I Learned

정형빈·2022년 10월 25일
0

TIL

목록 보기
35/71

10/19 오늘의 시간표

09:00 ~ 10:00 [프로젝트] 머신러닝 프로젝트 기초
10:00 ~ 11:00 [프로젝트] 머신러닝 프로젝트 기초
11:00 ~ 12:00 [프로젝트] 머신러닝 프로젝트 기초
12:00 ~ 13:00 [프로젝트] 머신러닝 프로젝트 기초
13:00 ~ 14:00 점심식사
14:00 ~ 15:00 [프로젝트] 머신러닝 프로젝트 기초
15:00 ~ 16:00 [프로젝트] 머신러닝 프로젝트 기초
16:00 ~ 17:00 [프로젝트] 머신러닝 프로젝트 기초
17:00 ~ 18:00 [프로젝트] 머신러닝 프로젝트 기초
18:00 ~ 19:00 저녁식사
19:00 ~ 20:00 [프로젝트] 머신러닝 프로젝트 기초
20:00 ~ 21:00 [프로젝트] 머신러닝 프로젝트 기초

머신러닝 프로젝트 4일차

내일은 오전에 발표준비로 시간을 다 사용해야 하기 때문에 사실상 오늘이 프로젝트를 준비하는 마지막날이라는 생각으로 프로젝트를 빡세게 준비해봐야 할 것 같다.
오늘은 어제 사물인식을 통해 나온 결과값을 DB에 올린 정보를 바탕으로 카테고리를 분류해 홈페이지에서 볼 수 있도록 하는 기능을 구현해야 했다. 하지만 당장 앞에 기능들은 지금까지 배운 내용을 토대로 어떻게든 구현이 가능했지만 이번 기능은 어떻게 해야할지 감이 전혀 오지가 않아서 혼자 머리를 싸매고 고민도 해보고 팀원들과 상의도 해보고 구글링도 해보았지만 답이 나오지 않아 결국 튜터님께 구현하는 방법에 대한 조언을 구하게되었다.

튜터님이 알려주신 방법은 PhotoModel 이외에 Category라는 모델을 하나 더 만들어서 거기에 사물인식을 통해 얻은 label값을 집어넣고 PhotoModel에서는 카테고리 필드값을 ManytoMany로 Category와 묶어주고 Category에는 미리 분류된 label값의 데이터셋을 미리 넣어두는 것이다.

나도 말로 풀어서쓰자니 아직도 이게 무슨소리인가 싶기는 하지만 실제로 코드작업을 해보니 어떤 것인지 이해가 가기 시작했다.

photo/models.py

from django.db import models
from user.models import UserModel

class Category(models.Model):
    class Meta:
        db_table = "category"

    name = models.CharField(max_length=30)

    def __str__(self):
        return self.name

class PhotoModel(models.Model):
    class Meta:
        db_table = "photo"

    img = models.ImageField(upload_to='photo/', null=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    categories = models.ManyToManyField(Category,default='')
    favorites = models.ManyToManyField(UserModel, related_name='favorites' ,blank=True)
    trash = models.ManyToManyField(UserModel, related_name='trash' ,blank=True)


    def __str__(self):
        return self.img.url

먼저 Category라는 모델을 하나 더 생성하고 그 안에는 사물인식 프로그램이 분류해내는 80가지의 사물 데이터셋을 미리 넣어둔다.

그리고 PhotoModel에 categories라는 ManyToMany필드값을 추가하고 이 필드값은 Category를 참조하도록 만든다.

photo/views.py

@login_required
def fileUpload(request):
    if request.method == 'POST':
        photo = PhotoModel()
        user = request.user

        photo.user = user
        photo.img = request.FILES["img"]
        photo.save()

        categories = classification(photo.img)[1]
        
        categories = Category.objects.filter(name__in=categories)
        if categories:
            photo.categories.add(*categories)
        else:
            photo.categories.add(81)
            
        return redirect('/')

    else:
        imageupload = ImageUpload
        context = {
            'imageupload': imageupload,
        }
        return render(request, 'upload.html', context)

그리고 다시 업로드 기능을 수정해서 업로드한 이미지파일을 사물인식 프로그램을 통해 돌렸을 때 추출한 label값이 Category안에 있다면 해당 값을 categories에 추가하도록 DB설정을 해둔다. cvlib에서 추출할 수 있는 80개의 데이터셋은 모두 Category안에 들어있기 때문에 만약 해당 프로그램이 인식하지 못하는 사물은 81번째 값인 '분류되지 않은 카테고리'로 지정을 해서 else문을 남겨두면 DB에 카테고리 정보가 비어있는 경우는 없어진다.
단 이렇게 하면 문제가 한가지 있었는데 내가 장고 DB를 통째로 날려버렸을 경우나 GitHub를 통해 프로젝트를 공유할 경우에는 Category에 80가지 데이터셋을 미리 넣어둘 수 없다. 그래서 이번에 활용한 기능이 dumpdata/loaddata 기능이다. 해당 기능을 통해 데이터베이스의 값을 json파일로 저장해 뒀다가 필요하면 불러오는 것이 가능해졌다. 이 기능은 권기현 튜터님의 관련 영상을 통해서 사용법을 알아보았다.

권기현 튜터님의 dumpdata/loaddata 사용법 강의 영상 링크

이제 남은것은 우리가 만든 페이지에서 카테고리별로 사진이 나오도록 html파일을 설정해두면 내가 구현해야할 기능은 끝이 난다. 하지만 이것 역시 오랜시간 직접 해보려고 시도해봤으나 잘 되지 않아 결국 또 튜터님에게 도움의 손길을 요청했다. 이때가 밤 12시 정도되는 늦은 시간이라 계시는 튜터님이 상호 튜터님 밖에 안계셨는데 상호 튜터님은 머신러닝쪽이 전문분야이시다보니 탬플릿 태그로 표기하는 법은 잘 모르신다 하셔서 포기하고 내일 아침에 구현해야하나 싶었지만 새벽에 민철 튜터님이 게더에 찾아오셔서 다행히도 질문을 통해 해결책을 구할 수 있었다.

photo/views.py

@login_required
def category(request):
    pht = PhotoModel.objects.all()
    ctg = Category.objects.all()
    return render(request, 'category.html', {'pht':pht, 'ctg':ctg})

우선 views.py에서 PhotoModel과 Category의 정보들을 참조해 올 수 있도록 값을 설정해 두고

category.html

{% for c in ctg.all %}
    {% for p in pht.all %}
    {% for category in p.categories.all %}
    {% if category.id == c.id %}
<a name="horizontal-scrolling"></a>
<h5 style="margin: 10px 0px 0px 50px;">{{c.name}}</h5>
<div id="scroll">

            <img src="{{ p.img.url }}" style="height : 150px; margin-top : 30px;">
            {% else %}
            {% endif %}
            {% endfor %}
            {% endfor %}
</div>

{% endfor %}

이 몇줄 안되는 코드를 작성하기 위해 시간을 얼마나 사용한지 모르겠다. 일단 카테고리의 정보를 가져와 for문을 만들고 그 for문 안에서 또 for문을 만들어 PhotoModel의 정보를 가져온 다음 이것을 다시 for문으로 반복하는데 조건을 if문을 통해 Category의 id값이 Photomodel내의 categories의 id값과 같으면 페이지에 표시하도록 코드를 작성했다. 그리고 이때 표시하는 내용은 Category의 이름, 그리고 해당되는 이미지파일들을 쭉 나열하게 설정했다.

오늘 하루를 마치며

길었던 프로젝트 준비의 마지막날이 지나갔다. 이제는 진짜 발표 당일만 남았는데 새벽 늦은 시간까지 다들 남아서 작업하느라 깃허브에서 연동을 확인하지 못했다. 어쩔수 없이 자고일어나서 아침에 급하게 결과물을 완성시킨 뒤에 발표준비를 해야할 것 같다. 내가 중간에서 조금만 더 조율을 잘했더라면 이렇게 늦게까지 남아서 작업하는 일은 없었을 텐데 하는 아쉬움도 많이 남는다. 그래도 다들 열심히 노력한 만큼 좋은 결과물이 나왔으면 좋겠다.

profile
스파르타 내일배움캠프 3기 수강생 정형빈

0개의 댓글