[Machine Learning] Introduction to machine learning

최근 AI, 인공지능 분야가 IT 업계를 포함한 전 분야에서 활발히 논의되기 시작하면서, 해당 분야를 공부해보고자 하는 사람들이 늘고 있다. 나 또한 그 중 하나로, 데이터 분석을 포함해서 인공지능, 머신러닝, 딥러닝, 강화학습 등 여러 분야에 대해서 (얕고 넓게) 공부해보고 있다. 인공지능 분야가 흥미로운 것은 컴퓨터 공학을 전공하는 사람이 아니더라도 간단한 파이썬 프로그래밍 지식만 있으면 누구나 (쉽지는 않지만) 공부하고 실습해 볼 수 있다는 것이다. 또한, 인공지능 기술이 적용되는 분야는 IT분야 뿐만 아니라 의학, 사회학, 언어학 등 데이터를 분석하여 의미있는 결과를 도출하고자 하는 분야는 어디든 적용할 수 있기 때문에 전공/비전공의 의미가 무색해졌다.

3 min read

[Deep Learning] Introduction to deep learning

What is Neural Network?

딥러닝은 머신러닝 기법의 하나로, 신경망 학습을 여러 층으로 설계하는 기법을 나타낸다. 신경망 학습은 입력값을 설계된 네트워크에 적용하여 결과를 예측하는 방식인데, 여기서 네트워크란 학습된 가중치들의 집합이라고 정의할 수 있겠다. 즉, 입력값(X, input layer)에 가중치(hidden layer)를 적용해서 미리 정의된 식에 대입하면 예측값(Y, output layer)를 얻게 되는 것이다.

1 min read

[Q-Learning] Frozen Lake 사용하기

강화학습이란

심리학개론 수업을 들으면 스키너의 강화이론이라는 것을 배운다. 교육학에서도 언급되는 이론인데, 요지는 이렇다. 대상이 어떤 행동을 하게 하려면 Reward를 주고, 어떤 행동을 하지 않게 하려면 Punishment을 주면 된다. 강화학습은 강화이론을 머신러닝에 적용한 형태라고 이해하면 되는데 알고리즘에 따라서 어떤 판단을 했을 때 돌아오는 Reward에 따라서 이 판단이 옳은 것이었는지를 학습하는 것이다.

3 min read

[기초 파이썬] 파이썬 함수의 숨은 기능들

프로그래밍을 처음 배우는 사람을 이해시키기 힘든 개념 중 하나가 바로 함수이다. 그도 그런 게 나 역시도 중학교 수학 시간에 함수라는 개념을 이해하지 못하고 넘어간 학생 중 하나였다. 기계적으로 문제만 맞게 풀었을 뿐 함수, Function이 어떤 의미인지 완벽하게 이해하지는 못했다.

함수는 말그대로 어떤 Function, 즉 기능을 수행하는 뭉치라고 이해할 수 있는데, 예를 들어, 수학에서 y = x라는 함수는 x가 어떤 값이 되었든 그 값을 y에게 돌려주는 기능을 한다. 프로그래밍에서의 함수도 마찬가지인데, 다만 수학에서 함수는 항상 Input이 있으면 1:1이든 다:1이든 Output을 내놓았다면, 프로그래밍에서의 함수는 Input과 Output이 있을 수도 있고, 없을 수도 있다. 그래서 프로그래밍에서의 함수는 Function을 가진 단위이다라고 이해하는 게 더 효과적이다.

보통 함수를 구성할 때는 세가지가 반드시 필요한데, 그것들은 1) 함수명 2) Parameter 3) Return 이다. 이 중 2번과 3번은 Null(없는)의 상태인 것도 포함한다. 다른 언어들에서보다 파이썬에서는 함수를 구성하기가 참 간단하다. C/C++, Java에서는 파라미터나 리턴값이 어떤 데이터형을 가지는지 일일이 명시해주어야 하는데 파이썬에는 변수에도 명시적인 데이터형을 주지 않기 때문에 함수에서도 마찬가지로 파라미터와 리턴값의 데이터형을 명시하지 않아도 문제가 되지 않는다.

위치 인자와 키워드 인자

위치인자는 함수를 정의할 때 파라미터 자리에 순서대로 이름을 매긴 것이다. 따라서 함수를 호출할 때는 정해진 위치인자 순서대로 의미에 맞는 매개변수를 전달해야 한다.

키워드인자는 각 매개변수에 맞는 이름을 붙인 것인데, 위치인자와 달리 키워드인자를 명시하여 매개변수를 전달하면 꼭 정의된 순서대로 전달하지 않아도 되는 이점이 있다.

단, 위치 인자와 키워드 인자를 섞어 사용한다면 위치인자가 먼저 나와야 한다.

def menu(wine, entree, dessert):
  return {'wine' : wine, "entree" : entree, "dessert" : dessert}

# 위치 인자를 사용한 함수 호출
menu('chardonnay', 'chicken', 'cake')

# 키워드 인자를 사용한 함수 호출
menu(wine='chardonnay', dessert='cake', entree='chicken')

args *과 kwargs **

파이썬에서 *은 포인터가 아니라 매개변수에서 __위치인자들을 튜플 하나로 묶어주는 역할__을 한다(포인터에 익숙한 나로서는 이 기능이 항상 헷갈린다).

**은 키워드인자들을 딕셔너리로 하나로 묶어준다.

마찬가지로, 위치인자를 나타낸느 args를 먼저 배치해야 한다.

함수도 객체다!

파이썬에서는 숫자, 문자열, 튜플, 리스트, 그리고 함수 할 것 없이 모두 객체이다. 이 말인즉슨, 우리가 숫자를 변수로 사용하고 함수의 인자로 사용하고, 리스트의 아이템으로 사용하는 것처럼 함수도 같은 방식으로 사용할 수 있다는 뜻이다.

def answer() :
  print("Function answer is called")
  
def run_something(func): # 함수명을 파라미터로
  func()
  
>>> run_something(answer)
# Function answer is called will be printed

그럼 아마 파이썬에서는 전역 변수와 같은 이름을 가진 함수를 사용하지 않는 게 좋겠다. 만약에 그렇다면 뒤에 정의된 것으로 덮어써질테니까 (from xxx import * 하지 않는 것과 비슷한 이유)

내부 함수

C/C++을 많이 쓴 나로서는 처음에 접했을 때 가장 놀라웠던 건 바로 이 내부 함수의 개념이었다. C에서 함수의 생명 주기는 return이 되면 끝나기 때문에 함수 안에 내부 함수가 있어도 리턴이 되면 생명이 끝난다고 생각했기 때문이다. 그런데 만약에 겉함수의 리턴값이 내부함수의 함수명인 경우 refcounter가 하나 있기 때문에 외부함수의 리턴값을 바탕으로 내부함수를 한번 더 호출할 수 있게 되는 것.

def outer() :
  def add(a, b):
    return a+b
  return inner
  
>>> func = outer()
>>> func(1, 2)
# 3이 출력

클로져(Closure)

몰랐는데 이런 동작을 하는 걸 클로져라고 부르나보다. 클로져는 다른 함수에 의해 동적으로 생성되고, 바깥 함수로부터 생성된 변수값을 변경하고, 저장할 수 있는 함수를 뜻한다.

def knights2(saying):
  def inner2():
    return "We are the knights who say : '%s'" % saying
    
>>> a = knights2("Duck") 
>>> b = knights2("Hasenpfeffer")

위 코드에서 a, b는 모두 inner2라는 내부 함수를 가리키겠지만, knights2 함수의 서로 다른 매개변수 값을 가지고 있을 것이다.

내부함수는 루프나 코드 중복을 피하기 위해 또 다른 함수 내에 어떤 복잡한 작업을 한 번 이상 수행할 때 유용하게 사용된다.

람다함수

람다함수는 간단하게 한줄로 표현되는 이름없는 함수이다.

stairs = ['thud', 'meow', 'hiss']
edit_story(stairs, lambda word : word.capitalize() + '!')

람다함수는 인자이름 : 수행할 작업의 형태로 간단하게 표현할 수 있다. 보통의 경우에는 함수를 명시적으로 작성하는 게 좋지만, 람다는 많은 작은 함수를 정의하고, 이들을 호출해서 얻은 모든 결과값을 저장해야하는 경우에 유용하다.

2 min read