2019. 10. 8. 22:36ㆍ해봤던것들
요약
기계학습은 인공지능의 한 분야로 컴퓨터가 학습할 수 있도록 하는 알고리즘과 기술을 사용하여 학습하는 것을 말합니다.
이 프로젝트에서는 손 글씨로 된 숫자 데이터로 이루어진 MNIST 데이터를 사용하여 학습합니다. 사용자가 직접 그린 손 글씨 이미지를 학습된 매개변수로 이루어진 신경망을 통과시켜 어떤 수를 입력했는지 판단하고 정확도를 출력하는 코드 작성을 목표로 합니다. 완성된 코드를 바탕으로 단순 신경망을 통한 학습이외에도 오차역전파법, CNN을 사용한 학습 데이터를 사용하여 각각의 정확도를 비교합니다.
프로젝트 준비(설계)
코드의 실행순서를 간략하게 요약하면 다음과 같습니다.
1. 코드를 실행시키면 CV창이 보여지고 사용자가 CV창에 마우스를 사용해서 숫자를 그립니다.
2. 스페이스바를 누르면 28x28 사이즈로 변환 후 전처리
3. 학습된 매개변수가 들어있는 신경망의 네트워크를 거쳐 입력된 손 글씨 이미지가 어떤 숫자인지 판단
4. 정답과 정확도를 CV창에 나타냅니다.
프로그램의 실행순서의 도식화는 아래의 그림과 같습니다.
사용된 모듈
*import sys, os sys.path.append(os.pardir) : 다른 파일에 있는 파이썬 코드의 함수(모듈)를 불러오기 위해서 사용
*import sigmoid, softmax : 신경망의 활성화 함수입니다.
*import numpy as np : 이미지 배열의 크기를 변경, 확률이 가장 높은 원소를 찾아내서 정답을 구하기 위해 사용
*import pickle : 이미 학습이 완료된 매개변수인 (가중치, 편향)들을 불러오기 위해서 사용
*import cv2 : 모듈은 마우스로 손 글씨를 입력하고 이미지를 저장, 불러오기 하는데 사용, 이미지의 사이즈 조절과 정답과 정확도를 출력하는데 사용되었습니다.
학습
학습 데이터는 약93퍼센트 확률의 정확도를 가진 “sample_weight” 피클 파일을 사용했습니다.
피클 파일에는 학습된 가중치 매개변수(가중치, 편향)의 값이 dictionary 타입으로 저장되어 있기 때문에 실행할 때마다 학습해야 하는 번거로움 없이 바로 매개변수 값들을 사용할 수 있습니다.
피클로 불러온 매개변수들은 네트워크에 넣고 예측 값을 구합니다.
def predict(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = softmax(a3)
return y
예측 값을 구하기 위해 predict라는 함수를 사용했습니다. 네트워크 값에는 피클로 받아온 매개변수의 값들이 들어가고 x의 값은 2-2에서 전처리한 이미지의 값이 들어가게 됩니다.
x의 값이 shape(1, 783) 이기 때문에 1개의 값이 들어가서 1개의 y값을 출력합니다.
위 코드의 predict함수를 실행했을 때 아래의 그림과 같은 과정을 거쳐 y값이 구해지게 됩니다.
위 그림에서 보이듯 직접 쓴 손 글씨 이미지 값이 x값에 들어가고 피클로 가져온 이미 구해진 매개변수 값(B, W)은 네트워크를 거쳐 y값을 구하게 됩니다. 그 과정에서 sigmoid함수를 사용하는데 sigmoid함수를 거치면 0과 1사이의 값을 가지게 되어서 확률 값을 쉽게 구할 수 있기 때문입니다. 마찬가지로 softmax함수는 0과 1사이의 실수를 출력 값으로 가지고 출력한 값의 총 합이 1이기 때문에 출력을 확률로 해석할 수 있기 때문에 사용했습니다.
p= np.argmax(y) # 확률이 가장 높은 원소의 인덱스를 얻는다.
ymax = max(y)
text1 =("Accuracy:" + str(ymax))
text2 = str(p)
print(text1)
print(text2) #5
위 코드와 같이 손 글씨로 5를 그렸을 때 예측한 결과 값에서 확률이 가장 높은 원소의 인덱스(p)를 정답으로 출력하고 그 확률(ymax)을 정확도로 출력했습니다.