인공지능 일기

AIFFEL 과정 9주차 정리

JadenM 2021. 2. 26. 16:25

2월의 마지막 주를 보내고 있다.

 

겨울도 얼마 남지 않았다.

 

www.youtube.com/watch?v=VJHIXzyrLp4

정재일 - 겨울

 

이 곡을 들으면서 겨울을 보내줘야겠다.

 

이제 SSAC에서 보낼 나날이 4개월도 채 남지 않았다.

 

그동안 배운 것을 내 것으로 만드는 것도 중요하지만

 

앞으로 경험하게 될 딥러닝의 세계를 잘 맞이하는 것이 더 중요할 것이다.

 

 


 

<2월 22일 월요일>

 

[Fundamental Stage]

파이썬으로 이미지 파일 다루기

 

이 노드는 OpenCV을 활용해 이미지를 다루는 방법에 대해 소개한다.

학습의 목표는 아래와 같다.

 

  • 컴퓨터에서 이미지가 표현되는 방식을 이해한다.
  • Pillow와 OpenCV로 Python에서 이미지 파일을 열고 정보를 추출할 수 있다.
  • CIFAR-100에서 히스토그램을 기반으로 유사한 이미지를 골라낼 수 있다.

OpenCV를 다루기에 앞서, 우선 Pillow 라이브러리의 사용법을 알아보았다. Pillow 라이브러리는 numpy와 결합하여 간편하게 사용할 수 있는 도구로써 Pillow를 활용해  CIFAR-100 데이터를 전처리하는 작업을 진행했다. Pillow를 활용해 이미지의 색상을 바꿔보기도 하고 사이즈를 Resize 해보기도 하면서 이미지를 가공하는 과정을 학습했다.

그런 다음, 노드의 주인공인 OpenCV를 다뤄보았다. OpenCV는 오픈소스로 제공되는 컴퓨터 비전용 라이브러리인데요. C++, Python, Java, MATLAB 등 다양한 언어에서 호출하여 사용할 수 있으며, 영상 처리에 대한 다양한 고급 기능들이 사용하기 쉽도록 구현되어 있다고 한다.

또한 OpenCV를 사용하면 각 이미지에서 색상 히스토그램을 추출하여 이를 서로 비교하여 비슷한 이미지끼리 분류할 수 있다.

그래서 히스토그램 간의 유사도를 측정하여 인풋 이미지와 비슷한 사진을 5장 추출하는 작업도 시도해보았다. 결과로 나온 이미지를 보니 전체적으로 비슷한 색상을 띠는 것을 확인하였지만, 사진 속 오브젝트들은 비슷하다고 하기는 힘들었다. 아마 색상 히스토그램을 바탕으로 이미지 분류를 시도하여서 그랬던 것 같다.

아무튼 CV분야에서 이미지를 분류하는 작업을 기본일테니 이번 노드에서 배운 내용을 활용해 본다면 다양한 작업에서 도움이 될 것 같다.

 

 

[Flipped School-deepML]

CS231 10강 Training Neural Networks I

 

이번 CS231 강의는 Training Neural Networks I라는 제목으로 뉴럴 네트워크를 구성하는 세팅 방법에 대해서 배웠다. 딥러닝 모델을 구현하는 것에 있어 신경 써줘야 할 부분은 한두 가지가 아니다. 그렇기 때문에 학습시키려는 모델의 성질에 맞게 다양한 세팅방법을 시도해 보는 것이 중요하다.

강의에서는 네트워크를 세팅하는 요소의 첫번째로 활성화 함수에 대해 소개하였다. 활성화 함수의 종류가 다양하기 때문에 각 함수들의 특징과 장단점에 대해 배울 수 있었다. 가장 처음으로는 Sigmoid함수를 소개하였는데 Sigmoid함수는 전통적으로 많이 쓰여온 활성화 함수로써 꽤 오랜 시간 동안 사용되었다고 한다. 그러나 역전파 시에 기울기가 점차 소실되면서 학습되어야 할 파라미터들의 업데이트가 잘 이루지지 않는 문제가 발생하여 최근에는 거의 사용되지 않는 함수라고 한다. Sigmoid에 이어 tanh 함수가 활성화 함수로써 등장하게 되었는데 여전히 기울기 소실이 발생하여 아쉬움을 남겼다. 그다음으로 나온 것이 바로 'ReLU'함수이다. ReLU함수를 사용하게 됨으로써 기울기 소실 문제를 해소하게 되었고 학습 시간 또한 많이 줄였다고 한다. 그래서 강의에서는 활성화 함수를 선택하는 것에 너무 고민을 하지 말고 되도록이면  ReLU함수를 사용하도록 권장을 한다.강의에서는 또 가중치를 초기화 하는 방법에 대해서 설명했다. 지금까지 연구가 지속되면서 가중치를 어떻게 초기화할 것인가에 대한 많은 논의가 있었다고 한다. 처음에는 가중치를 모두 0으로 초기화하는 방법이 제시되었지만 가중치를 모두 0으로 주게 되면 인풋과 상관없이 아웃풋은 모두 0이 되기 때문에 역전파 시에도 파라미터를 업데이트 하기에 무리가 있어서 이 방법은 사용하지 않는다고 한다. 그래서 가중치 값을 적은 수의 값을 곱해주어 초기화하는 방법도 제시되었지만 문제가 있어 최근에는 Xavier Initialization 방법을 가장 많이 사용한다고 한다. 활성화 함수 선택, 가중치 초기화 방법 이외에 Regulization을 하는 방법에 대해서도 소개했다. Regulization 작업을 거치지 않은 모델을 학습을 진행함에 따라 점차적으로 training셋에 과적합되어 새로운 데이터가 들어왔을 때 잘 학습이 되지 않는다는 문제가 생긴다. 그래서 Regulization을 해서 가중치 값에 패널티를 부여해서 학습을 방해하게 한다. 그렇게 하면 모델이 과적합 되는 문제를 어느 정도 해소할 수 있다고 한다.이번 강의를 통해서 모델을 구성할 때 존재하는 선택지들을 조금 줄일 수 있게 된 것 같다. 확실한 것은 아니지만 어느 정도의 가이드라인을 제시해 준 것 같아서 나중에 모델을 직접 만들어 본다면 좋은 참조가 될 수 있을 것 같은 강의였다.

 

 

 

<2월 23일 화요일>

 

[Exploration]

어제 오른 내 주식, 과연 내일은?

 

이번 Exploration 프로젝트는 시계열 데이터를 활용해서 미래의 주가를 예측하는 모델을 만들어 보는 것이었다. 그래서 시계열 예측(Time-Series Prediction)을 다루는 여러 가지 통계적 기법 중에 가장 널리 알려진 ARIMA(Auto-regressive Integrated Moving Average)에 대해 함께 알아보았다.우선 시계열이란 시간 순서대로 발생한 데이터의 수열이라는 뜻이다. 과거에 발생한 일을 토대로 미래를 예측하는 데에 활용되는 것이 시계열 데이터의 존재 목적이다. 본래 미래는 예측 불가능한 것이지만 그럼에도 예측하려 든다면 아래와 같은 전제가 필요하다.

 

  • 과거의 데이터에 일정한 패턴이 발견된다.
  • 과거의 패턴은 미래에도 동일하게 반복될 것이다.

 

위의 말은 곧 안정적 데이터가 필요하다는 말인데 안정적이란 뜻은 시계열 데이터의 특성이 변하지 않는 것을 말한다.

노드에서는 ARIMA 모델을 활용하여 여러 주식 종목의 미래 주가를 예측하는 모델을 만들어 보라고 했다. 그래서 처음에는 삼성전자의 주가 데이터를 바탕으로 모델을 학습시켰는데 높은 정확도를 결과로 내놓았다. 그래서 자신감을 가지고 다른 주식 종목으로 시도를 해보았는데 정확도가 몇십% 나 떨어지는 것이었다. 너무 결과가 황당해서 삼성전자 주가 데이터를 다시 보았더니 1년 치의 정보만이 들어 있는 것이었다. 2번째로 시도한 주식 종목 데이터는 20년 치의 데이터였으니 정확도가 차이가 날 수밖에!

그제야 그 날 아침, 퍼실님이 해주셨던 말이 떠올랐다. 기간을 너무 길게 잡지 말라. 

그 말이 생각나서 기간을 조금 수정하여 데이터를 다시 다운로드하고 시도를 해보았더니 다시 좋은 결과를 얻을 수 있었다. 아직 다른 주식 종목의 데이터로 시도를 해보는 중인데 기간은 10년 정도가 되어서 결과가 궁금하다. 실제로 이런 주가예측모델을 만들어서 주식투자에 활용하시는 분이 계신다고 하니 성능 좋은 모델을 만들 수만 있다면 나중에 투자를 시도해 보는  것도 좋을 것 같다.

 

 

 

<2월 24일 수요일>

 

[Fundamental Stage]

SQL을 이용해 DB와 대화해보자

 

SQL을 이용해 DB를 다루는 방법을 소개하는 노드였다.

노드에서는 SQLite라는 모델을 사용하는데 SQL은 파이썬과 DB를 연결해주는 수단이라고 할 수 있다. 파이썬과 DB가 멀리 떨어져서 휴대폰으로 대화를 시도할 때 SQL은 그 중간에서 중계기 역할을 한다. 우선 SQL을 사용해보기 위해선 간단한 DB가 필요하다. 노드에서는 드라마 '사이코지만 괜찮아'에 나오는 등장인물을 활용해서 도서대출 관련 여러 DB를 만들게 하였다.

DB가 만들어지면  SQL을 이용해서 DB를 다양하게 손 볼 수 있다. 대출일자를 내림차순으로 정렬해 볼 수도 있고 어떤 기간 내에 도서를 대출한 사람의 정보를 조회해 볼 수도 있다. 또한, JOIN이라는 기능을 활용해서 여러 DB를 공통된 column을 기준으로 합쳐 볼 수도 있다.

SQL을 사용해보니 비교적 간단한 코드를 통해서 DB를 마음껏 조정할 수 있었다. 앞으로 여러 데이터를 처리할 일이 많을 텐데 그럴 때  SQL을 활용해 보면 도움이 많이 될 것 같다. 그러니 그전에  SQL 활용법을 미리 익혀두는 것이 중요하다.

 

[Flipped School-Coding Master]

자료 구조 및 리트코드 문제 풀기

 

이번 코마 풀잎스쿨에서는 새롭게 자료 구조에 대해 알아보는 시간을 가졌다. 지금까지는 파이썬 기초 문법에 관해 배웠었고 그 과정이 모두 끝났기 때문에 새롭게 자료 구조를 알아보는 과정을 시작하게 되었다. 그 시작으로 stack, queue 등 여러 개념에 대해서 알아보았다. 일전에 진로상담을 통해 stack과 queue를 활용하는 것이 중요하다는 것을 알게 되어서 자료구조에 대해 공부해 보는 시간이 여간 반가운 것이 아니었다. 아직 파이썬 코딩에 대해서 더 배워보고 싶은 마음도 있지만 기초적인 문법들에 대해선 배웠으니 혼자 시간을 보낼 때 그것들을 내 것으로 만들어 봐야 할 것 같다.

자료 구조에 대해 알아보는 시간이 끝난 뒤에는 리트코드 사이트에 있는 코딩 문제를 풀어보았다. 처음 코딩마스터 시간에 리트코드 문제를 풀다가 좌절을 한번 겪어 봤기 때문에 문제를 보기도 전에 겁이 났지만, 퍼실님이 우리 반의 수준에 맞춰서 풀만한 문제를 선정해 주셨다. 물론 그 문제도 어려운 건 마찬가지였다. 그러나 그간 코딩 실력이 늘었는지 막막한 기분만 드는 것은 아니었다. 결국 혼자서 문제를 풀지는 못했지만, 같이 문제를 풀어보면서 조금만 더 공부하면 풀 수도 있겠다는 생각도 들었다.

리트코드 문제를 푼 뒤에는 날씨 데이터를 가져와서 활용해 보는 시간을 가졌다. 혼자 했으면 데이터를 어떻게 전처리하고 시각화할지 막막했을 것 같은데 퍼실님과 같이 보면서 코딩해보니 조금씩 감이 잡히는 것 같았다.

앞으로는 자료구조와 함께 케글 사이트에 있는 노트북을 조금씩 뜯어보자고 하셨는데 아주 기대가 된다. 해커톤을 겪어보니 정말 대단한 능력자들이 많은 것을 알았다. 그런 사람들의 노트북의 코드를 조금씩 파악할 수만 있다면 실력 향상에 아주 도움이 많이 될 것 같다.

 

 

 

<2월 25일 목요일>

 

[Exploration]

폐렴아 기다려라

 

이 프로젝트는 처음으로 의료영상을 처리해보는 노드였다. 의료영상을 다루는 것은 일반적인 이미지를 다루는 것과는 다르게 아주 까다로운데 그 이유는 아래와 같다. 

 

  • 의료영상 이미지는 개인정보 보호 등의 이슈로 인해 데이터를 구하는 것이 쉽지 않습니다.
  • 라벨링 작업 자체가 전문적 지식을 요하므로 데이터셋 구축 비용이 비쌉니다.
  • 희귀 질병을 다루는 경우 데이터를 입수하는 것 자체가 드문 일입니다.
  • 음성/양성 데이터 간 imbalance가 심합니다. 학습에 주의가 필요합니다.
  • 이미지만으로 진단이 쉽지 않아 다른 데이터와 결합해서 해석해야 할 수도 있습니다.

의료영상 데이터를 다루는 것은 인공지능 지식뿐만이 아니라 의료분야의 도메인 지식도 필요로 한다. 그렇기 때문에 노드에서는 의료영상 촬영기법과 함께 이번에 분석할 폐렴에 관해 알아보고 시작을 한다. 

사람의 눈으로는 인체 내부의 상태를 확인해 볼 수 없기 때문에 우리는 X-ray, CT, MRI 등을 활용해 몸 상태를 확인하고 질병 여부를 체크한다. 이번 프로젝트에 활용할 데이터는 X-ray로 촬영한 이미지들이었다. 

다운로드한 데이터에는 정상 환자들과 폐렴 환자들의 X-ray 이미지들이 담겨 있었다. 데이터는 이미 train, validation, test 셋으로 나눠져 있었다. 문제는 validation 셋의 수가 너무 적어서 train 데이터와 합쳐서 다시 나눠줘야 한다는 것이었다. 또한 폐렴 환자의 이미지보다 정상 환자의 이미지 수가 현저히 적은 imbalance문제도 있어서 Weight balancing이라는 방법으로 문제를 해결해줘야만 했다.

노드를 쭉 진행해 보니 정확도가 80% 정도로 나왔다. 프로젝트는 모델을 개선해서 정확도를 85%로 끌어올리는 것이 목표였다. 모델을 개선하는 방법은 여러가지인데, 배치 사이즈를 조절해 볼 수도 있고  epochs를 더 많이 줄 수도 있고 다른 활성화 함수를 사용해 보는 등 다양한 방법이 있었다. 그러나 이미 노드에서는 활성화 함수로 ReLU를, Optimizer로는 Adam을 사용하고 있었기 때문에 실제로 내가 조정해 볼 수 있는 변수들은 많지가 않았다. 활성화 함수와 Optimizer를 바꿔 보기도 했지만 결국은 다시 처음으로 돌아왔다.

프로젝트를 시작하기 전에는 금방 해결할 수 있을 것 같았는데 정확도를 끌어 올리는 일은 쉽지 않았다. 주말에 시간이 있을 때 다시 시도해 봐야 할 것 같다.

 

 

 

<2월 26일 금요일>

 

[Fundamental Stage]

TF2 API 개요

 

오늘 진행한 노드에서는 텐서 플로우 버전 2에 관한 내용이었다. 실제로 텐서 플로우를 활용은 했었지만 정확히 어떤 부분에서 사용되는지 몰랐기 때문에 오늘 노드는 꽤 흥미롭게 진행할 수 있었다.

텐서 플로우 2는 다소 사용하기 어려웠던 버전 1을 개선하고 keras라는 API를  표준 API로 삼으면서 큰 개선을 이뤄냈다.

만약 텐서 플로우를 사용하지 않는다면 간단한 모델조차도 설계하기 아주 벅찰 것이다.  그러나 텐서플로우를 활용하면 forward propagation 방향의 모델만 설계하면 그 모델의 gradient를 사전에 미리 구해둘 수 있다.

또한 텐서 플로우 2는 이전 모델에 비해 사용하기 쉬워지고 설계도 간단해졌으며 실행도 즉각적으로 변하는 등 많은 개선이 있었다.

실제로 코드를 몇 줄로 써서 구현할 수 있는 것을 텐서 플로우는 단 한 줄로 구현할 수 있도록 해준다. 만약 내가 텐서 플로우가 나오기 이전에 인공지능에 입문했다면 아마 좌절을 생각보다 일찍 겪었을 것 같다.

오늘 노드에서는 텐서 플로우를 활용해, MNIST와 CIFAR-100을 분류하는 모델을 구성해보았다. 텐서 플로우 2에는 딥러닝 모델을 설계하는 방법으로 Sequential, Functional, 그리고 Model Subclassing이 있다. 오늘은 저 3가지 방법을 모두 사용해서 두 가지의 데이터를 분류하는 모델을 만들었다.

이번에는 손 코딩을 해야 하는 코드 블록이 많아서 직접 코드를 쳐가면서 진행했는데 처음엔 앞 뒤로 왔다 갔다 하면 코드를 베껴 썼는데 그것을 계속하다 보니 어느샌가 머리에 저장이 되었다. 이래서 반복학습이 중요하다고 하는구나.

이번 노드를 통해 모델을 설계하는 코딩을 직접 해보니 이해도 잘되고 아주 도움이 많이 되었다.

 

 


[회고]

 

지금 마음이 불안한 것은 실력이 부족해서가 아니라, 그만큼 간절하기 때문이다.