AI Development/딥러닝

다층 퍼셉트론 파이썬 구현

JinWooHong Dev 2021. 4. 14. 02:02

언어 : 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)