๋ฐ๋ฐ๋ฅ๋ถํฐ ์์ํ๋ ๋ฅ๋ฌ๋ 3 : https://www.hanbit.co.kr/store/books/look.php?p_code=B6627606922
์์ค์ฝ๋ : https://github.com/WegraLee/deep-learning-from-scratch-3
- ๋ณ์์ ๋ฐ์ดํฐ๋ ๋ณ๊ฐ๋ค.
- ๋ณ์์ ๋ฐ์ดํฐ๋ฅผ ๋์ ํน์ ํ ๋นํ๋ค.
- ๋ณ์๋ฅผ ๋ค์ฌ๋ค๋ณด๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ ์ ์๋ค(์ฐธ์กฐํ๋ค).
- ์ฐจ์(dimension), ์ถ(axis) : ๋ค์ฐจ์ ๋ฐฐ์ด์์ ์์์ ์์์ ๋ฐฉํฅ
- ์ค์นผ๋ผ(scalar) : 0์ฐจ์ ๋ฐฐ์ด
- ๋ฒกํฐ(vector) : 1์ฐจ์ ๋ฐฐ์ด
- ํ๋ ฌ(matrix) : 2์ฐจ์ ๋ฐฐ์ด
- ์ ์ : ์ด๋ค ๋ณ์๋ก๋ถํฐ ๋ค๋ฅธ ๋ณ์๋ก์ ๋์ ๊ด๊ณ๋ฅผ ์ ํ ๊ฒ
- ํฉ์ฑ ํจ์(composite function) : ์ฌ๋ฌ ํจ์๋ก ๊ตฌ์ฑ๋ ํจ์
- ๊ณ์ฐ ๊ทธ๋ํ(computational graph) : ๋ ธ๋๋ค์ ํ์ดํ๋ก ์ฐ๊ฒฐํด ๊ณ์ฐ ๊ณผ์ ์ ํํํ ๊ทธ๋ฆผ, ๊ณ์ฐ ๊ทธ๋ํ๋ฅผ ์ด์ฉํ๋ฉด ๊ฐ ๋ณ์์ ๋ํ ๋ฏธ๋ถ์ ํจ์จ์ ์ผ๋ก ๊ณ์ฐํ ์ ์๋ค.
- ๋ฏธ๋ถ : (๊ทนํ์ผ๋ก ์งง์ ์๊ฐ์์์) ๋ณํ์จ
- ์ ์ง์ฐจ๋ถ(forward difference)
- ์ค์์ฐจ๋ถ(centered difference)
- ์์น ๋ฏธ๋ถ(numerical differentation) : ๊ทผ์ฌ๊ฐ๋ฅผ ์ด์ฉํ์ฌ ํจ์์ ๋ณํ๋์ ๊ตฌํ๋ ๋ฐฉ๋ฒ
- ๊ธฐ์ธ๊ธฐ ํ์ธ(gradient checking) : ์ญ์ ํ๋ฅผ ์ ํํ๊ฒ ๊ตฌํํ๋์ง ํ์ธํ๊ธฐ ์ํด ์์น ๋ฏธ๋ถ์ ๊ฒฐ๊ณผ ์ด์ฉ
- ์ญ์ ํ(backpropagation) : ๋ณ์๋ณ ๋ฏธ๋ถ์ ๊ณ์ฐํ๋ ์๊ณ ๋ฆฌ์ฆ
- ์ฐ์ ๋ฒ์น(chain rule) : ํฉ์ฑ ํจ์์ ๋ฏธ๋ถ์ ๊ตฌ์ฑ ํจ์ ๊ฐ๊ฐ์ ๋ฏธ๋ถํ ํ ๊ณฑํ ๊ฒ๊ณผ ๊ฐ๋ค.
- ์์ค ํจ์(loss function)์ ๊ฐ ๋งค๊ฐ๋ณ์์ ๋ํ ๋ฏธ๋ถ์ ๊ณ์ฐํ๊ธฐ ์ํด ์ฌ์ฉ
- ์์ ํ์ ์ญ์ ํ์ ๋์๊ด๊ณ
- ์ญ์ ํ ์๋ํ
- Define-by-Run
- Wengert List(or tape)
- ๋์ ๊ณ์ฐ ๊ทธ๋ํ(Dynamic Computational Graph)
import numpy as np
class Variable:
def __init__(self, data):
if data is not None:
if not isinstance(data, np.ndarray):
raise TypeError('{}์(๋) ์ง์ํ์ง ์์ต๋๋ค.'.format(type(data)))
self.data = data # ํต์๊ฐ
self.grad = None # ๋ฏธ๋ถ๊ฐ
self.creator = None # ํจ์์์ ๊ด๊ณ (ํต์ฌโ)
def set_creator(self, func):
self.creator = func
def backward(self):
if self.grad is None:
self.grad = np.ones_like(self.data) # dy/dy = 1
funcs = [self.creator]
while funcs:
f = funcs.pop()
x, y = f.input, f.output
x.grad = f.backward(y.grad)
if x.creator is not None:
funcs.append(x.creator)
def as_array(x):
'''0์ฐจ์ ndarray ์ธ์คํด์ค๋ ๊ณ์ฐ ๊ฒฐ๊ณผ์ ๋ฐ์ดํฐ ํ์
์ด ๋ฌ๋ผ์ง๊ธฐ ๋๋ฌธ์ ์กฐ์ ํด์ผ ํ๋ค.'''
if np.isscalar(x):
return np.array(x)
return x
class Function:
def __call__(self, input):
x = input.data
y = self.forward(x)
output = Variable(as_array(y))
output.set_creator(self) # ํจ์์์ ๊ด๊ณ ์ค์
self.input = input # ์
๋ ฅ ๋ณ์ ๊ธฐ์ต
self.output = output # ์ถ๋ ฅ ๋ณ์ ๊ธฐ์ต
return output
def forward(self, x):
raise NotImplementedError()
def backward(self, gy):
raise NotImplementedError()
# ================ ์์ ================================
# ์์ ๊ณ์ฐ ํด๋์ค ์ ์
class Square(Function):
def forward(self, x):
y = x ** 2
return y
def backward(self, gy):
x = self.input.data
gx = 2 * x * gy
return gx
class Exp(Function):
def forward(self, x):
y = np.exp(x)
return y
def backward(self, gy):
x = self.input.data
gx = np.exp(x) * gy
return gx
# ํ์ด์ฌ ํจ์๋ก ์ ์
def square(x):
return Square()(x)
def exp(x):
return Exp()(x)
# ์์ ์คํ
x = Variable(np.array(0.5))
y = square(exp(square(x))) # ํฉ์ฑ ํจ์
y.backward() # ๋งจ ๋ง์ง๋ง ๋ณ์๋ง backward ํธ์ถ
print(x.grad) # 3.297442541400256
test.py
- ์คํ ๋ฐฉ๋ฒ
- add to last line in test.py
and run
unittest.main()
python test.py
- run test.py
python -m unittest test.py
- run tests/test*.py
python -m unittest discover tests
- add to last line in test.py