티스토리 뷰

Implementing the hidden layer

 - 이전에 XOR 퍼셉트론을 사용해서 추가적으로 units의 layer를 추가하면

 - 우리의 네트워크 모델이 선형적으로 해결할 수 없는 문제점에 대한 해결이 가능했다.


 - 위 사진에서 보듯, multi-layer 퍼셉트론의 개념은

 - Input unit → Hidden unit → Output unit 으로 이어지는 구조를 가지고있다.

 - hidden layer에 대한 activation이 output layer의 input으로 사용된다.



- 이와같은 구조로 이어지게 된다.

 - 이 hidden layer의 수가 많을수록 정교한 네트워크를 형성하게되고

 - 이 개념이 딥러닝의 핵심이 된다.






Implementing the hidden layer

 - 신경망 네트워크에서 다층 퍼셉트론에 사용되는 수학을 먼저 훑어보자.

 - 벡터 복습

 - 행렬 복습



 - 이전까지 우리는 하나의 output node만을 다뤘었는데, 

 - 지금부터는 다중 input units와 다중 hidden units을 통해 연산을 진행하므로,

 - weights간의 인덱스가 두개가 필요하다 (ex. Wij)

 - 여기서 인덱스 i 는 input units을, j는 hidden units을 의미한다.


 - 네트워크를 표현한것인데, input unit으로는 X1, X2, X3 그리고 hidden unit으로는 h1과 h2가 있다

 - 각각의 input unit들에서 h1으로 가는 선이 주황색으로 표시되어있는데, 이 선이 의미하는 바가 weights이다.

 - weight의 인덱스에 있어 input unit의 번호를 i로, hidden unit의 번호를 j로 지정하였으므로

 - W11의 경우 X1 → h1 으로 가는 weight에 해당한다.

 - 마찬가지로 W12의 경우 X1 → h2 과 같은 방식이다.



 - 따라서 weights는 행렬로 저장되어야하고, 

 - 각 행은 input unit 중심의 weights를

 - 각 열은 hidden unit 중심의 weights와 대응된다고 볼 수 있다.



 - NumPy에서 이렇게 weights를 초기화하려면 행렬로 값을 할당해줘야 한다.

 - 만약 최초 데이터 features가 input data를 포함한 2D array일 경우 

 - 위와같이 설정해줘서 얻어낼 수 있다. 

 - 위의 결과 weights_input_to_hidden이라는 2D array 또는 행렬을 얻고, 이 때의 차원은 n_inputs 또는 n_hidden 이다.



 - 각 hidden layer unit인 Hj에 대해 위와같이 weight * input 의 합으로 처리해준다.

 - 다른 layer에서와 동일하다.

 - 이때 행렬 곱셈을 사용하여야 함.

 - 행벡터인 inputs와 weights를 곱해줘야하는데, 이를위해 dot product를 사용한다.



 - 예를들어 첫번째 hidden unit(j = 1) 에 대해 계산하려면 위와같이 input과 weight을 계산해준다.

 - 그냥 일반 행렬 곱셈과 같이 처리해주면 된다. 기억해야할 점은 dot product를 사용한다는것.

 - 위와같은 방식으로 hidden layer 에 대한 연산이 가능하다.



 - 넘파이에선 이러한 dot product 연산을 한번에 처리할 수 있음. 위와같이.

 - 당연하게 위의 연산은 각각 transpose 시켜 연산을 처리할 수 있음.



 - 당연한 얘기지만 행렬의 shape의 쌍이 맞지않으면 위와같은 에러를 출력하며 연산이 처리되지않음.



Making a column vector

 - NumPy 배열이 행벡터로 작동하더라도, 열벡터가 필요할 때가 있다.

 - 이럴때 Transpose를 적절히 이용해주면 됨. <array name>.T 와 같이 해주면 됨.

 - 대신 1차원 배열의 경우 transpose를 취해도 동일하게 행벡터를 리턴하기 때문에



 - 이렇게 처리해주면 됨



 - 또는 위와같이 2차원으로 만들어서 transpose 해주면 열벡터를 얻을 수 있다.

 - 하지만 벡터의경우 1차원으로 가지고 있는것이 직관적으로 계산하기 더 수월하다.






 - 코드로 보자면

import numpy as np

def sigmoid(x):
    """
    Calculate sigmoid
    """
    return 1/(1+np.exp(-x))

# Network size
N_input = 4
N_hidden = 3
N_output = 2

np.random.seed(42)
# Make some fake data
X = np.random.randn(4)

weights_input_to_hidden = np.random.normal(0, scale=0.1, size=(N_input, N_hidden))
weights_hidden_to_output = np.random.normal(0, scale=0.1, size=(N_hidden, N_output))


# TODO: Make a forward pass through the network

hidden_layer_in = np.dot(X, weights_input_to_hidden)
hidden_layer_out = sigmoid(hidden_layer_in)

print('Hidden-layer Output:')
print(hidden_layer_out)

output_layer_in = np.dot(hidden_layer_out, weights_hidden_to_output)
output_layer_out = sigmoid(output_layer_in)

print('Output-layer Output:')
print(output_layer_out)

 - 이런식으로 처리해준다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함