Ruby로 Keras 다루기

Source: Deep Learning on Medium

머신러닝 관련 프로젝트를 수행할 때는 주로 파이썬을 사용합니다. SciPy나 NumPy 같은 과학/수학용 라이브러리는 물론 scikit-learn, TensorFlow, Keras, PyTorch 등 대부분의 머신러닝/딥러닝 라이브러리들이 주로 파이썬 API를 기본으로 제공하기 때문입니다.

루비를 주로 쓰거나 혹은 루비온레일스 같은 도구를 사용하다 보면 종종 파이썬의 이런 라이브러리들을 어떻게든 불러와 쓰고 싶을 때가 있습니다. 욕심일까요?

마침 구글링을 하다 PyCall 이라는 루비 라이브러리를 발견했습니다. 루비 언어로 파이썬 함수를 호출하는 기능을 제공하는 라이브러리인데, 좀더 정확하게는 파이썬의 공유 라이브러리인 libpython 모듈에 대한 루비 바인딩이라 할 수 있습니다.

사용법은 간단합니다.

우선 젬(gem)을 설치합니다.

$ gem install —pre pycall

그런 다음 코드에서 다음과 같이 사용하면 됩니다.

require ‘pycall/import’
include PyCall::Import
pyimport :math
math.sin(math.pi / 4) - Math.sin(Math::PI / 4) # => 0.0

NumPy만 사용한다면, 같은 개발자가 만든 Numpy wrapper를 사용하여 다음과 같이 파이썬 NumPy를 간단하게 불러와 사용할 수도 있습니다.

require ‘numpy’

x = Numpy.asarray([[1, 2, 3], [4, 5, 6]])
puts x
# [[1 2 3]
# [4 5 6]]

puts x[1, 1..2]
# [5 6]

puts x.T
# [[1 4]
# [2 5]
# [3 6]]

puts x.dot x.T
# [[14 32]
# [32 77]]

puts x.reshape([3, 2])
# [[1 2]
# [3 4]
# [5 6]]

물론 TensowFlow나 Keras, PyTorch 같은 도구들도 불러 쓸 수 있죠.

예를 들어 Keras를 사용하여 MNIST 데이터셋을 학습하는 모델을 한번 만들어 볼까요? (아래 예제 코드는 Keras 창시자인 François Chollet이 쓴 책『Deep Learning with Python』을 참고하였습니다)

require 'pycall/import'
include PyCall::Import

pyfrom 'keras.datasets', import: :mnist
pyfrom 'tensorflow.keras', import: :models
pyfrom 'tensorflow.keras', import: :layers
pyfrom 'keras.utils', import: :to_categorical

(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
train_images = train_images.reshape([60000, 28 * 28])
train_images = train_images.astype('float32') / 255
test_images = test_images.reshape([10000, 28 * 28])
test_images = test_images.astype('float32') / 255

model = models.Sequential.()
model.add(layers.Dense.(512, activation: 'relu', input_shape: [28 * 28,]))
model.add(layers.Dense.(10, activation: 'softmax'))

model.compile(optimizer: 'rmsprop',
loss: 'categorical_crossentropy',
metrics: ['accuracy'])

train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)

model.fit(train_images, train_labels, epochs: 5, batch_size: 128)

아래는 위 코드를 실행한 결과 입니다(모델 학습).

$ ruby keras_mnist.rb
Using TensorFlow backend.
Train on 60000 samples
Epoch 1/5
60000/60000 [==============================] - 5s 86us/sample - loss: 0.2550 - accuracy: 0.9257
Epoch 2/5
60000/60000 [==============================] - 4s 67us/sample - loss: 0.1034 - accuracy: 0.9694
Epoch 3/5
60000/60000 [==============================] - 4s 67us/sample - loss: 0.0685 - accuracy: 0.9805
Epoch 4/5
60000/60000 [==============================] - 4s 68us/sample - loss: 0.0500 - accuracy: 0.9851
Epoch 5/5
60000/60000 [==============================] - 4s 67us/sample - loss: 0.0380 - accuracy: 0.9887

학습한 모델에 대한 테스트 결과는 생략합니다.

PyCall은 루비 언어에서 파이썬을 액세스할 필요가 있을 때 간단하게 사용하기에 좋은 도구입니다. PyCall에 관한 더 자세한 소개는 이 라이브러리 개발자가 직접 쓴 문서(일본어)를 참고하세요!