케라스(Keras) - 그 간결함에 빠지다.

케라스는 파이썬으로 구현된 쉽고 간결한 딥러닝 라이브러리입니다. 딥러닝 비전문가라도 각자 분야에서 손쉽게 딥러닝 모델을 개발하고 활용할 수 있도록 케라스는 직관적인 API를 제공하고 있습니다. 내부적으로는 텐서플로우(TensorFlow), 티아노(Theano), CNTK 등의 딥러닝 전용 엔진이 구동되지만 케라스 사용자는 복잡한 내부 엔진을 알 필요는 없습니다. 직관적인 API로 쉽게 다층퍼셉트론 모델, 컨볼루션 신경망 모델, 순환 신경망 모델 또는 이를 조합한 모델은 물론 다중 입력 또는 다중 출력 등 다양한 구성을 할 수 있습니다.


케라스 주요 특징

케라스는 아래 4가지의 주요 특징을 가지고 있습니다.

  • 모듈화 (Modularity)
    • 케라스에서 제공하는 모듈은 독립적이고 설정 가능하며, 가능한 최소한의 제약사항으로 서로 연결될 수 있습니다. 모델은 시퀀스 또는 그래프로 이러한 모듈들을 구성한 것입니다.
    • 특히 신경망 층, 비용함수, 최적화기, 초기화기법, 활성화함수, 정규화기법은 모두 독립적인 모듈이며, 새로운 모델을 만들기 위해 이러한 모듈을 조합할 수 있습니다.
  • 최소주의 (Minimalism)
    • 각 모듈은 짥고 간결합니다.
    • 모든 코드는 한 번 훏어보는 것으로도 이해가능해야 합니다.
    • 단 반복 속도와 혁신성에는 다소 떨어질 수가 있습니다.
  • 쉬운 확장성
    • 새로운 클래스나 함수로 모듈을 아주 쉽게 추가할 수 있습니다.
    • 따라서 고급 연구에 필요한 다양한 표현을 할 수 있습니다.
  • 파이썬 기반
    • Caffe 처럼 별도의 모델 설정 파일이 필요없으며 파이썬 코드로 모델들이 정의됩니다.

이 멋진 케라스를 개발하고 유지보수하고 있는 사람은 구글 엔지니어인 프랑소와 쏠레(François Chollet)입니다.


케라스 기본 개념

케라스의 가장 핵심적인 데이터 구조는 바로 모델입니다. 케라스에서 제공하는 시퀀스 모델로 원하는 레이어를 쉽게 순차적으로 쌓을 수 있습니다. 다중 출력이 필요하는 등 좀 더 복잡한 모델을 구성하려면 케라스 함수 API를 사용하면 됩니다. 케라스로 딥러닝 모델을 만들 때는 다음과 같은 순서로 작성합니다. 다른 딥러닝 라이브러리와 비슷한 순서이지만 훨씬 직관적이고 간결합니다.

  1. 데이터셋 생성하기
    • 원본 데이터를 불러오거나 시뮬레이션을 통해 데이터를 생성합니다.
    • 데이터로부터 훈련셋, 검증셋, 시험셋을 생성합니다.
    • 이 때 딥러닝 모델의 학습 및 평가를 할 수 있도록 포맷 변환을 합니다.
  2. 모델 구성하기
    • 시퀀스 모델을 생성한 뒤 필요한 레이어를 추가하여 구성합니다.
    • 좀 더 복잡한 모델이 필요할 때는 케라스 함수 API를 사용합니다.
  3. 모델 학습과정 설정하기
    • 학습하기 전에 학습에 대한 설정을 수행합니다.
    • 손실 함수 및 최적화 방법을 정의합니다.
    • 케라스에서는 compile() 함수를 사용합니다.
  4. 모델 학습시키기
    • 훈련셋을 이용하여 구성한 모델로 학습시킵니다.
    • 케라스에서는 fit() 함수를 사용합니다.
  5. 학습과정 살펴보기
    • 모델 학습 시 훈련셋, 검증셋의 손실 및 정확도를 측정합니다.
    • 반복횟수에 따른 손실 및 정확도 추이를 보면서 학습 상황을 판단합니다.
  6. 모델 평가하기
    • 준비된 시험셋으로 학습한 모델을 평가합니다.
    • 케라스에서는 evaluate() 함수를 사용합니다.
  7. 모델 사용하기
    • 임의의 입력으로 모델의 출력을 얻습니다.
    • 케라스에서는 predict() 함수를 사용합니다.

손글씨 영상을 분류하는 모델을 케라스로 간단히 구현해봤습니다. 가로세로 픽셀이 28 x 28인 이미지를 입력받아 이를 784 벡터로 구성한 다음 이를 학습 및 평가하는 코드입니다. 이 간단한 코드로 93.4%의 정확도 결과를 얻었습니다. 각 함수의 설명 및 인자에 대한 설명은 여러 모델을 실습해보면서 하나씩 설명드리겠습니다.

# 0. 사용할 패키지 불러오기
from keras.utils import np_utils
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Activation

# 1. 데이터셋 생성하기
(x_train, y_train), (x_test, y_test) = mnist.load_data()
x_train = x_train.reshape(60000, 784).astype('float32') / 255.0
x_test = x_test.reshape(10000, 784).astype('float32') / 255.0
y_train = np_utils.to_categorical(y_train)
y_test = np_utils.to_categorical(y_test)

# 2. 모델 구성하기
model = Sequential()
model.add(Dense(units=64, input_dim=28*28, activation='relu'))
model.add(Dense(units=10, activation='softmax'))

# 3. 모델 학습과정 설정하기
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])

# 4. 모델 학습시키기
hist = model.fit(x_train, y_train, epochs=5, batch_size=32)

# 5. 학습과정 살펴보기
print('## training loss and acc ##')
print(hist.history['loss'])
print(hist.history['acc'])

# 6. 모델 평가하기
loss_and_metrics = model.evaluate(x_test, y_test, batch_size=32)
print('## evaluation loss and_metrics ##')
print(loss_and_metrics)

# 7. 모델 사용하기
xhat = x_test[0:1]
yhat = model.predict(xhat)
print('## yhat ##')
print(yhat)
Epoch 1/5
60000/60000 [==============================] - 2s - loss: 0.6861 - acc: 0.8214     
Epoch 2/5
60000/60000 [==============================] - 2s - loss: 0.3472 - acc: 0.9021     
Epoch 3/5
60000/60000 [==============================] - 2s - loss: 0.2972 - acc: 0.9159     
Epoch 4/5
60000/60000 [==============================] - 2s - loss: 0.2671 - acc: 0.9243     
Epoch 5/5
60000/60000 [==============================] - 2s - loss: 0.2444 - acc: 0.9311     
## training loss and acc ##
[0.68605235149065658, 0.34716726491451261, 0.29719433775146803, 0.26708923313419025, 0.24437546383142472]
[0.82138333333333335, 0.90213333333333334, 0.91591666666666671, 0.92433333333333334, 0.93113333333333337]
 9728/10000 [============================>.] - ETA: 0s## evaluation loss and_metrics ##
[0.229048886179924, 0.93520000000000003]
## yhat ##
[[  8.87035931e-05   1.47768702e-07   9.51653055e-04   3.75617994e-03
    2.82607380e-06   4.90140701e-05   2.10885389e-08   9.94055033e-01
    6.05004097e-05   1.03587494e-03]]

왜 “케라스”인가?

케라스는 초기에 ONEIROS (Open-ended Neuro-Electronic Intelligent Robot Operating System) 프로젝트의 일부로 개발되었다고 합니다. 오네이로스(ONEIROS)의 복수형이 오네이로이입니다. 케라스(κέρας)는 그리스어로 을 의미하고, 오네이로이(ονειρο)는 그리스어로 꿈을 의인화 시킨 신이라는 의미입니다. 둘 다 그리스신화에 나오는 단어입니다. 첫 강좌인 만큼 가볍게 그리스신화 얘길 조금 해볼까요?

그리스 신화에 오네이로이라고 불리는 꿈의 정령들이 있습니다. 오네이로이는 헬리오스의 궁전 근처에 살면서 두 개의 문을 통해 인간들에게 꿈을 보냅니다. 신이 사람들에게 메시지를 전할 때 오네이로이에게 부탁하여 꿈을 보낸다고 합니다. 미래에 성취될 진실은 뿔로 된 문으로 보내고 거짓은 상아로 된 문으로 보내줍니다. 즉 꿈을 통해 미래로 인도하는 역할을 오네이로이가 하고, 그때 뿔(케라스)로 된 문을 통해 꿈을 보냅니다. 신이 심기가 좋지 않을 때 거짓꿈을 보내기도 하죠. 제우스는 트로이가 곧 망할 것이라는 거짓꿈을 아가멤논에게 보내고, 아가멤논은 이 꿈을 뀐 뒤 트로이를 공격했다가 그리스군 패배하죠. 거짓꿈이니 상아의 문을 통해 전달되었겠죠? 거짓꿈을 믿었다가 패가망신한 경우입니다.

gates 그림 출처

딴 얘기이지만 오네이로이는 밤의여신 닉스와 잠의 신 힙노스의 자식들이고 수천명이나 됩니다. 그 중에 모르페우스(Morpheus)라는 신이 있는 데, 이 신은 꿈에선 인간의 모습으로 보이며, .엄청나게 정교한 흉내를 낸다고 하네요. 모르페우스의 영어발음이 모피어스인데, 영화 매트릭스에선 이 이름의 인물이 네오의 가상세계에 나타나 진실로 이끄는 역할을 하죠.

학습된 모델이 진실을 알려줄지 거짓을 알려줄지는 사실 아무도 모릅니다. 학습이나 검증과정에서의 정확도는 준비된 데이터셋으로 측정할 수 있어도 실전에서는 그 결과를 검증하기 쉽지 않죠. 오네이로이가 보낸 꿈이 진실의 문으로 온 것인지 거짓의 문으로 온 것인지 모르는 것 처럼요. 학습된 모델이 알려준 결과가 진실을 담고 있기를 바라는 염원을 담아 딥러닝 라이브러리 이름을 케라스(뿔)라고 이름이 지어진 것 같습니다.

케라스로 모델을 만들었다고 하면 실전에서 좀 더 진실을 얘기해줄 것 같은 느낌이 들기 시작하죠? 그럼 이제 본격적으로 케라스를 알아봅시다.

(본 문단은 신화에 박식한 wingikaros님의 도움으로 작성되었습니다)


같이 보기