본문 바로가기

인공지능/이론 적용

Single-layer Perceptron for Multi-class Classification

Single-layer Perceptron for Multi-class Classification

MNIST Dataset

Single-layer Perceptron for Multi-class Classification

0~9 사이의 흑백 손글씨가 무슨 숫자인지 알아맞히는 알고리즘을 작성해보도록 하겠다.


mnist.load_data()에 커서를 옮긴 후 Shift+Enter를 쳐서 나온 설명에서 Returns 항목을 보면

<Tuple of Numpy arrays: (x_train, y_train), (x_test, y_test).>라고 쓰여있다.
그것을 토대로 mnist.load_data()의 반환형식을 파악한 후 해당하는 형태로 값을 받아주면 된다.

In [1]:
import numpy as np
from keras.datasets import mnist

(X_train, y_train), (X_test, y_test) = mnist.load_data()

print(X_train.shape, X_test.shape)
print(y_train.shape, y_test.shape)
Using TensorFlow backend.
(60000, 28, 28) (10000, 28, 28)
(60000,) (10000,)

28x28 size의 train 이미지가 6만개, test 이미지가 1만개 있음을 확인할 수 있다.
또한 정답이 들어있는 train과 test값들도 각각 6만개와 1만개씩 있음을 확인할 수 있다.


X에 들어있는 이미지와 y에 들어있는 label값이 잘 매칭되어 있는지 확인해 보겠다.
각각 0번부터 9번째 index의 값들을 추출해 비교해본다.

In [2]:
import matplotlib.pyplot as plt
%matplotlib inline

plt.gray() # mnist 데이터가 흑백이란 것을 명시

print(y_train[0:10])

figures, axes = plt.subplots(nrows=2, ncols=5)
figures.set_size_inches(18, 8)

for i in range(10):
    axes[int(i / 5)][i % 5].matshow(X_train[i])
[5 0 4 1 9 2 1 3 1 4]
<Figure size 432x288 with 0 Axes>

확인결과 잘 일치하고 있음을 알 수 있다.


Preprocessing

본격적으로 알고리즘을 작성하기에 앞서 몇가지 전처리(Preprocessing) 작업을 해주겠다.

먼저 3차원 배열로 구성되어있는 X값들을 2차원 배열의 형태로 바꿔주겠다.
그럼 마치 X_train의 경우 784개의 특성을 가지고 있는 6만개의 데이터셋이 되는데 이는 지금껏 다뤄오던 2차원 배열형태라서 친숙하고 쉬워보인다.

In [3]:
X_train = X_train.reshape(60000, 28 * 28)
X_test = X_test.reshape(10000, 28 * 28)

print(X_train.shape, X_test.shape)
(60000, 784) (10000, 784)

다음으론 y값들을 One-hot encoding 해주겠다.

In [4]:
y_train_hot = np.eye(10)[y_train]
y_test_hot = np.eye(10)[y_test]

print(y_train_hot.shape)
print(y_test_hot.shape)
(60000, 10)
(10000, 10)

아래와 같이 잘 되었음을 확인할 수 있다.

In [5]:
print(y_train[0:10])
print(y_train_hot[0:10])
[5 0 4 1 9 2 1 3 1 4]
[[0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
 [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]
 [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
 [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]]

Classification문제를 풀기 위한 수단으로 sigmoid function을 만들어준다. sigmoid의 역할은 값을 squashing하여 0~1사이로 그 범위를 좁혀주는 역할을 한다.

In [6]:
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

잘 동작하는지 확인해보겠다.

In [7]:
xx = np.linspace(-10, 10, num=41)
yy = sigmoid(xx)

plt.plot(xx, yy)
Out[7]:
[<matplotlib.lines.Line2D at 0x24dfe035e88>]

전형적인 sigmoid 그래프가 그려짐을 확인할 수 있다.


이제 본격적으로 Perceptron 알고리즘 작성을 시작해보자.

In [8]:
num_epoch = 1000
learning_rate = 0.005

num_data = X_train.shape[0]

w = np.zeros((10, 784))
b = np.zeros((10, 1))

for epoch in range(num_epoch):
    y_predict_hot = np.dot(w, X_train.T) + b
    y_predict_hot = sigmoid(y_predict_hot)
    
    y_predict = np.argmax(y_predict_hot, axis=0)
    
    accuracy = (y_train == y_predict).mean()
    
    if 0.90 < accuracy:
        break
        
    if epoch % 50 == 0:
        print(f"{epoch} accuracy = {accuracy:.5f}")
        
    w -= learning_rate * np.dot((y_predict_hot - y_train_hot.T), X_train) / num_data
    b -= learning_rate * (y_predict_hot - y_train_hot.T).mean(axis=1, keepdims=True)
    
print('----' * 10)
print(f"{epoch} accuracy = {accuracy:.5f}")
0 accuracy = 0.09872
50 accuracy = 0.76080
100 accuracy = 0.74943
150 accuracy = 0.83908
200 accuracy = 0.79268
250 accuracy = 0.83900
300 accuracy = 0.68175
350 accuracy = 0.82412
400 accuracy = 0.84523
450 accuracy = 0.85333
----------------------------------------
469 accuracy = 0.90167

끝으로 알고리즘이 훈련과정에서는 접해보지 못했던 Test 데이터들에 대해서도 제대로 동작하는지 확인해 해보겠다.

In [9]:
import pandas as pd

y_predict_hot = np.dot(w, X_test.T) + b
y_predict_hot = sigmoid(y_predict_hot)
y_predict = np.argmax(y_predict_hot, axis=0)

test_result = pd.DataFrame({'actual': y_test, 'predict': y_predict})

test_accuracy = (test_result['actual'] == test_result['predict']).mean()

print(f"Accuracy(test) = {test_accuracy:.5f}")

print(test_result.shape)
test_result.head(10)
Accuracy(test) = 0.90060
(10000, 2)
Out[9]:
actual predict
0 7 7
1 2 2
2 1 1
3 0 0
4 4 4
5 1 1
6 4 4
7 9 9
8 5 6
9 9 9

훈련 데이터와 예측률이 거의 동일하단 것을 확인할 수 있다.

'인공지능 > 이론 적용' 카테고리의 다른 글

MNIST with multi-layer perceptron  (0) 2020.02.12
Single-layer Perceptron 적용  (0) 2020.02.10