[인공지능] 퍼셉트론(Perceptron)

Updated:

퍼셉트론

2.4-3

퍼셉트론(Perceptron)은 인공신경망의 한 종류입니다. 단층 퍼셉트론은 입력층(input layer)과 출력층(output layer)으로 구성됩니다. 입력층은 학습 데이터가 입력되는 계층입니다. 입력된 데이터는 출력층 뉴런으로 전달되어 활성 함수에 따라 값이 출력됩니다. 퍼셉트론은 각 노드의 가중치와 입력치를 곱한 것을 모두 합한 값이 활성 함수에 의해 판단됩니다. 그 값이 임계치(보통 0)보다 크면 뉴런이 활성화되고 결과 값으로 1을 출력합니다. 이때 활성화 함수는 비선형적인 계단함수입니다. 뉴런이 활성화되지 않으면 결과값으로 -1을 출력합니다. 퍼셉트론의 학습 결과는 가중치바이어스 에 의해 결정됩니다.

퍼셉트론의 문제점은 선형 분류가 되지 않는다는 점입니다. 선형 분류란 개체의 속성을 이용하여 그 개체가 속하는 그룹 또는, 클래스를 판별하는 것 입니다. 퍼셉트론은 선형 분류가 되지 않아 XOR 연산이 불가능합니다. 이번 과제를 하면서 결과 데이터로 XOR의 진리값 [0, 1, 1, 0]을 넣어보았지만, 결과가 나오지 않았습니다.

퍼셉트론의 학습 목표는 학습 벡터를 두 분류로 선형 분류하기 위한 선형 경계를 찾는 것입니다. 즉, 모든 학습 벡터를 올바르게 분류하는 가중치를 구하는 것입니다. 가중치(Weight)는 이러한 선형 경계의 절편을 나타내는 값입니다. net 값은 입력값과 가중치의 곱을 모두 합한 값으로써, 기하학적으로 해석하면 선형 경계의 방정식과 같습니다. 활성 함수(activation function)는 뉴런에서 계산된 net 값이 임계치보다 크면 1을 출력하고 임계치보다 작은 경우에는 0을 출력하는 함수입니다. 이 정의는 단층 퍼셉트론에서만 유효합니다. 다층 퍼셉트론에서는 Sigmoid, TanH, ReLU와 같이 미분 가능한 함수를 사용합니다.

뉴런(neuron)은 인공신경망을 구성하는 가장 작은 요소로써, net 값이 임계치보다 크면 활성화되면서 1을 출력하고, 임계치보다 작으면 비활성화되면서 0을 출력합니다. 에포크(epoch)는 모든 훈련 데이터를 1회 학습하는 것을 1 에포크라고 합니다. 학습이 끝난 후 전체적인 샘플을 의미하기도 합니다.

퍼셉트론 구현하기

전체 코드

#Perceptron
class Perceptron():
    #클래스 생성자
    def __init__(self, X, y, eta=0.1):
        self.Input = X
        self.goal = y
        self.eta = eta
        print("Perceptron Class")

    #학습 시키는 메소드
    def fit(self):
        Output = [0,0, 0,0]
        weight1 = [0.0, 0.0]
        weight2 = [0.0, 0.0]
        
        bias = -0.1
        Epoch = 1
        
        while(1) :
            print("\n************************* Epoch %d *************************"  % (Epoch)) 
            for i in range(4) :
                Sum = 0
                for j in range(1) :
                    Sum = self.net_input(i, j, weight1, bias)
                    
                Output[i] = self.Activate(Sum)
                        
                if Output[i] == self.goal[i]:
                    print("입력:", self.Input[i][0], self.Input[i][1],
                          " | 실제 출력:", Output[i], "| 목표 출력:", self.goal[i],
                          " | 가중치:", weight1[0], weight1[1], " | Bias:", bias)
                    continue
                else :
                    for k in range(2) :
                        weight2[k] = self.calc_nextWeight(i, k, weight1, Output)
                        
                    bias = self.calc_Bias(i, bias, Output)
                    
                weight1 = weight2
                print("입력:", self.Input[i][0], self.Input[i][1],
                          " | 실제 출력:", Output[i], "| 목표 출력:", self.goal[i],
                          " | 가중치:", weight1[0], weight1[1], " | Bias:", bias)
          
            Epoch += 1
            if Output == self.goal :
                break

    #입력 값의 총 합 계산 메소드
    def net_input(self, i, j, weight1, bias):
        result = (self.Input[i][j] * weight1[j]) + (self.Input[i][j+1] * weight1[j+1]) + bias
        return result

    #활성화 메소드
    def Activate(self, Sum):
        if(Sum >= 0):
            return 1
        else:
            return 0
        
    #가중치 계산 메소드
    def calc_nextWeight(self, i, k, weight1, Output):
        weight = weight1[k] + self.eta * self.Input[i][k] * (self.goal[i] - Output[i])
        return weight

    #바이어스 계산 메소드
    def calc_Bias(self, i, bias, Output):
        bias = bias + self.eta * (self.goal[i] - Output[i])
        return bias


if __name__ == '__main__':
    X = [[0,0],[0,1],[1,0],[1,1]]
    y = [0,1,1,0]                   #OR

    perceptron = Perceptron(X, y)   #Perceptron 객체 생성
    perceptron.fit()                #Perceptron 객체의 fit()메소드 호출

결과

논리연산 OR 학습 결과

2.4-1

논리연산 AND 학습 결과

2.4-2

Leave a comment