
λ€μΈ΅ νΌμ
νΈλ‘ μ μ
λ ₯μΈ΅(input layer)κ³Ό μΆλ ₯μΈ΅(output layer) μ¬μ΄μ μλμΈ΅(hidden layer)μ ν¬ν¨ν μΈκ³΅μ κ²½λ§ κ΅¬μ‘°μ΄λ€.
κ° μΈ΅μ λ΄λ°μΌλ‘ ꡬμ±λλ©°, μΈ΅ κ°μλ κ°μ€μΉ(weight)κ° μ°κ²°λμ΄ μλ€.
μλ°©ν₯ ν¨μ€ (Forward Pass)
μ
λ ₯μ΄ μ£Όμ΄μ§λ©΄ μ΄λ₯Ό μ κ²½λ§μ κ° μΈ΅μ λ°λΌ μλ°©ν₯μΌλ‘ μ νμμΌ μΆλ ₯μ κ³μ°νλ€. μ΄ κ³Όμ μ ν΅ν΄ μ κ²½λ§μ νμ¬μ μ
λ ₯μ λν μμΈ‘ κ°μ μμ±νκ² λλ€.
μ€μ°¨ κ³μ° (Error Estimation)
μ κ²½λ§μ μΆλ ₯κ³Ό μ λ΅(label) κ°μ μ°¨μ΄λ₯Ό κ³μ°νμ¬ μ€μ°¨(error)λ₯Ό ꡬνλ€. μ΄ μ€μ°¨λ νμ΅ κ³Όμ μμ μ€μν μ λ³΄λ‘ νμ©λλ€.
μλ°©ν₯ ν¨μ€ (Backward Pass)
κ³μ°λ μ€μ°¨λ₯Ό λ°νμΌλ‘, μ κ²½λ§μ κ°μ€μΉμ λ°μ΄μ΄μ€ κ°μ μ‘°μ νλ€. μ΄λ μ€μ°¨λ₯Ό μ€μ΄κΈ° μν λ°©ν₯μΌλ‘ μ§νλλ©°, μΌλ°μ μΌλ‘ μμ ν μκ³ λ¦¬μ¦(backpropagation)μ΄ μ¬μ©λλ€.

1980λ
λμ μμ ν μκ³ λ¦¬μ¦(backpropagation)μ΄ κ°λ°λμκ³ , μ§κΈκΉμ§λ λ₯λ¬λμ κ·Όκ°μ΄ λκ³ μλ€.
μμ ν μκ³ λ¦¬μ¦(backpropatation) μ΄λ μ κ²½λ§μ μΆλ ₯κ³Ό μ λ΅κ³Όμ μ°¨μ΄, μ¦ μ€μ°¨λ₯Ό μλ°©ν₯μΌλ‘ μ νμν€λ©΄μ μ€μ°¨λ₯Ό μ€μ΄λ λ°©ν₯μΌλ‘ κ°μ€μΉ(weight)μ λ°μ΄μ΄μ€(bias)λ₯Ό λ³κ²½νλ μκ³ λ¦¬μ¦μ΄λ€.
μ΄ κ³Όμ μμ ν΅μ¬μ μΈ μν μκ³ λ¦¬μ¦μ κ²½μ¬νκ°λ²(gradient descent)μ΄λ€.
νμ±ν ν¨μλ μ
λ ₯μ μ΄ν©μ λ°μ μΆλ ₯κ°μ κ³μ°νλ ν¨μμ΄λ€.
βοΈ νΌμ
νΈλ‘ μ κ³λ¨ ν¨μ: μ΄κΈ° νΌμ
νΈλ‘ μμλ κ³λ¨ ν¨μ(step function)λ₯Ό μ¬μ©νμλ€.
βοΈ MLPμ λΉμ ν ν¨μ: MLPμμλ λ€μν λΉμ ν ν¨μ(nonlinear function)λ€μ΄ νμ±ν ν¨μλ₯Ό μ¬μ©νμ¬ λ³΅μ‘ν ν¨ν΄μ νμ΅ν μ μκ² ν΄μ€λ€.

μΌλ°μ μΌλ‘ νμ±ν ν¨μλ‘λ λΉμ ν ν¨μκ° λ§μ΄ μ¬μ©λλ€.
μ νν¨μ λ μ΄μ΄λ μ¬λ¬κ°λ₯Ό κ²°ν©ν΄λ κ²°κ΅μ μ ν ν¨μ νλμ λ μ΄μ΄λ‘ λμΉλ μ μλ€λ κ²μ΄ μνμ μΌλ‘ μ¦λͺ
λμκΈ° λλ¬Έμ΄λ€.
(볡μ‘ν ν¨μ, κ³ μ°¨μμ ν¨ν΄, λΉμ νμ κ΄κ³λ€μ λͺ¨λΈμ΄ νμ΅ν μ μκ² λλ€.)
0μ λμΌλ©΄ 1μ μΆλ ₯νκ³ , κ·Έλ μ§ μμΌλ©΄ 0μ μΆλ ₯
# κ³λ¨ ν¨μ μ μ (λ°©λ² 1: 쑰건문 μ¬μ©)
def step(x):
if x > 0.000001: # λΆλ μμμ μ€μ°¨ λ°©μ§
return 1
else:
return 0
# κ³λ¨ ν¨μ μ μ (λ°©λ² 2: λνμ΄ λ°°μ΄μ λ°κΈ° μνμ¬ λ³κ²½)
def step(x):
result = x > 0.000001 # True λλ False
return result.astype(np.int32) # μ μλ‘ λ°ν (1 λλ 0)
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-10.0, 10.0, 0.1)
y = step(x)
plt.plot(x, y); plt.show()
Sμ ννλ₯Ό κ°μ§
1980λ
λλΆν° μ¬μ©λμ΄ μ¨ μ ν΅μ μΈ νμ±ν ν¨μ. κ³λ¨ν¨μλ μμ κΈκ²©νκ² λ³ννμ¬ λ―ΈλΆμ΄ λΆκ°λ₯νμ§λ§ μκ·Έλͺ¨μ΄λ ν¨μλ λ§€λλ½κ² λ³ννκΈ° λλ¬Έμ μΈμ μ΄λμλ λ―ΈλΆμ΄ κ°λ₯νλ€λ μ₯μ μ΄ μλ€.
κ²½μ¬νκ°λ²μ΄λΌλ μ΅μ ν κΈ°λ²μ μ μ©ν μ μλ€.

import numpy as np
import matplotlib.pyplot as plt
def sigmoid(x):
return 1.0 / (1.0 + np.exp(-x))
x = np.arange(-10.0, 10.0, 0.1)
y = sigmoid(x)
plt.plot(x, y)
plt.show()
μ΅κ·Όμ λ§μ΄ μ¬μ©λλ νμ±ν ν¨μ.
μ
λ ₯μ΄ 0μ λμΌλ©΄ κ·Έλλ‘ μΆλ ₯, μ
λ ₯μ΄ 0λ³΄λ€ μμΌλ©΄ μΆλ ₯μ 0μ΄ λλ€.
λ―ΈλΆλ κ°λ¨νκ³ μ¬μΈ΅μ κ²½λ§μμ λνλλ gradient κ°μ κ° μΌμ΄λμ§ μμμ λ§μ΄ μ¬μ©λλ€.

import numpy as np
import matplotlib.pyplot as plt
def relu(x):
return np.maximum(x, 0)
x = np.arange(-10.0, 10.0, 0.1)
y = relu(x)
plt.plot(x, y)
plt.show()
numpyμμ μ 곡νκ³ μκΈ° λλ¬Έμ, λ³λμ ν¨μ μμ±μ΄ νμνμ§ μλ€.
μκ·Έλͺ¨μ΄λ ν¨μμ μμ£Ό λΉμ·νμ§λ§ μΆλ ₯κ°μ΄ -1μμ 1κΉμ§ μ΄λ€.
RNNμμ λ§μ΄ μ¬μ©λλ€.

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-np.pi, np.pi, 60)
y = np.tanh(x)
plt.plot(x, y)
plt.show()
μλ°©ν₯ ν¨μ€λ μ
λ ₯ μ νΈκ° μ
λ ₯μΈ΅μμ μμνμ¬ μλμΈ΅μ κ±°μ³ μΆλ ₯μΈ΅μΌλ‘ μ νλλ κ³Όμ μ μλ―Ένλ€.
μλμΈ΅μ 첫 λ²μ§Έ μ λμ λν κ³μ°μμ λ€μκ³Ό κ°λ€.

XOR λ¬Έμ μ 첫 λ²μ§Έ νλ ¨ μν μ λν μλμΈ΅κ³Ό μΆλ ₯μΈ΅μ κ³μ° νλ¦
- μ λ ₯μΈ΅:
- μλμΈ΅: (
μκ·Έλͺ¨μ΄λν¨μ μ¬μ© )- μΆλ ₯μΈ΅:
λͺ¨λ λ Έλλ κ°μ€μΉ μ λ°μ΄μ΄μ€ λ₯Ό ν΅ν΄ μ°κ²°λμ΄ μμ.

νμ±ν ν¨μ(sigmoid) μ μ©:
μ¦, μ μΆλ ₯μ μ½

μ ν κ²°ν© κ°:
νμ±ν ν¨μ(sigmoid) μ μ©:
μ¦, μ μΆλ ₯μ μ½

νμ±ν ν¨μ(sigmoid) μ μ©:
μ¦, μΆλ ₯κ°μ μ½ 0.71
μ λ΅(label)μ 0
μ κ²½λ§μ μΆλ ₯μ 0.709383
β‘οΈ μ€μ°¨κ° μλΉν νΌ β μμ νλ₯Ό ν΅ν΄ κ°μ€μΉλ₯Ό μ‘°μ ν΄μΌ ν¨
μ€μΉΌλΌ κ³μ°:
νλ ¬λ‘ νν:
νμ±ν ν¨μ (sigmoid) μ μ©:
μ€μΉΌλΌ κ³μ°:
νλ ¬λ‘ νν:
νμ±ν ν¨μ (sigmoid) μ μ©:
β‘οΈ κ³μ° ν¨μ¨ ν₯μ
β‘οΈ νμ΄μ¬, ν
μνλ‘μ° μ½λ μμ± μ©μ΄
β‘οΈ λ―ΈλΆ(μμ ν)λ κΉλνκ² μ 리λ¨
import numpy as np
# μκ·Έλͺ¨μ΄λ ν¨μ
def actf(x):
return 1 / (1 + np.exp(-x))
# μκ·Έλͺ¨μ΄λ ν¨μμ λ―ΈλΆ
def actf_deriv(x):
return x * (1 - x)
# μ κ²½λ§ κ΅¬μ‘° μ μ
inputs = 2 # μ
λ ₯ μ λ κ°μ
hiddens = 2 # μλ μ λ κ°μ
outputs = 1 # μΆλ ₯ μ λ κ°μ
# νμ΅λ₯ μ€μ
learning_rate = 0.2
# XOR νλ ¨ λ°μ΄ν° (μ
λ ₯κ³Ό μ λ΅)
X = np.array([
[0, 0],
[0, 1],
[1, 0],
[1, 1]
])
T = np.array([
[0],
[1],
[1],
[0]
])
# κ°μ€μΉμ λ°μ΄μ΄μ€ μ΄κΈ°ν
W1 = np.array([[0.10, 0.20],
[0.30, 0.40]])
W2 = np.array([[0.50],
[0.60]])
B1 = np.array([0.1, 0.2])
B2 = np.array([0.3])
# μλ°©ν₯ μ ν ν¨μ
def predict(x):
layer0 = x # μ
λ ₯μΈ΅
Z1 = np.dot(layer0, W1) + B1 # μλμΈ΅ μ ν κ²°ν©
layer1 = actf(Z1) # μλμΈ΅ νμ±ν
Z2 = np.dot(layer1, W2) + B2 # μΆλ ₯μΈ΅ μ ν κ²°ν©
layer2 = actf(Z2) # μΆλ ₯μΈ΅ νμ±ν (μμΈ‘κ°)
return layer0, layer1, layer2
# μμλλ‘ κ³μ°λ¨
def test():
for x, y in zip(X, T):
x = np.reshape(x, (1, -1)) # μ
λ ₯μ 2μ°¨μμΌλ‘ λ³ν (1ν, nμ΄)
layer0, layer1, layer2 = predict(x)
print(x, y, layer2)
# ν
μ€νΈ μ€ν
test()
[[0 0]] [1] [[0.70938314]]
[[0 1]] [0] [[0.72844306]]
[[1 0]] [0] [[0.71791234]]
[[1 1]] [1] [[0.73598705]]
# νμ΅μ΄ μμΌλ―λ‘ λμλ§ μΆλ ₯λλ€.
μ κ²½λ§μμ νμ΅μ μν¬ λ λ μ€μ μΆλ ₯κ³Ό μνλ μΆλ ₯ μ¬μ΄μ μ€μ°¨λ₯Ό μ΄μ©νλ€.
μ κ²½λ§μμλ νμ΅μ μ±κ³Όλ₯Ό λνλ΄λ μ§νλ₯Ό μμ€ν¨μ(loss function)


μμΈ‘κ°κ³Ό μ λ΅ κ°μ νκ· μ κ³± μ€μ°¨
β οΈ μμ λ λ―ΈλΆμ κ°λ¨νκ² λ§λ€κΈ° μν΄ λΆλ μμ

import numpy as np
# μμΈ‘κ°κ³Ό μ λ΅κ°
y = np.array([0.0, 0.0, 0.8, 0.1, 0.0, 0.0, 0.0, 0.1, 0.0, 0.0])
target = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
# νκ· μ κ³± μ€μ°¨ ν¨μ μ μ
def MSE(target, y):
return 0.5 * np.sum((y - target) ** 2)
# μ λ΅μ κ°κΉμ΄ μμΈ‘
print(MSE(target, y)) # 0.029999...
# μμΈ‘κ°μ΄ μ λ΅κ³Ό ν¬κ² λ€λ₯Έ κ²½μ°
y = np.array([0.9, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0])
print(MSE(target, y)) # 0.81
μμ ν μκ³ λ¦¬μ¦μ μ κ²½λ§ νμ΅ λ¬Έμ λ₯Ό μ΅μ ν λ¬Έμ (optimization)λ‘ μ κ·Όνλ€.
μμ€ ν¨μμ κΈ°μΈκΈ°(1μ°¨ λ―ΈλΆκ°)λ₯Ό μ¬μ©νμ¬, μ€μ°¨λ₯Ό μ€μ΄λ λ°©ν₯μΌλ‘ κ°μ€μΉλ₯Ό μ‘°μ νλ μ΅μ ν μκ³ λ¦¬μ¦μ΄λ€.

π‘ μ κ²½λ§μ΄ μ λ΅κ³Όμ μ€μ°¨λ₯Ό κ°μ₯ μκ² λ§λ€λλ‘ κ°μ€μΉλ₯Ό νμ΅νλ κ²!
λ‘ λ―ΈλΆν κ°μ΄λ©° μμ μ μ μ κΈ°μΈκΈ°λ₯Ό λ»νλ€.
:
β κ°μ€μΉλ₯Ό μ¦κ°μν€λ©΄ μ€μ°¨λ μ¦κ°
β λ°λΌμ κ°μ€μΉλ₯Ό μ€μ΄λ λ°©ν₯μΌλ‘ μ
λ°μ΄νΈ
:
β κ°μ€μΉλ₯Ό μ¦κ°μν€λ©΄ μ€μ°¨λ κ°μ
β λ°λΌμ κ°μ€μΉλ₯Ό λ리λ λ°©ν₯μΌλ‘ μ
λ°μ΄νΈ

β‘οΈ μ€μ°¨λ₯Ό μ΅μννκΈ° μν΄ νμ κΈ°μΈκΈ°μ λ°λ λ°©ν₯μΌλ‘ κ°μ€μΉλ₯Ό μ‘°μ !
Loss function:
gradient:
β loss function: ,
gradient: β

x = 10
learning_rate = 0.2
precision = 0.00001
max_iterations = 100
# μμ€ν¨μλ₯Ό λλ€μμΌλ‘ μ μνλ€.
loss_func = lambda x: (x - 3) ** 2 + 10
# κ·ΈλλμΈνΈλ₯Ό λλ€μμΌλ‘ μ μνλ€.
# μμ€ν¨μμ 1μ°¨ λ―ΈλΆκ°μ΄λ€.
gradient = lambda x: 2 * x - 6
# κ·ΈλλμΈνΈ κ°νλ²
for i in range(max_iterations):
x = x - learning_rate * gradient(x)
print("μμ€ν¨μκ°(", x, ") =", loss_func(x))
print("μ΅μκ° =", x)
μμ€ν¨μκ°( 7.199999999999999 )= 27.639999999999993
μμ€ν¨μκ°( 5.52 )= 16.350399999999997
μμ€ν¨μκ°( 4.512 )= 12.286143999999998
μμ€ν¨μκ°( 3.9071999999999996 )= 10.82301184
μμ€ν¨μκ°( 3.54432 )= 10.2962842624
...
μμ€ν¨μκ°( 3.0000000000000004 )= 10.0
μ΅μκ° = 3.0000000000000004
from mpl_toolkits.mplot3d import axis3d
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-5, 5, 0.5)
y = np.arange(-5, 5, 0.5)
X, Y = np.meshgrid(x, y) # μ°Έκ³ λ°μ€
Z = X**2 + Y**2 # λνμ΄ μ°μ°
fig = plt.figure(figsize=(6,6))
ax = fig.add_subplot(111, projection='3d')
# 3μ°¨μ κ·Έλνλ₯Ό κ·Έλ¦°λ€.
ax.plot_surface(X, Y, Z)
plt.show()

import matplotlib.pyplot as plt
import numpy as np
# x, y μ’ν μ€μ
x = np.arange(-5, 5, 0.5)
y = np.arange(-5, 5, 0.5)
# 2D 그리λ μμ±
X, Y = np.meshgrid(x, y)
# ν¨μ f(x, y) = xΒ² + yΒ²μ κ·ΈλλμΈνΈμ λ°λ λ°©ν₯ κ³μ°
U = -2 * X
V = -2 * Y
# λ²‘ν° νλ μκ°ν
plt.figure()
Q = plt.quiver(X, Y, U, V, units='width') # νμ΄νλ‘ νν
plt.title("Gradient Descent Directions")
plt.grid(True)
plt.show()

λ€μ ν¬μ€ν
μ μμ ν Backpropagationμ λν λ΄μμ λ€λ£¨κ² λ€.