Part4- 29. 쉽게 배우는 역전파 학습법 - 10. (STEP 3) 역전파 학습법을 이용한 심층 신경망 학습 - 1,2
동적학습법을 이용하기 위해 시그모이드, loss를 class로 구현
유틸리티 함수
def _t(x):
return np.transpose(x)
def _m(A, B):
return np.matmul(A, B)
시그모이드 구현
class Sigmoid:
def __init__(self):
self.last_o = 1
# forward때
def __call__(self, x):
self.last_o = 1 / (1.0 + np.exp(-x))
return self.last_o
#BP 할때
def grad(self): # 이전 구현 : sigmoid(x)(1-sigmoid(x))
return self.last_o * (1 - self.last_o)
Mean Squared Error 구현
class MeanSquaredError:
def __init__(self):
# gradient (체인룰 사용해서 계속 가져오기 위해 미리 저장)
self.dh = 1
self.last_diff = 1
def __call__(self, h, y): # 1/2 * mean ((h - y)^2) 미분해서 1/2과 상쇄됨
self.last_diff = h - y
return 1 / 2 * np.mean(np.square(h - y))
def grad(self): # h - y
return self.last_diff
뉴런 구현(Fully connected layer 하나구현)
class Neuron:
def __init__(self, W, b, a_obj):
# Model parameters
self.W = W
self.b = b
self.a = a_obj()
# gradient
self.dW = np.zeros_like(self.W)
self.db = np.zeros_like(self.b)
self.dh = np.zeros_like(_t(self.W)) #이전입력으로 인한 gradient
self.last_x = np.zeros((self.W.shape[0])) #마지막 x를 저장 이전입력을 알고 있어야 미분하기 때문에
self.last_h = np.zeros((self.W.shape[1])) #마지막으로 나가는 출력값
def __call__(self, x):
self.last_x = x
self.last_h = _m(_t(self.W), x) + self.b
return self.a(self.last_h)
def grad(self): # dy/dh = W
return self.W * self.a.grad()
def grad_W(self, dh): #dh는 지금까지의 그라디언트를 누적해서 계산해온 값
grad = np.ones_like(self.W) #W와 같은 크기의 1로 체워줌
grad_a = self.a.grad()
#출력하나하나마다 따로 계산
for j in range(grad.shape[1]): # dy/dw = x
grad[:, j] = dh[j] * grad_a[j] * self.last_x
return grad
#b로 미분하면 단순 1
def grad_b(self, dh): # dy/dh = 1
return dh * self.a.grad()
이전과 달라진 부분
심층신경망 구현
class DNN:
def __init__(self, hidden_depth, num_neuron, input, output, activation=Sigmoid):
def init_var(i, o):
return np.random.normal(0.0, 0.01, (i, o)), np.zeros((o,))
self.sequence = list()
# First hidden layer
W, b = init_var(input, num_neuron)
self.sequence.append(Neuron(W, b, activation))
# Hidden Layers
for index in range(hidden_depth):
W, b = init_var(num_neuron, num_neuron)
self.sequence.append(Neuron(W, b, activation))
# Output Layer
W, b = init_var(num_neuron, output)
self.sequence.append(Neuron(W, b, activation))
def __call__(self, x):
for layer in self.sequence:
x = layer(x)
return x
def calc_gradient(self, loss_obj):
loss_obj.dh = loss_obj.grad() #마지막 loss function에 대한 gradient
self.sequence.append(loss_obj) #편의성을 위해 loss를 넣어주고 나중 빼줌
# back-prop loop
for i in range(len(self.sequence) - 1, 0, -1): #순서로 반대로 구현
l1 = self.sequence[i]
l0 = self.sequence[i - 1]
l0.dh = _m(l0.grad(), l1.dh)
l0.dW = l0.grad_W(l1.dh)
l0.db = l0.grad_b(l1.dh)
self.sequence.remove(loss_obj)
len(self.sequence) - 1, 0, -1)
순서를 뒤집고 0을 제외
경사하강 학습법
def gradient_descent(network, x, y, loss_obj, alpha=0.01):
loss = loss_obj(network(x), y) # Forward inference
network.calc_gradient(loss_obj) # Back-propagation
for layer in network.sequence:
layer.W += -alpha * layer.dW
layer.b += -alpha * layer.db
return loss
동작테스트
x = np.random.normal(0.0, 1.0, (10,))
y = np.random.normal(0.0, 1.0, (2,))
t = time.time()
dnn = DNN(hidden_depth=5, num_neuron=32, input=10, output=2, activation=Sigmoid)
loss_obj = MeanSquaredError()
for epoch in range(100):
loss = gradient_descent(dnn, x, y, loss_obj, alpha=0.01)
print('Epoch {}: Test loss {}'.format(epoch, loss))
print('{} seconds elapsed.'.format(time.time() - t))
엄청난 속도 향상이 생김
'책&강의 학습 > 올인원 패키지 :딥러닝&인공지능' 카테고리의 다른 글
| [패스트캠퍼스 수강 후기] 인공지능강의 100% 환급 챌린지 36회차 미션 (0) | 2020.08.03 |
|---|---|
| [패스트캠퍼스 수강 후기] 인공지능강의 100% 환급 챌린지 35회차 미션 (0) | 2020.08.02 |
| [패스트캠퍼스 수강 후기] 인공지능강의 100% 환급 챌린지 33회차 미션 (0) | 2020.07.31 |
| [패스트캠퍼스 수강 후기] 인공지능강의 100% 환급 챌린지 32회차 미션 (0) | 2020.07.30 |
| [패스트캠퍼스 수강 후기] 인공지능강의 100% 환급 챌린지 31회차 미션 (0) | 2020.07.29 |
댓글