블로그 이미지
자유로운설탕

calendar

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

Notice

'머신러닝 machine learning'에 해당되는 글 1

  1. 2017.06.18 구글로 공부하는 파이썬 - 17교시 (머신러닝에서의 파이썬의 역활)
2017. 6. 18. 15:49 프로그래밍

  이번 시간에는 머신러닝에 대한 이런저런 생각들을 얘기하고, 이전 시간에 배웠던 numpy, scipy, 그리고 요즘 주목 받고 있는 텐서플로우(tensorflow) 라이브러리를 이용해서, 머신러닝 계의 구구단 이라고 할수 있는 최소제곱법(Least Square Fit)으로 데이터에 맞는 직선을 추정하는 샘플 3가지를 실행해 보려고 한다.

 

 시작하기전에 먼저 양해를 얻고 싶은 점은 스스로 생각했을 때 머신러닝에 대해서는 아주 조금 밖에는 알고 있지 못하다는 점이다. 비유하자면 수영을 해서 강을 건너야 하는 상황인데, 아직 강가에서 손가락만 살짝 담구고 '물이 얼마나 찬가' 하고 체크하는 레벨이라고 볼수 있다. 그래서 여기서 얘기한 얘기들이 틀릴 수도 있기 때문에, 내용을 최대한 비판적으로 받아 들이라고 권고를 드린다.

 

 

[목차]

0. 왜 파이썬 공부에 구글을 이용하는게 좋은가?

1. 언어를 바라보는 방법. 파이썬을 어떻게 바라봐야 할까?

2. 파이썬 설치와 환경, 버전 선택 하기의 이유.

3. 만들고자 하는 기능을 모르는 조각으로 나눠 조사해 보기

4. 데이터 베이스에서 내용 가져와 출력하기

5. 암호화 모듈을 이용해 암복호화 해보기

6. 퍼즐 조각들을 합쳐보기

7. 엑셀 파일 사용해 보기 -> 부록 : fuction 을 이용해서, 코드 정리해 보기

8. 정규표현식을 왜 사용해야 할까? 언어속의 미니 언어 정규표현식 살펴보기

9. 입력과 결과를 GUI 화면과 연결해 보기

10. Whois API 이용해 보기

11. 웹페이지 호출해 내용 파싱 하기(BeautifulSoup 그리고 한계)

12. 자동화 - 웹 자동화(with Selenium)

13. 자동화 - 윈도우즈 GUI 자동화(with pywinauto)

14. 자동화 - 작업 자동화

15. 수학 라이브러리 살펴보기

16. 그래픽 라이브러리 살펴보기

17. 머신러닝에서의 파이썬의 역활

18. 웹 프로그래밍 - Legacy Web

19. 웹 프로그래밍 - Flask 살펴보기(feat. d3.js)

20. 웹 프로그래밍 - Django 살펴보기

21. 정리 - 이런저런 이야기

 

 

 

 

[들어가면서]

  여러 웹사이트와 블로그들을 돌아다녀본 결과, 보통 두 가지 입장이 눈에 많이 뜨이는 것 같다.  한 측면은 수학이나 통계학에 대한 경험을 보유하고 있는 상태에서, R이나 매트랩 등의 연구 목적의 툴을 쓰다가, 좀더 일반적인 머신러닝 프레임윅에 관심을 가져 길을 가다보니, 파이썬 같은 범용 프로그래밍 언어를 해야될 필요성을 느끼게 되어 본격적으로 프로그래밍의 세계에 발을 들여 놓게 되는 경우 이다.

 

  다른 한 측면은 프로그래밍, DB, 보안, 시스템 등의 기술적인 업무 등을 하는 입장에서 머신러닝 책이나 강의를 찾아 보다보니, 원리를 설명하는데 사용하는 선형대수, 통계 그리고 RNN 같은 낯선 이론들을 만나게 되고, 책이나 강의를 이것저것 봐도 머신러닝 라이브러리를 작동 시키는 부분은 대충 따라 할 수 있을 것 같은데, 해당 도메인에 대한 부족한 이해 때문에 전체적인 그림이 그려지지 않고, 어떤 원리로 그런 일들이 가능한지, 어떤 데이터를 가져다 어떻게 가공해야 하는지 대해서는 여전히 모호한 상태임을 느끼게 되어, 수학이나 통계 분야에 대한 공부를 시작하는 경우일 것이다(저같은 경우는 후자 그룹에 속하는 경우인거 같다).

 

  그런데 사실 그렇게 가지지 못한 지식에 대한 대한 니즈나, 동경에서 공부를 시작한다고 해도, 만족할 만한 끝은 좀처럼 잘 보이지 않게 된다. 왜냐하면 그 동안에 관심이 없었던 상대의 영역의 본질에 접근하기는 쉽지 않기 때문이다. 다른 분야의 예를 들자면 캐릭터를 잘 만들거나 그림을 잘 그리기 위해서 3D 모델링 프로그램, 일러스트레이터, 페인터 등의 그래픽 관련 프로그램을 마스터 하려는 것과 비슷한 접근이라고 느껴진다. 아무리 해당 툴의 메뉴얼을 달달 외고, 기능을 잘 이해해서 쓴다고 해도, 그러한 행위의 본질이라고 할수 있는 미학적, 공간적인 감각을 기르는 경험들이 부재한다면, 그러한 노력이 올바른 결실을 맺긴 힘들다고 본다.

  

  마찬가지로 현재 올렸던 글들을 계속 읽어오신 분들은 공감하셨겠지만, 프로그래밍 이란 것은 단지 가시적으로 보이는 코드란 측면에 국한된 지식은 아니다. 외국어를 배울때 그 나라의 문화를 같이 이해해야 자연스럽고 맥락에 맞는 표현을 할수 있게 되는 것처럼, 머신러닝을 받치고 있는 프로그래밍 지식은 파이썬이란 언어 자체에서 출발하여 해당 언어가 동작하는 OS, 네트워크 등의 여러 주변환경과, 데이터를 담는 빅데이터 시스템 등 기술 생태계 전체가 포괄적으로 엮여 있다고 생각한다. 그래서 스펙트럼이 넓을 뿐만 아니라, 인기가 좋아 급속히 성장하며 확장되는 기술 영역들이 의례 그렀듯이 자료들이 초보자들에게 그다지 친절하게 정리되어 있진 않고 계속 변하기 때문에 접근 난이도가 높은 편인 것 같다. 물론 서로 다른 문화가 그렇듯이, 서로 다른 분야 사이에도 자신의 분야의 경험을 기반으로 유추할 수 있는 비슷한 공통 개념들도 많긴 하지만 말이다.

 

  잘은 모르지만 반대로 프로그래밍 영역과 비슷하게 짐작해 보면, 수학이나 물리, 통계 등의 분야도 단순히 보이는 이론과 수학적 지식들이 전부는 아닐 것 같다. 그 학문을 오래 접했던 사람들만이 가질 수 있는 특유의 사고 방식과 문제에 대한 접근법, 데이터와 숫자를 보는 시야나 감을 얻는다는 것은 단순히 통계나 선형대수 책을 공부하는 것과는 좀 많이 다른 일이 아닌가 하는 생각이 든다. 

 

  그래서 어떤 측면에서는 한 사람이 모든 부분을 다 잘 알순 없기 때문에, 효율성을 위해서는 데이터를 다루는 직군, 모델과 알고리즘을 다루는 직군, 프로그램을 관리하는 직군을 따로 나누어 조직해야 한다고 하는 주장도 있지만, 뭐 그런 경우라도 서로서로 상대방이 하는 일을 이해하면서 일을 하면 효율적이기도 하고, 이해 타산을 버리고 순수하게 공부하는 현 시점에서는 무시하기로 하자. 이 시간엔 조금이라도 머신러닝이라는 분야가 정밀한 숫자, 연관된 수학, 복잡한 통계이론을 차지하고도 합리적인 활동으로 보일 수 있는지 생각해보자.

 

 

 

 

[머신러닝이 하는 일에 대해 상상해보기]

  우선 어떻게 기계가 학습을 할수 있다는 것을 직관적으로 이해할 수 있을까? 기계가 학습을 한다는 것은 기계가 사람처럼 알고리즘을 만드는 작업, 즉 프로그래밍을 할수 있다는 얘기다. 예전부터 자동으로 프로그래밍을 짜는 일은 인간의 창조적인 능력의 한 부분이라고 믿어왔고, 여러가지 쉽고 자동화된 프로그래밍 툴을 만들려는 시도가 많이 실패 해 온것으로 알고 있는데, 모두 인간의 자만이였을뿐일까? 개인적인 생각으로는 기계가 학습하여 프로그래밍을 한다고 하는 부분은 사람이 프로그래밍을 하는 부분과는 다르면서도 동일한 모순적인 측면이 있다고 본다.

 

 

  예를 들어 하나의 프로그래밍 로직에 대해 생각해 보기 위해, '1교시 언어를 바라보는 방법'에서 보았던 아래 그림을 다시 한번 보자.

 

  당연한 얘기 같지만 모든 목적을 가진 프로그램은 입력과, 출력을 가지고 움직인다(실행 시점에 인자가 전달되지 않는 프로그램도 실행 시 시스템과 입력과 출력을 하고 있다고 볼수 있을 것이다). 그럼 프로그래머가 작성한 프로그램이 내부적으로 입력에 항상 3을 곱한 후 1을 더 해서 결과를 보여주는 프로그램이라고 해보자. 초등학교 수학식으로 나타내면 'y=3x+1' 일 것이다. 파이썬 식으로 나타내면 아래와 같다.

1
2
3
4
.... 입력으로 x 가 들어옴.
 
= 3x + 1
print (y)
cs

 

  근데 우리가 해당 로직을 이해할 수 없는 상태에서(곱하기가 엄청 고차원 적인 수학이라고 가정해 보자), 사람들이 해당 프로그램을 사용해서 쌓인 충분히 많은 입력-출력 쌍 데이터가 있다고 해보자. 예를 들면 (1, 4), (4, 13), ... (10000, 30001) 같은 형태일 것이다. 해당 데이터를 관찰해 보면 결과 데이터의 경우는 입력 데이터에 사람이 만든 어떤 프로그램 로직(여기서는 x*3 +1 )이 들어가 만들어지는 것이라고 볼수 있을 것이다.

 

  그럼 반대로 만약 어떤 임의의 시스템이 x 입력을 받아 y를 출력을 나타내는 것을, 위의 수집한 데이터에 대해서 최대한 높은 '옳음'으로 처리할 수 있다면, 해당 시스템의 속이 어떻게 생겼는지 상관없이, 해당 시스템은 사람이 작성한 위의 프로그램과 근사적으로(어쩌면 극한적으로) 동일한 자동화 프로그램이라고 할 수 있을 것이다(모든 사칙연산 데이터를 그대로 흉내내는 머신러닝 모델을 상상해 보자. 사람이 만든 계산기와 비슷하다 볼수 있지 않겠는가?).  

 

  즉 데이터 측면만을 보면 충분한 규모의 객관적으로 수집된 입력과 출력 데이터가 있고, 그 안에 현상을 왜곡하는 가짜 데이터가 무시할 만큼만 존재하고(또는 모델내에 그러한 데이터를 걸러내 무시하는 안전장치가 있어도 되고), 그 데이터들이 뭔가 사람이나 현상의 의미있는 활동을 나타낼 가능성이 있다면, 해당 데이터에는 사람이 논리적으로 파악하긴 힘들 수도 있지만, 그 데이터 쌍들을 만들어낸 로직을 포함하고 있다고 볼수 있지 않을까 싶다. 

 

 

  충분한 규모의 객관적인 입력과 출력 데이터 쌍은 비즈니스, 데이터 분석과, 빅데이터의 도움으로 이루어 진다고 보면 될것 같고, 가짜 데이터의 제거 부분은 비즈니스, 데이터 분석, 노이즈에 강한 모델 등을 포함해 모든 동원할수 있는 방법이 다 포함 될수 있을 것 같고, 입출력 데이터들 자체에 숨어있는 로직이나 패턴을 적절한 필터를 써서 참기름 짜듯 뽑아내는 것이 여러 머신러닝 알고리즘과 모델의 앙상블이라고 생각해보면 어떨까 싶다.

 

  그래서 사람이 가진 논리적 기술로 데이터를 가공하지 않고, 머신러닝 알고리즘(물론 이것도 넓은 범위에선 논리인것 같다)이 데이터 안의 로직이나 패턴을 추출해 내는 과정을 '기계학습'이라고 명명 지은게 아닌가 싶다. 로직을 짜내는 과정에서, 해당 머신러닝 필터는 데이터에 커스터 마이즈된 특정한 모양(모델이 데이터에 커스터마이즈 된 부분을 얘기하는지, 데이터에 독립된 필터를 얘기하는지는 좀 아리송 하긴 하긴 하지만. 현재로서는 왠지 모델 자체에 데이터의 숨은 로직의 특성도 포함되는거 같다)을 가진다. 이후 이 특정한 모양으로 커스터 마이즈된 필터를 향후 들어오게 되는 같은 타입의 새 데이터에 적용하게 되면, 사람이 프로그래밍 하지 않아도 기존 결과 데이터와 비슷한 로직의 영향을 받은, 결과 데이터를 만들어 내게 되지 않을까 싶다.

 

  그 후 일반적으로 만들어진 모델을 검증하기 위해서, 보통 전체 데이터셋을 트레이닝셋과 검증셋으로 적당히 나누어 트레이닝셋으로 훈련을 시킨 후에 검증셋으로 실제 경기를 진행 하게 한다. 트레이닝 셋은 일종의 원어민 회화 이고, 검증셋은 실제 다른 외국인에게 배운걸 시도 하는거라고 생각해봄 이상할까--; 

 

 

 

 

[몇가지 문제 들]

  머신러닝이 입력과 결과 데이터 사이에 숨어있는 로직을 뽑아내는 작업이라는 것이 어느정도 맞다는 가정에서, 몇가지 머리가 아픈 모호한 문제들이 발생할 수 있다.

 

 

  1번째 문제는 'garbage in garbage out' 이다. 어떤 우수한 머신러닝 모델이라도 좋은 데이터를 공급해 주어야 좋은 알고리즘을 추출해 준다는 것이다. 정신건강의학과 의사가 상담을 하는데, 환자가 거짓말만 늘어 놓는다면 어떻게 될까? 아무리 실력있는 의사라도 환자의 마음의 병의 원인에 대해서 잘못된 판단을 하게 될것 이다(물론 정말 뛰어나다면 거짓말을 한다는 것 자체를 눈치채고 진실을 얘기하도록 유도할 수도 있겠지만^^). 그럼 이러한 가짜 데이터들은 왜 들어 가게 될까?

 

  우선 충분히 신뢰할 만큼 데이터 양이 많지 않거나 특정 군으로 편향될 수도 있다. 우리가 매번 선거 시기에 듣는 여론 조사용 표본 데이터의 중요성이다. 게임센터를 들어가는 학생 10명의 의견을 듣고 우리나라 전체 학생이 어떤 생각을 가지고 있다라고 말하는 것은 의미 없을 것이다. 근데 사실 현실적으로 충분히 좋을 정도라는 표현은 참 추정하기 힘든 일인거 같다. 충분히 좋을 정도의 개발, 충분히 좋을 정도의 테스트 같이, 잘은 모르지만 통계적으로 의미 있는 충분한 데이터 라는 것도 약간은 바라보는 관점에 따라 애매한 영역이지 않을까 생각해 본다.

 

  다른 원인은 노이즈이다. 만약 누군가 사실을 들키는 것이 창피해서 속마음과는 다른 가짜 선택을 했다면? 데이터를 취합하는 과정에서 잘못된 정보들이 우연히 섞여졌다면? 쇼핑몰에서 연령대별 분석을 하는데 회원들의 아이디들을 가족이 모두 공유해서 사용하고 있다면?(뭐 예를 들어서 회원제인 코스트코 같은데는 지인이 부탁한 물건을 사다주는 사람도 많을거 같다) 해커가 들어와 정보를 본인에게 유리하게 몰래 변경했다면? 해당 데이터의 형태가 애초부터 랜덤적인 선택 요소가 표함되어 있다면? 등등.. 다양한 일들이 생길 수도 있다. 또는 아래의 알렉사 기사처럼 TV 에서 나온 음성 같은 외부 테이터를 잘못 받아들여 엉뚱한 판단을 하게 될지도 모른다.(뭐 홍채나 얼굴 인식이 사진으로 된다든지 하는 것도 비슷한 경우일 것이다) 

http://thegear.co.kr/13718

 

   

  2번째 문제는 데이터 무더기 에서 학습을 위해 제공하기 위해 골라낸 요소들이, 정말 해당 현상을 제대로 설명하는 인자인가 하는 문제이다. 어떤 인자는 혼동만 주는 필요 없는 인자일 수도 있고, 어떤 중요한 인자는 빠져있을 지도 모른다. 최악의 경우는 현재 수집을 안하고 있거나, 현실적으로 수집을 못하는 요소일 지도 모른다. 데이터를 제대로 이해 못하고 머신러닝 모델에게 전달한다는 것은, 사람이 비즈니즈 룰도 이해를 못하고 프로그래밍을 하는 것과 그닥 차이가 없을 것이다. 로직은 돌아 갈테지만 아마도 아무 의미도 없거나 재앙일 것이다.

 

  또는 데이터의 범위를 잘못 잡은 학습을 할수도 있다. 예를 들의 앞의 예가 아래와 같은 로직으로 동작하는데, 현실로 수집가능한 데이터가 10000 까지 였다면, 해당 데이터로 학습된 모델은 10000 을 넘어가는 데이터를 만날때 커다란 재앙을 안겨줄 지도 모른다(버퍼 오버플로우 처럼 말이다).

1
2
3
4
if input <= 10000:
    우리가 수집한 데이터(0~10000)가 적용된 로직
else:
    새로운 타입의 데이터가 생성됨
cs

 

  비슷하게 여론 조사 결과 조작이나, 통계의 여러 부작용 처럼, 데이터의 어떤 집합, 성질을 선택 하느냐에 따라서 의도된 답을 선택하거나 실제와는 다른 결과를 보여줄 수도 있을 듯 싶다. 

 

 

 3번째 문제는 학습된 모델을 실제 현실에 적용할수 있느냐 하는 문제이다. 자율자동차와 같이 운전자의 보호냐 보행자의 보호냐를 선택하는 문제일 수도 있고, 99.9999% 의 정확도라도 false-positive(안전하다고 판단했지만 실제로는 위험함) 가능성이 존재하는 한 실수에 대한 윤리적 문제가 일어날 수 있다. 예로서 머신러닝 기반의 의료검사를 신뢰 하다가 드문 케이스 때문에 암을 놓쳤다고 해보자. 시스템의 정확도가 엄청 높고, 해당 경우의 데이터가 트레이닝 데이터에 포함되지 못한 정말 운이 없는 경우기 때문에 어쩔수 없다라고 할수 있겠는가? 이런 분야라면 의사가 먼저 체크 후 괜찮다고 판단한 환자를 머신러닝으로 2차 체크 하여, 의사의 실수를 줄이는 방식으로 이용하는 등의 사람들이 납득할 수 있는 합리적인 기술 적용 프로세스가 필요하다. 그래서 어떤 사람들은 머신러닝을 기존 기술의 대체제가 아닌 보완제의 관점에서 접근하기도 한다.

 

 

  마지막 문제는 아마도 모델의 오차와 별개로 우리가 가지고 있는 데이터 자체가 제공된 시점부터 이미 실제 진실과는 조금은 차이가 날 수 있을지 모른다는 것이다. 사람들의 해당 데이터를 만들게된 모든 이유를 다 이해한다면 모르지만, 그런 전지전능함을 가지지 못한 우리는 데이터에 담긴 fact 만을 믿어, 중요한 사실을 놓칠지도 모른다. 마치 우리가 매일 만나는 사람이 겉모습과는 다른 속마음을 가질 수 있는 것과 비슷하게 말이다. 또한 해당 진실은 해당 시간대에서만 유효했을 수도 있다. 시간이 흐름에 따라 다른 영향을 받을 수도, 또한 아예 해당 데이터는 시간에 따라 변화를 하는 데이터일 수도 있으니 말이다.

 

 

  그래서 알파고가 바둑이나 스타크래프트 같은 분야를 선택한건 아주 영리한 선택이라고 생각한다. 현실의 데이터가 왜곡되듯이 바둑기사가 불리하다고 바둑알을 속이거나 바둑판을 엎는 일 따위는 없을 테니까 말이다. 또한 바둑과 같은 테이블 게임은 경우의 수는 무한대일지 모르겠지만, 바둑 룰과 선의 공간, 그리고 승리라는 목적으로 닫힌 세상이라는 부분은 그 무한대 성을 많이 제한해 주며, 데이터의 무결성을 보장하는데 오픈된 분야보다 많이 유리하다고 생각한다(게임이란건 사람의 이해 가능성을 전제로 성립될 수 있기 때문에 무한에 가깝다곤 하지만 어째든 제한은 있다고 본다. 다만 해당 부분은 효율적인 승리의 관점에서 제한된다는 거지, 바둑의 철학적 관점에 대한 제한을 얘기하는 것은 아니다). 그것은 다음에 도전할 지도 모른다는 스타크래프트 같이 현재 머신러닝이 강세를 보이고 있는 게임 분야도 비슷할 듯 싶다. 아무리 자유도가 높더라도 게임 분야는 사람이 흥미를 가지도록 방향이 제한되고, 추출해야될 로직들이 머물고 있는 데이터들에게 비교적 안전한 닫힌 세상이라고 생각한다(뭐 그렇다고 쉽다는 얘기가 아니라 real world 에 비해서 상대적으로 그렇다는 의미다. 그리고 부루마블 같은 주사위와 황금열쇠라는 랜덤요소를 가지는 게임 같은건 좀 다른 문제일 것이다). 어떤 기사의 마지막에서 살짝 언급했듯이 알파고의 승리의 숨은 주역은 뒤에 적절한 장르와 데이터를 선택하고, 적절한 알고리즘으로 학습시킨 과학자 들이라는 말이, 물위를 헤엄치는 오리의 바쁜 발을 떠올리게 된다.

 

 

 

 

[기술적인 미래]

  이왕 이것저것 얘기를 한 김에, 앞으로의 머신러닝 기술이 어떻게 될까도 추측해 보자. 빅데이터 분야의 진행을 기반으로 추측해보면, 처음에 나온 하둡이 hive 나 pig 같은 좀더 쉬운 작업을 가능케 하는 프레임윅들로 감싸지듯이, 현재 같이 하나하나 이해하며 초기 값 및 모델, 제어 요소들을 조정해, 좀더 빠르고 높은 정확도의 결과를 얻으려 하는 부분은 점차 통합되고 자동화된 로직으로 대체될 가능성이 높을 듯 하다. 군웅할거중인 머신러닝 프레임윅들도 한두개의 강력한 범용 프레임 윅과, 몇개의 특수 프레임윅들로 정리되지 않을까 생각한다(안 쓰는 애들은 버려지니...). 여튼 머신러닝 기법을 사용하는 방법은 점점 쉬워지며 블랙박스로 감싸질 것 같다. 이런 부분이 많은 강의 하는 분들이, 관련 수학을 깊게 몰라도 머신러닝을 배우는덴 무리가 없다고 강조하는 측면인 듯 싶다. 우리가 기계공학을 몰라도 자동차를 운전할수 있듯이 말이다.

 

  물론 머신러닝 분야의 알고리즘 개발에 발을 담그고 있는 분들이나, 좀더 디테일하며 컨트롤을 원하는 분들은 껍데기 안쪽을 다루기 위해서 좀 더 깊게 이해하려 하는게 맞을 수도 있지만, 어느 정도 깊이로 이해하려 하는지는 좀 생각해 볼 문제 같다. 깊이 문제도 수학식이나 통계 공식의 논리적 정확성의 증명에 너무 집착하다보면 원래 그 식이 얘기하려고 했던 이미지나, 본질을 놓칠수도 있으니까 말이다(공부하기 싫어서 하는 얘긴 아니다^^). 수학은 연산보다는 그 연산이 무엇을 의미하는지를 이해하는게 더 중요한 듯도 싶다. 그리고 아마도 커다란 메이저 회사들이 필요한 프로그래밍 기술들을 머신러닝 프레임윅 안 쪽에 쉬운 인터페이스로 구현해 놓음으로서 현재의 프로그래밍 성격의 장벽은 점점 낮게 될 것 같다. 물론 어려운건 마찬가지 겠지만 현재보다 상대적으로 쉬울수 있다는 얘기긴 하다. 또한 개인이나 자그마한 기업들은 유용한 데이터 자체를 수집하기 힘들수도 있기 때문에 일반적인 분야에 대해서는 1+1 상품처럼 데이터와 학습된 머신러닝을 같이 묶어서 제공하는 부분들도 늘어날 것 같다. 지금 한참 관심을 받고 있는 음성이나 이미지 인식 분야 같은 인류의 공공재 분야에서 말이다.

 

 

  그리고 반대로 생각해 보면 미래에도 개선되기 힘들 것 같은 부분들이 있다. 우리가 비즈니스를 이해하고, 적정한 테이터를 디자인해 수집하고, 학습에 필수적인 값들을 뽑아내고, 머신러닝이 추출해낸 반투명한(뭐 RNN 같은 신경망 이론인 경우는 가중치 들이 왜 그런지 사람은 이해하기 힘들 듯 하다) 로직들이 맞는지를 이해하고, 오차의 본질을 이해해 모델을 조정하는 능력이다(원석을 감정하는 능력이라고 할까..). 또 문제를 파악하고 적절한 기법(알고리즘과 모델)을 선택하는 것도 오랜기간은 수학적, 통계적 기법을 잘 아는 사람들의 손을 대부분 필요로 하지 않을까 싶다. 물론 프레임 윅들이 여러가지 시각화 툴을 통해, 해당 작업을 많이 도와줄 것은 같지만 말이다. 또 아마 지금의 장미빛 전망의 끝이 지나면, 자동화된 프로그램이 못하는 분야에 대해 다른 해결을 원하는 새로운 장르가 생겨날 것도 같다(어차피 현재의 로직으로도 해결 못하는 문제는 많으니까. 왠지 머신러닝은 로직을 벗어난 로직이라 그러한 부분을 일부 해결해 줄것은 같다). 

 

  현재 트레닝셋과 검증 셋으로 나누어, 리그레이션 테스트와 비슷하게 신뢰도를 확인 하는 방법은, 뭔가 약간 너무 낙관주의적인면(출처가 같은 트레이닝과 검증 데이터가 무조건 옳다고 가정하는 측면에서)도 있다고 느껴지기 때문에, 수집을 포함한 전체적인 데이터 케어 관점에서 추출된 로직에 대해 테스트 및 검증 하거나, 구성된 시스템의 여러 부분과 보안적인 측면을 검토하는 검증 활동 영역도 활성화 되지 않을까 싶다. 다만 머신러닝으로 추출된 로직은 프로그래머가 만든 로직과 다르게 명확히 알수 없으므로(그래서 앞에서 반투명이라고 표현했다), 모순적으로 알고리즘과 모델을 이해해야 최소한의 검증이 가능하므로 기존에 일반적인 테스팅이나 보안 활동을 하던 사람들이 접근하기는 장벽이 높은 분야 같기도 하다.


  결과적으로 머신러닝은 데이터를 기반으로 현대의 많은 과학 분야가 그렇듯이 완전한 해에 대한 실용적인 근사로 나아가는 로직이다(퍼펙트할수 있는 예외는 일부 게임과 같이 닫힌 세상의 데이터 일 것이다). 프로그래머들이 프로그래밍 언어를 통해 기호로 분리해 놓은 논리 기호들을 녹여 다시 새로운 기호를 만드는 느낌이라고 할까? 그래서 머신러닝을 바라볼때는 수학이나 통계학을 기호의 학문이 아닌 알고리즘을 구성할 레고의 블록(블랙박스적 도구)으로 바라보는 접근법도 어떨까 싶다. 실제로 우리가 파이썬을 할때도 모든 세세한 라이브러리의 내부 로직까지 모르면서 사용하는 것과 비슷하게 말이다.

 

  왠지 헤메고 있는 사람을 더 복잡하게 만드는 어설픈 얘기들을 늘어놨는지도 모르겠지만^^;, 이런저런 블로그를 돌아다니다가 알게되어 읽어봤던 몇 가지 괜찮았던 머신러닝의 '주변영역'을 건드리는 책들을 소개하면서 생각의 나래를 마무리 하려 한다. 혹시 위의 생각에 조금은 일리가 있다고 생각하시는 분들은, 아래의 책들과 함께, 아래 링크의 유투브의 유명한 '모두를 위한 딥러닝 강좌' 를 보시고, 이후 스스로 자기가 갈 공부 방향을 선택하시면 될것 같다.

https://www.youtube.com/playlist?list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm

 

  • 틀리지 않는 법 : 수학적 사고의 힘 (현실을 심리학, 경제학으로 해석하는 대신 수학으로 해석해 보며 수학적 접근법의 한계도 얘기 한다. 은근 그 과정에서 머신러닝의 한계 또한 생각해 보게 되는 듯 하다)
  • 화이트헤드의 수학이란 무엇인가(앞의 수학 라이브러리의 복소수 파트에 대해 아이디어를 얻은 책이다. 왜 이런 수학 장르가 생겨나게 됬을까를 찬찬히 생각하게 하는 책 같다. 수학과 별로 안 친한 저와 비슷한 레벨이면 이해가 안가서 살짝 넘겨야 되는 수학적 개념들이 좀 있다)
  • 마스터 알고리즘 (머신러닝에 대한 얘기다. 해당 분야를 오래 경험해온 전문가가 세상에는 5종류의 머신러닝에 대한 접근방식들이 있고, 그들을 조화시킬 궁극의 알고리즘이 있을수 있다는 얘기를 한다. 이 책을 읽게 되면 머신러닝 책들이 왜 그렇게 여러 주제의 잡학 사전처럼 구성되어들 있는지 이성적이면서 감성적으로 수긍이 되게된다)
  • 헤드 퍼스트 통계학 (통계를 직관적으로 설명하려는 시도를 한다. 뒤로 갈수록 직관성이 사라지고 수학만 남는 아쉬움이 있다--;)
  • How to solve it (어떻게 문제를 풀어나가느냐에 대한 책이다. 문제 풀이에 대한 접근 방법을 얘기하는 책이고, 학생들에게 어떻게 수학을 가르치느냐에 대해 얘기하는 책이지만, 어려워서 이해가 안가는 문제들이 종종 있음에도 읽을 가치가 있다. 이 수업의 방향이 이 책 영향을 좀 받은듯 하다^^;) 
  • CODE 코드 : 하드웨어와 소프트웨어에 숨어 있는 언어(이건 프로그래밍 공부가 의미 없게 느껴지는 분들을 위해서 덤으로~ 불빛 신호에서 컴퓨터가 만들어지기 까지의 과정을 설명한다. 중간에서 길을 잃어 필름이 끊기더라도 읽어볼 가치가 있다고 본다. 비 전공자한테는 생각보다 어려울지도 모르지만, 해당 책의 저자가 비전공자도 읽을 수 있도록 노력해 쓴 책이고 파이썬 공부를 하고자 하는 의지 정도만 있음 가능할 듯 싶다.)

 

[몸풀기 - 공학 라이브러리의 푸리에 변환]

   머신러닝을 하다 갑자기 이름도 낯선 푸리에 변환이란 것이 나오게되서 이상하게 생각할지 모르겠지만, 이 라이브러리를 소개하는 이유는, 머신러닝 라이브러리가 특별한 형태의 라이브러리라는 생각을 버리게 하고 싶어서 이다. 그리고 지금 소개하는 라이브러리를 잘 보면 왠지 머신러닝 라이브러리랑 닮아있다는 느낌도 있어서 이다. 그래도 맘에 안든다면 opencv 라는 이미지 라이브러리(정확하게 얘기함 컴퓨터 비전 쪽 라이브러리)를 살펴보는 부록 챕터라고 생각해도 좋다.

 

  푸리에 변환은 보통 전자기파 쪽에서 많이 쓰는 이론으로, 저도 수학적으론 잘 모르지만, 모든 주기를 가지는 신호는 사인과 코사인의 합으로 분리해 나타낼 수 있다는 이론이다(우리가 쓰는 스마트폰의 통신들도 이런 이론들 땜에 가능하게 됬다) 그러다보니 분리된 사인, 코사인 함수들의 주기를 보면, 해당 신호가 어떤 주파수(1초에 몇번 지그재그로 움직이나. 2.6G 와이파이의 경우 1초에 2억 6천번 파형이 움직인다)들을 포함하고 있는지 알게된다. 뭐 주기가 없는 신호도 무한대의 주기를 가졌다고 가정해서 변환하는 신묘함도 있다.

 

  근데 묘하게 이걸 그림에 적용하면, 그림에 분포되 있는 명암 요소에 따라서 주파수 영역으로 변환할 수 있다(사실 정확히 설명하기 위해 이리저리 사이트 들을 찾아봤는데, 그림의 평균적인 명암값 으로부터의 차이를 가지고 판단하는지, 경계 값과의 변화정도 인지 기준을 잘 모르겠다. 아시는 분은 댓글에 좀 --;). 여튼 그렇게 그림에 푸리에 변환을 적용해 정리하면, 그림과 동일한 2차원 영역의 주파수 그림이 나오는데, 중심 부분에 가까울 수록 그림에서 주로 면이라고 얘기하는 색이 비슷한 공간속의 점들의 정보를 가지고 있고, 중심에서 멀어질 수록 그림의 외곽선 이라고 부르는 경계를 구분해 주는 점들의 정보를 가지고 있다. 

 

  그래서 그림을 읽어와 푸리에 변환을 해서 나온 네모난 주파수 평면에서, 가운데 원 영역의 값을 0 값으로 덮어 지워버리면(보통 마스킹 한다고 한다. 밑의 그림 처럼 까맣게 정보를 없앴다), 그림의 외곽선 정보만이 남는 효과를 가져오게 된다(약하게 삭제하면 sharpening effect 가 되는듯 하다). 그것은 뭐 포토샵 같은 전문 프로그램에선 더 정밀한 로직을 쓰겠지만, 이 로직을 적용하면 어떤 그림을 적용하든 동일한 윤곽선 추출 효과를 가져온다(마치 학습된 머신러닝 로직이 데이터에 동일한 효과를 가져오는 것처럼 말이다)

 

 

 

  그럼 예제를 보자(요건 머신러닝 예제가 아니라 구글을 헤맨 과정은 생략한다^^). 일단 컴퓨터에 있는 사진 등을 복사해도 좋고 적당한 이미지가 없다면 무료 사진 사이트인 https://pixabay.com/ 로 가서 이미지를 하나 다운 받아서, c:\python\code 폴더에 mypic.jpg 라고 저장한다.

 

  그리고 opencv 를 설치해야 되는데 불행하게도 python 3.5 버전은 pip 인스톨이 안되는 듯하다. https://www.solarianprogrammer.com/2016/09/17/install-opencv-3-with-python-3-on-windows/ 사이트에서 안내하는 데로, http://www.lfd.uci.edu/~gohlke/pythonlibs/ 사이트로 가서, opencv_python-3.2.0-cp35-cp35m-win_amd64.whl 를 다운받아(가끔 파일이 이름이 바뀌어서 그런데 cp35 가 파이썬 3.5란 의미이고, amd64가 64비트 윈도우이다.) c:\python\code 에 넣고, 아래와 같은 명령어로 whl 파일을 설치했다. whl 파일이 무언가는 예전 시간에 설명했다~

(참고로 어떤 블로그 보다보니 python 3.6 버전에서는 pip 로 그냥 설치가 되는걸 보긴 했다)

 

c:\Python\code>pip install opencv_python-3.2.0-cp35-cp35m-win_amd64.whl
Processing c:\python\code\opencv_python-3.2.0-cp35-cp35m-win_amd64.whl
Installing collected packages: opencv-python
Successfully installed opencv-python-3.2.0

 

 

 그럼 예제를 위해 만든 소스를 구글에서 'python opencv fft low pass filter image' 라고 찾아서, 돌려보다 보니 python 2를 기준으로 만든거라서 나누기 코드 부분에서 문제가 생겨서(나누기 후 결과를 integer 로 취급할거냐 float 로 취급할거냐가 버전이 올라가면서 달라졌다), 아래의 사이트를 찾아, 코드를 조금 수정했다.

[소스 사이트]

http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_transforms/py_fourier_transform/py_fourier_transform.html

 

[에러 메시지와 해결 사이트]

TypeError: slice indices must be integers or None or have an __index__ method 에러

https://stackoverflow.com/questions/28272322/typeerror-slice-indices-must-be-integers-or-none-or-have-an-index-method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import cv2
import numpy as np
from matplotlib import pyplot as plt
 
# 이미지를 읽어옴
img = cv2.imread('mypic.jpg',0)
 
# 푸리에 변환 하고 이런저런 맞춤
= np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))
 
# 작은 마스크를 만들어서 푸리에 변환한 영역의 가운데를 지워 버림(하이패스 필터)
rows, cols = img.shape
crow,ccol = rows//2 , cols//2
fshift[crow-30:crow+30, ccol-30:ccol+30= 0
f_ishift = np.fft.ifftshift(fshift)
 
# 다시 이미지로 역변환
img_back = np.fft.ifft2(f_ishift)
img_back = np.abs(img_back)
 
# 그림으로 보여줌.
plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_back, cmap = 'gray')
plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
 
plt.show()
 
print ("ok")
 
cs

 

 

  언제나 처럼 c:\python\code 폴더에 'python opencv_fft_sample.py' 란 이름으로, 파일형식은 '모든 파일'을 선택하고,  인코딩은 'utf-8' 로 저장하고 실행한다.

c:\Python\code>python opencv_fft_sample.py
ok

 


  위와 같이 그림이 세개 나오는데 왼쪽이 원본 이미지, 가운데의 빛이 가운데 모인듯한 이미지가 푸리에 변환을 통해 주파수 영역으로 변환된 이미지, 오른쪽이 주파수 영역의 가운데 데이터를 삭제하여(코드안에 로직이 있다). 다시 이미지로 복구하였을때, 주로 경계선 요소들만 남기고 평면 요소들이 사라진 경우이다.

 

  보시면 푸리에 변환이 왠지 머신러닝과 비슷한 느낌이 들지 않는가?(머신러닝은 사실 데이터를 적절히 해석해 내부 특징을 얻을 수 있는 모든 알고리즘 들을 가져다 쓴다고도 할수 있다) 차이라면 데이터에서 로직을 추출하진 않는다. 하지만 데이터를 넣으면(디지털 이미지 또한 좌표 기반의 데이터 이다) 임의의 처리를 해서 데이터에 특정한 특징을 노출해준다는 부분에서 왠지 비슷하다는 느낌이 들어 굳이 이 시점에 소개했다. 그럼 실제 머신러닝 로직으로 가보자.

 

 

 

 

[최소제곱법 이란]

  많은 머신러닝 및 데이터 분석 책에서, 제일 처음에 나오는게 회귀분석이고(과거의 데이터를 기반으로 미래의 데이터를 예측함), 그 중 가장 먼저 나오는게 최소 제곱법 같다(이후는 최우추정법, 베이즈 같은 낯선 이론들이 나온다). 디테일한 의미를 다 알진 못하지만 개념적으로만 근사한다면, 해당 컨셉은 제공되는 데이터들로부터 가장 가까운 어떤 선(직선 or 곡선 : 사실 직선은 곡선의 한 형태 일 것이지만)을 찾기위해서, 선과 데이터 들의 수직 거리를 제곱한 값들의 합이 제일 작아지는 선을 나타내는 방정식의 상수들을 찾는 것이다. 즉 직선이라고 가정한다면 y = ax + b 의 a, b 값을 계속 특정 방향으로 조금씩 변화해 가면서, 각 점과의 거리를 제곱한 합이 제일 작아지는 지점을 찾는다(엑셀의 추세선이라고 봐도 될것 같다). 뭐 자세한 내용은 관련 책이나 블로그 등에서 보시라고 하고 살짝 넘어간다 --; 

    

 

 


[numpy 에서의 최소제곱법 구현]

  원래 numpy 는 계획에 없었는데, 찾다보니 있어서 다른 라이브러리와 비교를 위해서 넣게 되었다.구글에서 'linear least square fit python' 라고 찾아 아래의 페이지를 찾는다.

https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.lstsq.html

 

  이후 적당히 편집하여, y = 3x + 1 의 공식에 맞도록 x, y 값을 바꿔 넣었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import numpy as np
import matplotlib.pyplot as plt
 
# x, y 좌표 지정(y = 3x + 1), 방정식 모델 지정
= np.array([1257])
= np.array([471622])
= np.vstack([x, np.ones(len(x))]).T
 
# 선형대수 라이브러리의 least squre 호출
slope, intercept = np.linalg.lstsq(A, y)[0]
print("기울기:", slope, ", 절편:", intercept)
 
# 기존 값을 점으로, 찾은 기울기를 선으로 그린다.
plt.plot(x, y, 'o', label='Original data', markersize=10)
plt.plot(x, slope*+ intercept, 'r', label='Fitted line')
plt.legend()
plt.show()
cs

 

  앞 시간의 예제들을 시연해 봤다면 이미 라이브러리들을 설치되어 있을테니(아니라면 설치 방법은 15, 16교시를 참고한다), c:\python\code 폴더에 'numpy_least_sample.py' 이름으로, 파일형식은 '모든 파일'을 선택하고,  인코딩은 'utf-8' 로 저장하고 실행한다(지금보니 utf-8 로 저장하면 한글 주석이 달리는 경우에도 상단에  '#-*- coding: utf-8 -*-' 를 안 넣어도괜찮다). 정상적으로 해를 찾아 기울기 3, 절편 1 을 찾게 된다.

 

c:\Python\code>python numpy_least_sample.py
기울기: 3.0 , 절편: 1.0

 

 

 

 

[scipy 에서의 최소제곱법 구현]

  이번에는 과학 라이브러리인 scipy 를 이용해 보자. 구글에 'linear least square fit python scipy' 라고 찾아 아래의 2개 페이지를 찾아 적당히 믹스 했다. 전체적인 흐름은 numpy 와 거의 같다고 보면 될 듯 하다.

http://www2.warwick.ac.uk/fac/sci/moac/people/students/peter_cock/python/lin_reg/
https://docs.scipy.org/doc/scipy-0.19.0/reference/generated/scipy.stats.linregress.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
 
# 데이터 지정
= np.array([1257])
= np.array([471622])
 
# 데이터에 맞는 값 찾기, Slope: 기울기, Intercept: 절편
slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)
print ("Slope and intercept", slope, intercept)
print ("R-squared", r_value**2)
 
# 데이터를 점으로, 찾은 선과 같이 화면에 표시
plt.plot(x, y, 'o', label='original data')
plt.plot(x, intercept + slope*x, 'r', label='fitted line')
plt.legend()
plt.show()
cs

 

  c:\python\code 폴더 'scipy_least_sample.py' 이름으로, 파일형식은 '모든 파일'을 선택하고,  인코딩은 'utf-8' 로 저장하고 실행한다.

c:\Python\code>python scipy_least_sample.py
Slope and intercept 3.0 1.0
R-squared 1.0

 

  뭐 결과가 같으니 이미지도 동일하다.

 

 

 

 

[tensorflow 에서의 최소제곱법 구현]

  마지막으로 tensorflow 인데, 운이 좋게도 금년에 텐서플로우가 64비트 윈도우 버전의 python 3.5 까지 지원하게 되서 시연이 가능하게 됬다. 근데 뭐 아직 윈도우즈는 텐서플로우에게 관심의 바깥 같은 느낌이 좀 들어서, 텐서플로우를 사용하는 사람들은 보통 리눅스나 맥환경에서 많이 쓰는 것은 같다. 

 

  먼저 pip 를 이용해서 텐서플로우를 설치한다(꼭 윈도우 64비트에, 파이썬 3.5 대 버전이여야 가능하다!. 구글을 찾다 보니 새로 빌드를 해서 32비트에 설치해 쓰는 사람들도 있다고는 한다)

c:\Python\code>pip install tensorflow
Collecting tensorflow
  Downloading tensorflow-1.2.0-cp35-cp35m-win_amd64.whl (21.2MB)
...
Successfully installed backports.weakref-1.0rc1 bleach-1.5.0 html5lib-0.9999999 markdown-2.2.0 protobuf-3.3.0 tensorflow-1.2.0 werkzeug-0.12.2 wheel-0.29.0

 

 

  이후 구글에 'tensorflow least squares matplotlib' 라고 검색하여 아래의 두 페이지를 찾았다.

https://gist.github.com/tomonari-masada/ed2fbc94a9f6252036eea507b7119045
https://github.com/aymericdamien/TensorFlow-Examples/blob/master/examples/2_BasicModels/linear_regression.py

 

  위의 페이지의 예제가 좀더 간단하게 보이지만 텐서플로우에서 생성된 변수(x, y_)를 matplotlib 의 넘겼을때 plot 에서 타입 에러가 난다. numpy 리스트 형태를 넘겨야 괜찮다. 그리고 두번째 예제가 좀 모범답안 같이 전체적인 사용 플로우를 잘 보여주는거 같아서 두번째 예제에서 훈련 후 검증 테스트를 하는 코드 부분만 제거하고, 적당히 편집하면 아래와 같다. (상세 로직은 어차피 텐서플로우에서 하라는데로 하는거니, 전체적인 코드의 흐름을 보자 )

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import tensorflow as tf
import numpy
import matplotlib.pyplot as plt
rng = numpy.random
 
# 파라매터들 변수 조정 수치, 전체 실행 수, 몇 번마다 화면에 로그를 보여주는지
learning_rate = 0.01
training_epochs = 1000
display_step = 50
 
# 훈련용 데이터 지정
train_X = numpy.asarray([1257])
train_Y = numpy.asarray([471622])
n_samples = train_X.shape[0]
 
# 텐서플로우 변수들 만들기
= tf.placeholder("float")
= tf.placeholder("float")
 
= tf.Variable(rng.randn(), name="weight")
= tf.Variable(rng.randn(), name="bias")
 
# 모델 만들기 'y = Wx + b' 를 정의한다.
pred = tf.add(tf.multiply(X, W), b)
 
# least square 공식을 이용하여 최소값을 만들 요소를 지정한다. 
cost = tf.reduce_sum(tf.pow(pred-Y, 2))/(2*n_samples)
 
# 기울기를 보정하는 경사하강법이란것을 사용하고, 비용을 최소화 하는 방향으로 학습 한다.
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(cost)
 
# 초기화?
init = tf.global_variables_initializer()
 
# 텐서플로우 기동
with tf.Session() as sess:
    sess.run(init)
 
    # 데이터 넣기
    for epoch in range(training_epochs):
        for (x, y) in zip(train_X, train_Y):
            sess.run(optimizer, feed_dict={X: x, Y: y})
 
        # 50번 마다 로그 뿌려서 찾는 값 변화를 보여 줌.
        if (epoch+1) % display_step == 0:
            c = sess.run(cost, feed_dict={X: train_X, Y:train_Y})
            print("Epoch:"'%04d' % (epoch+1), "cost=""{:.9f}".format(c), \
                "W=", sess.run(W), "b=", sess.run(b))
 
    # 완료 되면 결과 출력
    print("Optimization Finished!")
    training_cost = sess.run(cost, feed_dict={X: train_X, Y: train_Y})
    print("Training cost=", training_cost, "W=", sess.run(W), "b=", sess.run(b), '\n')
 
    # 찾은 결과 그래프로 보여주기
    plt.plot(train_X, train_Y, 'ro', label='Original data')
    plt.plot(train_X, sess.run(W) * train_X + sess.run(b), label='Fitted line')
    plt.legend()
    plt.show()
cs

 

    c:\python\code 폴더에 'tensorflow_least_sample.py' 이름으로, 파일형식은 '모든 파일'을 선택하고,  인코딩은 'utf-8' 로 저장하고 실행한다.

 

c:\Python\code>python tensorflow_least_sample.py
Epoch: 0050 cost= 0.031498514 W= 3.08722 b= 0.53246
Epoch: 0100 cost= 0.023787469 W= 3.07587 b= 0.593684
Epoch: 0150 cost= 0.017966598 W= 3.06593 b= 0.64688
Epoch: 0200 cost= 0.013570149 W= 3.0573 b= 0.693111
Epoch: 0250 cost= 0.010249456 W= 3.0498 b= 0.73329
Epoch: 0300 cost= 0.007741358 W= 3.04328 b= 0.768208
Epoch: 0350 cost= 0.005847037 W= 3.03761 b= 0.798554
Epoch: 0400 cost= 0.004416286 W= 3.03269 b= 0.824928
Epoch: 0450 cost= 0.003335610 W= 3.02841 b= 0.847849
Epoch: 0500 cost= 0.002519361 W= 3.02469 b= 0.867768
Epoch: 0550 cost= 0.001902884 W= 3.02146 b= 0.88508
Epoch: 0600 cost= 0.001437244 W= 3.01865 b= 0.900125
Epoch: 0650 cost= 0.001085538 W= 3.01621 b= 0.913202
Epoch: 0700 cost= 0.000819894 W= 3.01409 b= 0.924565
Epoch: 0750 cost= 0.000619259 W= 3.01224 b= 0.934442
Epoch: 0800 cost= 0.000467722 W= 3.01064 b= 0.943025
Epoch: 0850 cost= 0.000353270 W= 3.00925 b= 0.950485
Epoch: 0900 cost= 0.000266819 W= 3.00804 b= 0.956967
Epoch: 0950 cost= 0.000201530 W= 3.00698 b= 0.962601
Epoch: 1000 cost= 0.000152215 W= 3.00607 b= 0.967497
Optimization Finished!
Training cost= 0.000152215 W= 3.00607 b= 0.967497

 

  데이터를 보면 1000번을 찾으면서 50번마다 화면에 현재 상태를 출력하라고 했으니 (1000/50) 번 해서 20개의 로그가 화면에 표시된 것을 볼수 있다. Epoch(찾기 반복 횟수), cost 및 optimizer(해 찾기의 목표가 되는 기준 값과, 기준 값을 어떻게 사용할 것인지. 여기서는 최소제곱값 함수가 가장 작아지는 값을 기울기 하강법으로 찾는다). W(기울기) b(절편) 값의 변화를 보면 점점 횟수가 늘수록 기울기와 절편 값들이 의도했던 3과 1로 수렴해 가는 것을 볼 수 있다.

 

  이렇게 비교해 보면 뭔가 전문적인 머신러닝 라이브러리들은 위의 numpy, scipy 같은 일반 선형대수 라이브러리 처럼 결과만 그냥 보여주기 보다는, 모델을 지정하고(pred = tf.add(tf.multiply(X, W), b)), 잘된 학습의 판단기준도 정하고(cost = tf.reduce_sum(tf.pow(pred-Y, 2))/(2*n_samples)), 학습 과정을 살펴보며(로그) 조정하는 듯 체계적인 접근 방식을 유도하고 있다. 뭐 제가 모르는 다른 기능 들도 많겠지만, 꼭 개발쪽의 유닛테스트 프레임윅이 하는 역활과 비슷한 느낌이 든다(저런 프레임윅들은 관련 기능과 함께 조금 논란의 여지는 있지만 'best practice' 를 동시에 제시한다)

 

  matplotlib 으로 그린 그래프 화면은 원래 정답(3, 1)과 비교함 소수점 약간 차이라서, 앞의 2개 그래프와 구분이 안되서 생략했다. 설명의 일관성을 위해 정답을 제한해 놓은게 맘에 안드신다면, 아래와 같이 소스에서 train_X, train_Y 의 배열 값들을 임의의 값으로 바꾸거나 배열 데이터 갯수를 늘여보면 좀더 점들의 중심에 위치하고자 하는 선의 모양을 볼 수 있을 듯 하다. 머신러닝 및 텐서플로우에 이론과 기능에 대한 더 깊은 내용들은 관련 커뮤니티의 강좌나 책을 참고하시면 될듯 하다.

1
2
train_X = numpy.asarray([135912])
train_Y = numpy.asarray([45101813])
cs

 

 

 

[마치면서]

  자 그럼 마무리를 위해 먼 길을 돌아 처음 목적으로 돌아갈 시간이 됬다. 머신러닝에서의 파이썬의 역활은 무엇일까? 개인적인 생각으로는 numpy, panda, matplotlib 과 같이 입출력 데이터를 선, 후처리 할 수 있는 기능을 머신러닝 라이브러리들에게 무료로 제공해 주며, 더 나아가서 세계 공용어인 영어의 역활과 비슷하게 머신러닝과 관련된 여러 관련 라이브러리들이 서로 대화와 협력을 나눌 수 있도록 중재하는 역활을 한다고 하고 싶다. 아마 다른 언어에 의해서 뒤집어 지긴 힘들듯한 이런 중요성 때문에 머신러닝을 배우려는 분들은 꼭 파이썬을 조금씩, 하지만 꾸준히 관심을 가지는게 맞을 듯 싶다.

 

  그리고 다시 한번 얘기하지만 머신러닝 라이브러리는 최근 화려한 스포트라이트와 지원을 받고 있어 그렇지, 어쩌면 원래는 일반 공학 라이브러리와 같은 평범한 라이브러리 출신 일지도 모른다. 그래서 아마도 현재 유행되는 머신러닝 장르 이외에도 데이터의 특별한 측면을 노출해주는 기존의 평범한 알고리즘들이 재조명되어 새로운 머신러닝의 장르를 열수도 있을 것이다. 

 

  또한 앞의 푸리에 변환 라이브러리의 사용과 같이, 사용자가 가진 라이브러리의 동작 원리와 적용 대상에 대한 이해의 깊이에 따라서 그 유용성이 달라지게 된다. 그러므로 머신러닝 프레임윅들의 사용법이나 트레이닝, 오버피팅, 모델, 학습율, 초기값, 오차 등의 방법론들에 집중하는 것도 좋지만, 그것은 어쩌면 그림자만을 쫓는 행위일수도 있으므로, 파이썬을 공부할 때와 마찬가지로 그 기술의 배경이 되는 여러가지의 주변 요소들에 대해서도 교양이라고 생각하고 꾸준히 관심을 가지도록 해보자. 모든 진실은 데이터 안에 숨어있다는 것을 잊지말고...(데이터도 가끔 거짓말을 하긴 하지만 말이다.)

 

 

 

[보충]

1) 이런저런 블로그를 보다보니 푸리에 변환도 컴퓨터 비전 측면에서 머신러닝 쪽에 포함된다고 하는 얘기가 있다. 그럼 예제가 엉뚱한건 아니게 되서 더 다행이다~

 

2) 한 분이 numpy 예제를 보고 "파이썬에선 함수가 2개의 리턴이 가능해요?" 하고 물어보셨다. 그러려니 하고 별 생각 없이 넘어갔던 저였지만--;, 궁금해서 함 찾아봤다. google 에서 'python function multiple return' 으로 찾으면 여러 스타일이 나오는데, 가장 간단한 샘플을 보인다.

https://stackoverflow.com/questions/354883/how-do-you-return-multiple-values-in-python

1
2
3
4
def f():
    return 12
x, y = f()
print ("x = ",x, ",y = ", y)
cs

 

c:\Python\code>python return_test.py
x =  1 ,y =  2

 

3) 아래 글도 괜찮은 듯 해서 참고 자료로 링크를 건다.

머신러닝속 수학(번역)

https://mingrammer.com/translation-the-mathematics-of-machine-learning

 

 

2017.6.25 by 자유로운설탕
cs

 

  

 

 

 

 

 

 

posted by 자유로운설탕
prev 1 next