[Python]BackPropagation numpy로 구현하기

민지·2024년 8월 14일
0

Python

목록 보기
2/2
post-thumbnail

23-1학기에 backpropagation을 numpy로 구현했었는데
1년 지났다고 기억이 안 난다....
일단 그때 봤던 자료들을 다시 살펴봤는데 그때는 이해가 됐는데 왜 지금은 이해가 안되는걸까
다시 차분하게 정리해봐야지

2 layer라고 가정하고 numpy로 구현하기
실제로는 class로 짰는데
필요한 부분만 함수로 정리해봤다

  1. 파라미터 초기화
  2. forward
  3. backpropagation
  4. 파라미터 업데이트

1. 파라미터 초기화


def init_parameter(input_dim,num_hiddens,num_classes):

	limit_w1 = np.sqrt(6/(input_dim + num_hiddens))
    limit_w2 = np.sqrt(6/(num_hiddens + num_classes))
    
    w1 = np.random.uniform(-limit_w1,limit_w1,(input_dim,num_hiddens))
    w2 = np.random.uniform(-limit_w2,limit_w2,(num_hiddens,num_classes))
    
    b1 = np.zeros((1,num_hiddens))
    b2 = np.zeros((1,num_classes))

🧐 이때 bias도 0으로 초기화 해준다
그 이유는 ..?
-> 초기에는 가중치에 신경을 쓰는게 맞아서라고 직관적으로 이해해보자
-> 그리고 대칭성 유지 bias를 0으로 유지

2. forward

def forward(X):
	z1 = X.dot(w1) + b1
    a1 = sigmoid(z1)
    
    z2 = a1.dot(w2) + b2
    y = softmax(z2) # 마지막은softmax로 
    
    return z1,a1,z2,y

그냥 계산을 쭉 하면 되는 것

3. backpropagation

문제의 backpropagation
수식으로 보는거랑 코드로 보는거랑 이해가 잘 안된달까

def backpropagation(X,Y,z1,a1,z2,y):
	
    #일단 제일 마지막 gradient
    dz2 = -(Y-y)
    dw2 = a1.dot(dz2) /X.shape[0] # 배치 크기로 나눠준다
    db2 = np.sum(dz2,axis = 0,keepdims = True)/X.shape[0]
    
    da1 = w2.T.dot(dz2)
    dz1 = da1 * (a1*(1-a1))
    dw1 = X.T.dot(dz1) / X.shape[0] # 배치 크기로 나눠준다
    db1 =np.sum(dz1,axis = 0,keepdims = True)/X.shape[0]
	
    return dw1,db1,dw2,db2

🧐 X.shape[0]를 나누는 이유
미니 배치 학습을 위해 전체 데이터를 여러 작은 배치로 나누워서 학습을 진행함
즉, 배치 크기로 나누어 줌으로써 각 배치에서 평균 기울기를 계산 할 수 있음 -> 배치 크기에 상관없이 모델이 매번 일관된 크기의 업데이트 가능

🧐 bias 업데이트
손실함수 L에 대한 바이어스 b에 대한 기울기는
∂L/∂b
바이어스는 모든 입력 데이터에 동일하게 적용
따라서, 바이어스에 대한 기울기는 각 데이터 포인트에서 발생한 오차의 총합으로 나타낼 수 있음
바이어스는 입력 데이터와 상관없이 뉴런의 출력에 항상 일정하게 더해지는 값이다. 따라서, 바이어스를 얼마나 조정해야 할지를 결정하는 데 필요한 정보는 단순히 모든 데이터 포인트에서 발생한 오차의 총합

4. 파라미터 업데이트


lr = 0.01
z1,a1,z2,y = forward(X_batch)
dw1,db1,dw2,db2 = backward(X_batch, Y_batch, z1,a1,z2,y)

#  파라미터 업데이트
W1 -= lr * grads['dW1']
b1 -= lr * grads['db1']
W2 -= lr * grads['dW2']
b2 -= lr * grads['db2']

추가로 이야기 나온 num_hiddens는 어떻게 정해야하나...?
적절한 Hidden layer의 노드 개수에 대해서도 한 번 찾아봐야겠다
backpropagation을 완전히 이해하지는 못했는데 그래도 80%는 이해한 거 같다

0개의 댓글