neuralNetworkLearning
Neural Network Learning
: ์ ๊ฒฝ๋ง ํ์ต์์ ํ์ต์ด๋ ํ๋ จ ๋ฐ์ดํฐ๋ก๋ถํฐ ๊ฐ์ค์น ๋งค๊ฐ๋ณ์์ ์ต์ ๊ฐ์ ์๋์ผ๋ก ํ๋ํ๋ ๊ฒ
๋ฐ์ดํฐ ์ฃผ๋ ํ์ต
: ๊ธฐ๊ณํ์ต์ ๋ฐ์ดํฐ์์ ๋ต์ ์ฐพ๊ณ ๋ฐ์ดํฐ์์ ํจํด์ ๋ฐ๊ฒฌํ๊ณ ๋ฐ์ดํฐ๋ก ์ด์ผ๊ธฐ๋ฅผ ๋ง๋๋ ๊ฒ์ด๋ค
๊ธฐ๊ณํ์ต์ ๋ฐฉ๋ฒ (์ด๋ฏธ์ง์ ์)
์ฒซ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ฌ๋์ด ์๊ฐํ๋ ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ์ฌ๋๋ง๋ค ๋ฒ๋ฆ์ด ๋ฌ๋ผ ํน์ ์ง๋ ๊ท์น์ ์ฐพ๊ธฐ๋ ์ฝ์ง ์ํน ์๊ฐ๋ ์ค๋ ๊ฑธ๋ฆฐ๋ค
๋๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ด๋ฏธ์ง์์ ํน์ง(feature)์ ์ถ์ถํ๊ณ ๊ทธ ํน์ง์ ํจํด์ ๊ธฐ๊ณํ์ต ๊ธฐ์ ๋ก ํ์ตํ๋ ๋ฐฉ๋ฒ
์ด๋ฏธ์ง์ ํน์ง์ ๋ณดํต ๋ฒกํฐ๋ก ๊ธฐ์ ํ๊ณ , ์ปดํจํฐ ๋น์ ๋ถ์ผ์์๋ SIFT, SURF, HOG ๋ฑ์ ํน์ง์ ๋ง์ด ์ฌ์ฉํ๋ค.
์ด๋ฐ ํน์ง์ ์ฌ์ฉํ์ฌ ์ด๋ฏธ์ง ๋ฐ์ดํฐ ๋ฐ์ดํฐ๋ก ๋ณํํ๊ณ , ๋ณํ๋ ๋ฒกํฐ๋ฅผ ๊ฐ์ง๊ณ ์ง๋ ํ์ต ๋ฐฉ์์ ๋ํ ๋ถ๋ฅ ๊ธฐ๋ฒ์ธ SBM, KNN ๋ฑ์ผ๋ก ํ์ตํ ์ ์๋ค.
์ธ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ ๊ฒฌ๋ง์ ์ด๋ฏธ์ง ์๋ ๊ทธ๋๋ก ํ์ตํ๋ค. ๋๋ฒ์งธ ์ ๊ทผ ๋ฐฉ์์์๋ ํน์ง์ ์ฌ๋์ด ์ค๊ณํ์ง๋ง ์ ๊ฒฝ๋ง์ ์ด๋ฏธ์ง์ ํฌํจ๋ ์ค์ํ ํน์ง๊น์ง๋ ๊ธฐ๊ณ๊ฐ ์ค์ค๋ก ํ์ตํ ๊ฒ์ด๋ค. ๊ทธ๋์ ๋ฅ๋ฌ๋์ ์ข ๋จ๊ฐ ๊ธฐ๊ณํ์ต (end-to-end machine learning)์ด๋ผ๊ณ ๋ ํ๋ค. ์ฌ๊ธฐ์ ์ข ๋จ๊ฐ์ด๋ผ ์ฒ์๋ถํฐ ๋๊น์ง๋ผ๋ ์๋ฏธ๋ก ๋ฐ์ดํฐ(์ ๋ ฅ)์์ ๋ชฉํํ ๊ฒฐ๊ณผ(์ถ๋ ฅ)๋ฅผ ์ฌ๋์ ๊ฐ์ ์์ด ์ป๋ ๋ค๋ ๋ป์ ๋ด๊ณ ์๋ค
ํ๋ จ๋ฐ์ดํฐ์ ์ํ๋ฐ์ดํฐ
: ๊ธฐ๊ณ ํ์ต ๋ฌธ์ ๋ ๋ฐ์ดํฐ๋ฅผ ํ๋ จ๋ฐ์ดํฐ์ ์ํ ๋ฐ์ดํฐ๋ก ๋๋ ํ์ต๊ณผ ์ํํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์ด๋ค
ํ๋ จ๋ฐ์ดํฐ(training data) : ํ๋ จ๋ฐ์ดํฐ๋ง ์ฌ์ฉํ๋ฉด์ ์ต์ ์ ๋งค๊ฐ๋ณ์๋ฅผ ์ฐพ๋๋ค
์ํ๋ฐ์ดํฐ(test data) : ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์์ ํ๋ จํ ๋ชจ๋ธ์ ์ค๋ ฅ์ ํ๊ฐํ๋ค
์? ํ๋ จ ๋ฐ์ดํฐ์ ์ํ ๋ฐ์ดํฐ๋ฅผ ๋๋ ์ผ ํ ๊น?
์ฐ๋ฆฌ๊ฐ ์ํ๋ ๊ฒ์ ๋ฒ์ฉ์ (์์ง ๋ณด์ง ๋ชปํ ๋ฐ์ดํฐ(ํ๋ จ๋ฐ์ดํฐ์ ํฌํจ๋์ง ์๋ ๋ฐ์ดํฐ)๋ก๋ ๋ฌธ์ ๋ฅผ ์ฌ๋ฐ๋ฅด๊ฒ ํ์ด๋ด๋ ๋ฅ๋ ฅ)์ผ๋ก ์ฌ์ฉํ ์ ์๋ ๋ชจ๋ธ์ด๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฒ์ฉ ๋ฅ๋ ฅ์ ์ ๋๋ก ํ๊ฐํ๊ธฐ ์ํด์ ํ๋ จ๋ฐ์ดํฐ์ ์ํ๋ฐ์ดํฐ๋ฅผ ๋ถ๋ฆฌํ๋ ๊ฒ์ด๋ค.
๋ฐ์ดํฐ์ ํ๋๋ก๋ง ๋งค๊ฐ๋ณ์์ ํ์ต๊ณผ ํ๊ฐ๋ฅผ ์ํํ๋ฉด ์ฌ๋ฐ๋ฅธ ํ๊ฐ๊ฐ ๋ ์ ์์ต๋๋ค. ์์ค์ ๋ฐ์ดํฐ์ ์ ์ ๋๋ก ๋งํ๋๋ผ๋ ๋ค๋ฅธ ๋ฐ์ดํฐ์ ์๋ ์๋ง์ธ ์ผ๋ ๋ฒ์ด์ง๋๋ค. ์ด๋ ๊ฒ ํ๋์ ๋ฐ์ดํฐ์ ์๋ง ์ง๋์น๊ฒ ์ต์ ํ๋ ์ํ๋ฅผ ์ค๋ฒํผํ (overfitting)์ด๋ผ๊ณ ํ๋ฉฐ, ์ค๋ฒํผํ ์ ํผํ๋ ๊ฒ์ด ๊ธฐ๊ณํ์ต์ ์ค์ํ ๊ณผ์ ์ด๊ธฐ๋ ํ๋ค.
์์คํจ์ (loss function)
: ์ ๊ฒฝ๋ง์ ํ๋์ ์งํ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ต์ ์ ๋งค๊ฐ๋ณ์ ๊ฐ์ ํ์ํ๋ค. ์ด๋ ์ฌ์ฉํ๋ ์งํ๋ ์์คํจ์์ด๋ค. ์ด ์์คํจ์๋ ์์์ ํจ์๋ฅผ ์ฌ์ฉํ ์๋ ์์ง๋ง ์ผ๋ฐ์ ์ผ๋ก ํ๊ท ์ ๊ณฑ ์ค์ฐจ์ ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ๋ฅผ ์ฌ์ฉํ๋ค Tip) ์์คํจ์๋ ์ ๊ฒฝ๋ง ์ฑ๋ฅ์ ๋์จ์ ๋ํ๋ด๋ ์งํ๋ก, ํ์ฌ์ ์ ๊ฒฌ๋ง์ด ํ๋ จ๋ฐ์ดํฐ๋ฅผ ์ผ๋ง๋ ์ ์ฒ๋ฆฌํ์ง ๋ชปํ๋๋ฅผ ๋ํ๋ธ๋ค. ํ์ง๋ง ์์คํจ์์ ๋ง๋์ด์ค๋ง ๊ณฑํ๋ฉด ์ผ๋ง๋ ์ข์ผ๋๋ผ๋ ์งํ๋ก ๋ณํ๊ธฐ ๋๋ฌธ์, ๋์จ๊ณผ ์ข์ ์ค ์ด๋์ชฝ์ผ๋ก ์งํ๋ก ์ผ์๋ ๋ณธ์ง์ ์ผ๋ก ์ํํ๋ ์ผ์ ๋ค๋ฅด์ง ์๋ค
ํ๊ท ์ ๊ณฑ ์ค์ฐจ (Mean Squared Error, MSE)

yk : ์ ๊ฒฝ๋ง์ ์ถ๋ ฅ (์ ๊ฒฝ๋ง์ด ์ถ์ ํ ๊ฐ)
tk : ์ ๋ต ๋ ์ด๋ธ
k : ๋ฐ์ดํฐ์ ์ฐจ์์
import numpy as np
def mean_squared_error(y , t):
return 0.5 * np.sum((y-t)**2)
# t : ์ ๋ต ๋ ์ด๋ธ
# y : ์ ๊ฒฝ๋ง์ด ์ถ์ ํ ๊ฐ
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] # ์-ํซ ์ธ์ฝ๋ฉ, ์ ๋ต 2
y1 = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0] # '2'์ผ ํ๋ฅ ์ด ๋๋ค๊ณ ์ถ์
y2 = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0] # '7'์ผ ํ๋ฅ ์ด ๋๋ค๊ณ ์ถ์
a1 = mean_squared_error(np.array(y1), np.array(t))
a2 = mean_squared_error(np.array(y2), np.array(t))
print(a1) # 0.09750000000000003
print(a2) # 0.5975๋ค์๊ณผ ๊ฐ์ด ์ ๋ต 2์ด๊ณ ์ถ๋ ฅ์ 2์ผ๋์ 7์ผ๋๋ฅผ ๋น๊ตํ์๊ณ , ๊ฐ๊ฐ์ ์ถ๋ ฅํ์๋ค. ์ด์คํ์ ๊ฒฐ๊ณผ๋ก 2์ธ ๊ฒฐ๊ณผ๋ ์์คํจ์ ์ชฝ ์ถ๋ ฅ์ด ์์ผ๋ฉฐ ์ ๋ต ๋ ์ด๋ธ๊ณผ์ ์ค์ฐจ๋ ์์ ๊ฒ์ผ๋ก ์ ์ ์์ผ๋ฉฐ, 7์ธ ๊ฒฐ๊ณผ๋ ์ ๊ฒฝ๋ง ์ถ๋ ฅ์ ๋์ ๊ฒฐ๊ณผ๊ฐ ๋์๋ค. ์ฆ, ํ๊ท ์ ๊ณฑ ์ค์ฐจ๋ฅผ ๊ธฐ์ค์ผ๋ก๋ ์ค์ฐจ๊ฐ ๋์์ ์ฒซ๋ฒ์งธ ๊ฒฐ๊ณผ๊ฐ ๊ฒฐ๊ณผ์ ๋ ๊ฐ๊น์ด ๊ฒ์ผ๋ก ํ๋จํ ์ ์๋ค.
์-ํซ ์ธ์ฝ๋ฉ : ํ ์์๋ง 1๋ก ํ๊ณ ๊ทธ์ธ๋ 0์ผ๋ก ๋ํ๋ด๋ ํ๊ธฐ๋ฒ
๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ (cross entropy error: CEE)
: ์์คํจ์๋ก์ ํ๊ท ์ ๊ณฑ ์ค์ฐจ์ ๊ฐ์ด ์์ฃผ ์ฌ์ฉํ๋ค

๋ค์๊ณผ ๊ฐ์ด yk๋ ์ ๊ฒฝ๋ง์ ์ถ๋ ฅ, tk๋ ์ ๋ต ๋ ์ด๋ธ์ด๋ฉฐ, tk๋ ์-ํซ ์ธ์ฝ๋ฉ์ ์ฌ์ฉํ์ฌ ์ธ๋ฑ์ค์ ์์๋ง 1์ด๊ณ ๋๋จธ์ง๋ 0์ด๋ค
์๋ฅผ ๋ค์ด ์ ๋ต ๋ ์ด๋ธ์ 2๊ฐ ์ ๋ต์ด๋ผ ํ๊ณ ์ด๋์ ์ ๊ฒฝ๋ง ์ถ๋ ฅ์ด 0.6 ์ด๋ผ๋ฉด ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ๋ -log0.6 = 0.51 ์ด ๋๋ค
๋ํ, ๊ฐ์ ์กฐ๊ฑด์์ ์ ๊ฒฝ๋ง ์ถ๋ ฅ์ด 0.1 ์ด๋ผ๊ณ ํ๋ฉด -log0.1 = 2.30 ์ด ๋๋ค. ์ฆ ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ๋ ์ ๋ต์ผ ๋์ ์ถ๋ ฅ์ด ์ ์ฒด ๊ฐ์ ์ ํ๊ฒ ๋๋ค
import numpy as np
def cross_entropy_error(y , t):
delta = 1e-7
return -np.sum(t*np.log(y + delta))
t = [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] # ์-ํซ ์ธ์ฝ๋ฉ, ์ ๋ต 2
y1 = [0.1, 0.05, 0.6, 0.0, 0.05, 0.1, 0.0, 0.1, 0.0, 0.0] # '2'์ผ ํ๋ฅ ์ด ๋๋ค๊ณ ์ถ์
y2 = [0.1, 0.05, 0.1, 0.0, 0.05, 0.1, 0.0, 0.6, 0.0, 0.0] # '7'์ผ ํ๋ฅ ์ด ๋๋ค๊ณ ์ถ์
a1 = cross_entropy_error(np.array(y1), np.array(t))
a2 = cross_entropy_error(np.array(y2), np.array(t))
print(a1) # 0.510825457099338
print(a2) # 2.302584092994546๋ฏธ๋๋ฐฐ์น ํ์ต
: ํ๋ จ๋ฐ์ดํฐ์ ๋ํ ์์ค ํจ์์ ๊ฐ์ ๊ตฌํ๊ณ , ๊ทธ ๊ฐ์ ์ต๋ํ ์ค์ฌ์ฃผ๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ฐพ์๋ธ๋ค. ์ด๋ ๊ฒ ํ๋ ค๋ฉด ๋ชจ๋ ํ๋ จ๋ฐ์ดํฐ๋ฅผ ๋์์ผ๋ก ์์ค ํจ์์ ๊ตฌํ์ ํ๋ค ์ฆ, ํ๋ จ ๋ฐ์ดํฐ๊ฐ 100๊ฐ ์์ผ๋ฉด ๊ทธ๋ก๋ถํฐ ๊ณ์ฐํ 100๊ฐ์ ์์คํจ์ ๊ฐ๋ค์ ํฉ์ ์งํ๋ก ์ผ๋ ๊ฒ์ด๋ค. ๊ทธ๋ฐ๋ฐ ํ๋ จ๋ฐ์ดํฐ๊ฐ ์๋ง๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋์์ผ๋ก ์์คํฉ์ ๊ตฌํ๋ฉด ์๊ฐ ๋ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ค. ์ด๋ฌ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ์ผ๋ถ๋ฅผ ์ถ๋ ค ์ ์ฒด์ ๊ทผ์ฌ์น๋ฅผ ์ด์ฉํ ์ ์์ผ๋ฉฐ, ์ ๋ช ๋ง ํ์ต์์๋ ํ๋ จ ๋ฐ์ดํฐ๋ก๋ถํฐ ์ผ๋ถ๋ง ๊ณจ๋ผ ํ์ต ์ํํ๋ ๋ฏธ๋ ๋ฐฐ์น(mini-batch)๊ฐ ์๋ค.
np.random.choice(60000, 10) #์ง์ ํ ๋ฒ์ ์ ์ค์์ ๋ฌด์์๋ก ์ํ๋ ๊ฐ์๋ง ๊บผ๋ผ ์ ์๋ค(๋ฐฐ์น์ฉ) ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ ๊ตฌํํ๊ธฐ
์-ํซ ์ธ์ฝ๋ฉ์ผ๋ ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ
def cross_entropy_error(y , t):
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
batch_size = y.shape[0]
return -np.sum(t*np.log(y + 1e-7 )) / batch_size: y๊ฐ 1์ฐจ์์ด๋ผ๋ฉด, ์ฆ ๋ฐ์ดํฐ ํ๋๋น ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ๋ฅผ ๊ตฌํ๋ ๊ฒฝ์ฐ๋ reshape ํจ์๋ก ๋ฐ์ดํฐ์ ํ์์ ๋ฐ๊ฟ์ค๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฐฐ์น์ ํฌ๊ธฐ๋ก ๋๋ ์ ๊ทํํ๊ณ ์ด๋ฏธ์ง 1์ฅ๋น ํ๊ท ์ ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ๋ฅผ ๊ณ์ฐํ๋ค
์ ๋ต ๋ ์ด๋ธ์ด ์-ํซ ์ธ์ฝ๋ฉ์ด ์๋๋ผ 2๋ 7 ๋ฑ์ ์ซ์ ๋ ์ด๋ธ๋ก ์ฃผ์ด์ก์ ๋ ๊ต์ฐจ ์ํธ๋กํผ์ค์ฐจ
def cross_entropy_error(y , t):
if y.ndim == 1:
t = t.reshape(1, t.size)
y = y.reshape(1, y.size)
batch_size = y.shape[0]
return -np.sum(np.log(y[np.arange(batch_size), t] + 1e-7 )) / batch_size: ์ด ๊ตฌํ์์๋ ์-ํซ ์ธ์ฝ๋ฉ์ผ ๋ t๊ฐ 0์ธ ์์๋ ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ๋ 0์ด๋ฏ๋ก, ๊ทธ ๊ณ์ฐ์ ๋ฌด์ํด๋ ์ข๋ค๋ ๊ฒ์ด ํต์ฌ ๋ค์ ๋งํ๋ฉด ์ ๋ต์ ํด๋นํ๋ ์ ๊ฒฝ๋ง์ ์ถ๋ ค๋ง์ผ๋ก ๊ต์ฐจ ์ํธ๋กํผ ์ค์ฐจ๋ฅผ ๊ณ์ฐํ ์ ์๋ค.
np.log(y[np.arange(batch_size), t]์์ np.arange(batch_size)์ 0๋ถํฐ batch_size-1๊น์ง ๋ฐฐ์ด(ex) [0, 1, 2, 3, 4])์ ์์ฑํ๊ณ , t์๋ ๋ ์ด๋ธ(ex) [2, 4, 6, 8, 1])์ด ๊ฐ๊ฐ ์ ์ ๋์ด ์์ผ๋ฏ๋ก, np.log(y[np.arange(batch_size), t]๋ ๊ฐ ๋ฐ์ดํฐ ์ ๋ต ๋ ์ด๋ธ์ ํด๋นํ๋ ์ ๊ฒฝ๋ง์ ์ถ๋ ฅํ๋ค. (ex) y[0, 2], y[1, 4], y[2, 6], y[3, 8], y[4, 1])
์? ์์ค ํจ์๋ฅผ ์ค์ ํ๋๊ฐ?
: ์ ๊ฒฝ๋ง ํ์ต์์๋ ์ต์ ์ ๋งค๊ฐ๋ณ์(๊ฐ์ค์น์ ํธํฅ)๋ฅผ ํ์ํ ๋ ์์ค ํจ์์ ๊ฐ์ ๊ฐ๋ฅํ ํ ์๊ฒ ํ๋ ๋งค๊ฐ๋ณ์ ๊ฐ์ ์ฐพ์ต๋๋ค. ์ด๋ ๋งค๊ฐ๋ณ์์ ๋ฏธ๋ถ(์ ํํ๋ ๊ธฐ์ธ๊ธฐ)์ ๊ณ์ฐํ๊ณ , ๊ทธ ๋ฏธ๋ถ ๊ฐ์ ๋จ์๋ก ๋งค๊ฐ๋ณ์์ ๊ฐ์ ์์ํ ๊ฐฑ์ ํ๋ ๊ณผ์ ์ ๋ฐ๋ณตํ๋ค. ์ด๋ ๊ทธ ๊ฐ์ค์น ๋งค๊ฐ๋ณ์์ด ์์ค ํจ์์ ๋ฏธ๋ถ์ด๋ '๊ฐ์ค์น ๋งค๊ฐ๋ณ์์ ๊ฐ์ด ์์ฃผ ์กฐ๊ธ ๋ณํ์์ผฐ์ ๋, ์์คํจ์๊ฐ ์ด๋ป๊ฒ ๋ณํ๋'๋ผ๋ ์๋ฏธ์ด๋ค
์ ๊ฒฝ๋ง์ ํ์ต ํ ๋ ์ ํ๋๋ฅผ ์งํ๋ก ์ผ์์๋ ์๋๋ค. ์ ํ๋๋ฅผ ์งํ๋ก ํ๋ฉด ๋งค๊ฐ๋ณ์์ ๋ฏธ๋ถ์ด ๋๋ถ๋ถ์ ์ฅ์์์ 0์ด ๋๊ธฐ ๋๋ฌธ์ด๋ค
์ ํ๋๋ฅผ ์งํ๋ก ์ผ์ผ๋ฉด ๋งค๊ฐ๋ณ์์ ๋ฏธ๋ถ์ด ๋๋ถ๋ถ ์ฅ์์์ 0์ด ๋๋ ์ด์ ๋ ์ ํ๋๋ ๋งค๊ฐ๋ณ์๋ฅผ ์ผ๊ฐ๋ง ์กฐ์ ํด์๋ ์ ํ๋๊ฐ ๊ฐ์ ๋์ง ์๊ณ ์ผ์ ํ๊ฒ ์ ์ง๋๋ค. ํ์ง๋ง ์์คํจ์์ ๋งค๊ฐ๋ณ์์ ๊ฐ์ด ์กฐ๊ธ ๋ณํ๋ฉด ๊ทธ์ ๋ฐ์ํ์ฌ ์์คํจ์์ ๊ฐ๋ ๋ณํ๋ค.
์ด๋ ๊ณ๋จํจ์๋ฅผ ํ์ฑํ ํจ์๋ฅผ ์ฌ์ฉํ์ง ์๋ ์ด์ ๊ฐ ๋์ผํ๊ฒ ๋งค๊ฐ ๋ณ์์ ์์ ๋ณํ๊ฐ ์ฃผ๋ ํ์ฅ์ ๊ณ๋จ ํจ์๊ฐ ๋ง์ดํ์ฌ ์์คํจ์์ ๊ฐ์๋ ์๋ฌด๋ฐ ๋ณํ๊ฐ ๋ํ๋์ง ์๊ฒ ๋๊ธฐ ๋๋ฌธ์ด๋ค.
์์น ๋ฏธ๋ถ
: ๋ฏธ๋ถ์ด๋ ํ์๊ฐ์ ๋ณํ๋์ ํ์ํ ๊ฒ์ผ๋ก ๊ฒฝ์ฌ๋ฒ์์๋ ๊ธฐ์ธ๊ธฐ(๊ฒฝ์ฌ) ๊ฐ์ ๊ธฐ์ค์ผ๋ก ๋์๊ฐ ๋ฐฉํฅ์ ์ ํ๋ฉฐ, ์์น ๋ฏธ๋ถ์ด๋ ์์ฃผ ์์ ์ฐจ๋ถ์ผ๋ก ๋ฏธ๋ถํ๋ ๊ฒ์ ๋งํ๋ค
๊ฐ๋จํ ๋งํด ํด์์ ๋ฏธ๋ถ์ ์ฐ๋ฆฌ๊ฐ ์ํ์๊ฐ์ ๋ฐฐ์ด ๊ทธ ๋ฏธ๋ถ์ด๊ณ , ์์น ๋ฏธ๋ถ์ ์ด๋ฅผ ๊ทผ์ฌ์น๋ก ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ด๋ค
๋ฏธ๋ถ
์์ ๊ณต์์ ์ด์ฉํ์ฌ ์ฝ๋๋ฅผ ๊ตฌํํ๋ฉด ๋๊ฐ์ ๋ฌธ์ ์ ์ด ๋ฐ์ํ๋ค
๋ฐ์ฌ๋ฆผ ์ค์ฐจ(rounding error, ์์์ 8์๋ฆฌ ์ดํ๋ ์๋ต)์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉฐ 1e-50์ float32ํ(32๋นํธ ๋ถ๋์์์ )์ผ๋ก ๋ํ๋ด๋ฉด 0.0์ด ๋๋ค
๊ทธ๋์ 1e-4์ ๋์ ๊ฐ์ ์ฌ์ฉํ๋ฉด ์ข์ ๊ฒฐ๊ณผ๋ฅผ ์ป๋๋ค๊ณ ์๋ ค์ ธ ์๋ค
๋๋ฒ์งธ ๊ฐ์ ์ ํจ์f์ ์ฐจ๋ถ๊ณผ ๊ด๋ จ๋๊ฒ์ด๋ค. ๊ทผ์ฌ๋ก ๊ตฌํ ์ ์ ๊ณผ ์ง์ ํ ์ ์ ์๋ ์ค์ฐจ๊ฐ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์, ์ด ์ค์ฐจ๋ฅผ ์ค์ด๊ธฐ ์ํด์ (x + h)์ (x - h)์ผ ๋์ ํจ์ f์ ์ฐจ๋ถ์ ๊ณ์ฐํ๋ ๋ฐฉ๋ฒ์ ์ด๋ค. ์ด ์ฐจ๋ถ์ x๋ฅผ ์ค์ฌ์ผ๋ก ๊ทธ ์ ํ์ ์ฐจ๋ถ์ ๊ณ์ฐํ๋ค๋ ์๋ฏธ์์ ์ค์ฌ์ฐจ๋ถ ํน์ ์ค์ ์ฐจ๋ถ์ด๋ผ ํ๋ค
def numerical_diff(f, x):
h = 1e-4
return (f(x+h) - f(x-h)) /(2*h)์์น ๋ฏธ๋ถ์ ์

import numpy as np
import matplotlib.pylab as plt
def function_1(x):
return 0.01*x**2 + 0.1*x
def numerical_diff(f, x):
h = 1e-4
return (f(x+h) - f(x-h)) /(2*h)
def tangent_line(f, x):
d = numerical_diff(f, x)
print(d)
y = f(x) - d*x
return lambda t: d*t + y
x = np.arange(0.0, 20.0, 0.1)
y1 = function_1(x)
tf1 = tangent_line(function_1, 5)
y2 = tf1(x)
tf2 = tangent_line(function_1, 10)
y3 = tf2(x)
plt.xlabel("x")
plt.ylabel("f(x)")
plt.plot(x, y1)
plt.plot(x, y2, linestyle=":", label = "x=5")
plt.plot(x, y3, linestyle="--", label = "x=10")
plt.legend()
plt.show()
๋ค์์ ์์ ์ํ ๊ทธ๋ํ๋ฅผ ํํ
x=5, x=10์์์ ์ ์ : ์ง์ ์ ๊ธฐ์ธ๊ธฐ๋ ์์น๋ฏธ๋ถ์์ ๊ตฌํ ๊ฐ์ ์ฌ์ฉ
๊ฐ๊ฐ์ ๊ฐ์ x=5์ผ๋๋ 0.1999999999990898, x=10์ผ๋๋ 0.2999999999986347์ ์์น ๋ฏธ๋ถ ๊ฐ์ ๊ตฌํ์๋ค
ํธ๋ฏธ๋ถ
: ๋ค๋ณ์ ํจ์์ ํน์ ๋ณ์๋ฅผ ์ ์ธํ ๋๋จธ์ง ๋ณ์๋ฅผ ์์๋ก ์๊ฐํ์ฌ ๋ฏธ๋ถ

import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
def f(x0,x1):
return x0**2 + x1**2
# f(x,y) = x^2 + y^2 ํจ์์ ๊ทธ๋ํ ๊ทธ๋ฆฌ๊ธฐ
fig = plt.figure()
ax = fig.gca(projection='3d')
x0 = np.arange(-3, 3, 0.25)
x1 = np.arange(-3, 3, 0.25)
x0, x1 = np.meshgrid(x0, x1)
f= f(x0,x1)
surf = ax.plot_wireframe(x0, x1, f, color='blue')
plt.xlabel('x0')
plt.ylabel('x1')
ax.set_zlabel('f(x0,x1)')
plt.show()
์์ ๊ณต์์ ๋ฐ๋ผ ๊ทธ๋ํ๋ฅผ ๊ตฌํํ์๋ค
๋ถ x0=3, x1=4 ์ผ๋, x0์ ํธ๋ฏธ๋ถ๊ณผ x1์ ํธ๋ฏธ๋ถ
import numpy as np
def function_x0(x0):
return x0*x0 + 4.0**2.0
# ์ฃผ์) x0*x0๋ฅผ ์ฌ์ฉํด์ผ ํ๋ฉฐ, 2*x0์ ๋ค๋ฅธ ๊ฒฐ๊ณผ๊ฐ์ด ๋์จ๋ค
def function_x1(x1):
return 3.0**2.0 + x1*x1
def numerical_diff(f, x):
h = 1e-4
return (f(x+h) - f(x-h)) /(2*h)
x0 = numerical_diff(function_x0, 3.0)
x1 = numerical_diff(function_x1, 4.0)
print("x0์ ๋ํ ํธ๋ฏธ๋ถ", x0) # 6.00000000000378
print("x1์ ๋ํ ํธ๋ฏธ๋ถ", x1) # 7.999999999999119๊ธฐ์ธ๊ธฐ
: ๋ชจ๋ ๋ณ์์ ํธ๋ฏธ๋ถ์ ๋ฒกํฐ๋ก ์ ๋ฆฌํ ๊ฒ์ ๊ธฐ์ธ๊ธฐ (gradient)๋ผ๊ณ ํ๋ค
import numpy as np
import matplotlib.pylab as plt
from mpl_toolkits.mplot3d import Axes3D
def _numerical_gradient_no_batch(f, x):
h = 1e-4 # 0.0001
grad = np.zeros_like(x) # x์ ํ์์ด ๊ฐ์ ๋ฐฐ์ด์ ์์ฑ
for idx in range(x.size):
tmp_val = x[idx]
# f(x+h) ๊ณ์ฐ
x[idx] = float(tmp_val) + h
fxh1 = f(x)
# f(x-h) ๊ณ์ฐ
x[idx] = tmp_val - h
fxh2 = f(x)
grad[idx] = (fxh1 - fxh2) / (2*h)
x[idx] = tmp_val # ๊ฐ ๋ณต์
return grad
def numerical_gradient(f, X):
if X.ndim == 1:
return _numerical_gradient_no_batch(f, X)
else:
grad = np.zeros_like(X)
for idx, x in enumerate(X):
grad[idx] = _numerical_gradient_no_batch(f, x)
return grad
def function_2(x):
if x.ndim == 1:
return np.sum(x**2)
else:
return np.sum(x**2, axis=1)
def tangent_line(f, x):
d = numerical_gradient(f, x)
print(d)
y = f(x) - d*x
return lambda t: d*t + y
if __name__ == '__main__':
x0 = np.arange(-2, 2.5, 0.25)
x1 = np.arange(-2, 2.5, 0.25)
X, Y = np.meshgrid(x0, x1)
X = X.flatten()
Y = Y.flatten()
grad = numerical_gradient(function_2, np.array([X, Y]) )
plt.figure()
plt.quiver(X, Y, -grad[0], -grad[1], angles="xy",color="#666666"))
plt.xlim([-2, 2])
plt.ylim([-2, 2])
plt.xlabel('x0')
plt.ylabel('x1')
plt.grid()
plt.legend()
plt.draw()
plt.show()
๊ธฐ์ธ๊ธฐ๋ ๋ฐฉํฅ์ ๊ฐ์ง ๋ฒกํฐ(ํ์ดํ)๋ก ๊ทธ๋ ค์ง๋ค. ๊ธฐ์ธ๊ธฐ๋ ํจ์์ ๊ฐ์ฅ ๋ฎ์ ์ฅ์(์ต์๊ฐ)์์ ๋ฉ์ด์ง์๋ก ํ์ดํ์ ํฌ๊ธฐ๊ฐ ์ปค์ง์ ์์ ์๋ค
ํ์ง๋ง ๊ธฐ์ธ๊ธฐ๋ ๊ฐ ์ง์ ์์ ๋ฎ์์ง๋ ๋ฐฉํฅ์ ๊ฐ๋ฆฌํจ๋ค
๋ ์ ํํ ๋งํ์๋ฉด ๊ธฐ์ธ๊ธฐ๊ฐ ๊ฐ๋ฆฌํค๋ ์ชฝ์ ๊ฐ ์ฅ์์์ ํจ์์ ์ถ๋ ฅ ๊ฐ์ ๊ฐ์ฅ ํฌ๊ฒ ์ค์ด๋ ๋ฐฉํฅ์ด๋ค.(์ค์)
๊ฒฝ์ฌ ํ๊ฐ๋ฒ(๊ฒฝ์ฌ๋ฒ, gradient descent)
: ์ ๊ฒฝ๋ง์ ์ต์ ์ ๋งค๊ฐ๋ณ์(๊ฐ์ค์น์ ํธํฅ)๋ฅผ ํ์ต ์์ ์ฐพ์์ผ ํ๋ค. ์ฌ๊ธฐ์์ ์ต์ ์ด๋ ์์ค ํจ์๊ฐ ์ต์๊ฐ์ด ๋ ๋์ ๋งค๊ฐ๋ณ์ ๊ฐ์ด๋ค.
๊ธฐ์ธ๊ธฐ๋ฅผ ์ ์ด์ฉํด ํจ์์ ์ต์๊ฐ(๋๋ ๊ฐ๋ฅํ ์์ ๊ฐ)์ ์ฐพ์ผ๋ ค๋ ๊ฒ์ด ๊ฒฝ์ฌ ํ๊ฐ๋ฒ(๊ฒฝ์ฌ๋ฒ)์ด๋ค
๊ธฐ์ธ๊ธฐ์ง ๋ฐฉํฅ์ด ๊ผญ ์ต์๊ฐ์ ์๋๋ฉฐ, ๊ธฐ์ธ๊ธฐ ์ ๋ณด๋ฅผ ๋จ์๋ก ๋์๊ฐ ๋ฐฉํฅ์ ์ ํด์ผ ํ๋ค
๊ฒฝ์ฌ๋ฒ์ ํ ์์น์์ ๊ธฐ์ธ์ด์ง ๋ฐฉํฅ์ผ๋ก ์ผ์ ๊ฑฐ๋ฆฌ๋งํผ ์ด๋ํ ํ์ ๋ฐ๋ณตํ๋ฉด์ ๊ธฐ์ธ๊ธฐ๋ฅผ ๊ตฌํ๋ค. ์ด๋ ๊ฒ ํด์ ํจ์์ ๊ฐ์ด ์ ์ฐจ ์ค์ด๋ ๊ฒ์ ๊ฒฝ์ฌ๋ฒ์ด๋ค
tip) ํจ์๊ฐ ๊ทน์๊ฐ, ์ต์๊ฐ, ๋๋ ์์ ์ (saddle point)์ด ๋๋ ์ฅ์์์๋ ๊ธฐ์ธ๊ธฐ๊ฐ 0์ด๋ค. ์ด๋ ์์ ์ ์ ์ด๋ ๋ฐฉํฅ์์ ๋ณด๋ฉด ๊ทน๋๊ฐ์ด ๋๊ณ ๋ค๋ฅธ ๋ฐฉํฅ์์ ๋ณด๋ฉด ๊ทน์๊ฐ์ด ๋๋ ์ ์ด๋ค. ๊ฒฝ์ฌ๋ฒ์ ๊ธฐ์ธ๊ธฐ๊ฐ 0์ธ ์ฅ์๋ฅผ ์ฐพ์ง๋ง ๊ทธ๊ฒ์ด ๋ฐ๋์ ์ต์๊ฐ์ด๋ผ๊ณ ํ ์ ์๋ค. ๋ ๋ณต์กํ๊ณ ์ฐ๊ทธ๋ฌ์ง ๋ชจ์์ ํจ์๋ผ๋ฉด(๋๋ถ๋ถ) ํํํ ๊ณณ์ผ๋ก ํ๊ณ ๋ค๋ฉด์ ๊ณ ์(plateau, ํ๋ํ )์ด๋ผ ํ๋, ํ์ต์ด ์งํ๋์ง ์๋ ์ ์ฒด๊ธฐ์ ๋น ์ง ์ ์๋ค. tip) ๊ฒฝ์ฌ๋ฒ์ ์ต์๊ฐ๊ณผ ์ต๋๊ฐ์ ๋ฐ๋ผ ๊ฒฝ์ฌํ๊ฐ๋ฒ, ๊ฒฝ์ฌ์์น๋ฒ์ผ๋ก ๋๋๋ฉฐ ๋ถํธ๋ง ๋ฐ์ ์ด๋ฏ๋ก ๋ณธ์ง์ ์ผ๋ก๋ ์ค์ํ์ง ์๋ค

์ํ ๊ธฐํธ๋ ๊ฐฑ์ ํ๋ ์์ ๋ํ๋ด๋ฉฐ, ์ด๋ฅผ ์ ๊ฒฝ๋ง ํ์ต์์๋ ํ์ต๋ฅ (learning rate)๋ผ๊ณ ํ๋ค.
ํ๋ฒ์ ํ์ต์ผ๋ก ์ผ๋ง๋งํผ ํ์ตํด์ผ ํ ์ง, ์ฆ ๋งค๊ฐ๋ณ์ ๊ฐ์ ์ผ๋ง๋ ๊ฐฑ์ ํ๋๋๋ฅผ ์ ํ๋ ๊ฒ์ด ํ์ต๋ฅ ์ด๋ค
def gradient_descent(f, init_x, lr=0.01, step_num = 100):
x = init_x
for i in range(step_num):
grad - numerical_gradient(f,x)
x -= lr * grad
return xtip)ํ์ต๋ฅ ๊ฐ์ ๋งค๊ฐ๋ณ์๋ฅผ ํ์ดํผํ๋ผ๋ฏธํฐ(hyper parameter, ์ด๋งค๊ฐ๋ณ์)๋ผ๊ณ ํ๋ค. ์ด๋ ๊ฐ์ค์น์ ํธํฅ ๊ฐ์ ์ ๊ฒฝ๋ง์ ๋งค๊ฐ๋ณ์์๋ ์ฑ์ง์ด ๋ค๋ฅธ ๋งค๊ฐ๋ณ์์ด๋ค. ์ ๊ฒฝ๋ง์ ๊ฐ์ค์น ๋งค๊ฐ๋ณ์๋ ํ๋ จ๋ฐ์ดํฐ์ ํ์ต ์๊ณ ๋ฆฌ์ฆ์ ์ํด์ ์๋์ผ๋ก ํ๋๋๋ ๋งค๊ฐ๋ณ์์ธ ๋ฐ๋ฉด, ํ์ต๋ฅ ๊ฐ์ ํ์ดํผํ๋ผ๋ฏธํฐ๋ ์ฌ๋์ด ์ง์ ์ค์ ํด์ผ ํ๋ ๋งค๊ฐ๋ณ์์ด๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ด๋ค ํ์ดํผํ๋ผ๋ฏธํฐ๋ ์ฌ๋ฌ ํ๋ณด ๊ฐ ์ค์์ ์ํ์ ํตํด ๊ฐ์ฅ ์ ํ์ตํ๋ ๊ฐ์ ์ฐพ๋ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋ค
Last updated
Was this helpful?