본문으로 바로가기

4-6 로지스틱 회귀 뉴런으로 단일층 신경망 제작

category AI 2020. 11. 18. 03:12
728x90

일반적인 신경망

- 활성화 함수는 은닉층과 출력층에 포함된 한 부분으로 간주

 

단일층 신경망


단일층 신경망 구현

  • 앞서 진행한 LogisticNeuron 클래스를 복사하여 SingleLayer로 변경하여 시작

 

  • 손실 함수의 결괏값 조정해 저장 기능 추가
    • 손실 함수 결괏값 저장 리스트 self.losses를 제작
    • 샘플마다 손실 함수를 계산하고 그 결괏값을 모두 더한 다음 샘플 개수로 나눈 평균을 저장
    • self.activation()으로 계산하는 a는 np.log()의 계산을 위해 한번더 조정
    • np.clip을 이용해 조정
class SingleLayer :
    def __init__(self) :
        self.w = None
        self.b = None
        self.losses = []
    
    ....
    
    def fit(self, x, y, epochs=100) :
        self.w = np.ones(x.shape[1])        # 가중치 초기화
        self.b = 0                          # 절편 초기화
        for i in range(epochs) :            # epochs 만큼 반복
            loss = 0                        
            indexes = np.random.permutation(np.arange(len(x)))   # 인덱스 섞기
            for i in indexes :              # 모든 샘플에 대해 반복
                z = self.forpass(x[i])   # 정방향 계산
                a = self.activation(z)  # 활성화 함수 적용
                err = -(y[i] - a)        # 오차 계산
                w_grad, b_grad = self.backprop(x[i], err)    # 역방향 계산
                self.w -= w_grad        # 가중치 업데이트
                self.b -= b_grad        # 절편 업데이트
                # 안전한 로그 계산을 위해 클리핑 후 손실 누적
                a = np.clip(a, 1e-10, 1-1e-10)  
                loss += -(y[i]*np.log(a)+(1-y[i])*np.log(1-a))      # 에포크 마다 평균 손실 저장
            self.losses.append(loss/len(y))

-- 차이점이 많으니 잘 비교해가면서 수정한다.

 

  • score() 메서드 추가
    • 정확도를 계산해주는 score() 메서드 추가 predict() 메서드도 수정
    • score()는 정확도를 직접 계산시 사용한 np.mean() 사용
    def predict(self, x) :
        z = [self.forpass(x_i) for x_i in x]        # 정방향 계산
        return np.array(z) > 0                      # 계단 함수 적용

    def score(self, x, y) :
        return np.mean(self.predict(x) == y)

단일층 신경망 훈련

 

  • 단일층 신경망 훈련하고 정확도 출력
    • 객체 생성하여 확인
layer = SingleLayer()
layer.fit(x_train, y_train)
layer.score(x_test, y_test)

 

- 약 92%의 정확도를 가진다.

- 정확도가 높아진 이유는 에포크마다 훈련 세트를 무작위로 섞어 손실 함수의 값을 감소 시켰기 때문

 

  • 손실 함수 누적 값 확인
plt.plot(layer.losses)
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

- 에포크가 진행됨에 따라 손실함수 값이 점차 감소중이라는 것을 알 수 있다.

728x90