딥 러닝과 퍼셉트론

퍼셉트론(perceptron)은 인공신경망의 한 종류로서, 1957년에 코넬 항공 연구소(Cornell Aeronautical Lab)의 프랑크 로젠블라트 (Frank Rosenblatt)에 의해 고안되었다. - 위키피디아

딥 러닝은 머신 러닝의 하위 범주에 속하며 머신 러닝으로 해결하기 복잡한 문제를 해결할 수 있다.

1969년 출판된 마빈 민스키의 저서 “퍼셉트론즈”에서 단층 퍼셉트론 문제의 한계를 지적했다.

이 문제는 1980년 즈음이 되서야 다층 레이어 네트워크 구조가 발명되어 해결되었으며 딥러닝의 시초가 된다.

딥 러닝에 등장하는 다층 레이어 네트워크 구조는 마치 인간의 시냅스와 유사하며, 이 때문에 인공신경망(ANN)이라고 부른다.

소스코드

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import numpy as np

class ANN:
def __init__(self, layers):
self.W = []
self.b = []
for x_nodes, h_nodes in layers:
self.add_layer(x_nodes, h_nodes)

def add_layer(self, x_nodes, h_nodes):
self.W.append(np.random.rand(x_nodes, h_nodes))
self.b.append(np.random.rand(h_nodes))

def feed_forward(self):
delta = 1e-7
a = self.x
for i, w in enumerate(self.W):
b = self.b[i]
z = np.dot(a, w) + b
a = self.activate(z)
y = a
return -np.sum(self.t*np.log(y + delta) + (1-self.t) * np.log((1 - y) + delta))

def train(self, x, t, epochs=1, learning_rate=1e-2, activate=None, debug_step=None):
self.x = x
self.t = t
self.activate = activate or ANN.sigmoid
if not debug_step:
debug_step = int(epochs * 0.1)
f = lambda x: self.feed_forward()
for step in range(epochs):
for i in range(len(self.W)):
self.W[i] -= learning_rate * ANN.derivative(f, self.W[i])
self.b[i] -= learning_rate * ANN.derivative(f, self.b[i])
if step % debug_step == 0:
print('step = ', step, 'loss value = ', self.feed_forward())

def predict(self, input_data):
a = input_data
for i, w in enumerate(self.W):
b = self.b[i]
z = np.dot(a, w) + b
a = self.activate(z)
return a

@staticmethod
def derivative(f, x, dx=1e-5):
grad = np.zeros_like(x)
it = np.nditer(x, flags=['multi_index'], op_flags=['readwrite'])

while not it.finished:
idx = it.multi_index
tmp_val = x[idx]
x[idx] = tmp_val + dx
fx1 = f(x)
x[idx] = tmp_val - dx
fx2 = f(x)
grad[idx] = (fx1 - fx2) / (2 * dx)
x[idx] = tmp_val
it.iternext()
return grad

@staticmethod
def sigmoid(z):
return 1 / (1+np.exp(z))

XOR 문제 해결

xor with deep learning
1
2
3
4
5
6
7
8
9
10
11
12
13
14
xdata = np.array([[0, 0],[0, 1],[1, 0],[1, 1]]).reshape(4,2)
tdata = np.array([0, 1, 1, 0]).reshape(4,1)

xor_model = ANN([(2, 2), (2, 1)])
xor_model.train(xdata, tdata, epochs=30001)

test_data = np.array([[0, 0],[0, 1],[1, 0],[1, 1]])

for x in test_data:
y = xor_model.predict(x)
if y >= 0.5:
print(f'{x} = 1')
else:
print(f'{x} = 0')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
step =  0 loss value =  2.835243992618905
step = 3000 loss value = 2.6522861520968903
step = 6000 loss value = 2.1730020821222085
step = 9000 loss value = 1.7215880605383187
step = 12000 loss value = 0.6008394493810707
step = 15000 loss value = 0.24859044596202917
step = 18000 loss value = 0.14805128453811897
step = 21000 loss value = 0.10387565328910175
step = 24000 loss value = 0.0795236416934344
step = 27000 loss value = 0.06422180128812002
step = 30000 loss value = 0.05376022277921273
[0 0] = 0
[0 1] = 1
[1 0] = 1
[1 1] = 0