이번 글에서는 "딥러닝"에 대해 간단히 소개하고자 한다.
우리는 지난 글에서 기계학습에 대해서, 그 중에서도 선형회귀모델을 분석하는
간단한 예제를 진행했었다.
기계학습 중에서도 최근 큰 성공을 거두고 있는 딥러닝이라는 기술에 대해 알아보자.
인간의 뇌는 뉴런이라는 수많은 신경세포가 연결되어있다.
이들은 서로 화학적 신호를 주고 받는다.
인간의 뇌와 유사하도록 인공적인 신경세포를 흉내내는 프로그램을 컴퓨터 과학자들은
"퍼셉트론 perceptron" 이라고 한다.
퍼셉트론이 하나의 신경세포를 흉내내는 것이라면 인간의 뇌는 입력신호를 바로 출력으로 바꾸는 것이 아니라
입력신호를 받아 숨겨진 여러 층을 거친 뒤에 출력신호를 내어 놓을 것이다.
이것을 복잡하게 만들면 많은 층을 거쳐 가는 깊은 신경망의 될 것이다.
이것이 딥러닝 개념의 시작이다.
단순한 형태의 인공 신경망은 두 개의 입력 노드와 하나의 출력 노드가 연결된 것으로
표현할 수 있다.
입력 데이터는 입력 노드에 전달되고, 입력 노드는 출력 노드에 연결되어 있다.
이 신경망 연결을 통해 신호가 전달되는 것이다.
신호의 전달은 입력이 그대로 넘겨지는 것이 아니라 연결강도가 곱해져서 출력 노드로 넘어가게 된다.
출력 노드는 두 개의 기능으로 구분할 수 있다.
먼저 전달되어 오는 신호를 모두 합하는 부분이다.
이렇게 합산된 신호에 따라 다음 계층으로 신호를 보낼 것인지 말 것인지는 "활성화 activation" 함수에 의해 결정된다.
만약 이 노드가 최종 노드라고 하면 이 결과가 옳은 지 답이 되는 레이블과 비교하여 오차를 구할 수 있다.
이제 우리는 Tensorflow 에 대해 알아보려 한다.
텐서플로우는 구글이 2011년에 개발을 시작하여 2015년에 오픈 소스로 공개한 기계학습 라이브러리이다.
머신러닝과 딥러닝을 위한 플랫폼으로 여러 종류가 있지만
현재 가장 많은 사용자를 확보하고 있는 플랫폼이 텐서플로우다.
우수한 기능과 서비스를 제공하고 있으며, 병렬처리를 잘 지원한다.
또한 고급 신경망 네트워크 모델을 쉽게 구현할 수 있다.
우선 텐서플로우를 사용하기 이전에 우리는 파이썬 개발을 위한 새로운 환경을 사용해보고자 한다.
바로 구글의 Colaboratory 라는 것인데, 줄여서 코랩 colab 이라고 부른다.
이 웹 서비스는 클라우드 환경에서 파이썬 개발이 가능하다.
다음 링크에 접속해서 로그인을 진행하자.
https://colab.research.google.com/
로그인을 하고 새로운 파이썬 파일을 생성한 이후 파이썬 코드를 작성해보자.
코드를 작성한 이후 Ctrl+Enter 를 누르면 프로그램을 실행시킬 수 있다.
그럼 이제 코랩을 사용해서 바로 텐서플로우를 간편하게 이용해보자.
앞선 글에서 당뇨병환자 데이터를 가지고 선형회귀 모델 예제를 진행했듯이,
텐서플로우 역시 학습 데이터를 제공하고 있다.
그 중 하나가 바로 패션 MNIST 이다.
운동화나 셔츠같은 옷과 신발의 이미지와 이 이미지에 대한 레이블을 제공하고 있다.
이제 이 데이터를 읽어와보자.
코드는 다음과 같다.
import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
# 패션 MNIST 데이터는 keras의 데이터셋에 있는데 이를 읽어와서 학습용, 테스트 데이터로 구분
fashion_mnist = keras.datasets.fashion_mnist
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
텐서플로우에서는 이미지를 제공하는 케라스라는 모듈을 포함하고 있고,
이 이미지 데이터셋을 fashion_mnist 라는 경로를 통해서 읽어올 수 있다.
실행결과는 다음과 같다.
이제 가져온 데이터를 좀 더 상세하게 살펴보자.
학습 데이터 집합에 있는 데이터 중에서 가장 먼저 나타나는 3개의 이미지를 가져와서 화면에 출력해보자.
우리가 앞서 배웠던 matplotlib 을 사용하면 되겠다.
fig = plt.figure()
ax1 = fig.add_subplot(1, 3, 1)
ax2 = fig.add_subplot(1, 3, 2)
ax3 = fig.add_subplot(1, 3, 3)
ax1.imshow(train_images[0]) # 첫 번째 훈련용 데이터
ax2.imshow(train_images[1]) # 두 번째 훈련용 데이터
ax3.imshow(train_images[2]) # 세 번째 훈련용 데이터
plt.show()
각각 구두, 티셔츠, 티셔츠임을 확인할 수 있다.
이제 이 세 이미지의 레이블을 출력해보자.
print(train_labels[:3]) # 첫 세 개의 레이블을 출력해 본다
딥러닝이라는 것은 인공신경망의 층을 깊이 쌓아 학습을 하는 것이다.
다음 코드로 몇 개의 신경망 층을 형성해보자.
model = keras.Sequential([
keras.layers.Flatten(input_shape=(28, 28)),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dense(10, activation='softmax')
])
이는 3개의 층을 가진 네트워크 모델 생성을 의미한다.
Flatten 은 2차원 입력을 1차원으로 변경한다.
그 다음 두 층은 촘촘한 연결을 하는 Dense 네트워크이다.
Flatten 네트워크에는 입력을 그대로 한 줄로 만드는 것이기 때문에 필요한 매개변수는 입력의 크기이다.
이 경우는 28X28 이다
Dense 네트워크의 입력은 앞 층에서 주어지기 때문에
몇 개의 출력으로 연결할지를 정하는 매개변수가 있다.
그리고 출력 값을 결정하는 함수가 "활성화 activation" 함수이다.
위의 예에서는 ReLU 와 SoftMax 를 사용하고 있다.
위에서 만든 모델은 아직 데이터를 가지고 학습을 한 상태가 아니다.
신경망의 학습은 기본적으로 추측을 한 뒤에 정답과 비교하여 오차가 얼마인 지 확인한 뒤에
이 오차를 줄이는 방법으로 연결의 강도를 조절하는 것이다.
오차를 측정하는 방법과 오차를 줄이는 방법을 지정해야 학습이 이루어질 수 있다.
다음 코드를 입력하여 설정하자.
model.compile(optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])
모델을 점점 더 좋은 상태로 만드는 것을 "최적화 optimization" 이라고 부른다.
이를 위해서는 현재 모델이 얼마나 잘못되었는지를 알아야 한다.
이 오차를 측정하는 것이 "손실함수" 이다.
여기서는 sparse_categorical_crossentropy 함수를 사용하기로 했다.
모델이 완성되면 훈련 데이터와 정답 데이터를 주고 학습을 실시한다.
학습 시작함수는 fit() 메소드인데, 훈련용 입력과 여기에 대응하는 정답 레이블 데이터 셋을 차례로 주면 된다.
훈련 데이터 모음을 가지고 한 번 훈련을 실시하는 것을 "에폭 epoch" 이라고 부른다.
아래에서는 5 개의 에폭을 지정하였으므로 훈련을 5 차례 실시하는 것이다.
model.fit(train_images, train_labels, epochs=5)
에폭이 진행되면서 매 에폭 단계에서의 손실값 loss 와 정확도 accuracy 가 화면에 출력된다.
이 값의 변화를 자세하게 살펴보면 훈련이 진행됨에 따라 손실값은 감소하고,
예측의 정확성 값은 증가함을 확인할 수 있다.
이제 테스트 데이터를 이용해 이 모델이 정답 레이블을 잘 맞히는지 확인해보자.
test_loss, test_acc = model.evaluate(test_images, test_labels, verbose=2)
print('\n테스트 정확도:', test_acc)
우리가 학습을 하는 이유는 이렇게 해서 얻은 모델을 새로운 데이터에 적용하기 위해서이다.
위에서 훈련시킨 모델을 사용해 어떤 이미지든 분류해보고 싶다.
대상이 될만한 데이터를 우선 확보하자.
가장 간단한 것은 이미 가지고 있늰 test_images 배열에 있는 이미지들이다.
이 데이터의 형태를 출력해보면 (10000, 28, 28) 로 나타나는데,
이것은 28X28 크기의 이미지 10,000 개를 가진 3차원 배열이라는 의미이다.
이 중에 하나의 데이터를 넘파이의 random 을 이용하여 무작위로 선택하자.
randimt() 함수로 임의의 인덱스를 만들어 해당 위치의 이미지를 가져와 화면에 그려보자
import numpy as np
randIdx = np.random.randint(0, 1000)
plt.imshow(test_images[randIdx])
이 데이터를 모델에 집어 넣어 결과를 얻어 내는 것은 predict() 함수이다.
예측을 진행해보자.
진행하는 도중 에러가 뜨는 것을 확인할 수 있었다.
이유는 모델에서 사용하는 차원과 일치하지 않아서 이다.
위에서 우리는 28X28 크기 이미지가 여러 개 담길 수 있는 3차원 배열 입력을 처리하는 모델을 만들었는데,
test_images[randidx] 의 형태는 (28, 28) 이고,
이것은 28개 1차원 배열을 입력 데이터로 하고, 이 입력 데이터가 28개 제공된 것으로 해석한 것이다.
우리는 이를 넘파이의 newaxis 를 이용해 해결할 수 있다.
yhat = model.predict( test_images[randIdx][np.newaxis, :, :])
yhat
이제 predict() 함수를 실행시키면, 각각의 레이블과 일치하는 정도를 출력하는데
이 값을 살펴보면 출력 노드 10개 중에서 가장 큰 출력을 갖는 노드는 3번 노드라는 것을 확인 할 수 있다.
3번은 여성용 드레스를 의미한다.
우리는 이번 글에서 텐서플로우를 이용해 딥러닝에 대한 것을
아주 간단하게 맛만 보았다.
지금은 4차 산업혁명 시대이고, 인공지능에 대해 알고 있는 것은 중요한 무기가 된다.
인공지능에 대해 더 공부하고 흥미를 붙이면,
재밌는 경험을 할 수 있을 것이라 생각한다.
책을 공부하며 파이썬 기초 문법에서부터 딥러닝이 어떤 것인지 경험하는 것까지,
좋은 경험이 되었다.
출처 : 따라하며 배우는 파이썬과 데이터 과학 - 천인국, 박동규, 강영민