기존의 포스트 대로 작업하면 일반적인 형태의 챗봇을 만들 수가 있지만, 한글은 교육 효과가 떨어질 수 밖에 없습니다. 실은 어마 어마한 교육 데이터가 존재한다면 이런 걱정 안하겠지만 애초에 교육 데이터가 많이 존재하지 않으니 그리고 실제로 많이 존재한다고 해도 한글은 원리상 형태소 분석을 추가해야 교육 효율이 좋아집니다. 


즉 seq2seq 방식에서는 


춘천에, 춘천에는, 춘천까지 


등등 춘천이 들어가는 단어를 전부 다르게 분류합니다. 춘천 이라는 명사에 의미를 주기가 어렵습니다. 영어라면 단어 위주로 나뉘어 지니까 이런 문제가 없지만 한글은 조사 때문에 형태소 분석이 필요합니다. 명사랑 조사를 분리시켜서 교육을 시키면 춘천 이라는 단어에 대한 교육을 시킬 수가 있기 때문에. 교육 효과가 높을 수가 있습니다. 


형태소 분석은 KoNLPy  를 씁니다. GPL 이기 때문에 나중에 상업용으로 적용하실 때는 형태소 분석 모듈을 새로 짜줘셔야 합니다. 


-- EDITED -- 

혹시라도 설치가 안되면 라이브러리 다시 링크후에 재시도 하면 됩니다. 

libmecab.so.2를 찾을 수 없는 에러가 나는 경우, 다음과 같이 할 수 있습니다.

  • 라이브러리를 다시 링크하고 확인후 재시도

    $ sudo ldconfig



저번 자동진화 웹버젼 챗봇 에 추가 설명을 하겠습니다. 처음부터 어떻게 해야 하는지 모르겠다는 평을 들었기 때문입니다. 


자연스럽게 따라하기 편하게 명령을 쭈욱 나열하겠습니다. 이 명령은 아나콘다 가 설치되어 있는 OSX(또는 우분투 머신) 기준에서 작성했습니다. Windows 는 알아서 적용하시길 바랍니다. 


$ conda create -n tensor python=3.6
$ git clone git@github.com:crazia/NM-chatbot.git
$ cd NM-chatbot
$ pip install -r requirements.txt
$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py makedata --initial
$ python manage.py runserver


여기까지 진행하시면 자연스럽게 http://localhost:8000/admin 으로 접속해서 만들어둔 id/password 로 로그인 할 수가 있습니다. 


자동진화 웹버젼 챗봇 을 참조해서 대화 데이타를 만들어 줍니다. Admin 에서 작업하셔도 되고, http://localhost:8000 에 접속해서 나오는 대화창에 대화내용을 입력하면 자동으로 데이터베이스에 대화 내용이 저장되니 그 내용을 수정해서 작업해도 됩니다. 


이렇게 대화가 저장이 되면 


$ python manage.py makedata


다시 이 명령을 실행해주면 저장된 대화록을 바탕으로 자동으로 교육자료를 만들고 교육을 시켜서 새로운 모델로 만들어진 교육자료를 지정하게 바뀝니다. 



지난 포스트 


NMT를 이용한 챗봇(console)


NMT를 이용한 챗봇(Web 버젼)


에 이어서 세번째 자동 진화 버젼입니다. 간단한 교육시스템을 추가 했습니다. 원리는 간단합니다. 


1. 챗봇을 이용하면 모든 대화의 내용이 데이터베이스에 저장됩니다. 


2. 저장된 내용을 검토해서 올바른 대답으로 올바른 대답으로 바꾸고 '검토 완료'로 상태를 바꿔서 저장




3. 이렇게 저장된 내용을 교육데이터(train) , 아직은 테스트 데이터를 따로 만들기 어렵기 때문에 교육과 train 을 같이 씁니다. 추후에 따로 분리할 예정입니다. 그리고 train 데이터로부터 단어집을 만들어 줍니다. 





4. 이렇게 만들어진 데이터를 바탕으로 교육을 시작합니다. (참고로 aws 저 사용에서 돌리니 서버가 멈출정도로 부하를 주더군요. 알아서 상황에 따라 돌리는 걸 추천합니다)


5. 기존 데이터셋을 새로 만들어진 데이터셋으로 바꾸고 서비스를 재시작 합니다. 



이것을 자동화할 수 있는 명령이 바로 


python manage.py makedata 


입니다. 물론 $PROJECT/chat/management/commands/makedata.py 파일에 필요한 내용을 채워서 돌려야 하는건 필수 입니다. 


https://github.com/crazia/NM-chatbot (소스)

https://chat.crazia.org (Live Demo)



seq2seq 를 이용해서 챗봇을 만든 시리즈중에서 3번째 입니다. 


콘솔버젼


웹버젼


에 이어서 웹버젼 을 실제 AWS 에 디플로이 한 버젼입니다. 현재는 교육 자료가 간단한 문답 6개로 이루어져 있어서 제대로 동작하지는 않지만 추후에 데이타가 많아지면 좀 제대로 대답할 듯 합니다. 


https://chat.crazia.org 에서 확인 가능합니다. Websocket 을 띄우는데 많이 애 먹었습니다 ㅋㅋ 



저번  NMT를 이용한 챗봇(Console) 에 간단하게 웹 인터페이스(web interface) 를 붙여봤습니다. 저번 버젼에서 옵션같은 것을 조정하고 환경변수에 모델이 저장된 위치를 지정하고 웹만 띄우면 되는 버젼으로 가볍게 고쳤습니다.


교육(Train) 시키고 이런 것은 저번 포스트에서 다루었기 때문에 실제로 구동하는 것만 할 줄 알면 될것 같습니다.  웹 버젼은 장고를 이용해서 작성했으면 채널을 이용해서 간단한 웹소켓을 이용하는 식으로 만들었습니다. 


저번 포스트 참조하기


다만 저반하고 달라진건 교육 시키는 방법 입니다. 저번에는 급하게 만드느라 package path 연결시키는 것을 무시했는데 이번에는 그걸 다 맞췄습니다. 


python -m core.nmt \
    --attention=scaled_luong \
    --src=req --tgt=rep \
    --vocab_prefix=/tmp/nmt_chat/vocab  \
    --train_prefix=/tmp/nmt_chat/train \
    --dev_prefix=/tmp/nmt_chat/test  \
    --test_prefix=/tmp/nmt_chat/test \
    --out_dir=/tmp/chat_model \
    --num_train_steps=12000 \
    --steps_per_stats=100 \
    --num_layers=4 \
    --num_units=128 \
    --dropout=0.2 \
    --metrics=bleu


이제 교육이 된 모델을 소유하고 있다면 ENV 에 그 내용을 추가해 줍니다. 



export OUT_DIR='POSITION FOR MODEL'



PROJECT ROOT 로 이동해서 



python manage.py runserver 



하면 서버가 띄워지고 http://localhost:8000 으로 가서 확인이 가능합니다. 


모든 소스는 


https://github.com/crazia/NM-chatbot


에서 받을수 있습니다. 


이름이 멋있는 영지식 증명(zero-knowledge proof)이 최근 뜨고 있습니다. 개념 자체는 1985년때부터 내려오고 있는데 최근 이름이 언급되는건 zcash 가 사용하는 zk-Snarks 때문 일것입니다. 


http://설명이 잘 되어 있는 사이트


전 위키피디아 글 보다 위의 사이트가 더 설명이 잘 되어 있더군요. 


영지식 증명은 증명자(prover) 가 검증자(verifier) 에게 '무언가가 참'이라는 것을 증명하는 방법입니다. 단 '무언가'에 관한 어떤 정보도 노출 시키지 않습니다.



정의 보다는 예를 보면 확실하게 느껴질 수가 있습니다. 


색이 다른 두 공이 있습니다. 

내가 (prover) 맹인에게(verifier) 두 공을 주고, '두 공이 색이 다르다는 사실'을 증명 시키되 맹인에게 색을 직접적으로 언급하지 않습니다. 


맹인은 한손에 공을 한개씩 쥐고 테이블 밑으로 손을 내린 다음에 공을 위로 올려서 나에게 보이면 내가 그 공의 색을 말하지는 않지만 전꺼와 색이 같네 전꺼와 색이 다르네 라는 검증을 반복하면 할 수록 맹인은 두개의 공의 색이 정말 다르다는 것을 인식할 수가 있습니다. 


이게 블록체인에 적용이 되면 더 실용적으로 이해할 수가 있습니다. 기존 블록체인에서는 보내는 사람(sender), 받는 사람(receiver), 수량 등이 노출되어 있었습니다. 따라서 거래를 주고 받는 당사자 뿐만 아니라 그 트랜잭션을 지켜볼 수 있는 사람들도 전부 민감한 정보를 볼 수 있었죠.






위 그림에서 보듯이 트랜잭션의 센더(sender) 와 리시버(receiver) 끼리 센더가 리시버의 공개키로 내용을 암호화 해서 보내면 세상에서 리시버만 내용을 풀어볼 수가 있습니다. 그리고 이 트랜잭션을 밖에서 바라보는 사람들은 둘이 주고 받는 내용이 어떤 내용인지 알 수는 없지만 (PKI 란?   참조) 내용이 제대로 전달 되었다는 사실 여부는 알 수가 있습니다. 



최근 열심히 공부해서 간단한 챗봇을 만들 수가 있었습니다. 형태가 간단할 뿐이지 그 안에 들어 있는 Deep Learning 은 구글의 최신 NMT example 을 참조해서 만들었습니다. 


github 에 올리는 거라 대충 영어로 올렸지만 좀 자세한 설명은 여기에 남길려고 합니다. 


NMT(Neural Machine Traslation) 과 chatbot 은 원리상 거의 같습니다. seq2seq 방식으로 RNN 세팅해서 교육시키는 것 까지 동일합니다. 따라서 잘 만들어진 NMT 는 training 자료만 교체해서 챗봇으로 활용 가능합니다. 


소스는 https://github.com/crazia/NM-chatbot 에서 받을 수 있습니다. 


파이썬(python) 버젼은 3.6 이고 tensorflow 버젼은 1.8 입니다. 그 외 다른 라이브러리는 필요 없습니다. 


기본적으로 NMT 소스는 많이 복잡하고 옵션도 다양합니다. 이 소스를 기반으로 했기 때문에 트레이닝(Training)은 NMT 의 옵션과 실행을 그대로 가져갑니다. 대신 입출력을 최소한으로 간소화 시켰기 때문에 추후에 다른 방면으로 이용할 때(서비스 등을 만들때)는 chat.py 만 연구해서 떼어 붙이면 됩니다. 


챗봇을 구동 시킬려면 우선 교육을 시켜야 합니다. 그러면 교육 시키는 방법부터 알아야 합니다. 그러면 교육시키기 위한 자료들 부터 규정합니다. 



1. Train set 


교육을 시키기 위해서 필요한 자료 입니다. 챗봇은 사용자가 '질문'을 던지면 '응답'을 하는 구조로 되어야 합니다. 따라서 train.req 와 train.rep 두 파일이 필요합니다. 각각의 파일은 질문이 들어 있는 (req) 파일과 응답이 들어있는 rep 파일이 쌍으로 필요합니다. train.req 의 132 번째 줄에 있는 질문에 대한 답은 train.rep 의 132 번째 줄에 존재해야 합니다. 

당연히 훌륭한 챗봇은 이 데이타가 확실하게 많아야 합니다. 



2. Test set


교육이 잘 됐는지 확인하기 위해서 필요한 자료입니다. train 에 있는 내용을 발췌해서 써도 되고 아니면 한번 train 에 있는 단어들을 이용해서 적당히 만들어서 써도 됩니다. 



3. Dev set


Test set 하고 다른 케이스의 Test 를 정리해도 되지만 같은 것을 써도 무방합니다. 



4. Vocabulary file


교육과 테스트 전 과정에서 쓰이는 단어집이 필요합니다. 따라서 train.req 와 train.rep 에서 쓰이는 모든 단어를 모아서 단어집으로 가지고 있는 것이 좋습니다. 기본적으로 NMT 는 통역이라 각각의 과정에서 쓰이는 단어집이 다릅니다. (영어-> 베트남 이라면 영어 단어집 하고 베트남 단어집이 따로 존재) 하지만 챗봇은 같은 언어 이기 때문에 굳이 다를 필요는 없을 것이라고 판단했습니다. 


이 단어집을 쉽게 만들어줄 수 있는 파일이 존재해서 그냥 가져다가 조금 바꿔 줬습니다. 


$PROJECT/bin/generate_vocab < train.file > vocab.req
cp vocab.req vocab.rep


이와 같이 하면 단어집을 쉽게 만들어 줄 수 있습니다. 



5. 이 모든 파일을 한 디렉토리에 모아 둡니다. 


mkdir -p /tmp/nmt_chat
cp train.req train.rep test.req test.rep vocab.req vocab.rep /tmp/nmt_chat



이제 교육 시키기 위한 모든 자료가 준비 됐으니 교육을 시키면 됩니다. 



   $PROJECT/python nmt.py \
    --attention=scaled_luong \
    --src=req --tgt=rep \
    --vocab_prefix=/tmp/nmt_chat/vocab  \
    --train_prefix=/tmp/nmt_chat/train \
    --dev_prefix=/tmp/nmt_chat/test  \
    --test_prefix=/tmp/nmt_chat/test \
        --out_dir=/tmp/chat_model \
    --num_train_steps=12000 \
    --steps_per_stats=100 \
    --num_layers=4 \
    --num_units=128 \
    --dropout=0.2 \
    --metrics=bleu


여기에서 신경 써야할 몇가지 사안들을 지적하겠습니다. 


attention 알고리즘을 선택해야 효율이 좋아지기 때문에 꼭 선택을 해줘야 합니다. 

src 와 tgt 는 내가 이용하는 파일의 확장자들입니다. 저는 req 와 rep 를 썼기 때문에 그걸 지정해 준것입니다. 

vocab_prefix 는 단어장으로 써야할 파일의 파일명입니다. (확장자는 req 와 rep)

train_prefix 는 교육시킬때 써야할 파일의 파일명입니다. 여기서는 train 이라고 씁니다. 

dev_prefix 와 test_prefix 는 테스트 할때 쓸 파일의 파일명입니다. 여기서는 test 라고 만든것을 써줍니다. 


정말 중요한 out_dir 입니다. 교육시킨 결과물이 저장되는 곳입니다. 그리고 이후에 실행할 때 교육된 정보값을 가져오기 위해서도 입력해야 합니다. 


num_train_steps 얼마만큼 교육을 시킬것인가 하는것입니다. RNN 은 제대로 효과를 볼려면 꽤 많은 횟수로 교육을 시켜야 합니다. 

steps_per_stats 몇번 마다 로그를 남길것인가 하는것입니다. 체크포인트(checkpoint: 교육 결과 저장이 10x steps_per_stats 마다 일어납니다)

num_layers 는 RNN 을 몇 계층으로 할 것인지 입력하는 것입니다. 간단한 건 2 계층, 시스템이 허용된다면 8 계층에서 가장 최적의 효과를 보였다고 벤치마크는 말합니다. 

num_units 는 네트워크 사이즈 입니다. 

dropout 은 Deep Learning 에서 교육중 건너뛰고(?) 얼마만큼 교육시킬건지 지정해 주는 수치 입니다. 교육자료가 많을 때 사용하면 좋습니다. 


너무나 당연하지만 gpu 버젼으로 교육시키면 효과가 훨씬 좋습니다. 저는 개발은 OSX 에서 하지만 교육은 제 PC 에서 합니다. nvdia 그래픽 카드를 소유하고 있어서..


이제 모든 교육이 끝났으니까 챗봇을 구동하면 됩니다. 


챗봇 구동시키기



python chat.py --out_dir=/tmp/chat_model


최근 핫한 AI 에 대해서 강의를 하기 위해서 작성한 노트 정리입니다. 실제로 반응도 나쁘지 않았습니다. 개발자 대상이기 때문에 최소한의 수학을 알면 좋을 것 같습니다. 이후에 뉴럴 네트워크쪽까지 다룰 예정이기 때문에 거의 필수 입니다. 바로 텐서플로우 이용법으로 시작해도 좋지만 기본 원리를 파악한 상태에서 사용하는 것이 더 효율적입니다. 



회사 CTO 로서 팀원들에게 최근 가장 핫한 딥 러닝 관련 공부를 시키기 위해서 작성했습니다. 2018 최고의 핫트렌드로 예약 되어 있습니다. 최근 Computer Science 이슈의 블랙홀. 당연히 개발자들은 궁금해 합니다. 그래서 따로 설명을 잘해 주려고 정리했습니다. 



최근 가장 핫한 분야입니다. 너도 나도 관심을 가지고 여기 저기서 이야기를 하는 분야이기도 합니다. 저는 이 분야에 관심이 아주 많았습니다. 실제로 졸업 논문도 이 분야로 썼고 관심은 작년부터 가지고 있었지만 바로 적용을 시도 못했습니다. 왜냐하면 생각보다 어렵습니다. -ㅅ- 어떤 말을 하는지는 알겠지만 이걸 어떻게 해야 하지? 라는 고민이 많았습니다. 그래서 여기 저기 공부도 하고 자료도 모으면서 이 정도면 충분히 사용할 만하고 팀원들에게 설명 할 만 하다고 여겨서 이 자료를 작성했습니다. 


이 AI 분야는 비단 최근 핫한 분야로서만 아니라 앞으로 몇 년간 IT 계를 먹여 살릴 화두라고도 생각합니다. 왜 그리 생각하는지 조금 정리해 보겠습니다. 



IT 계에서 많은 변혁을 일으킨 첫 번째 플랫폼(이런 의미는 아니지만 이렇게 부르기로 하겠습니다)이라고 생각하고 있습니다. 이 PC 의 출현으로 반복적인 작업들이 엄청나게 줄어 들었습니다. 엑셀이나 워드 같은 소프트웨어가 사무직들의 기본 소양이 되버렸지요. 



인터넷은 PC 가 일으킨 혁신을 확대를 했습니다. 글로벌 시대를 가능하게 했으며 수 많은 일자리를 없앤 주범입니다. 중간 관리자를 없앴으며 조직의 형태가 애자일 하게 만들었습니다. 그 외의 데이터의 흐름으로 보자면 PC 에 갇혀있던 데이터가 중앙집중 형식으로 모아서 처리하게 되는 시대가 열렸습니다. 그리고 웹 기술을 만나서 정말 다양한 혁신이 이루어 졌습니다. 



가장 최근에 이루어진 혁신입니다. 여러분이 살고 있는 요즘 시대를 일구어낸 혁신입니다. 데이터의 흐름으로 보면 탈중앙화(decentralization)가 이루어 졌습니다. 데이터가 중앙에서도 모이지만 기본적으로 모바일을 바탕으로 각각의 디바이스에서도 연산이 이루어지고 서로 기기간의 상호작용도 중요해졌습니다. 이 시절의 키워드는 Connected  나 IOT 그리고 Big Data 등이라고 할 수 있습니다. 



이게 사실 저의 고민이였습니다. 모바일 다음 IT 쪽의 주요 관심사 또는 플랫폼이 무엇일까? 쉽게 말하면 '개발자들은 어떤 분야로 돈을 벌 것인가?' 모바일 시대가 2007년 정도부터 됐다고 한다면 대략 10년이 지난 요즘 다음 플랫폼이 무엇이 될까? 고민을 많이 했습니다. VR(virtual reality) 이 될 것인지 AR (augmented reality) 가 될 것인지? AI 가 될 것인지? 그 중 진입 장벽이 제일 높은 분야가 AI 라고 판단했습니다. 개발자들도 쉽게 진입 못하는 분야라면 어렵다고는 하지만 개발자들이 익혀서 먹고 살만한 환경을 만들어 갈 수 있겠다. 그래서 열심히 연구하고 개발하면 향후 10년도 충분히 먹고 살 수 있지 않을까? 라고 판단 했습니다.



AI 라는 것은 하루 아침에 생긴 개념은 아닙니다. 최근 유명세를 얻고 있는 딥 러닝의 기본이 되는 뉴럴 네트워크도 1960 년대부터 있던 개념이라고 합니다. 

AI 라는 큰 범주 안에, 기계학습 (Machine Learning)이 들어 있고, 기계 학습중에서 '뉴럴 네트워크(neural network)'를 깊고(deep), 넓게(wide) 연결해서 쓰는 형식을 딥 러닝(deep learning) 이라고 합니다.



스팸 필터(Spam Filter)를 예로 들어볼까요? 일반적인 AI 즉 기계 학습을 쓰지 않고 스팸 필터를 만든다면 규칙(rule)을 이용하는 방식으로 만듭니다. 특정 단어가 반복해서 나온다던지 어떤 형태를 보이면 이것은 스팸이다 아니다. 와 같은 식으로 규정합니다. 

기계 학습은 형태가 다릅니다. 데이타를 충분히 마련해서 어떤 형태의 메일은 '스팸'이다. 그리고 어떤 형태의 메일은 '스팸이 아니다' 와 같은 식으로 계속해서 '훈련'(train) 시키고 나중에 메일이 스팸인지 아닌지 물어보는(test) 방식입니다. 

그리고 뉴럴 네트워크를 이용해서 각각의 레이어를 깊고 넓게 연결하는 형태의 기계 학습이 딥 러닝 입니다.



선형 회귀(Linear Regression)입니다. 처음이라 '선형 회귀'라고 말했지만 거의 영어로 말을 합니다. 이 리니어-또는 라이니어- 리그레션 (Linear Regression) 은 정말 중요합니다. 모든 기계학습의 원리를 설명하기에 가장 좋고 또 다른 알고리즘들은 이 알고리즘에서 파생되는 것들입니다. 따라서 이 '선형 회귀'의 원리와 목적 방식들을 이해 하면 추후에 다른 리그레션(regression)들을 쉽게 이해할 수가 있고, 더 나아가 딥 러닝까지도 이해하는데 편합니다.



리니어 레그레션 이나 다른 기계학습의 기초적인 목적은 주어진 데이타가 있을 때 특정한 값을 예측하는 방법에 관한 것입니다. 일반적인 글로는 이해가 잘 안갈 수가 있기 때문에 예를 들어 보겠습니다.'X = 1  일때 Y = 1 이고, X = 2 일 때 Y = 2 이고, X = 3 일 때 Y = 3 이라고 하자, 그렇다면 X = 4 일때는 얼마 인가?' 라는 질문에 대답을 하자면 사람들은 보통 Y = 4 겠네? 라고 주어진 데이타를 이용해서 유추할 수 있을 것입니다. 이 유추는 사람이기 때문에 가능하며 기계는 이러한 유추 능력이 없습니다. 



그렇다면 기계는 어떻게 유추하게 만들까요? 이렇게 유추하게 만드는 것이 기계 학습의 방법이자 원리입니다. 그리고 기계이기 때문에 '수학적인 방법'으로 유추하는 과정을 기계에게 알려줘야 하는것이지요. 



그래서 매번 AI 관련 이야기 하면 이 식부터 나오는 것입니다. 주어진 데이타셋 (X,Y) 을 잘 만족시키는 W 랑 B 가 있다고 가정하고, 적절한 W 와 B 를 찾아낸다면 새롭게 주어진 X 에 대한 값 Y 를 알아낼 수 있다는 것입니다. 



그렇기 때문에 기계 학습은 일정한 패턴을 보입니다. 이것은 모든 종류의 리그레션(regression) 과 딥 러닝까지 동일합니다. 그 각각은 목적에 따라 W,B 를 알아내기 위한 가정(hypothesis)과 그 가정(함수)에 X 를 대입했을 때 얻어내는 hypothesis(X) 와 실제 Y 값과의 격차를 의미하는 cost/loss 함수를 정하고 그리고 최적의(더 나은) W,B 를 알아내기 위한 방법에 대한 경사하강(gradient descent)을 설정하고 이렇게 정해진 수식들에 반복적으로 테스트 데이터를 입력해서 교육(train) 시킵니다. 그래서 충분히 교육시킨 알고리즘이 교육이 잘 됐는지 확인하는(test) 작업입니다. 



가설 또는 가정 함수 입니다. X = [1, 2, 3] 일 때 Y = [1, 2, 3] 이 나오는 함수를 H(X) = WX + B 라고 가정하는 것입니다. 그리고 W,B 를 랜덤하게 정하자는 것입니다. 가령 예를 들어서 W=2, B=0 이라고 한다면 H = [2, 4, 6] 이겠죠 



코스트 또는 로스 함수입니다. 가정 함수를 통해서 나온 값과 (W, B 가 정해져야 하겠죠?) 주어진 W,B 를 적용한 H(X) 값과 주어진 데이터 Y 값과의 차이를 제곱해서 평균한 값(유클리디안 거리 계산법) 이 코스트 값입니다. 



코스트 함수는 리니어 리그레션의 경우에는 주어진 X, Y 데이터셋을 기반으로 볼 때 대략 W의 제곱에 관한 그래프로 표현될 꺼라는 것을 짐작할 수가 있습니다. 그래서 각각의 W,B 에 대해서 가정 함수의 값을 표현해서 cost 값을 계산해 보자면 W=2 일때 14, W=1.5 일때 1.166 , W=1 일때 0 이라는 것을 알 수가 있습니다. 



그래서 코스트 함수는 계산을 쉽게 하기 위해서 B=0 이라고 가정을 해서 표현을 하자면 2차원 그래프의 형태를 그릴 수가 있습니다. 그래프 상에서 Cost(W) 값이 최소가 되는 지점은 W=1 이 되는 지점입니다. 



코스트 값이 최소가 되는 W 를 찾아 나가는 과정이 경사하강(gradient descent)입니다. 주어진 예를 보자면 처음 랜덤으로 W=2 로 가정하고 시작하면 W=1.5 W=1 로 줄어가는 과정이 되겠습니다. 이 과정을 수식으로 표현해야 합니다. 그래야 기계가 알아 먹기 때문입니다. 



이를 코스트 함수의 그래프와 합쳐서 보자면 이렇습니다. 랜덤으로 정해진 W=2 인 점부터 W=1 인 점으로 변화시키는 과정입니다. 이 변화시키는 방법이 바로 경사 하강입니다. 



경사하강의 수식입니다. 지금 W 에서 다음번의 W 를 찾는 방법에 대한 수식입니다. 다음 W(n 번째) 는 지금 W (n-1 번째) 에서 그 시점(n-1 번째)에서의 편미분값을 러닝 레이트(람다)값을 곱한 값을 뺀 것입니다. 이게 수식으로만 이야기 하면 잘 이해를 못하시더군요. 



조금 쉽게 설명을 하기 위해서 만들어 본 자료입니다. 러닝 레이트(learning rate)가 0.05 라고 가정을 한다면 경사 하강은 랜덤으로 W=2 라고(시작점) 하면 그 시점에서 편미분 값이 대략 10이라고 한다면, 다음 W 는 2 - 0.05 * 10 = 1.5 입니다. 그러면 현재 W 는 1.5 가 됐다고 하면 다음 W 는 1.5 - 0.05 * 6 = 1.2 가 됩니다. 경사하강은 이런식으로 반복적으로 다음 W 를 찾아 나가는 과정입니다. 



핵심이 되는 가정(Hypothesis) 과 코스트(cost/loss) 그리고 경사하강(gradient descent) 가 정해지면 주어진 테스트 데이터셋을 이용해서 반복적으로 최적의 W, B 를 찾아내는 과정이 교육(train) 입니다. 이렇게해서 최적의 W 를 찾아냈는지 알아내기 위해서 새로운 X,Y 쌍이 맞는지 확인해 보는 과정이 테스트(Test) 입니다. 


여기까지가  AI 의 개론과 선형회귀에 대한 원리 설명입니다. 이 후로는 Logistic Regression, Softmax Regression, Deep Learning 을 위한 원리 설명이 있을 예정입니다. (열심히 자료 만드는 중) 애초에 개발자들이 범람하는 AI 자료에 겁먹지 말고 원리를 파악해서 실전에 활용할 수 있기를 바라는 마음으로 쉽게 원리를 이해시키고자 하는 목적으로 만들어진 자료입니다. 바로 실전에 들어가는 것도 나쁘지 않지만 원리를 파악해서 실전에 들어가는 것이 더 잘 이해하고 혹시나 설명이 필요한 사람한테 쉽게 설명해 줄 수 있기를 바랍니다. 


이 블로그로 충분하지만 원본 KeyNote 를 원하시면 댓글 달아주시기 바랍니다. 



Elasticsearch 설정하기

드디어!! AWS 에 있는 Elasticsearch 서비스에 은전한닢 플러그인이 추가 됐습니다. 예전에는 이런 기능이 없어서 제가 따로 elasko 라고 은전한닢에 패치된 형태의 엘라스틱서치의 도커 형태를 만들었습니다. 이제 시간이 지나서 elasticsearch 6.0 이 나오고 (제가 만든 elasko 는 5.5 기반) 문법도 많이 바뀌고 해서 다시금 정리할 필요가 있습니다.

Elasticsearch 편하게 쓰는걸 원하신다면

  1. AWS 에 있는 서비스 추천입니다.
    • 기업 서비스용이라면 100% 추천입니다.
    • kibana 까지 이용하실려면 vpc 가 아닌 ip 기반으로 관리를 선택하세요

그러나 가난한 개인 개발자라면 한달에 EC2 가격만 해도 부담이 되겠지요. 이 글은 가난한 개발자들 위주로 진행하겠습니다. EC2 한대만 허용되어 있다면 docker 에 elasticsearch 를 이용해서 적용하는것이 가성비가 훌륭한 선택입니다.


  1. Elasticsearch 6.1.1 설치하기
    $ docker run -dit --name elastic -p 9200:9200 -p 9300:9300 \
        docker.elastic.co/elasticsearch/elasticsearch:6.1.1
    

    편하게 elasticsearch 가 설치됩니다.  


  2. elastic 컨테이너에 접속하기
    $ docker exec -it elastic /bin/bash
    

    접속해서 root console이 뜹니다.


  3. zip 설치하기

    필요한 것만 설치되어 있는 docker 컨테이너 특성상 zip 이 없습니다.

    # yum install zip
    

    마지막에 물어보는 대답에 'y' 하시면 됩니다.


  4. 은전한닢 패치하기
    $ bash <(curl -s \
       https://bitbucket.org/eunjeon/seunjeon/raw/master/elasticsearch/scripts/downloader.sh)\
         -e 6.1.1 -p 6.1.1.1
    

    엘라스틱서치 6.1.1 버젼에 플러그인 대상 6.1.1.1 버젼을 설치한다는 것입니다.

    $ ./bin/elasticsearch-plugin install \
      file://`pwd`/elasticsearch-analysis-seunjeon-6.1.1.0.zip
    

  5. Elasticsearch 재시작

    꼭 해야 하는지는 모르겠지만 한번쯤 해주는 것도 나쁘지 않아 보입니다.

    $ ps -ef | grep elasticsearch
    

    로 찾은 process 번호를

    $ kill -SIGTERM [process id]
    

    로 죽이면. 컨테이너 밖으로 튕겨 나가게 됩니다.

    $ docker start elastic
    

    밖에서 이 명령으로 다시 띄우시고


  6. 테스트 하기

    제대로 패치된게 맞는지 확인합니다. 기존 은전한닢 사이트에서 제공하는 확인 스크립트를 새버젼 (6.1.1)에 맞게 바꾸어 줍니다.

    #!/usr/bin/env bash
    
    ES='http://localhost:9200'
    ESIDX='seunjeon-idx'
    
    curl -XDELETE "${ES}/${ESIDX}?pretty"
    sleep 1
    curl -XPUT "${ES}/${ESIDX}/?pretty" \-H 'Content-Type: application/json' -d '{
      "settings" : {
        "index":{
          "analysis":{
            "analyzer":{
              "korean":{
                "type":"custom",
                "tokenizer":"seunjeon_default_tokenizer"
              }
            },
            "tokenizer": {
              "seunjeon_default_tokenizer": {
                "type": "seunjeon_tokenizer",
                "index_eojeol": false,
                "user_words": ["낄끼+빠빠,-100", "c\\+\\+", "어그로", "버카충", "abc마트"]
              }
            }
          }
        }
      }
    }'
    
    sleep 1
    
    echo "# 삼성/N 전자/N"
    curl -XGET "${ES}/${ESIDX}/_analyze?&pretty" -H 'Content-Type: application/json' -d '
    {
      "analyzer": "korean",
      "text":  "삼성전자"
    }
    '
    
    echo "# 빠르/V 지/V"
    curl -XGET "${ES}/${ESIDX}/_analyze?&pretty" -H 'Content-Type: application/json' -d '
    {
      "analyzer": "korean",
      "text":  "빨라짐"
    }
    '
    
    echo "# 슬프/V"
    curl -XGET "${ES}/${ESIDX}/_analyze?&pretty" -H 'Content-Type: application/json' -d '
    {
      "analyzer": "korean",
      "text":  "슬픈"
    }
    '
    
    echo "# 새롭/V 사전/N 생성/N"
    curl -XGET "${ES}/${ESIDX}/_analyze?&pretty" -H 'Content-Type: application/json' -d '
    {
      "analyzer": "korean",
      "text":  "새로운사전생성"
    }
    '
    
    echo "# 낄끼/N 빠빠/N c++/N"
    curl -XGET "${ES}/${ESIDX}/_analyze?&pretty" -H 'Content-Type: application/json' -d '
    {
      "analyzer": "korean",
      "text": "낄끼빠빠 c++"
    }
    '
    


요즘 바빠서 글을 잘 못 남기지만 정말 추천할 만한 포스트가 있어서 추천합니다. 간단한 파이썬 코드만 알면 요즘 유행하는 블록체인의 기본 원리를 알고 응용이 가능합니다. 쭈욱 따라하시면 됩니다. 


http://ecomunsing.com/build-your-own-blockchain



끝으로 요즘 여러 이야기가 있지만, 저는 블록체인을 흠잡을 이유가 없습니다. 분산 저장은 시대에 맞는 트렌드라고 봅니다. 다만 거래소가 안전하냐는 이야기는 절대 반대입니다. 돈이 오고 가는 서비스를 그리 허술하게 만들면 안된다고 봅니다. 



+ Recent posts