요약
⏱ 52:511. 핵심 원리와 학습 포인트
⏱ 52:51발표자는 머신러닝을 어렵다고 지레 포기하기보다 함께 공부하며 실무에 활용할 정도부터 익히자고 제안한다. 자바카페에서 자신을 포함한 다섯 명이 스터디를 시작했지만 모두 초보였고, 영어 용어와 부족한 한국어 자료, 오래전에 배운 수학이 장벽이었다. 김성훈 교수의 한국어 강의가 도움이 되었으며, 발표 내용에도 공부 중인 사람의 이해와 추측이 포함되어 있음을 밝힌다.
⏱ 06:47지도학습은 입력과 정답으로 예측을 실행하고 실제 결과와 비교하여 프로그램이 스스로 예측 방식을 수정하는 과정이다. 선형 회귀에서는 학습 시간과 토익 점수처럼 비례 관계를 가정해 H(x)=wx+b를 세운다. 예측 오차를 제곱해 평균한 비용을 최소화하도록 w와 b를 찾으며, 경사하강법은 미분으로 비용이 작아지는 방향을 알아내 학습률만큼 갱신한다. 텐서플로우는 이 최적화 기능을 제공하므로 짧은 코드로도 학습과 예측을 실행할 수 있다.
⏱ 18:28학습 시간만으로 성적을 설명하지 못하면 해외 거주 경험 같은 다른 변인을 찾아야 한다. 다변수 회귀는 각 입력에 가중치를 주며, 행렬 곱을 쓰면 앞의 가설과 코드를 거의 그대로 활용한다. 상수항은 입력의 첫 열에 1을 넣어 포함할 수 있다. CSV에서 학습 시간·거주 개월·점수를 읽으면 데이터 추가 때마다 코드를 고칠 필요도 없다. 참·거짓 분류에는 시그모이드와 로그 비용을, 학점처럼 여러 범주를 고를 때에는 소프트맥스를 활용하는 흐름으로 확장한다.
⏱ 34:13MNIST는 28×28 필기체 그림을 픽셀의 진하기에 따른 수치 행렬로 바꾸고, 0~9의 열 범주를 소프트맥스로 분류한다. 학습용과 테스트용 데이터를 나누어 성능을 확인해야 한다. 스터디에서는 HTML·자바스크립트 그림판, Flask, OpenCV를 연결해 직접 그린 숫자를 시험했다. 시연의 전체 정확도 91%와 특정 그림이 7일 소프트맥스 확률 87%는 서로 다른 값이며, 가장 높은 확률의 숫자를 최종 예측으로 반환한다.
⏱ 00:071. 발표 소개와 머신러닝의 진입장벽
⏱ 00:07안녕하세요. 자바카페 안귀정입니다. 머신러닝과 텐서플로우를 주제로 발표를 준비했습니다. 먼저 머신러닝의 진입장벽이 너무 높지 않으냐는 이야기를 하고, 머신러닝이 무엇인지와 회귀 같은 기본 개념들을 짚어 보겠습니다. 요즘 관심이 높은 딥러닝도 잠깐 알아보고, 텐서플로우를 어떻게 활용하는지 공유하겠습니다. 저도 지금 스터디를 하는 입장이므로, 스터디하면서 겪은 일과 배운 내용을 나누는 발표입니다.
⏱ 01:05간략하게 제 소개를 하겠습니다. 저 역시 슈퍼 개발자는 아니고, 구글과 스택 오버플로의 도움을 많이 받습니다. 지금도 공부 중이기 때문에 발표 내용에 틀린 부분이 있을 수 있습니다. 머신러닝이나 텐서플로우를 잘 아시는 분이 듣고 잘못된 부분을 발견하시면 피드백을 주셨으면 합니다. 그런 점을 양해 부탁드립니다. 발표 경험도 많지 않아서 말을 더듬거나 설명에 두서가 없을 수 있으니 그 부분도 이해해 주시면 좋겠습니다.
⏱ 01:41첫 번째 이야기는 머신러닝의 진입장벽이 너무 높지 않을까 하는 것입니다. 인공지능이나 머신러닝에 관심은 있지만 너무 어려울 것이라고 지레짐작하여 시도조차 하지 않는 분이 많습니다. 어떤 기술이든 깊이 배우려면 상당히 어렵습니다. 그렇지만 우리가 모든 것을 깊이 알고 나서 코딩하고 생계를 유지하는 것은 아니잖아요. 전부 알지는 못해도 개발해서 먹고살 만큼은 할 줄 압니다. 머신러닝도 마찬가지라고 생각합니다. 앞으로 중요해지고 대세가 될 기술이므로, 우리도 실무에 쓸 정도는 공부할 수 있다는 것입니다. 구글이나 스택 오버플로를 보면 해외에서는 이미 공부를 많이 진행하는 것 같습니다. 영어라는 장벽은 있지만 그래도 해볼 수 있습니다.
⏱ 02:42올해 상반기에 알파고와 이세돌 선수가 바둑 대결을 했고, 굉장한 화제가 된 끝에 알파고가 이겼습니다. 그 뒤에는 기사가 대부분 인공지능 이야기로 채워졌습니다. 인공지능이 사람의 직업을 빼앗을 것이라는 등 여러 이야기가 나왔습니다. 지금 인공지능에 대한 관심이 매우 높고, 앞으로는 대부분의 개발자가 한 번쯤 해보지 않을까 생각합니다. 저도 알파고가 이긴 뒤 관심을 갖고 무엇으로 이루어졌는지 찾아봤습니다. 그때 딥러닝, 머신러닝, 텐서플로우라는 말이 나왔습니다.
⏱ 03:302. 다섯 명의 스터디와 학습 자료
⏱ 03:30텐서플로우 사이트에 들어가면 그럴듯해 보이는 그림들이 나옵니다. 텐서플로우는 오픈 소스 머신러닝 라이브러리이고, 아래에는 무엇을 어떻게 하는지 설명이 있습니다. 하지만 처음 보면 전혀 이해가 가지 않습니다. 저도 처음 보고 혼자서는 못 하겠다고 생각했습니다. 자바카페에서는 1년에 한두 번, 상반기와 하반기로 나누어 오프라인 스터디를 합니다. 여러 명이 모여 공부하면 낫지 않을까 해서 올해 상반기에 모집했고, 저를 포함해 다섯 명이 함께 공부하게 되었습니다. 오늘은 그 스터디 내용을 발표하는 자리입니다. 모집 연도는 원문 자막에 “2012년 상반기”로 전사되어 있어 확정하기 어렵습니다.
⏱ 04:26스터디를 시작할 때는 잘하는 분도 있지 않을까 기대했지만, 사실 모인 사람 모두 잘 몰랐습니다. 스터디를 모집하면 대부분 그렇지 않을까 싶습니다. 전혀 해보지 않은 분야라 새로운 영어 용어가 너무 많다는 점도 진입장벽이었습니다. 저희가 영어를 잘하는 편도 아닙니다. 지금은 한글 자료가 조금 생겼지만 상반기에는 거의 없었고, 대부분 영어 자료였습니다. 수학도 나오는데, 보통 고등학교를 졸업하면 자주 하지 않잖아요. 저도 수학을 손에서 놓은 지 10년이 넘어서 그 부분이 상당히 난감했습니다.
⏱ 05:15다행히 한국어 동영상 강의를 올려 주신 분이 있었습니다. 김성훈 교수님인데, 강의를 굉장히 잘 올려 놓으셨습니다. 관심 있는 분들이 참고하시면 좋을 것 같아서 소개합니다. 이제 머신러닝을 공부하려면 우선 머신러닝이 무엇인지 알아야 하므로, 일반적인 프로그램과 어떤 점이 다른지부터 생각해 보겠습니다.
⏱ 05:433. 명시적 프로그래밍과 지도학습
⏱ 05:43일반적인 프로그램은 프로그램의 동작 방식을 사람이 모두 설계합니다. 이를 명시적 프로그래밍(explicit programming)이라고 합니다. 프로그램을 만들 때 if 같은 조건문을 써서 이때는 이렇게, 저때는 저렇게 하라고 다 알려 주잖아요. 물론 프로그램이 제 생각대로 안 움직일 때도 많지만, 그런 것은 버그입니다. 머신러닝은 이런 명시적 프로그래밍으로 처리하기 곤란한 문제가 있어서 나온 것입니다. 자동 주행이나 스팸 필터는 필요한 규칙이 너무 많습니다. 사람이 일일이 조건문을 달아 구현하기는 거의 불가능하므로, 프로그램이 스스로 학습하게 해보자는 생각입니다.
⏱ 06:30머신러닝에는 여러 학습 방법이 있습니다. 강화학습도 있고 비지도학습(unsupervised learning)도 있지만, 제가 공부해 본 것은 지도학습(supervised learning)뿐입니다. 지도학습은 학습 데이터를 사용합니다. 학습 데이터가 대단한 것은 아니고, 입력과 정답이 함께 있는 것입니다. 예를 들어 고양이 사진이 있고 그 정답이 cat이고, 다른 사진의 정답은 dog인 식으로 학습 데이터가 주어집니다.
⏱ 07:00기계가 학습한다는 것이 무슨 의미인지 제 나름대로 정리해 보았습니다. 머신러닝 소프트웨어는 어떤 입력값에 대해 결과를 예측하는 소프트웨어입니다. 학습 데이터로 결과 예측 알고리즘을 실행하고, 예측한 결과와 실제 결과를 비교하여 예측 알고리즘을 수정합니다. 이 수정을 사람이 하는 것이 아니라 프로그램이 스스로 한다는 점이 앞에서 말한 명시적 프로그래밍과 다릅니다. 그러면 자기 알고리즘을 스스로 바꿀 수 있는 소프트웨어를 어떻게 만들 것인가라는 문제가 남습니다. 이제 그것을 하나씩 알아보겠습니다.
⏱ 07:524. 선형 회귀의 가설과 비용 함수
⏱ 07:52첫 사례는 선형 회귀(linear regression)입니다. 입력과 결과가 비례 관계에 있다고 여겨지는 경우를 다룹니다. 대체로 공부를 많이 하면 성적이 좋아지듯이, 학습 시간이 많으면 공부를 잘할 것이라는 관계입니다. 제가 만든 표에서는 54시간 공부한 사람의 토익 성적이 800점, 8시간 공부한 사람은 320점, 24시간 공부한 사람은 630점입니다. 이것을 그래프로 그리면 x축은 학습 시간, y축은 토익 성적이 됩니다.
⏱ 08:35비례 관계가 있다고 보았으니 일차함수 형태라는 가설을 세울 수 있습니다. 대강 직선을 그어서 이런 관계일 것이라고 추측하는 것입니다. 일차함수의 기본 형태는 고등학교에서 배운 y = ax + b입니다. 여기서는 기울기 a를 가중치(weight)를 뜻하는 w로 바꾸어 쓰고, b는 그대로 상수입니다. 사실 같은 식이지만 이 분야에서는 이런 표기를 많이 씁니다. 가설은 H(x) = wx + b가 됩니다. 여러 w와 b가 만드는 직선 중 그림의 파란 직선처럼 실제 결과와 가장 비슷한 값을 내는 직선을 고르는 것이 목표입니다.
⏱ 09:43학습 데이터를 바탕으로 여러 직선 가운데 가장 좋은 직선을 찾는 것이 프로그램이 학습한다는 의미입니다. 그럼 최적의 직선은 어떻게 찾을까요? 여기서 비용 함수(cost function)가 나옵니다. 각 직선에 대해 비용을 돌려주는 함수라고 생각하시면 됩니다. 직선 위의 값이 예측값이고 데이터에 있는 값이 실제값입니다. 두 값의 차이가 가장 적은 직선이 가장 좋은 직선이므로, 단순하게는 차이를 모두 구해서 더하는 것을 생각할 수 있습니다.
⏱ 10:33그런데 차이를 그대로 더하면 어떤 것은 음수, 어떤 것은 양수로 나옵니다. 그래서 보통 실제값에서 예측값을 빼거나 그 반대로 뺀 뒤 제곱합니다. 그러면 부호 문제가 사라지고, 많이 틀릴수록 비용이 크게 증가하며 적게 틀리면 적게 증가합니다. 선형 회귀에서는 보통 이렇게 비용 함수를 설계합니다. 수식으로 보면 복잡해 보이지만, 결국 각 실제값과 예측값의 차이를 제곱한 것을 모두 더하고 데이터 개수로 나눈 평균입니다. 즉 cost(w,b) = (1/m)Σ(H(xᵢ) − yᵢ)²입니다. 이 비용 함수의 결과가 가장 작은 값을 찾는 것이 학습입니다. 이제 그 비용을 어떻게 점점 줄여 최적화할 것인가가 남습니다.
⏱ 11:475. 경사하강법과 텐서플로우 실행

⏱ 11:47가장 간단하게는 비용 함수를 그래프로 그려 봅니다. 제곱을 사용했으므로 이차함수 같은 밥그릇 모양이 나옵니다. 일단 아무 점이나 선택한 다음 더 낮은 비용 쪽으로 한 칸 내려가 보자는 것입니다. 그렇게 스텝을 밟다 보면 어느 순간 가장 작은 비용에 도달하지 않을까요? 다만 한쪽에 있으면 이 방향으로, 반대쪽에 있으면 반대 방향으로 내려가야 합니다. 이를 알아내려면 해당 점에서 미분하여 기울기를 구해야 합니다. 기울기의 부호가 양수인지 음수인지에 따라 비용이 작아지는 방향으로 스텝을 밟는 것입니다.
⏱ 12:55경사하강법(gradient descent)은 수식으로 쓰면 어려워 보이고 미분 기호도 잘 기억나지 않을 수 있습니다. 말로 풀면 현재 가중치에서 비용 함수의 미분값에 스텝을 곱한 것을 빼고, 그 결과를 새 가중치로 삼는 것입니다. 즉 w ← w − α·∂cost/∂w입니다. 이것을 반복하면 좋은 가중치를 찾아갈 수 있습니다. 말로만 들으면 감이 잘 오지 않을 것 같아서 텐서플로우 샘플을 준비했습니다. 화면이 뒤까지 보이시나요? 처음에는 다음 예제를 열었는데, 이제 해당 샘플을 보겠습니다.
⏱ 13:45학습 시간을 x 데이터로 두었습니다. 값은 54시간, 8시간, 30시간, 24시간이고, 토익 점수는 y 데이터로 800점, 320점, 600점, 630점입니다. 변수 설정 부분은 파이썬과 텐서플로우 문법입니다. 우리가 세운 일차함수 가설도 가중치에 x를 곱하고 b를 더하는 식 그대로입니다. 비용 함수는 가설에서 나온 예측값에서 실제값을 빼고 제곱한 뒤 평균을 냅니다. 이를 점차 줄여 가려는 것입니다. 학습률(learning rate)은 앞의 밥그릇 모양 그래프에서 한 단계씩 내려가는 스텝입니다. 경사하강법 알고리즘 자체는 텐서플로우가 제공하므로, 학습률과 비용 함수를 넣어 주면 됩니다.
⏱ 15:09실행하면 약간 시간이 걸립니다. 실제 학습 코드는 스텝을 밟으면서 2만 번 학습하도록 되어 있습니다. 출력되는 비용을 보면 점차 줄어들고, 함께 나오는 값은 가중치 w와 상수 b입니다. 어느 순간에는 값의 차이가 거의 없어지는데, 거의 최적해를 찾아냈다는 뜻입니다. 학습을 마친 뒤에는 “10시간 공부한 사람의 토익 점수는 몇 점일까?”, “40시간이면 몇 점일까?”라고 물어봅니다. 자막에는 예측 결과가 각각 “523”, “73점”으로 전사되어 있어 정확한 화면 수치는 확인하기 어렵습니다. 프로그램이 이렇게 예측값을 출력해 줍니다. 코드가 48줄밖에 되지 않는 것은 텐서플로우가 대부분을 제공하기 때문입니다.
⏱ 16:156. 볼록 함수와 여러 입력 변인의 필요성
⏱ 16:15선형 회귀는 매우 기초적인 내용이지만 저는 이것을 모르고 텐서플로우를 시작해서 정말 어려웠습니다. 알고 나면 별것 아닌 것처럼 느껴집니다. 중요한 이유는 앞으로도 계속 나오기 때문입니다. 선형 회귀에서 조금씩 변경해 가면서 결국 딥러닝까지 이어집니다. 또 비용 함수와 관련해 볼록 함수(convex function)를 알아야 합니다. 비용 그래프가 구불구불하면 어느 점에서 출발했느냐에 따라 스텝을 밟아 내려갔을 때의 결과가 달라집니다. 그러면 곤란하고, 앞에서 설명한 방식으로 경사하강법을 적용할 수 없다는 이야기입니다. 어디서 시작해도 같은 최저점으로 가는 형태를 볼록 함수라고 부릅니다.
⏱ 17:06선형 회귀를 정리하면 비례 관계가 있다고 여겨지는 사건의 결과를 예측할 때 사용할 수 있습니다. 프로그램이 학습한다는 것은 가설 wx + b에서 최적의 w와 b를 찾아내는 것입니다. 이를 위해 실제값과 예측값의 차이를 제곱한 값을 비용으로 쓰도록 비용 함수를 설계했습니다. 임의의 w와 b를 선택한 뒤 비용이 줄어드는 방향으로 계속 수정하면, 선형 회귀에서 학습하는 프로그램이 됩니다.
⏱ 17:45다음은 다변수 선형 회귀(multivariable linear regression)입니다. 학습 시간과 토익 성적이 꼭 일치하지 않을 수 있습니다. 70시간 공부했는데 300점밖에 안 나온 사람이 있고, 20시간 공부했는데 자막에 “92점”으로 전사된 높은 성적을 받은 사람이 있다고 해봅시다. 이런 데이터를 직선으로 나타내면 60시간을 공부해도 약 730점, 0시간을 공부해도 730점이라고 예측하는 형태가 나옵니다. 그러면 의미 없는 소프트웨어가 되어 버립니다. 고려할 조건이 하나가 아니라 여러 변인일 수 있다는 점을 생각해야 합니다.
⏱ 18:28학습 시간만 토익 성적에 영향을 미치는 것이 아니라 해외 거주 경험도 영향을 줍니다. 숨겨진 변인을 찾아내는 일도 굉장히 중요합니다. 알고 보니 70시간 공부한 사람은 해외 거주 경험이 전혀 없고, 20시간 공부한 사람은 3년이나 있었습니다. 그래서 앞 사람은 300점, 뒤 사람은 자막에 “92점”으로 나온 성적을 받은 것입니다. 이런 경우에는 각 변인마다 w를 구하면 됩니다. 예를 들어 학습 시간을 x₁, 해외 거주 경험을 x₂로 두고 w₁x₁ + w₂x₂처럼 구성합니다.
⏱ 19:207. 행렬과 파일을 이용한 다변수 실습

⏱ 19:20행렬을 곱하면 w₁x₁ + w₂x₂ + w₃x₃처럼 각각 곱해서 더한 것과 같은 결과가 나옵니다. 행렬을 쓰면 wx + b의 b도 따로 쓰지 않을 수 있습니다. 가중치 쪽 첫 자리에 b를 두고 입력의 첫 자리에 항상 1을 두면, 곱한 결과가 원래 식과 같습니다. 가중치 행렬을 대문자 W, 입력 행렬을 대문자 X라고 하면 선형 회귀에서 쓰던 WX라는 가설을 그대로 사용할 수 있습니다. 같은 가설을 쓰고 코드도 거의 변경하지 않아도 된다는 점이 중요합니다.
⏱ 20:15코드로 보겠습니다. 앞의 예제에 해외 거주 데이터가 추가됐고, 슬라이드에 있던 값을 그대로 적었습니다. 여기서는 먼저 행렬을 쓰지 않고 가설을 w₁*x₁ + w₂*x₂로 직접 적었습니다. 아래 코드는 같으므로 위쪽 두 줄만 바꾸고 실행하면 됩니다. 학습이 끝나면 30시간 공부하고 해외에서 10개월 산 사람은 몇 점인지, 2시간 공부하고 24개월 거주한 사람은 몇 점인지 물어볼 수 있습니다. 출력은 첫 사람이 약 595점, 두 번째 사람이 667점이라고 예측합니다. 이 데이터에서는 공부 시간보다 해외 거주가 더 중요하다는 것입니다.
⏱ 21:32그 아래 예제는 같은 내용을 행렬로 바꾼 것입니다. 행렬을 배열 형태로 코드에 쓰면, 앞에서 사용한 가설을 그대로 쓸 수 있습니다. 텐서플로우가 제공하는 matmul이 행렬의 곱셈이므로, W와 X를 곱한 것이 새로운 가설입니다. 실행 결과는 앞의 직접 적은 식과 같습니다. 행렬로 바꾸면 좋은 점이 하나 더 있습니다. 학습 데이터를 파일에서 가져올 수 있다는 것입니다. 데이터가 추가될 때마다 코드를 변경하면 굉장히 번거롭지만, 행렬은 배열로 바꾸어 읽을 수 있습니다.
⏱ 22:16train.csv에는 학습 데이터를 옮겨 두었습니다. 첫 열은 b에 대응하는 입력으로 항상 1이고, 그다음 열은 학습 시간, 해외 거주 개월 수, 마지막 열은 토익 점수입니다. 파이썬의 NumPy로 텍스트 파일을 읽으면 자동으로 배열이 됩니다. x 데이터는 맨 마지막 열을 제외한 부분이고, 여기서 -1은 마지막 열을 가리킵니다. y 데이터는 그 마지막 열입니다. 나중에 학습 데이터가 늘면 파일 아래에 한 줄만 추가하면 됩니다. 예를 들어 첫 값은 항상 1을 적고, 60시간 공부하고 38개월 거주한 사람이 900점을 받았다는 데이터를 넣는 식으로 쉽게 추가할 수 있습니다.
⏱ 23:198. 로지스틱 분류와 시그모이드

⏱ 23:19다음은 로지스틱 분류기(logistic classifier)입니다. 앞에서는 비례 관계를 살펴봤지만, 이번에는 결과가 참이나 거짓으로 나오는 경우입니다. 스팸 필터는 스팸인지 아닌지 두 경우가 있고, 주가에서도 상승과 하락만 알아본다고 가정하면 두 경우로 볼 수 있습니다. 여기에 앞의 가설을 그대로 적용해 볼 수 있을까요? 학습 시간에 따른 기술 이민 성공 여부를 예로 들겠습니다. 통과(pass)는 1, 실패(fail)는 0으로 두고 선형 회귀처럼 직선을 그어 봅니다. 0.5 이상이면 합격, 0.5 미만이면 불합격으로 예측하는 것입니다.
⏱ 24:21그런데 120시간을 공부했더라도 결과는 여전히 1입니다. 이런 데이터가 추가되면 예측 직선이 크게 바뀝니다. 0.5가 되는 위치도 달라져서 실제로 합격했던 앞의 세 명을 불합격이라고 잘못 예측하게 됩니다. 이 문제 때문에 기존 방식을 유지하면서 사용할 방법을 수학자들이 찾아낸 것이 시그모이드(sigmoid) 함수입니다. z는 앞의 wx + b이고, 함수는 σ(z) = 1/(1 + e^(−z))입니다. 수학을 자세히 따지는 대신 역할을 보면, 선형으로 나온 결과를 최솟값 0과 최댓값 1 사이에 놓이도록 모양을 바꾸어 줍니다.
⏱ 25:40시그모이드를 사용해도 더 좋은 방향으로 학습하려면 비용 함수가 필요합니다. 저는 시그모이드가 지수 형태이므로 비용 함수가 로그 형태로 나오는 것이라고 추측합니다. 수학을 잘 아는 것은 아니어서 추측이라는 점을 말씀드립니다. 실제 결과 y가 1이면 −log H(x)를 비용으로 주고, y가 0이면 −log(1 − H(x))를 줍니다. 맞게 예측하면 낮은 비용, 틀리면 높은 비용을 주려는 목적입니다. y가 1인데 1로 예측하면 비용은 거의 0이고, 0으로 예측하면 비용이 무한대에 가까워집니다. 실제 시그모이드는 딱 0이나 1보다는 그 사이 값을 내므로 그에 맞는 비용을 줄 수 있고, y가 0일 때도 마찬가지입니다. 두 경우를 합치면 밥그릇 같은 볼록 함수 형태가 된다고 설명할 수 있습니다.
⏱ 27:16말로만 들으면 감이 오지 않으니 코드를 실행해 보겠습니다. 학습 데이터는 파일로 빼 두었고, b에 대응하는 입력은 모두 1, 그다음은 학습 시간, 결과는 성공이면 1이고 실패면 0입니다. 행렬의 곱은 선형 회귀처럼 그대로 쓰고, 여기에 앞의 1/(1 + e^(−z))를 직접 적용했습니다. 비용 함수도 앞서 쓴 로그 식 그대로입니다. −[y·log H(x) + (1−y)·log(1−H(x))]로 한 줄에 쓰면 y가 1일 때는 뒤 항이, 0일 때는 앞 항이 사라지므로 두 경우를 합칠 수 있습니다. 출력에서는 한 사례는 기술 이민에 실패하고 40시간 공부한 사람은 성공한다고 예측합니다. 첫 사례의 시간은 이 구간 자막에 빠져 있습니다. 시그모이드를 적용하는 부분을 빼면 선형 회귀에서 쓰던 것을 그대로 적용할 수 있습니다.
⏱ 29:139. 여러 범주를 예측하는 다항 로지스틱 회귀
⏱ 29:13다음은 다항 로지스틱 회귀(multinomial logistic regression)입니다. 결과가 참·거짓도 아니고 비례 관계도 아니며, 특정 유형으로 정해지는 경우입니다. 학점은 A, B, C, D, F 가운데 하나이므로 여기에 해당합니다. 입력이 주어졌을 때 그것이 A인지 B인지 C인지 알고 싶고, 가능하면 각 학점의 확률을 구하고 싶습니다. 발표에서는 앞의 로지스틱 회귀처럼 A인지 아닌지, B인지 아닌지, C인지 아닌지, D인지 아닌지, F인지 아닌지를 각각 다섯 번 구하는 방식으로 설명합니다.
⏱ 30:10그다음 소프트맥스(softmax) 함수를 사용합니다. 발표에서는 각 경우의 시그모이드 값을 모두 합하고, 그 합에서 자기 값의 비중을 구한다고 설명합니다. 예를 들어 A의 값이 0.3, B가 0.2, 나머지 세 개가 각각 0.1이면 합은 0.8입니다. A의 확률은 0.3/0.8, B는 0.2/0.8, 나머지는 각각 0.1/0.8로 보는 것입니다. 각 값이 전체 합에서 차지하는 비중이므로 확률들을 모두 더하면 1이 됩니다. 이렇게 각 학점의 확률을 구하겠다는 설명입니다.
⏱ 31:04앞의 로지스틱 회귀를 그대로 활용할 수 있지만 비용 함수는 조금 달라집니다. 앞에서는 참·거짓이라는 한 가지 경우를 다뤘고, 여기서는 다섯 경우를 합치므로 로그를 포함한 식이 복잡해 보입니다. 발표에서는 각각 구한 값을 합친 것에 대해 실제값과의 차이를 비용으로 삼는다고 설명합니다. 직접 샘플을 돌려 보면 더 이해하기 쉬울 것입니다. 예를 들어 54시간 공부하고 해외에 12개월 거주한 사람이 B학점을 받았다는 데이터를 가정하여 텐서플로우로 구현해 보겠습니다. 학습 데이터는 이번에도 파일로 빼 두었습니다.
⏱ 31:5210. 다항 분류 코드와 출력값 읽기

⏱ 31:52입력 데이터는 상수에 대응하는 1, 학습 시간, 해외 거주 기간으로 구성합니다. 결과 부분은 앞의 예제와 다릅니다. 앞에서는 1 또는 0 하나였지만, 여기서는 A이면 A 자리만 1, B이면 B 자리만 1인 식으로 표시합니다. 예를 들어 B라면 (0, 1, 0, …)처럼 해당 학점 자리에만 1을 두고 나머지에는 0을 주는 것입니다. 각각의 학점에 대해 구하기 때문에 이런 형태로 데이터를 줍니다. 코드를 실행해 보겠습니다. 전체 구성은 앞과 거의 같고, 소프트맥스도 텐서플로우가 지원하므로 우리의 가설을 넘겨 주면 됩니다.
⏱ 32:53출력의 첫 번째는 스텝이고 다음은 비용, 그다음은 A, B, C, D 등에 대한 확률입니다. 다른 출력 부분에는 가중치도 나옵니다. 확률을 읽을 때 지수 표기를 알아야 합니다. e−01이면 10으로 나눈 것이므로 여기 보이는 값은 약 12%이고, e−02이면 100으로 나눈 것으로 약 1%입니다. 다른 값은 약 86%입니다. 이 표기를 처음 봤을 때 저는 뒤에 붙은 e−01 같은 부분을 몰라 상당히 난해하게 느꼈습니다. 단순히 10이나 100으로 나누어 읽으면 되는 것입니다.
⏱ 33:28최종 분류값에서 0은 A, 1은 B, 2는 C에 대응합니다. 따라서 출력이 2인 사례는 C학점으로, 다른 사례는 A학점으로 예측한 것입니다. 이런 식으로 소프트맥스를 구해 학점처럼 정해진 범주 중 하나를 선택할 수 있다는 것을 보여 드렸습니다. 이제야 텐서플로우 사이트의 예제에 들어갈 준비가 되었습니다. 사이트에서 가장 기본적인 튜토리얼로 제시하는 것이 MNIST라는 필기체 숫자 인식 예제입니다.
⏱ 34:1311. MNIST를 행렬과 소프트맥스로 이해하기

⏱ 34:13MNIST는 필기체 숫자를 인식합니다. 그림을 그대로 사용하는 대신 픽셀마다 진한 정도를 값으로 바꿉니다. 그림 크기는 28×28이고, 화면에서 가장 검은 부분은 1, 조금 흐린 부분은 0.6, 하얀 부분은 0입니다. 이런 식으로 그림을 행렬 데이터로 바꾸어 버린 것입니다. 앞에서 이미 행렬을 배웠으므로, 이런 경우에도 WX로 행렬을 곱하면 되겠다는 것을 알 수 있습니다. 저는 앞의 내용도 모르고 이 예제부터 접근해서 굉장히 어려웠는데, 앞의 것을 알고 나니 이해가 되었습니다.
⏱ 34:59MNIST 데이터를 행렬로 취급하면 지금까지 배운 것만으로도 학습시킬 수 있습니다. 결과가 0부터 9까지 열 가지로 정해져 있으므로 소프트맥스를 사용할 수 있습니다. 실행하는 모습을 보여 드리겠습니다. 이 소스는 제가 만든 것이 아니라 다른 분이 만드신 것입니다. 화면에 작성자 이름이 있는데 제가 영어를 잘 못해서 어떻게 읽어 드려야 할지 모르겠습니다. 텐서플로우와 MNIST로 검색해 보면 대부분 이와 비슷한 형태의 코드가 나옵니다.
⏱ 35:48처음 하는 일은 서버에서 학습 데이터를 받는 것입니다. 실행 로그는 데이터를 받아 압축을 풀었다는 뜻이고, 이어 비용을 계속 출력하면서 줄여 갑니다. 아래쪽에서도 결국 소프트맥스로 결과값을 냅니다. 소스를 보면 앞에서 다뤘던 소프트맥스와 행렬 곱이 나오고, 경사하강법 알고리즘도 같습니다. 데이터가 1만 개 있다고 가정하면 그중 8,000개로 학습하고 나머지 2,000개는 테스트 데이터로 사용하고 싶은 것입니다. 코드에서 학습용 데이터와 테스트용 데이터를 나누어 놓았습니다.
⏱ 36:46학습한 다음에는 테스트 세트에서 무작위로 고른 데이터의 결과가 맞는지 틀리는지 봅니다. 마지막 콘솔 출력에서 예측(prediction)은 1이고, 레이블(label)은 실제 정답입니다. 여기서는 정확하게 예측했습니다. 하지만 남이 짠 코드를 그대로 쓰다 보면 궁금해집니다. 그냥 되는 것인지, 정말 제대로 실행되는 것인지, 제가 제대로 공부하고 있는 것인지 의문이 드는 것입니다. 떠주는 것만 받아먹다 보면 그렇게 됩니다. 실행할 때마다 무작위로 뽑힌 결과는 달라지는데 매번 맞으니, 정말 항상 100% 올바른 결과만 나오는 것인지 알고 싶어졌습니다.
⏱ 37:4212. 직접 그린 숫자를 인식하는 웹 시연

⏱ 37:42스터디 도중에 직접 테스트할 수 있는 소스를 만들어 봤습니다. 간단하게 HTML과 자바스크립트 그림판 소스를 구해 적당히 편집하고 수정했습니다. Flask는 파이썬에서 REST API를 만들 수 있는 경량 프레임워크입니다. 텐서플로우가 파이썬이므로 Flask로 작성하면 유리합니다. 또 이미지 처리 라이브러리인 OpenCV를 사용해 그림판의 그림을 MNIST 형태의 데이터로 바꿉니다. 그 데이터를 텐서플로우에 넣어 결과를 예측해 보려는 것입니다. 소스는 자바카페 스터디의 GitHub 페이지에 공개해 두었습니다. 아직 정리가 많이 안 되어 있지만 내려받아 사용해 볼 수 있습니다.
⏱ 38:35만든 소스를 실행하면 이런 화면이 나옵니다. 그림판을 전부 저희가 만든 것은 아니고, 인터넷에 공개된 것을 저희 용도에 맞게 수정한 것입니다. 여기에 대략 7을 쓰고 숫자 인식을 누릅니다. 맞을 때도 있고 틀릴 때도 있습니다. 학습이 항상 100% 정확하게 되는 것은 아니기 때문입니다. 이번에는 학습한 결과를 바탕으로 7이라고 예측했습니다. 지금까지 학습한 데이터를 기준으로 표시되는 정확도는 91%입니다.
⏱ 39:17마지막 소프트맥스에서는 1일 확률, 2일 확률, 3일 확률처럼 각 숫자일 확률이 모두 나옵니다. 이번 계산에서는 7일 확률이 87%로 가장 높아서 7이라고 예측했습니다. 화면의 다른 부분은 파이썬과 Flask에서 찍은 로그입니다. 실제 소프트맥스 결과에는 0일 확률, 1일 확률, 2일 확률, 3일 확률 등이 순서대로 있습니다. 그중 7의 확률이 가장 높기 때문에 7을 반환한 것입니다.
⏱ 40:02여기까지 하고 나면 정확도 91%가 그렇게 높은 수치는 아니라는 생각이 듭니다. 요즘 딥러닝을 사용하면 98% 이상이 나오고, 오히려 사람보다 더 잘 인식합니다. 그래서 딥러닝 이야기를 빼놓을 수 없습니다. 시간이 얼마 남지 않아 빨리 진행하겠습니다. 발표에서는 딥러닝을 뉴럴 네트워크, 즉 신경망과 같은 말로 설명합니다. 우리가 하고 싶은 일은 인간처럼 생각하는 기계를 만드는 것입니다. 인간이 사고하는 장기는 뇌이므로, 뇌를 모델링해 보자는 생각에서 출발합니다.
⏱ 40:4713. 뉴런의 모델과 단층 신경망의 한계

⏱ 40:47뇌는 굉장히 복잡하지만 각각의 뉴런을 하나씩 보면 의외로 간단하다는 것입니다. 그림이 잘 보이지 않을 텐데, 입력 신호가 들어오면 특정 가중치 w를 주고 상수를 더합니다. 앞에서 나온 wx + b입니다. 마지막에는 활성화 함수(activation function)가 있어서 다음 뉴런에 신호를 전달할지 결정합니다. 전달할지 말지라면 0 아니면 1이라는 느낌이 들죠. 그래서 wx + b에 시그모이드를 적용하면 모델링할 수 있지 않을까 생각한 것입니다. 이런 이야기가 1950년쯤에 나왔다고 합니다.
⏱ 41:45컴퓨터공학 시간에 배운 AND 게이트와 OR 게이트를 스스로 학습시키고 싶었던 것입니다. 이런 식으로 기계를 만들어 봤더니 앞의 선형 회귀와 연결되는 방식으로 된다는 것입니다. 적당한 직선을 그으면 OR 게이트를 예측할 수 있고, 다른 직선을 그으면 AND 게이트도 예측할 수 있으니 학습할 수 있습니다. 그런데 XOR는 구현할 수 없다는 문제가 발생했습니다. 어떻게 직선을 그어도 정확도가 50% 이상으로 올라가지 않는다는 설명입니다. 그래서 이 방법이 한동안 사장되었습니다.
⏱ 42:32이것이 1950~1960년대 이야기이고, 슬라이드에는 1969년이라고 나와 있습니다. 방법이 없을까 하다가 하나로 처리하지 말고 두 개를 연결하면 된다는 생각이 나왔습니다. 첫 층에서 학습한 뒤 두 번째 층에서 다시 학습하면 XOR를 풀 수 있다는 것입니다. 그런데 마빈 민스키는 층을 둘로 나누면 결과는 만들 수 있어도 학습시킬 수 없다고 이야기했습니다. 앞에서는 입력, 알고리즘, 출력이 있어서 바로 학습했지만, 이번에는 출력에 대해 또 학습해야 하므로 불가능하다는 설명입니다. 발표에서는 그 뒤 약 30년 동안 정체되었다고 이야기합니다.
⏱ 43:2314. 역전파와 깊은 신경망의 학습
⏱ 43:23나중에 1986년 힌턴이 어떻게 학습시킬지 알아냈다는 설명입니다. 순서대로 차근차근 앞으로 가며 학습시키기는 너무 복잡하니, 일단 결과를 보고 잘못되었으면 뒤로 보내 거꾸로 학습시키자는 것입니다. 앞에서 뒤로만 진행하는 대신 결과에서부터 거슬러 올라가면 학습이 된다는 것을 발견한 것입니다. 만약 그때 문제가 모두 해결되었다면 벌써 인공지능 시대가 왔겠지만, 여기에도 또 문제가 생겼습니다.
⏱ 44:00층이 복잡하게 많이 쌓이면 신호를 뒤로 전달하다가 어느 순간 너무 약해져 끝까지 학습되지 않는 문제가 생깁니다. 발표에서는 시그모이드가 0과 1 사이의 값을 내기 때문에, 1보다 작은 값을 계속 곱하면 0.01, 0.001처럼 점점 작아진다는 식으로 설명합니다. 다만 이것은 제 생각이고 정확한 설명은 아닐 수 있습니다. 아무튼 이 문제로 또 한참 정체기가 이어졌습니다.
⏱ 44:40그러다가 초기값을 잘 주면 해결할 수 있다는 것을 찾아냈고, 그것이 2006년에 나왔다고 합니다. 기존 이름은 뉴럴 네트워크였지만 이미 많은 사람이 “신경망은 안 될 것이다”라고 실망한 상태였습니다. 그래서 이름을 딥러닝으로 바꾸었다는 설명입니다. 초기값을 어떻게 주느냐는 이렇게 학습의 성패에 중요한 영향을 미칩니다.
⏱ 45:0015. 이미지 인식·강화학습·순환 신경망
⏱ 45:00다른 측면에서는 고양이의 시신경을 관찰했습니다. 고양이가 사물을 인식할 때 뇌 전체가 활성화되는 것이 아니라, 어떤 직선이나 가로 직선을 인식할 때 활성화되는 부위가 각각 다르다는 것입니다. 여기서 착안한 알고리즘은 이미지 전체를 한 번에 인식하지 않고 잘게 나눕니다. 이렇게도 쪼개고 저렇게도 쪼개어 나누어 학습한 뒤, 그것들을 합쳐 전체 결과에 도달하자는 것입니다.
⏱ 45:39이런 방법을 썼더니 이미지넷(ImageNet)에서 좋은 결과가 나왔습니다. 발표에서는 이미지넷을 이미지가 무엇을 나타내는지 맞히는 곳으로 소개합니다. 단순히 사람인지 알아보는 것뿐 아니라, 티셔츠를 입고 드럼을 연주하는 것처럼 구체적인 내용까지 맞히는 데 도전한다는 것입니다. 이런 방법을 사용하면서 놀랍게도 2015년에는 사람을 능가하게 되었다고 설명합니다.
⏱ 46:04또 딥 Q 러닝(deep Q-learning)이 있습니다. 원래는 동영상을 함께 보려고 했지만 시간이 없으니 간단히 이야기하면, 블록 깨기 게임을 스스로 하는 것입니다. 저도 내려받아 해봤는데 처음에는 매우 못하지만 시간이 지나면 사람보다 더 잘합니다. 게임 규칙을 따로 알고 있는 것이 아닙니다. 화면의 점수가 얼마나 높아지는지만 생각하고, 적당한 입력을 계속 넣어 보는 것입니다. 이제는 인공지능이 될 것 같다는 시대가 왔습니다.
⏱ 46:41그런데 왜 과거에는 안 됐을까요? 당시에는 데이터 세트가 너무 적었고 컴퓨터가 너무 느렸습니다. 지금은 빅데이터가 있지만 과거에는 데이터가 부족했습니다. 직접 딥러닝 실습을 해보면 컴퓨터가 느릴 경우 결과가 정말 안 나오고 계속 학습만 합니다. 초기값을 너무 어리석게 주었다는 문제도 있었습니다. 지금은 초기값 연구가 많아서 텐서플로우에서도 함수 하나로 영리하게 줄 수 있습니다. 또 가설을 단순한 직선처럼 생각하기보다 주어진 데이터에 너무 맞도록 구불구불하게 만들었다는 문제도 있습니다.
⏱ 47:30순환 신경망(RNN)도 이야기해야 하지만 시간이 많지 않아 간단히 설명하겠습니다. RNN은 시퀀스 데이터의 학습을 다룹니다. 앞의 예는 여러 입력이 있을 때 결과가 무엇인지 예측했지만, 시퀀스 데이터는 앞의 데이터가 뒤의 데이터에 영향을 줍니다. 언어가 그 예입니다. 제가 하는 말도 앞의 구문을 알아야 뒤의 구문을 예측할 수 있잖아요. 저도 공부 중이라 명확하게 답하기 어렵지만, 간단히는 과거에 학습한 데이터나 가설에서 나온 결과를 새로운 입력으로 사용하는 것입니다. 방금 학습한 것에 과거 데이터를 다시 넣으며 순환하는 구조로 학습하므로 순환 신경망이라고 합니다.
⏱ 48:2716. 텐서플로우 응용과 다루지 못한 내용
⏱ 48:27텐서플로우를 어떻게 응용할 수 있는지도 준비했습니다. 첫 사례는 중학교 2학년 학생이 개발한 것으로, 시각장애인을 위해 이미지를 보고 그 내용을 설명해 주는 것입니다. 소개하는 사이트에 나와 있습니다. 중학교 2학년도 텐서플로우로 이런 개발을 하고 있는 것이죠. 이것을 보면 “내가 이러려고 개발했나” 하는 말이 나올 수도 있겠습니다.
⏱ 49:02다음은 오이를 구별하는 사례입니다. 이것도 텐서플로우로 개발했고, 일본에서 만든 장치가 실제로 작동하는 영상입니다. 여기에 오이를 넣으면 아래로 내려가고, 이미지를 보고 어느 등급인지, A인지 등을 자동으로 구분합니다. 발표에서는 이를 오이의 품종을 구별하는 사례라고 소개합니다. 이미 텐서플로우를 이용해 이런 개발이 많이 이루어지고 있습니다.
⏱ 49:38이번 발표에서 제대로 다루지 못한 내용도 있습니다. 시간이 없기도 하고 저 역시 공부 중이라 핵심만 짧게 정리하기 어렵기 때문입니다. 앞서 말한 RNN, 그리고 이미지를 조각조각 분석한 뒤 다시 합치는 합성곱 신경망(convolutional neural network)이 있습니다. 앞에서는 학습 문제를 어떻게 해결했는지만 이야기했지만 실제로는 ReLU 같은 방법을 사용한다는 내용도 다루지 못했습니다. 구글 클라우드에서도 머신러닝을 제공하고, API 형태인 것 같습니다. 원래 직접 해보고 비교해서 발표하고 싶었으나 시간 관계로 사용해 보지 못했습니다.
⏱ 50:2517. 실습 환경·수학·학습률에서 겪은 어려움

⏱ 50:25스터디하면서 어려웠던 점도 공유하겠습니다. 앞서 실습으로 보여 드린 일반적인 머신러닝은 기본 환경에서도 잘 돌아갑니다. 이때 하드웨어 표현은 자막에 “일반 GPU”로 전사되어 있습니다. 딥러닝에는 GPU 가속이 필요합니다. 그렇지 않으면 정말 느립니다. 문제는 맥북에서 GPU를 설정하기가 굉장히 까다롭다는 것입니다. 계속 시도했지만 아직 성공하지 못했습니다. 그래서 이런 경우에는 마음 편하게 우분투를 쓰시라고 말씀드립니다. 제가 해보니 우분투에서는 잘 되었습니다.
⏱ 50:57지금은 한글 자료가 조금 있는 것 같지만 제가 공부할 때는 너무 없어서 어려웠습니다. 요즘은 늘었으니 관심이 있으면 충분히 할 수 있다고 생각합니다. 수학 공식도 상당히 많이 나옵니다. 하지만 기억이 안 날 뿐, 우리가 어쨌든 한 번은 공부했던 내용들입니다. 제 생각에는 대략적인 원리를 이해하면 됩니다. 그 원리를 이해하고 응용할 수 있으면 된다는 것입니다.
⏱ 51:24학습률 조절도 상당히 중요합니다. 앞에서는 자막에 “0.08”로 전사된 학습률을 사용했는데, 이 값을 너무 크게 주면 발산합니다. 포물선 모양의 비용 그래프에서 조금씩 타고 내려가야 하는데 스텝이 너무 크면 한쪽에서 반대쪽으로 점프하고, 다시 이쪽으로 점프하며 발산하는 것입니다. 따라서 학습률을 잘 정하는 것도 굉장히 중요합니다.
⏱ 51:4518. 자바카페 소개와 함께 공부하자는 제안
⏱ 51:45커뮤니티 홍보를 잠깐 하겠습니다. 제가 발표하게 된 자바카페는 오프라인 스터디 중심의 개발자 모임입니다. 매년 상반기와 하반기에 스터디를 모집하고, 원하면 저처럼 세미나에서 발표할 기회도 제공합니다. 저도 대단한 개발자는 아니지만 이렇게 발표하고 있잖아요. 오프라인 모임만의 강점이 분명히 있습니다. 온라인보다 사람 냄새가 나고 친목을 다질 수 있으며, 이직할 때 추천을 받는 일에도 좋습니다.
⏱ 52:27원래 오프라인 위주로 운영되어 오픈 소스 활동은 많이 하지 못했지만, 최근에는 좀 활발해진 것 같습니다. 자바카페에서 어떤 오픈 소스를 하고 있는지 궁금하시면 문의해 주시면 될 것 같습니다. 준비한 내용은 여기까지입니다. 제가 드리고 싶은 말씀은, 머신러닝과 텐서플로우에 관심이 있다면 진입장벽이 너무 높을 것이라고 생각하지 말고 같이 공부했으면 좋겠다는 것입니다. 관심이 없으면 상관없지만 관심은 있는데 어렵다고만 생각하지는 않으셨으면 합니다.
⏱ 52:56스프링을 사용하는 분은 굉장히 많습니다. 사람이 많으니 자료가 많고, 자료가 많아지면 진입장벽이 낮아져 다시 자료가 더 많아지는 선순환이 이루어집니다. 머신러닝을 공부하는 분은 아직 많지 않지만, 공부하는 사람이 늘어나면 자료가 많아지고 진입장벽이 다시 낮아질 것입니다. 그 결과 자료가 또 늘어나는 식으로 이어질 수 있습니다. 더 관심을 갖고 같이 공부해 나갔으면 좋겠습니다. 제 발표는 여기서 마치겠습니다.






