NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 팁 앤 테크
  • 매뉴얼

    팁과 테크니컬 노하우를 확인하세요.

    팁 앤 테크

    팁과 테크니컬 노하우를 확인하세요.

    본 사이트의 컨텐츠는 저작권법의 보호를 받으므로 무단 복사, 게재, 배포 등을 금합니다.

    기타 머신러닝 5부 - Inception V3 학습 모델을 엔지엠에서 사용하기.

    페이지 정보

    본문

    안녕하세요. 소심비형입니다. 인셉션 V3 아키텍쳐를 이용해서 나만의 이미지 검출기를 만드는 마지막 시간입니다. 오늘은 학습시킨 모델을 엔지엠에서 어떻게 사용해야 하는지 알아보도록 하겠습니다. 우선, 엔지엠의 텐서플로우 추론 액션은 인셉션 모델을 사용합니다. 텐서플로우 매치는 디텍션 모델을 사용해야 하죠. 이 둘은 사용방법에 차이가 존재합니다. 추론은 이미지가 무엇인지 알아내기 위한 용도입니다. 디텍션도 동일하지만, 추가로 해당 이미지가 어느 위치에 있는지도 알 수 있습니다. 이 내용이 끝나면 디텍션도 진행하도록 하겠습니다^^;

    img.gif 

     

     

    머신러닝 4부까지 진행했으면 여러분도 학습 모델을 가지고 있을겁니다. 저와 동일하게 했다면 C:\tmp폴더 안에 모델 파일(pb)과 분류 레이블 파일(txt)이 존재할겁니다. 엔지엠 에디터를 실행하고 모델 파일과 레이블 파일을 선택하세요.

    img.png 

     

     

    어디에서 이미지를 추론할지 결정하지는 않았습니다. 보통은 핸들을 잡거나 찾기 영역을 선택해야겠죠^^; 아무튼 지금 실행하면 전체 화면에서 학습한 이미지를 찾으려고 할겁니다. 실행해보면 아래와 같은 에러 메시지를 만나게 됩니다.

    img.png 

     

     

    속성에 보면 입력 노드 이름출력 노드 이름이 보일겁니다. 대부분 구글링해서 찾은 샘플 또는 다른 사람들이 공유하고 있는 학습 모델의 입력 노드 이름과 출력 노드 이름이 input(인풋), output(아웃풋)으로 되어 있습니다. 물론, 아닌 경우도 존재합니다. 간단하게 입력 노드 이름은 인풋, 출력 노드 이름은 아웃풋이라고 부르도록 할께요. 인풋은 학습시킨 이미지를 찾기 위한 원본 이미지를 말합니다. 그리고, 아웃풋은 찾은 이미지를 분류하고 추론한 결과값입니다. 좀 더 쉽게 설명하면 이미지를 모델에게 주면(input), 모델은 인풋으로 들어온 이미지를 분석하여 결과(output)를 사용자에게 줍니다.

    img.png 

     

     

    파이썬 텐서플로우의 케라스(Keras)까지 잘 활용한다면 딥러닝까지 도달할 수 있습니다. 요즘 계속해서 지켜보고 있는 자료들은 Accord.NET과 ML.NET입니다. 모두 신경망 딥러닝을 쉽게 구현할 수 있도록 해주는 프레임워크를 제공하고 있습니다. Accord.NET은 이미 엔지엠에 모듈이 탑재되어 있긴한데요^^; 어떻게 사용해야 할지를 아직 모르겠네요-_-; 아무튼, 논점에서 벗어나긴 했지만~ 데이타의 흐름은 위 그림과 동일합니다. 그렇다면 위 에러는 왜 발생할까요? input 노드 이름을 찾을 수 없기 때문에 발생합니다. 그렇다면, output_graph.pb 파일의 입력 노드 이름(input)과 출력 노드 이름(output)을 어떻게 알 수 있을까요? 텐서보드를 이용하면 쉽게 파악이 가능합니다^^

    img.gif 

     

     

    텐서보드에 대한 자세한 내용은 아래 링크에서 확인할 수 있습니다.

    https://www.tensorflow.org/tensorboard 

     

    비주얼 스튜디오 코드를 실행하고, 아래 명령을 입력합니다. 아나콘다로 진행하신 분들은 텐서보드가 이미 설치되어 있을겁니다. pip로 진행하신 분들은 pip install tensorboard를 입력해서 직접 설치해야 합니다.

    tensorboard --logdir C:\tmp\retrain_logs 

    img.png 

     

     

    로그 디렉토리 경로가 다를수도 있지만, 저 부분은 이전 글에서 학습한 내용을 토대로 모델이 생성된 위치의 retrain_logs 폴더로 설정하면됩니다. 텐서보드가 정상적으로 실행되었으면 웹브라우저에서 아래 주소로 접근할 수 있습니다.

    http://localhost:6006

    img.png 

     

     

    여기서 중요한건 입력 노드 이름과 출력 노드 이름을 확인하는겁니다. 그래야 적절한 데이타를 넣고, 결과를 받아볼 수 있으니까요. 아래 그림처럼 그래프로 이동하세요. 로딩하는데 약간 시간이 소요될수도 있습니다. 복잡도와 학습량에 따라 달라지겠지만요^^;

    img.png 

     

     

    이 그래프에서 중요한건 들어가는 입구와 나오는 입구의 노드 이름입니다. 가장 아래쪽이 시작이고 위가 끝이니, 하나씩 확인해보죠~

    우선 아래 그림처럼 가장 밑의 노드부터 확인해보세요. 콘텐츠가 들어오는 노드의 이름이 DecodeJpeg입니다. 일단 이 이름을 기억해두고 출력 노드를 확인하러 갑시다.

    img.png 

     

     

    출력 노드의 이름은 final_result입니다.

    img.png 

     

     

    엔지엠에서 입력 노드 이름과 출력 노드 이름을 텐서보드를 통해 알아낸 DecodeJpeg와 final_result로 변경하고 실행해봅니다. 여러분도 아마... 아래와 동일한 에러 메시지를 만나게 될겁니다. 텐서보드에서 확인한 인풋과 아웃풋 이름을 정확하게 입력했는데도 말이죠. 뭐가 문제였을까요?

    img.png 

     

     

    에러 내용을 보면, Expects arg[0] to be uint8 but float is provided라고 알려줍니다. 이 내용은 DecodeJpeg 노드로 들어온 값이 언사인드 정수형 8 타입이어야 하는데, 실제로 주어진 데이타는 부동소수점(float)으로 제공되었다는 뜻입니다. 그렇다면 왜 이런 에러 메시지를 뱉었는지 분석해봐야겠죠? 좀 더 심도있는 고민이 필요해집니다. 다시 텐서보드로 이동해서 처음부터 들어오는 데이타가 무엇인지 확인해봐야 합니다. 아래 그림처럼 contents를 확인해보면 문자열인걸 알 수 있습니다. 이 부분에서 원래는 학습 모델의 소스를 확인해보고 어떤 데이타가 들어가는지 봐야하지만, 굳이 소스를 안보더라도 ① 문자열이기 때문에 어떤 이미지의 경로일거라고 예측할 수 있습니다. 그리고, 우리가 입력 노드 이름으로 선택했던 DecodeJpeg를 보면 이 값은 문자열로 들어온 이미지 경로의 파일을 ② Jpeg로 변환한다는 걸 알 수 있습니다.

    img.png 

     

     

    ③은 Cast인데요. 이 부분이 핵심이라는걸 금방 알 수 있었습니다. 에러 내용과 일치하는 Attributes를 찾았기 때문입니다. 내용을 보면 소스(출발) 데이타 타입이 UINT8이죠? 그리고 데스티네이션(도착) 데이타 타입은 FLOAT입니다. 그 아래 Input과 Output를 보면 이 노드에서 UINT8값을 DecodeJpeg로부터 받아서 FLOAT값으로 변경해서 ExpandDims로 준다는걸 확인할 수 있었습니다.

    img.png 

     

     

    결론은, input으로 주어진 데이타가 학습 모델에서 처리할 수 없는 데이타였기 때문입니다. 좀 더 정확하게 말하면 학습 모델은 이미지의 경로(문자열)를 받아서 내부적으로 바이트로 변환하고 이 바이트 값을 메모리로 로드합니다. 그리고 학습을 진행하게 되는데요. 이미지 경로를 줘야하는 곳에 엔지엠은 이미 바이트로 변환된 이미지 값을 주었기 때문에 타입 불일치가 발생했던겁니다. 위 분석에서 알 수 있듯이 입력 노드 이름에 "ExpandDims"를 입력해야합니다. 다시 실행해볼까요? 

    img.png 

     

     

    에러 없이 정상 동작하는걸 확인할 수 있었습니다. 이제 해야할일은 내가 원하는 이미지 샘플을 수집해서 학습시키고, 엔지엠에서 학습 모델을 이용해서 이미지를 추론하여 일정 값 이상이면 어떤 동작을 수행하도록 하면 됩니다. 10년된 노트북인데도... 속도가 엄청나게 빠르네요. 괜찮은 장비만 있다면 순식간에 이미지를 추론, 분류하여 작업할 수 있을듯 보입니다^^

     

    다음에는 아래 내용으로 진짜 99프로 가능한지 한번 진행해보도록 할께요~ 단, 요청자가 많으면요!

    https://github.com/gabriel-dev/rune-breaker

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    profile_image

    시네라리아님의 댓글

    no_profile 시네라리아 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일 Date

    ㅎㅎ 조금 복잡하긴 하네요 ㅎㅎ 간소화 되면 ㅠ 좋을텐데 아직은 복잡 ㅠ
    한번 도전해보겠습니다

    profile_image

    유신달마님의 댓글

    no_profile 유신달마 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일 Date

    역쉬 시네라리아님 공부에 끝은없습니다 저도 도전하겠습니다 물론 다음주말이 될듯 하지만 ㅠㅠ

    profile_image

    롤로노이님의 댓글

    no_profile 롤로노이 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일 Date

    개발자님 매치에서는 출력노드 값이 이리 많은데 여기서 개발자님이 알려주신대로 출력 노드를 입력하면 오류가 뜨고 안넣으면 검색이 되긴하는데 매치율이 0%로 맞춰도 실패라고 뜨는데 혹시 이부분은 어떻게 해야 하는건가여?

    profile_image

    엔지엠소프트웨어님의 댓글

    엔지엠소프트웨어 쪽지보내기 메일보내기 홈페이지 자기소개 아이디로 검색 전체게시물 작성일 Date

    다른 액션입니다~ 위에 스샷은 디텍션이고요. 이 글은 인퍼런스입니다.