[5악장-concerto] 머신러닝과 코딩
그렇다면 인공지능을 위한 코딩은 어떻게 배워가야 할까요? 예전보다 코딩 언어를 배울 기회가 많아졌고 관심이 높아졌습니다. 그러나 만약 학교에서 코딩과 관련한 프로그램이 없는 경우도 아직은 많죠. 스스로 코딩을 공부하고 싶지만 어떤 방법으로 무엇부터 배워야 할지 막막하기도 합니다.
코딩은 컴퓨터 언어이기 때문에 어휘, 문법, 구조 등과 같은 언어의 요소가 존재합니다. 코딩에서 배우는 기초적인 내용은 다음과 같습니다.
가장 먼저 컴퓨터 언어로 프로그램을 작성할 때 사용하는 변수, 연산 기호 등을 배웁니다. 컴퓨터는 숫자뿐만 문자열을 다루기도 하고, 다양한 값들의 모음인 리스트, 배열 등과 같은 자료형도 있습니다. 코딩을 배울 때는 문자, 숫자 등과 같은 데이터를 다루기 때문에 이러한 값들을 담는 자료형과 연산에 대해서 다룹니다. 이 단계는 수학을 공부할 때 숫자와 연산 기호, 변수, 좀 더 나가 벡터 등을 배우는 것과 비슷하다고 할 수 있습니다.
우리가 대화를 할 때는 생각을 말이나 글로 표현하고, 상대방의 이야기를 귀로 듣거나 글로 읽는 과정들이 필요합니다. 적절하게 상대방에게 의사를 전달하고 전달받는 교류 과정이 있어야만 원활한 의사소통을 할 수 있죠.
컴퓨터 언어에서도 마찬가지입니다. 때로는 컴퓨터가 처리한 결과를 사람이 눈으로 확인할 수 있어야 하고, 원하는 값을 컴퓨터에게 직접 입력해야 할 때도 있습니다. 파이썬의 경우 컴퓨터가 처리한 결과를 모니터에 출력해주는 명령어가 print이고, 프로그램이 실행 중 키보드를 통해 값을 컴퓨터에게 전달해주는 함수가 input입니다. 이러한 입출력을 통해 컴퓨터 프로그램과 사용자 사이에 상호 작용을 할 수 있는 하나의 통로가 열리게 됩니다.
프로그램을 통해 어떠한 값들을 처리할 때 조건에 따라 값을 판정해야 하기도 하고, 판정 결과에 따라 처리해야 하는 과정이 달라질 수 있습니다.
가령 연령에 맞게 발급된 교통카드에 기반하여 교통 요금을 다르게 부과하는 프로그램을 작성한다고 해봅시다. 먼저 인식한 카드가 청소년용인지, 어른용인지, 노약자 무료 탑승 카드인지 판별을 해야 합니다. 그리고 판정 결과에 따라 맞는 요금을 부과해야 합니다. 즉 어떠한 조건에 따라 판정이 필요하고 해당하는 처리 절차가 달라지게 됩니다.
어떤 조건에 의해 마치 갈림길과 같이 다르게 처리할 수 있도록 해주는 구문을 ‘조건문’이라고 합니다. 프로그래밍을 할 때 모든 상황의 결과를 사람이 확인하고 그에 따른 절차를 지정하는 것이 아니라 프로그램 내에서 값에 따라 어떻게 할지를 규칙을 정해놓음으로써 자동화된 처리를 할 수 있습니다.
컴퓨터에서 사람과 가장 큰 차이를 보이는 것은 ‘엄청나게 빠른’ 계산 능력과 ‘지치지 않는’ 반복 능력입니다. 특히 많은 양의 데이터들을 확인하고 처리하는 과정에서 컴퓨터의 반복 능력은 필수적으로 사용됩니다. 인터넷 검색에서도 수많은 데이터를 하나하나 검색하여 원하는 값들을 찾아내는 과정에서 반복 구문은 활용됩니다.
파이썬을 비롯한 대부분의 언어에서 반복 구문은 크게 조건을 만족할 때까지 반복을 계속하는 while과 정해진 횟수만큼 순차적으로 반복하는 for 구문을 주로 다룹니다. while 구문은 조건을 만족할 때까지는 계속해서 반복을 해야 하는 경우에 사용하며, for 구문은 어떠한 순서에 따라 순차적으로 반복합니다. for에도 언어에 따라 조건을 활용할 수 있습니다.
반복 구문은 인공지능의 여러 알고리즘에서 활용됩니다. 비지도 학습의 대표적인 예시였던 k평균 군집화의 경우, 각 군집의 중심을 찾기 위한 과정을 중심이 거의 움직이지 않을 때까지 계속해서 반복합니다. 딥러닝에서도 가중치의 계산과 오차 역전파 방법을 통한 가중치의 재조정을 계속해서 반복하는 과정이 필요합니다.
무엇인가 새로 배운다는 것은 참 어렵습니다. 처음으로 자전거를 타거나 스케이트, 혹은 운전면허를 갓 취득했을 때는 익숙하지 않아 많은 고생을 합니다. 차 뒤에 ‘초보운전’이라고 붙여놓고 진땀을 뻘뻘 흘립니다. 주차를 한 번 하려면 한참을 움찔거리며 왔다 갔다를 해야 겨우 ‘삐딱하게’ 주차를 완성하곤 합니다. 그런 불편함에도 불구하고 왜 사람들은 자전거나 자동차를 탈까요? 잘하게 되었을 때의 편리함이 매우 크기 때문입니다. 그 때문에 비틀거리는 자전거와 긴장감 가득한 초보 운전 시기를 버티면서 능숙함을 키워가는 것이죠.
코딩을 배울 때 익숙해질 때까지는 ‘불편하고 어색한 것이 당연하다.’는 여유를 가져야 합니다. 코딩 수업에 참여했을 때 선생님의 설명을 들을 때는 이해가 되는 것 같지만, 막상 직접 코딩을 시작할 때 무엇을 입력해야 할지 막막한 마음에 모니터의 깜빡이는 커서만 바라보는 경우가 꽤 많거든요. 그때 ‘난 코딩에 재능이 없나 봐.’라고 생각을 하는 학생들을 많이 봤습니다. 저 또한 처음에 코딩을 배울 때 그랬습니다.
그런 막막함은 재능이 없어서 오는 것이 아니라 익숙하지 않음에서 오는 것이라는 걸 기억해주세요. 처음 걸음마를 시작하는 아기나 어린이 때 자전거를 처음 배울 때 비틀거리는 단계입니다. 저는 수업 시간에 이 단계의 학생들을 가리켜 ‘초보 프로그래머’라고 이야기합니다. 실수해도 얼마든지 이해받을 수 있다는 의미이며 누구나 겪게 되는 단계입니다. 대부분의 사람들이 초보 운전을 겪고, 능숙하게 운전을 할 수 있듯 코딩도 어색한 초보 단계는 누구에게나 찾아옵니다.
그래서 실패를 즐기는 마음으로 코딩을 시작하는 것이 좋습니다. 코딩 실습을 하다 보면 오타가 나거나 구문의 사용이 익숙지 않아 틀리는 경우도 있고, 아예 접근을 잘못해서 오는 오류도 있습니다. 오류를 바로 잡는 과정을 디버깅(Debugging)이라고 하는데 디버깅은 컴퓨터 언어를 다루다 보면 반드시 만나게 되는 과정입니다. 용기를 내서 코딩을 했지만 계속 오류가 나타나고, 어떻게 고쳐야 할지도 막막해 디버깅이 늪에서 허우적대다가 코딩을 포기하는 경우도 많이 있습니다.
한 학기 허우적대던 학생들 중 일부를 다음 수업에 학생 조교로 발탁하면 재미있는 현상이 일어납니다. 학생 조교는 수강생들의 코드를 검토하고 고쳐주는 역할을 하는데, 학생 조교 역할을 제안하면
“에이, 제가 어떻게 다른 친구들 코드 디버깅을 해요?”
라고 손사래를 치죠. 실제 수업에 학생 조교를 투입해보면
“신기하게도 제가 했던 실수들을 똑같이 하네요.”
라고 이야기를 합니다. 그러면서 조교들의 실력이 일취월장하죠. 누구나 비슷한 실수를 하고, 코드를 해석하고 디버깅을 하면서 논리와 표현력이 확 늘어나는 것을 볼 수 있습니다.
포트란 언어의 창시자인 존 배커스는 아래와 같이 말했습니다.
“여러분은 항상 실패를 꺼려하지 않아야 한다. 여러분은 많은 아이디어를 만들어 내야 하고, 단지 그것들이 작동하지 않는다는 사실을 발견하기 위해 매우 열심히 노력해야 한다. 그리고 작동하는 것을 발견할 때까지 여러분은 그 과정을 계속 반복해야 한다.”
앞에서 살펴본 자료형, 연산, 입출력 구문, 조건문, 선택 구문, 반복 구문 등을 익숙해질 수 있도록 실습을 많이 하고 자꾸 써보면 손에 익습니다. 실제로 영어 타자조차 더듬더듬거리던 학생들이 자주 하다 보니 주요 명령어가 손에 익어가면서 하나씩 단계를 해쳐나가는 것을 많이 볼 수 있었습니다. 그러니 어색하다고, 자꾸 오류가 난다고 염려하지 마세요. 어느 누구나 뒤뚱거리며 넘어지면서 걸음마를 배웠던 것처럼 코딩도 그렇게 늘어갑니다. 태어나면서부터 우사인 볼트처럼 뛰어다니길 기대할 수는 없지 않겠어요?