파이썬 이것저것/파이썬 딥러닝 관련

[Python] 딥러닝 다층 퍼셉트론

agingcurve 2022. 7. 14. 09:05
반응형

비 선형적인 문제 해결

Input layer와 Output layer 두가지만으로 구분을 할 수 없다는 것을 깨닫고 둘 사이에 다른 것을 넣은 것을
연구하였고, 그것이 Multilayer 퍼셉트론이 만들어 졌다. 이 사이에 NAND, OR 등을 넣고 이들을 연결하는 방식으로
구성하였다. 이것의 경우, 선을 2개 그어서 이를 표현하였는데 XOR 연산은 하나의 레이어로는 표현하는게 불가능 하지만, NAND와 OR 연산을 함께하면 구분이 가능하다는 것이다. 이를 통해 다층 퍼셉트론이 만들어 졌다.그리고 중간에 있는것을 Hidden Layer라고 하여 만들어지게 되었다.

 

 

Hidden Layer가 3층 이상일때 Deep Learning단어를 사용하게 된다.
Hidden Layer층이 많을 수록 표현이 강력해진다고 볼 수 있다

 

수학적으로 본다면
y = 2x + 3 으로 시작해서  x제곱의 수를 올리면서 power가 올라가는 것처럼
히든레이어가 있는 노드 수가 많아질 수록 표현할 수 있는 power가 올라간다고 볼 수 있다.

 

 

 

 

 

결정할 수 있는 영역

히든레이어가 하나,히든레이어가 2개,히든레이어가 n개 등 다양하게 표현할 수 있게 된다.

 

다층 퍼셉트론으로 XOR gate를 구현해보자

import numpy as np


def AND_gate(x1,x2):
    
    x = np.array([x1, x2])
    
    weight = np.array([0.5, 0.5])
    
    bias = -0.7
    
    y = np.matmul(x, weight) + bias
    
    return Step_Function(y) 


def OR_gate(x1,x2):
    
    x = np.array([x1,x2])
    
    weight = np.array([0.5, 0.5])
    
    bias = -0.3
    
    y = np.matmul(x, weight) + bias
    
    return Step_Function(y) 

def NAND_gate(x1,x2):
    
    x = np.array([x1, x2])
    
    weight = np.array([-0.5 , -0.5])
    
    bias = 0.7
    
    y = np.matmul(x, weight) + bias
    
    return Step_Function(y) 


def Step_Function(y):
    
    return 1 if y >= 0 else 0


def XOR_gate(x1, x2):
    
    nand_out = NAND_gate(x1, x2)
    
    or_out = OR_gate(x1, x2)
    
    
    
    return AND_gate(nand_out, or_out)

def main():
    
    # XOR gate에 넣어줄 Input
    array = np.array([[0,0], [0,1], [1,0], [1,1]])
    
    # XOR gate를 만족하는지 출력하여 확인
    print('XOR Gate 출력')
    
    for x1, x2 in array:
        print('Input: ',x1, x2, ', Output: ', XOR_gate(x1, x2))

if __name__ == "__main__":
    main()

다층 퍼셉트론(MLP) 모델로 2D 데이터를 분류해보자

train data.txt

10 10
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 1 1 1 0 0 0 0
0 0 1 1 1 1 1 0 0 0
0 1 1 1 1 1 1 1 0 0
0 1 1 1 1 1 1 1 0 0
1 1 1 1 1 1 1 1 1 0
1 1 1 1 1 1 1 1 1 0
1 1 1 1 1 1 1 1 1 0

 

test data.txt

10 10
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 1 1 0 0
0 0 0 0 1 1 1 1 1 0
0 0 0 1 1 1 1 1 1 0
0 0 1 1 1 1 1 1 1 0
0 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1

코드작성

import numpy as np
from visual import *
from sklearn.neural_network import MLPClassifier

from elice_utils import EliceUtils
elice_utils = EliceUtils()

import warnings
warnings.filterwarnings(action='ignore')

np.random.seed(100)
    
def read_data(filename):
    
    X = []
    Y = []
    
    with open(filename) as fp:
        N, M = fp.readline().split()
        N = int(N)
        M = int(M)
        
        for i in range(N):
            line = fp.readline().split()
            for j in range(M):
                X.append([i, j])
                Y.append(int(line[j]))
    
    X = np.array(X)
    Y = np.array(Y)
    
    return (X, Y)


def train_MLP_classifier(X, Y):
    
    clf = MLPClassifier(hidden_layer_sizes =(100,100))

    clf.fit(X, Y)
        
    return clf


def report_clf_stats(clf, X, Y):
    
    hit = 0
    miss = 0
    
    for x, y in zip(X, Y):
        if clf.predict([x])[0] == y:
            hit += 1
        else:
            miss += 1
    
    score = hit / len(X) * 100
    
    print("Accuracy: %.1lf%% (%d hit / %d miss)" % (score, hit, miss))


def main():
    
    X_train, Y_train = read_data("data/train.txt")
    
    X_test, Y_test = read_data("data/test.txt")
    
    clf = train_MLP_classifier(X_train, Y_train)
    
    score = report_clf_stats(clf, X_test, Y_test)
    
    visualize(clf, X_test, Y_test)

if __name__ == "__main__":
    main()

 

퍼셉트론 선형 분류기를 이용하여 붓꽃 데이터 분류하기

import numpy as np

from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.linear_model import Perceptron

np.random.seed(100)

def load_data():
    
    iris = load_iris()
    
    X = iris.data[:,2:4]
    Y = iris.target
    
    X_train, X_test, Y_train, Y_test = train_test_split(X,Y,test_size = 0.2, random_state = 0)
    
    return X_train, X_test, Y_train, Y_test
    

def perceptron_model(X, Y):
    
    percep = Perceptron(max_iter =100 , eta0 = 1)

    percep.fit(X, Y)

    return percep

def predict(lean_model,X):
    lean_model.predict(X)
    return lean_model



def main():   
    
    X_train, X_test, Y_train, Y_test = load_data()
    
    perceptron = perceptron_model(X_train, Y_train)
    
    
    pred = predict(perceptron, X_test)
    
    accuracy = accuracy_score(pred, Y_test)
    
    print("Test 데이터에 대한 정확도 : %0.5f" % accuracy)
    
    return X_train, X_test, Y_train, Y_test, pred

if __name__ == "__main__":
    main()

 

손글씨 데이터 분류하기

import numpy as np
import random

from sklearn.datasets import load_digits
from sklearn.neural_network import MLPClassifier

import warnings
warnings.filterwarnings(action='ignore')

np.random.seed(100)

def load_data(X, Y):
    
    X_train = X[:1600]
    Y_train = Y[:1600]
    
    X_test = X[1600:]
    Y_test = Y[1600:]
    
    return X_train, Y_train, X_test, Y_test
    

def train_MLP_classifier(X, Y):
    
    clf = MLPClassifier(hidden_layer_sizes =(100,100))
    
    clf.fit(X, Y)
    
    return clf


def report_clf_stats(clf, X, Y):
    
    hit = 0
    miss = 0
    
    for x, y in zip(X, Y):
        if clf.predict([x])[0] == y:
            hit += 1
        else:
            miss += 1
    
    score = hit / len(X) * 100
    
    print("Accuracy: %.1lf%% (%d hit / %d miss)" % (score, hit, miss))


def main():
    
    digits = load_digits()
    
    X = digits.data
    Y = digits.target
    
    X_train, Y_train, X_test, Y_test = load_data(X, Y)
    
    clf = train_MLP_classifier(X_train, Y_train)
    
    score = report_clf_stats(clf, X_test, Y_test)
    
    return score

if __name__ == "__main__":
    main()