Keras - 수치 예측하기 예제

|

Keras를 이용한 수치 예측하기 예제

다음과 같은 랜덤 데이터셋을 만들었을 때, 그 데이터를 학습한 다음 향후 들어오는 입력값을 예측하는 예제코드입니다.

import numpy as np

x_train = np.random.random((1000, 1))
y_train = x_train * 2 + np.random.random((1000, 1)) / 3.0

x_test = np.random.random((100, 1))
y_test = x_test * 2 + np.random.random((100, 1)) / 3.0

import matplotlib.pyplot as plt

plt.plot(x_train, y_train, 'ro')
plt.plot(x_test, y_test, 'bo')
plt.legend(['train', 'test'], loc='upper left')
plt.show()

Image

입력값 X에 2를 곱해서 Y 값을 만들어내는 식이기 때문에 `Y = w * X + b’ 형태의 수식으로 표현할 수 있으며, w는 2에 가깝고, b는 0.16에 가까워지면 정답에 근접해집니다.


일반적인 선형회귀 모델(numpy 활용)

import numpy as np
from sklearn.metrics import mean_squared_error

x_train = np.random.random((1000, 1))
y_train = x_train * 2 + np.random.random((1000, 1)) / 3.0

x_test = np.random.random((100, 1))
y_test = x_test * 2 + np.random.random((100, 1)) / 3.0

x_train = x_train.reshape(1000, )
y_train = y_train.reshape(1000, )
x_test = x_test.reshape(100, )
y_test = y_test.reshape(100, )

w = np.cov(x_train, y_train, bias=1)[0, 1] / np.var(x_train)
b = np.average(y_train) - w * np.average(x_train)

print('w:{0}, b:{1}'.format(w, b))

y_predict = w * x_test + b
mse = mean_squared_error(y_test, y_predict)
print('mse: {}'.format(mse))


퍼셉트론 신경망 모델

import numpy as np
from keras.models import Sequential
from keras.layers import Dense

x_train = np.random.random((1000, 1))
y_train = x_train * 2 + np.random.random((1000, 1)) / 3.0

x_test = np.random.random((100, 1))
y_test = x_test * 2 + np.random.random((100, 1)) / 3.0

model = Sequential()
model.add(Dense(1, input_dim=1))

model.compile(optimizer='rmsprop', loss='mse')

hist = model.fit(x_train, y_train, epochs=50, batch_size=10)
w, b = model.get_weights()
print('w:{0}, b:{1}'.format(w, b))

import matplotlib.pyplot as plt

plt.plot(hist.history['loss'])
plt.ylim(0.0, 1.5)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train'], loc='upper left')
plt.show()

loss = model.evaluate(x_test, y_test, batch_size=10)
print('loss: {0}'.format(loss))

결과는 다음과 같습니다.

w:[[2.009994]], b:[0.16119921]
...
loss: 0.010309214843437076

Image


다층 퍼셉트론 신경망 모델

import numpy as np
from keras.models import Sequential
from keras.layers import Dense

x_train = np.random.random((1000, 1))
y_train = x_train * 2 + np.random.random((1000, 1)) / 3.0

x_test = np.random.random((100, 1))
y_test = x_test * 2 + np.random.random((100, 1)) / 3.0

model = Sequential()
model.add(Dense(64, input_dim=1, activation='relu'))
model.add(Dense(1))

model.compile(optimizer='rmsprop', loss='mse')

hist = model.fit(x_train, y_train, epochs=50, batch_size=10)

import matplotlib.pyplot as plt

plt.plot(hist.history['loss'])
plt.ylim(0.0, 1.5)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.legend(['train'], loc='upper left')
plt.show()

loss = model.evaluate(x_test, y_test, batch_size=10)
print('loss: {0}'.format(loss))

결과입니다.

...
loss: 0.008995027653872967

Image

Keras - 다층 퍼셉트론(MLP, Multi-Layer Perception)

|

Keras 다층 퍼셉트론 구현

Keras에서 다층 퍼셉트론은 다음과 같은 코드를 이용해서 구현합니다.

model = Sequential()
model.add(Dense(12, input_dim=8, activation='relu'))
model.add(Dense(8, activation='relu))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

첫 번째 라인의 Sequential()으로 다층 퍼셉트론 형태를 만들겠다는 의미이며, 그 다음 라인의 Dense()들이 각 계층을 의미합니다. 또한 마지막에 compile() 과정을 거쳐 모델을 생성합니다.


Dense 파라메터

Dense() 계층을 생성할 때 각 파라메터는 다음과 같은 의미를 가집니다.

model.add(Dense(12, input_dim=8, activation='relu'))

맨 앞의 숫자 12는 해당 계층의 노드 개수입니다. input_dim=8의 경우 입력단에 8개의 데이터 항목이 존재한다는 의미이며, 보통 첫 번째 Layer에서만 input_dim 파라메터를 입력합니다. activation은 활성화 함수를 의미합니다.

활성화 함수는 다음과 같은 종류를 사용할 수 있습니다.

  • linear : 기본값이며, 가중치 결과값이 출력으로 그대로 나옵니다.
  • relu : ReLU 함수입니다. 은닉층에서 주로 사용합니다.
  • sigmoid : 주로 출력층에서 사용합니다.
  • softmax : 출력값들의 합이 1.0이 되도록 하는 함수로 보통 출력층에서 사용합니다.


compile 옵션

compile() 함수의 옵션은 각각 다음과 같습니다.

  • loss : 현재 가중치 세트를 평가하는데 사용하는 손실 함수입니다.
  • optimizer : 최적의 가중치를 찾는 최적화 알고리즘으로, adam은 효율적인 경사 하강법 알고리즘 중 하나입니다.
  • metrics : 평가 척도를 의미하며, 일반적으로 accuracy를 사용합니다.

블록체인 소개 - (4) 스마트 컨트랙트(Smart Contract)

|

스마트 컨트랙트

블록체인을 4차 산업 혁명의 대표 기술이라고 말하는 이유에는 블록체인의 핵심 기능인 ‘스마트 컨트랙트(Smart Contract)’ 때문일 것입니다. ‘똑똑한 계약’이라고도 번역하는 스마트 컨트랙트가 과연 어떤 기술인지 살짝만 포스팅해보도록 하겠습니다.


스마트 컨트랙트의 개념

우리 주위에서 흔히 볼 수 있는 부동산 계약을 생각해봅시다.

부동산 계약은 보통 집을 파는 매도자, 집을 구매하는 매수자, 그리고 중간에서 계약을 성사시켜주고 관리해주는 중개자로 구성되어 있습니다. 정해진 날짜에 계약을 하고 계약금을 걸고, 정해진 날짜에 중도금, 잔금 등을 치르면서 집 문서를 거래합니다. 스마트 컨트랙트도 비슷합니다. 부동산 거래에서는 보통 부동산 중개업자를 포함해서 계약을 진행하지만, 스마트 컨트랙트는 중개인 없이 자동으로 거래를 성사시켜줍니다.

즉, 중개자없이 계약 당사자들끼리 자동으로 거래를 할 수 있게 해주는 것이 스마트 컨트랙트입니다.

사실 별 것이 없습니다. 스마트 컨트랙트 개념은 오래된 용어입니다. 1996년 Nick Szabo에 의해 제안된 용어이고, 지금도 이미 PC나 인터넷을 통해 제공되고 있는 서비스입니다.


스마트 컨트랙트 예시

Image

위 이미지는 (블록체인과 무관한) 아주 기본적인 스마트 컨트랙트 예시입니다. 계약서 내용을 보면 계약 내용, 당사자들 정보, 금액, 보증금 등이 있습니다. 보증금은 부동산 거래에서 계약금과 같은 역할을 하는 금액입니다. 계약 미체결시 보증금을 못 돌려받도록 해서 계약의 강제성을 갖도록 하고 있습니다.


스마트 컨트랙트의 장점

스마트 컨트랙트의 가장 큰 장점은 중개인이 없다는 점입니다. 중개인이 없다보니 비용 절감 효과가 아주 큽니다.

  • 빠르고 Realtime에 가깝다.
  • 정확도가 높다. (사람에 의해 실수하는 부분이 없다.)
  • 중개자의 수를 없애거나 줄일 수 있다.
  • 비용이 절감된다.


스마트 컨트랙트 활용 사례

스마트 컨트랙트는 블록체인이 나타나기 전부터 다양한 형태로 적용되어 왔습니다. 예를 들어 불법 복제를 막는 DRM은 스마트 컨트랙트의 초기 컨셉이라고 볼 수 있습니다. 불법 복제를 막음으로써 계약 위반을 강제적으로 방지하는 개념입니다.

옥션이나 지마켓 등 온라인 쇼핑몰에서 상품을 구매하는 것도 스마트 컨트랙트의 일종입니다. 각 마켓 서비스에서는 소비자가 금액을 지불하면 상품을 보내주거나 상품 구매 내역을 증명해줍니다.

신용 카드로 자동차를 구매했다가 구매자가 할부금을 갚지 못할 경우 자동으로 자동차 문이 안 열리게 된다거나, 할부금을 갚지 못한 전자 제품이 망가지도록 Kill Switch를 적용한 것도 스마트 컨트랙트입니다.


블록체인과 스마트 컨트랙트

블록체인에서의 스마트 컨트랙트도 위 스마트 컨트랙트와 크게 다르지 않습니다. 다만 기존에는 중앙 서버에서 계약을 관리하고 증명해야 했다면, 블록체인에서는 분산 장부를 통해 네트워크에 참여한 모든 사람들이 계약을 증명한다는 점만 다릅니다.

현실 세계의 계약이든 스마트 컨트랙트든 모두 ‘조건’과 ‘실행’으로 이루어져 있습니다. 예를 들어 부동산 거래나 물건 거래는 ‘돈을 입금하면’이라는 조건과 조건이 만족되었을 때, ‘집 문서를 전달한다’라는 실행 부분으로 구성되어 있습니다.

블록체인에서도 마찬가지입니다. 어떤 조건이 만족지면 무엇인가를 실행하도록 블록체인내에 코드로 기록할 수 있습니다. 스크립트로 작성되어질 수 있으며, 블록체인에 기록되어 네트워크의 모든 노드들이 해당 계약을 확인하고 증명합니다. 계약의 강제성을 위해 두 계약자 모두에게 일정 금액의 보증금을 입력하기도 합니다. 게약 조건이 만족되면 블록체인내에 스크립트로 작성한 실행 내용이 자동으로 이행되어집니다.

비트코인같은 경우는 Contract Code라고 부르는 아주 작은 스크립트 정도를 작성가능하며(보통은 비트코인은 스마트 컨트랙트 기능이 없다라고도 많이 표현합니다.), 이더리움 같은 경우는 스마트 컨트랙트를 위해 Solidity라는 스크립트 언어를 제공하고 있습니다. 프로그래밍 언어이다보니 코딩하듯이 스마트 컨트랙트를 작성할 수 있습니다. 프라이빗 블록체인들의 경우는 대부분 스마트 컨트랙트 기능을 제공하고 있습니다. IBM 주도하의 하이퍼레저(Hyperledger)같은 경우는 Chaincode라는 이름으로 스마트 컨트랙트를 제공하고 있습니다.

스마트 컨트랙트를 이용하면 다음과 같은 일들을 자동으로 할 수 있습니다.

  • 정해진 금액을 입금하면, 영화 1시간 스트리밍 이용권을 제공
  • 전자 장비를 보증금을 맡기면서 빌리고 사용한 시간만큼만 제하고 다시 돌려받는 서비스

프로그래밍 언어처럼 표현되다보니 조건에 돈이나 금액이 들어가지 않더라도 다음과 같은 예시도 가능합니다.

  • 내일 날씨가 맑으면, 아침 6시에 깨워저

물론, 위 조건은 블록체인의 스마트 컨트랙트가 해결하지 못하는 나쁜 예제(Bad case)이긴 하지만 그만큼 다양하게 계약 코드를 작성할 수 있다는 의미입니다.


스마트 컨트랙트가 만능은 아님

사실 이 부분은 이번 포스팅에서 적을 내용은 아니지만 위에서 이상한 예제를 하나 들었기에 살짝 언급을 해봅니다.

‘내일 날씨가 맑으면, 아침 6시에 깨워줘’와 같은 계약은 ‘내일 날씨가 맑으면’이라는 조건이 너무 모호합니다. 블록체인은 합의 기반이다보니 모든 노드들의 날씨 정보가 같지 않으면 합의가 될 수가 없습니다. 물론, ‘내일 기상청에서 발표하는 서울 강남 지역의 일기 예보가 맑음이라고 뜨면’과 같이 구체적이고 객관적인 조건으로 이를 해결할 수는 있겠지만, 또다른 조건이 누락될 수도 있고 항상 모든 조건을 커버할 수는 없기 때문에 스마트 컨트랙트를 무조건 적용하기는 어렵습니다.

또한, ‘내가 농협 계좌로 100만원을 입금하면 비트코인으로 1BTC를 나에게 전송해줘’와 같은 계약문도 블록체인만으로 해결하기는 쉽지 않은 예제입니다. 농협 계좌로 100만원을 입금하는 일은 블록체인 외부의 작업이며, 송금의 결과도 블록체인 외부에서만 확인가능합니다. 즉 블록체인 내의 노드들이 해당 조건을 확인할 수도 없으며, 설사 농협에서 해당 기록을 조회할 수 있는 API를 제공한다고 하더라도 모든 노드에서 그 결과 확인을 위해 API 호출을 할 수도 없는 일입니다.

Keras - History 기능 사용하기

|

Keras 학습 이력 기능

Keras에서는 모델 학습을 위해 fit() 함수를 사용합니다. 이 때, 리턴값으로 학습 이력(History) 정보를 리턴합니다. 여기에는 다음과 같은 항목들이 포함되어 있습니다.

아래 항목들은 매 epoch 마다의 값들이 저장되어 있습니다.

  • loss : 훈련 손실값
  • acc : 훈련 정확도
  • val_loss : 검증 손실값
  • val_acc : 검증 정확도


학습 이력 확인

학습이 끝난 후 다음 코드로 쉽게 확인이 가능합니다.

hist = model.fit(X_train, Y_train, validation_data=(X_validation, Y_validation),
          epochs=30, batch_size=500)

print(hist.history['loss'])
print(hist.history['acc'])
print(hist.history['val_loss'])
print(hist.history['val_acc'])


학습 이력 그래프로 확인

matplotlibpyplot를 이용해서 각 결과를 그래프로 조회할 수 있습니다.

from keras.datasets import mnist
from keras.utils import np_utils
from keras.models import Sequential
from keras.layers import Dense

(X_train, Y_train), (X_validation, Y_validation) = mnist.load_data()

X_train = X_train.reshape(X_train.shape[0], 784).astype('float64') / 255
X_validation = X_validation.reshape(X_validation.shape[0], 784).astype('float64') / 255

Y_train = np_utils.to_categorical(Y_train, 10)
Y_validation = np_utils.to_categorical(Y_validation, 10)

model = Sequential()
model.add(Dense(512, input_dim=784, activation='relu'))
model.add(Dense(10, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam',
              metrics=['accuracy'])

hist = model.fit(X_train, Y_train, validation_data=(X_validation, Y_validation),
          epochs=30, batch_size=500)

print('\nAccuracy: {:.4f}'.format(model.evaluate(X_validation, Y_validation)[1]))


import matplotlib.pyplot as plt

fig, loss_ax = plt.subplots()
acc_ax = loss_ax.twinx()

loss_ax.plot(hist.history['loss'], 'y', label='train loss')
loss_ax.plot(hist.history['val_loss'], 'r', label='val loss')
loss_ax.set_xlabel('epoch')
loss_ax.set_ylabel('loss')
loss_ax.legend(loc='upper left')

acc_ax.plot(hist.history['acc'], 'b', label='train acc')
acc_ax.plot(hist.history['val_acc'], 'g', label='val acc')
acc_ax.set_ylabel('accuracy')
acc_ax.legend(loc='upper left')

plt.show()

Image

위와 같이 그래프로 각각의 항목들의 추이를 확인할 수 있습니다. 사실 위 경우는 학습 속도 조절을 위해 epochs 값과 batch_size 값을 임의로 조정해놓아서 과적합이 발생하는 시점을 확인할 수 없지만, 보통 epochs 값이 지나치게 클 수록 과적합이 발생하여 실제 검증 정확도 val_acc는 점점 하락하는 것을 확인할 수 있습니다.

Keras - Model.fit 옵션

|

Keras 학습 함수 fit()

Keras에서는 모델 학습을 위해 fit() 함수를 사용합니다.

model.fit(X, Y, batch_size=100, epochs=10)
  • X : 입력 데이터
  • Y : 결과(Label 값) 데이터
  • batch_size : 한 번에 학습할 때 사용하는 데이터 개수
  • epochs : 학습 데이터 반복 횟수


batch_size

batch_size는 학습할 때 문제를 몇 번 풀고 정답을 확인하는 지를 결정하는 값입니다. 만약 batch_size10이라면, 총 10개의 데이터를 학습한 다음 가중치를 1번 갱신하게 됩니다.

100문제를 풀고 가중치를 갱신하는 것과, 1문제를 풀고 가중치를 갱신하는 것은 학습 결과에 큰 차이가 있습니다. 사람이 문제집으로 공부를 하는 것과 비슷합니다. 100문제를 풀고 한 번에 채점하면서 학습하는 것과, 1문제를 풀고 채점한 다음 다음 문제를 푸는 것과 비슷합니다.

batch_size 값이 크면 클수록 여러 데이터를 기억하고 있어야 하기에 메모리가 커야 합니다. 그대신 학습 시간이 빨라집니다. batch_size 값이 작으면 학습은 꼼꼼하게 이루어질 수 있지만 학습 시간이 많이 걸립니다.


epochs

학습 데이터 전체셋을 몇 번 학습하는지를 의미합니다. 동일한 학습 데이터라고 하더라도 여러 번 학습할 수록 학습 효과는 커집니다. 하지만, 너무 많이 했을 경우 모델의 가중치가 학습 데이터에 지나치게 최적화되는 과적합(Overfitting) 현상이 발생합니다.

다양한 학습 데이터를 이용해서 학습하는 것이 제일 좋지만, 현실적으로 학습 데이터를 다량으로 획득하는 것이 어렵기 떄문에 동일 데이터를 반복해서 학습하는 것은 피하기 어렵습니다. 따라서 과적합이 발생하지 않는 적절한 학습 횟수를 찾는 것도 딥러닝이 가진 숙제 중 하나입니다.