밑바닥 부터 시작 하는 딥러닝 2 - 1장

승준·2021년 4월 14일
0

신경망 복습

  • 시그모이드 함수에 대한 설명 링크
import numpy as np
# 시그모이드 함수 정의
def sigmoid(x):
    return 1 / (1 + np.exp(-x))
x = np.random.randn(10, 2) # 10의 샘플 데이터, 데이터 한개에 입력이 2개 들억마
W1 = np.random.randn(2, 4)
b1 = np.random.randn(4)
W2 = np.random.randn(4, 3)
b2 = np.random.randn(3)

h = np.matmul(x, W1) + b1
a = sigmoid(h)
s = np.matmul(a, W2) + b2

여기서 xx의 형상은 (10,2)이다. 2차원 데이터 10개가 미니배치로 처리된다는 뜻이다. 그리고 최종 출력인 ss의 형상은 (10,3)이 된다.
즉, 각 데이터는 3차원 데이터로 변환 되었다는 뜻이다. (10개의 데이터)

x
array([[-0.39959216, -1.26027167],
       [-0.13697825, -0.2312922 ],
       [ 0.13345798, -1.28692136],
       [ 0.62518337,  0.37462177],
       [-1.84475205,  0.37937758],
       [-0.32832423, -0.17646416],
       [ 1.46191943,  0.51041203],
       [ 0.04261429, -0.46560677],
       [-1.94713215,  0.54752009],
       [ 0.7493157 , -0.76367089]])
s
array([[ 0.72186119, -1.01256548, -1.10551936],
       [ 0.47398161, -0.48646988, -0.65897571],
       [ 0.52016285, -0.80258435, -1.11434382],
       [ 0.21748565, -0.08393493, -0.51858371],
       [ 0.99902309, -0.93415585, -0.43569061],
       [ 0.53207949, -0.53726852, -0.63283426],
       [ 0.05121435,  0.11233593, -0.59398933],
       [ 0.44128334, -0.50703545, -0.75716494],
       [ 1.00661807, -0.91473425, -0.37854799],
       [ 0.24762023, -0.37328523, -0.90560412]])

이렇게 신경망은 3차원 데이터를 출력한다. 따라서 각 차원의 값을 이용하여 3개의 클래스 분류를 할 수 있다. 이 경우, 출력된 3차원 벡터의 각 차원은 각 클래스에 대응하는 점수(score)가 된다.

1번째 클래스일 확률2번째 클래스일 확률3번째 클래스일 확률
-1.166188451.833879141.21169264

1.2.2 계층으로 클래스화 및 순전파 구현

신경망의 계층(Layer)를 구현 해보자.

순전파(Forward Propagation): 입력층에서 출력층으로 향하는 전파
역전파(Backward Propagatoin): 데이터(기울기)를 순전파와 반대 방향으로 전달

여기서는 각 계층을 모두 클래스 형태로 구현 할 것입니다. 본 포스팅에서는 계층을 구현할 때 다음과 같은 구현 규칙을 따르겠습니다.

  • 모든 계층은 forward()와 backward() 메소드르 가진다.
  • 모든 계층은 인스터든 변수인 params와 grads를 가진다

params: 가중치와 편향 같은 매개변수를 저장
grads: params에 저장된 각 매개변수에 대응하여, 해당 매개변수의 기울기를 보관

Sigmoid 계층 구현

class Sigmoid:
    def __init__(self):
        self.params = []
    def forward(self, x):
        return 1 / (1 + np.exp(-x))

Affine 계층 구현

class Affine:
    def __init__(self, W,b):
        self.params = [W,b] # 가중치와 편향 저장
        
    def forward(self, x):
        W,b = self.params
        out = np.matmul(x, W) + b
        return out

Affine 계층이 초기화 될때 무조건 가중치과 편향을 입력 받아 params 리스트에 저장한다. foward를 진행 할때 이 params에서 가중치와 편향을 가져와서 out을 출력 한다.

이 번 포스팅에서 구현할 신경망의 구조는 다음 그림과 같다.

class TwoLayerNet:
    def __init__(self, input_size, hidden_size, output_size):
        I,H,O = input_size, hidden_size, output_size
        
        # 가중치, 편향 초기화
        W1 = np.random.randn(I, H)
        b1 = np.random.randn(H)
        W2 = np.random.randn(H, O)
        b2 = np.random.randn(O)
        
        
        # Layer Class 저장
        self.layers = [
            Affine(W1,b1),
            Sigmoid(),
            Affine(W2, b2)
        ]
        
        # 도는 가중치를 리스트에 모은다.
        self.params = []
        for layer in self.layers:
            self.params += layer.params
            
    def predict(self, x):
        for layer in self.layers:
            x = layer.forward(x)
        return x
x = np.random.randn(10, 2)
model = TwoLayerNet(input_size = 2, hidden_size = 4, output_size = 3)
s = model.predict(x)
s
array([[-2.74807127, -0.70833847,  0.13451208],
       [-2.65646907, -0.69859353,  0.14993761],
       [-2.5864815 , -0.88469718,  0.04788455],
       [-1.52908705, -1.26782452, -0.00661778],
       [-1.67642691, -1.04623033,  0.08542495],
       [-1.91460404, -0.95817067,  0.09925629],
       [-2.5885    , -0.37993438,  0.37490405],
       [-2.2228201 , -0.93142298,  0.07506297],
       [-2.91104053, -0.88898108, -0.00955292],
       [-2.42675602, -0.90774917,  0.05919498]])

아까와 동일하게 클래스틀 통해 3개의 클래스의 값을 얻을 수 있다.

profile
내일을 기록하기 위해서 오늘을 기록합니다 🤗

0개의 댓글