[회고] 신입 iOS 개발자가 되기까지 feat. 카카오 자세히보기

🛠 기타/Data & AI

단층 퍼셉트론 - 이진판단 구현

inu 2020. 7. 27. 22:22
반응형

https://inuplace.tistory.com/460?category=912534

 

단층 퍼셉트론 - 회귀분석 구현

데이터를 기반으로 전복의 고리수를 예측하는 단층 퍼셉트론을 구현해보자. 주어진 데이터는 'Sex', 'Length', 'Diameter', 'Height', 'Whole weight', 'Shucked weight', 'Viscera weight', 'Shell weight', 그리..

inuplace.tistory.com

  • 이전에 작성한 코드 중 일부를 재활용한다.
  • 별 데이터를 분석해 일반 별과 펄서를 구별한다.
  • 수업에 사용된 코드를 분석한 자료입니다.

코드 재활용

%run ../abalone.ipynb
  • 회귀분석 구현시 작성되었던 함수 일부를 활용하기 위해 해당 파일명을 run하여 코드를 사용할 수 있도록 한다.

메인함수 정의

def pulsar_exec(epoch_count = 10,mb_size = 10, report=1 ): 
    load_pulsar_dataset()     
    init_model()            
    train_and_test(epoch_count, mb_size, report)
  • 데이터를 적재하는 load_pulsar_dataset() 부분을 제외하고는 기존 회귀 코드와 유사하다.
  • 데이터를 가져오고, 모델을 초기화하고, 학습 및 테스트를 진행한다.

데이터 적재 함수 정의

def load_pulsar_dataset(): 
    with open('pulsar_stars.csv') as csvfile:
        csvreader = csv.reader(csvfile)
        next(csvreader, None)
        rows = [] 
        for row in csvreader:
            rows.append(row)

    global data, input_cnt, output_cnt  
    input_cnt, output_cnt = 8,1
    data = np.asarray(rows, dtype = 'float32') 
  • 별에 대한 정보가 담긴 pulsar_start.csv로부터 데이터를 불러온다.
  • 8개의 독립변수와 1개의 종속변수로 구성한다.
  • 따라서 input_cnt와 output_cnt는 각각 8과 1로 정의한다.
  • 최종적으로 numpy형태로 data변수를 정의한다.

시그모이드 관련 함수

def relu(x):
    return np.maximum(x,0)

def sigmoid(x): 
    return np.exp(-relu(-x)) / (1.0 + np.exp(-np.abs(x)))

def sigmoid_derv(x,y):
    return y * (1-y)

def sigmoid_cross_entropy_with_logits(z,x): 
    return relu(x) - x * z + np.log( 1 + np.exp(-np.abs(x)))

def sigmoid_cross_entropy_with_logits_derv(z,x):
    return -z + sigmoid(x)
  • 앞으로 계산에 활용되는 각종 시그모이드 관련함수를 미리 정의해놓는다.
  • 시그모이드에서 x값이 -1000 이상의 매우 작은 음수일 경우, e^-x의 값이 커져 오버플로가 발생했다는 메세지가 출력된다. (하지만 이를 무한대로 처리하여 최종 결과값은 정상적으로 처리한다.) 따라서 수식을 조금 변경했다.
  • 수식 자체는 결과적으로 동일하지만 파이썬 코드상에서 오버플로 메세지가 출력되는 것을 방지해준다.
  • 교차 엔트로피도 이와 유사한 이유로 식을 수정했다.

순전파 함수 일부 재정의

def forward_postproc(output, y): 
    entropy = sigmoid_cross_entropy_with_logits(y, output)
    loss = np.mean(entropy) 
    return loss, [y,output,entropy] 
  • 회귀와 다르게 손실함수를 교차 엔트로피로 정의한다.
  • 따라서 교차 엔트로피 값을 구한다. 그리고 그에 대한 평균값으로 손실함수값(loss)을 정의한다.
  • 역전파 과정에서 y,output,entropy 3개의 값이 모두 필요하기 때문에 aux로 해당 값들의 리스트도 전달해준다.

역전파 함수 일부 재정의

def backprop_postproc(G_loss, aux): 
    y, output, entropy = aux 

    g_loss_entropy = 1.0 / np.prod(entropy.shape)
    g_entropy_output = sigmoid_cross_entropy_with_logits_derv(y,output)

    G_entropy = g_loss_entropy * G_loss
    G_output = g_entropy_output * G_entropy

    return G_output
  • 손실함수가 MSE에서 교차 엔트로피로 바뀌었으니 손실기울기를 구하는 과정도 달라질 수 밖에 없다.
  • 앞서 정의한 교차 엔트로피 미분 값을 그대로 가져와서 사용한다.

정확도 계산 함수 재정의

def eval_accuracy(output,y):
    estimate = np.greater(output, 0) 
    answer = np.greater(y,0.5)
    correct = np.equal(estimate, answer)

    return np.mean(correct) 
  • 정확도를 계산하는 과정도 다르다.
  • 예측값과 정답값을 불린 형태로 변경한 뒤, 둘의 동일 여부를 체크하고 그의 평균값을 리턴한다.
반응형