언어 : Python
개발환경 : Anaconda jupyter Notebook
사용 라이브러리 : numpy, math, scipy.special
(jupyter notebook에서는 !pip install numpy을 통해 라이브러리 설치 가능)
결과까지 나온 github 링크입니다. (star도 눌러주시면 감사합니다)
: https://github.com/Jalbin1307/multi-layer_perceptron
# 필요한 라이브러리 import
import numpy as np
import math
import scipy.special
# 데이터 시각화 함수
def output_prt(data):
x, y = data.shape
for i in range(x):
for j in range(y):
if data[i][j] == 1 :
print("■",end ='')
else :
print("□",end ='')
print("")
# Sigmoid 함수 정의
def sigmoid(x):
return scipy.special.expit(x)
# 학습시킬 초기 데이터 0~9까지 np.array로 정의
input_layer = np.array([
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1]], # 0
[[0, 0, 1, 0, 0],
[1, 1, 1, 0, 0],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[1, 1, 1, 1, 1]], # 1
[[1, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 0],
[1, 1, 1, 1, 1]], # 2
[[1, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1]], # 3
[[1, 0, 0, 1, 0],
[1, 0, 0, 1, 0],
[1, 0, 0, 1, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 1, 0]], # 4
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1]], # 5
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1]], # 6
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1]], # 7
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1]], # 8
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1]], # 9
])
num, size_x, size_y = input_layer.shape
# 0~9까지 one-hot encoding
output_layer = np.array(
[[1,0,0,0,0,0,0,0,0,0],
[0,1,0,0,0,0,0,0,0,0],
[0,0,1,0,0,0,0,0,0,0],
[0,0,0,1,0,0,0,0,0,0],
[0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0],
[0,0,0,0,0,0,1,0,0,0],
[0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,0,1,0],
[0,0,0,0,0,0,0,0,0,1]])
print(output_layer.shape)
# input data 시각화
for i in range(num):
output_prt(input_layer[i])
print("")
# 초기 가중치 설정
W1 = np.random.randn(5,25)
W2 = np.random.randn(5,10)
# parameter 설정
eta = 0.1
epochs = 10000
t1=sigmoid(np.dot(test.T,W1.T))
t2=sigmoid(np.dot(t1,W2))
# 모델 학습
for epoch in range(epochs):
for i in range(num):
m1 = sigmoid(np.dot(input_layer[i].reshape(1,25),W1.T))
m2 = sigmoid(np.dot(m1, W2))
out_error = m2*(1-m2)*(output_layer[i]-m2)
hidden_error = m1*(1-m1)*np.dot(out_error,W2.T)
W2 = W2 + eta*np.dot(m1.T,out_error)
W1 = W1 + eta*np.dot(hidden_error.T,input_layer[i].reshape(1,25))
# test data (각 숫자마다 노이즈 발생시킨 값)
test = np.array([
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 0],
[1, 1, 0, 1, 1]], # 0
[[0, 0, 1, 0, 0],
[1, 1, 1, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 1, 0, 0],
[1, 1, 1, 0, 1]], # 1
[[1, 1, 1, 1, 1],
[0, 0, 0, 0, 0],
[1, 1, 1, 0, 1],
[1, 0, 0, 0, 0],
[1, 1, 1, 1, 1]], # 2
[[0, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[0, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[0, 1, 1, 1, 1]], # 3
[[0, 0, 0, 0, 0],
[1, 0, 0, 1, 0],
[1, 0, 0, 1, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 1, 0]], # 4
[[1, 1, 1, 0, 0],
[1, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 1, 1, 1]], # 5
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 0],
[1, 1, 1, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 0, 1, 1]], # 6
[[1, 1, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[0, 0, 0, 0, 1],
[0, 0, 0, 0, 1]], # 7
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[1, 0, 1, 0, 1],
[1, 1, 0, 1, 1]], # 8
[[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1],
[0, 0, 0, 0, 1],
[1, 1, 0, 0, 1]], # 9
])
# test data 시각화
for i in range(num):
output_prt(test[i])
print("")
# 학습한 모델에 test data 입력후 결과 출력
for i in range(10):
max = 0
t1 = sigmoid(np.dot(test[i].reshape(1,25),W1.T))
t2 = sigmoid(np.dot(t1,W2))
t2 = t2.reshape(10)
for i in range(10):
if t2[i]>max:
max = t2[i]
x = i
print(x)