PyTorch - autograd
๋ณธ ๊ธ์ ์ ๊ฐ PyTorch Turotial์ autograd
๋ถ๋ถ์ ์ฝ๊ณ ์ดํด๊ฐ ์ ๋๋ ๋ถ๋ถ์ ๋ณด์ถฉํ๊ธฐ ์ํด ์ ๋ฆฌํ ๊ธ์
๋๋ค. ์ง์ ์ ์ธ์ ๋ ํ์์
๋๋ค :)
์ฝ๊ธฐ์๋ฃ:
PyTorch Tutorials - AUTOGRAD: AUTOMATIC DIFFERENTIATION
autograd
์ ๋ฅ๋ฌ๋์ Backpropagation์ ์ฝ๋๋ก ๊ตฌํํ PyTorch์ ํ๋ถ ํจํค์ง์
๋๋ค. ๊ทธ๋์ Backpropagation์ ๋ํด ๋จผ์ ์์งํ๊ณ ๋ณธ ๊ธ์ ์ฝ์ผ์๊ธธ ๋ฐ๋๋๋ค.
Backpropagation์ ๊ฐ ๋ด๋ฐ์ ๊ฐ์ค์นweight๋ฅผ ์
๋ฐ์ดํธํ๋ ๊ณผ์ ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ์ ๋ฐ์ดํธ ๊ณผ์ ์ ์ถ๋ ฅ์ธต์์ ์ ๋ ฅ์ธต ์์๋ก ์งํ๋๋ค. |
autograd
๋?
autograd
๋ PyTorch์์ Backpropagation์ ์ํํ๋ PyTorch์ ํ๋ถ ํจํค์ง์ด๋ค. Backpropagation์ ์ํํ๊ธฐ ์ํด์ ๋ด๋ฐ์์ ํํด์ง๋ ์ฐ์ฐ์ ๋ํ Gradient๋ฏธ๋ถ๊ฐ๋ฅผ ๊ตฌํด์ผ ํ๋ค. autograd
๋ ํ
์ ๊ฐ์ฒด์ ๋ณ์ grad
์ Gradient ๊ฐ์ ๋ด์์ค๋ค.
์์ฝ: autograd
๋ ํ
์์ ์ฐ์ฐ์ ๋ํด ์๋์ผ๋ก Gradient ๊ฐ์ ๊ตฌํด์ฃผ๋ ํจํค์ง์ด๋ค.
ํ
์ ๊ฐ์ฒด์ autograd
ํ
์๋ฅผ ์์ฑํ ๋ requires_grad
์ต์
์ True
๋ก ์ค์ ํ๋ฉด, ์์ผ๋ก ๊ทธ ํ
์์ ํํด์ง๋ ๋ชจ๋ ์ฐ์ฐ์ ์ถ์ ํ๊ณ ๊ทธ์ ๋ํ Gradient๋ฅผ ๊ณ์ฐํด์ค๋ค.
requires_grad
์ต์
์ True
๋ก ํ๊ณ ํ
์ x
๋ฅผ ๋ง๋ค์ด ๋ณด์๋ค.
x = torch.ones(2, 2, requires_grad=True)
ํ
์ x
์ ๋ง์
์ฐ์ฐ์ ์ํํ์ฌ ์๋ก์ด ํ
์ y
๋ฅผ ๋ง๋ ๋ค.
y = x + 2
out
tensor([[3., 3.],
[3., 3.]], grad_fn=<AddBackward0>)
ํ
์ y
๋ grad_fn
์ด๋ผ๋ ๋ฉค๋ฒ ๋ณ์๋ ๊ฐ์ง๊ณ ์๋ค. grad_fn
์ ํด๋น ํ
์ ๊ฐ์ฒด๊ฐ ์ด๋ค ์ฐ์ฐ์ผ๋ก๋ถํฐ ์์ฑ๋์๋์ง๋ฅผ ์๋ ค์ค๋ค.
๋จ, ํ
์ ๊ฐ์ฒด๊ฐ ๋ค๋ฅธ ํ
์์์ ์ฐ์ฐ์ ํตํด ์์ฑ๋ ๊ฒ์ด ์๋๋ผ torch.ones()
๋ torch.rand()
์ ๊ฐ์ด ์ฌ์ฉ์๊ฐ ์ง์ ํ
์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๊ฒฝ์ฐ๋ grad_fn
๊ฐ์ด none
์ด๋ค.
์ฐ์ฐ์ ๋ ์ฌ์ฉํด์ ํ ์ ๊ฐ์ฒด๋ฅผ ๋ ๋ง๋ค์ด๋ณด์.
z = y * y * 3
out = z.mean()
out
tensor([[27., 27.],
[27., 27.]], grad_fn=<MulBackward0>)
tensor(27., grad_fn=<MeanBackward0>)
Gradient
Backpropagation์ ํ๊ธฐ ์ํด์ ํ
์ ๊ฐ์ฒด์์ backward()
ํจ์๋ฅผ ์คํํด์ผ ํ๋ค.
out.backward()
๊ทธ๋ฆฌ๊ณ ๊ทธ ๊ฒฐ๊ณผ์ธ Gradient ๊ฐ์ ํ
์ ๊ฐ์ฒด์ grad
์ ๋ด๊ธด๋ค.
print(x.grad)
out
tensor([[4.5000, 4.5000],
[4.5000, 4.5000]])
์ด๋, x.grad
์ ๊ฐ์ d(out)/dx์ ๋ํ ๊ฐ์ด๋ค.
๊ฒฐ๊ณผ๋ฅผ ์ ๊ฒฝ๋ง์ ๊ด์ ์์ ํด์ํด๋ณด์.
์ฐ๋ฆฌ๊ฐ ์ง๊ธ๊น์ง ์ฐ์ฐ(*
, +
, mean()
)์ผ๋ก ํ
์ x
, y
, z
, out
์ ๋ง๋ ๊ณผ์ ์ ์ผ์ข
์ Loss functionLoss function์ ๋ง๋ ๊ฒ์ด๋ค.
์ฒ์์ ๋ง๋ ํ
์ x
๋ ๊ฐ์ค์น์ด๋ค. ์ง์ ๋ง๋ ํ
์ ๊ฐ์ฒด์๋ grad_fn
๊ฐ์ด ์๋ค๊ณ ํ๋๋ฐ, ๊ฐ์ค์น ์์ฒด๋ ์ด๋ค ์ฐ์ฐ์ผ๋ก๋ถํฐ ์ ๋๋ ๊ฐ์ด ์๋๊ธฐ ๋๋ฌธ์ grad_fn
์ด ์๋ ๊ฒ์ด ๋น์ฐํ๋ค.
out
์ Loss function์ ๊ฐ ์์ฒด๋ฅผ ์๋ฏธํ๋ค. Backpropagation์ โ๊ฐ ๋ด๋ฐ์ธต์ ๊ฐ์ค์น๋ฅผ ๊ฐฑ์ ํด์ฃผ๋ ์์
โ์ด๋ค. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๊ณผ์ ์์ Gradient ๊ฐ์ด ์ฌ์ฉ๋๋ค. Gradient ๊ฐ์ ๊ฐ์ค์น์ ํด๋นํ๋ ํ
์ ๊ฐ์ฒด์ grad
์ ๋ด๊ฒจ์๋ค. ์ฐ๋ฆฌ๋ ๋ง์ง๋ง์ out.backward()
๋ฅผ ํธ์ถํ๊ณ , x.grad
๊ฐ์ ํ์ธํ์๋ค. x.grad
๋ d(out)/dx ๊ฐ์ ์๋ฏธํ๋ค.
GDGradient Descent์์๋ d(Loss)/dw๋ฅผ ๊ตฌํ์ฌ ๊ฐ์ค์น๋ฅผ ๊ฐฑ์ ํ๋ค. ์ฐ๋ฆฌ๊ฐ ์ป์ x.grad
(=d(out)/dx)๊ฐ ๊ฐ์ค์น๋ฅผ ๊ฐฑ์ ํ๋ d(Loss)/dw์ธ ๊ฒ์ด๋ค.
autograd
ํจํค์ง๋ฅผ define-by-run์คํ์์ ์ ์ ์ ํ๋ ์์ํฌ๋ผ๊ณ ์ค๋ช
์ ํ๋ค. ์ด๊ฒ์ Backpropagation์ด ์ ์ ์ผ๋ก, ํ๋์ ํํ๋ก ๊ณ ์ ๋ ๊ฒ์ด ์๋๋ผ python ์ฝ๋๊ฐ ์คํ๋๋ ์์ ์ ๋์ ์ผ๋ก ์ ์๋๊ณ , ๊ทธ์ ๋ฐ๋ผ Backpropgation์ ํํ๊ฐ ๋ณํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
autograd
ํจํค์ง์ ์ฝ์
ํธ์ ์ ๋ฆฌํ๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
- ํธ๋ฆฌํ(?) Backpropagation์ ์ ๊ณต
backward()
์ ํธ์ถํ๋ฉด, Gradient๋ฅผ ์๋์ผ๋ก ๊ณ์ฐgrad_fn
์ ํตํด์ ์ฐ์ฐ์ ์ถ์ ํ๊ณ ๊ธฐ๋ก
(๋ฒ์ธ) autograd
์ vector-Jacobian Product
PyTorch Tutorial์์๋ vector-Jacobian Product(VJP)๋ฅผ ์ธ๊ธํ๊ณ ์๋ค.
Jacobian $J$๋ vector-valued function1์ Gradient๋ฅผ ํํํ ํ๋ ฌ์ด๋ค.
์ด๋ฒ์ ๋ฒกํฐ $\vec { y }$๋ฅผ ์ ๋ ฅ์ผ๋ก ๊ฐ๋ ์ค์นผ๋ผ ํจ์ $L = g\left( \vec { y } \right)$๋ฅผ ์ดํด๋ณด์. ํจ์ $L$์ $\vec { y }$์ ๋ํ Gradient์ธ ๋ฒกํฐ $\vec { v }$๋ ๋ค์๊ณผ ๊ฐ๋ค.
์ด์ ๋ฒกํฐ $\vec { v }$์ Jacobian $J$๋ฅผ ๊ณฑํ ๊ฒ์ด๋ค. ์ด๋, $J$๋ ๋ฒกํฐ $\vec { y }$์ ๋ฒกํฐ $\vec { x }$์ ๋ํ Gradient์ด๋ค. ๊ฒฐ๊ณผ๋ Chain Rule์ ์ํด ๋ค์๊ณผ ๊ฐ๋ค. 2
์ด์ vector-Jacobian Product๊ฐ PyTorch์ ๋ฌด์จ ๊ด๋ จ์ด ์๋์ง ์ดํด๋ณด์.
์์ ์์์์ $\vec { x }$๋ฅผ ๊ฐ์ค์น๋ก, $L$์ Loss function์ด๋ผ๊ณ ์๊ฐํด๋ณด์. ๊ฐ์ค์น $\vec { x }$๋ ์ด๋ค ์ฐ์ฐ๋ค(=ํจ์ $f$)์ ๊ฑฐ์ณ์ ๋ฒกํฐ $\vec { y }$๊ฐ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฒกํฐ $\vec { y }$๋ ๋ ์ด๋ค ์ฐ์ฐ(=ํจ์ $g$)๋ฅผ ๊ฑฐ์ณ์ Loss function $L$์ ๋ง๋ ๋ค.
๋ฒกํฐ $\vec { v }$๋ Loss $L$์ $\vec { y }$์ ๋ํ Gradient์ธ๋ฐ, $\vec { v }$๋ grad_tensor
๋ก backward()
ํจ์์ ์ธ์๋ก ์ ๋ฌ๋๋ค.3 (๋ฒกํฐ $\vec { v }$๋ฅผ ์ ๋ฌํ๋ ์ด์ ๋ ์๋๋ L.backward()
๋ฅผ ํธ์ถํด์ ๊ตฌํ์ด์ผ ํ $\nabla_{\vec{ y }} {L}$๋ฅผ $\vec{ v }$๋ก ๋์ฒดํ๊ธฐ ๋๋ฌธ์ด๋ค.)
์ด์ PyTorch Tutorial์ ์ ์๋ ์ฝ๋๋ฅผ ์ฝ๊ฐ ๋ณํํ์ฌ ์ดํด๋ณด์.
x = torch.randn(3, requires_grad=True)
y = x * 2
v = torch.tensor([0.1, 1.0, 0.0001], dtype=torch.float)
y.backward(v)
print(x.grad)
tensor([1.0240e+02, 1.0240e+03, 1.0240e-01])
non-scalar function์ธ y
์ ๋ํ Gradient๋ฅผ ๊ตฌํ๋ ค๋ฉด vector-Jacobian Product๋ฅผ ์ฌ์ฉํด์ผ ํ๊ณ , VJP๋ฅผ ํ๋ ค๋ฉด ๋ฒกํฐ $\vec {v}$๊ฐ ํ์ํ๋ค. ๊ทธ๋์ ๋ฒกํฐ v
๋ฅผ ์์ฑํ ํ, backward()
ํจ์์ ์ธ์๋ก ์ ๋ฌํ์๋ค.
๊ฒฐ๋ก ์ โautograd
๋ backward()
๊ฐ ์คํ๋ ๋, ๋ด๋ถ์ ์ผ๋ก vector-Jacobian Product๋ฅผ ํตํด Gradient๋ฅผ ๊ตฌํ๋คโ๋ ๊ฒ์ด๋ค.
Tips
- ๋ง์ฝ
backward()
ํจ์๋ฅผ ์คํํ์ง ์๊ณ ,x.grad
์ ์ ๊ทผํ๋ค๋ฉด,None
์ด ๋ฆฌํด๋๋ค. - non-scalar function์ธ
y
์์backward()
๋ฅผ ํธ์ถํ ๋,grad_tensor
์์ดy.backward()
ํ๊ฒ ๋๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค. .grad
์์ ์ฃผ์ํ ์ ์ ๊ณ์ฐ ๊ทธ๋ํ์์ leaf node์ ํด๋นํ๋ ํ ์์.grad
๊ฐ์๋ง ์ ๊ทผํ ์ ์๋ค๋ ๊ฒ์ด๋ค. ๋ง์ฝ non-leaf node ํ ์์.grad
์ ์ ๊ทผํ๋ ค ํ๋ค๋ฉด,backward()
ํจ์ ํธ์ถ ์ ์.retain_grad()
ํจ์๋ฅผ ์คํํ์!- ์ ๋ฐฉ๋ฒ์ผ๋ก ํ
์
z
์grad
๋ฅผ ํ์ธํด๋ณด๋ฉด,z.grad
๋ d(out)/dz๊ฐ ๋๋ค.
- ์ ๋ฐฉ๋ฒ์ผ๋ก ํ
์
์ฐธ๊ณ ์๋ฃ
- ๋ฐ์ดํฐ ์ฌ์ด์ธ์ค ์ค์ฟจ - ํ์ดํ ์น ํจํค์ง ์ค๊ธ
- Autograd: ๋ฏธ๋ถ ์๋ํ5
- VJP - PyTorch Autograd
-
vector-valued function $\vec { y } =f\left( \vec { x } \right)$์ ๋ฒกํฐ๋ฅผ ์ถ๋ ฅํ๋ ํจ์์ด๋ค. ์ด๋, ์ ๋ ฅ์ด ๋ฒกํฐ์ด๊ธฐ ๋๋ฌธ์ ํจ์ $\vec { y }$๋ ๋ค๋ณ์ ํจ์์ด๋ค. ๋ค๋ณ์ ํจ์์ Gradient๋ Jacobian $J$ ๊ฐ์ ํ๋ ฌ์ ๊ผด๋ก ํํ๋๋ค.ย ↩
-
์ด๋ฆ์ โvector-Jacobianโ์ธ๋ฐ ${ J }^{ T }\cdot v$๋ฅผ ํ ์ด์ ๋ ${ v }^{ T }\cdot J$๊ฐ row vector๋ฅผ ๋ฆฌํดํ๊ธฐ ๋๋ฌธ์ด๋ค. column vector๋ฅผ ์ทจํด์ผ ๋๋ค๋ฅธ Jacobian $J_2$์ ํจ์์ฒ๋ผ ${ J_1 }^{ T }\cdot v$ ๊ฒฐ๊ณผ ์์ ์์ธ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ${ J_2 }^{ T }\cdot \left( { J_1 }^{ T }\cdot v \right)$ย ↩
-
์์์๋
backward()
ํจ์์ ์ธ์๋ฅผ ๋ฃ์ง ์์์์ ์ฃผ๋ชฉํ๋ผ. ๊ทธ ๊ฒฝ์ฐ๋out
์ด scalar function์ด๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ ๊ฒ์ด๋ค. ๋ง์ฝ non-scalar function์์backward()
๋ฅผ ํธ์ถํ๋ค๋ฉด,grad_tensor
๋ผ๋ ์ธ์๊ฐ ํ์ํ๋ค!ย ↩ -
x
๋ฅผrandn()
์ผ๋ก ์์ฑํ๊ธฐ ๋๋ฌธ์ output ๊ฐ์ ์๋ฏธ๊ฐ ์๋ค.ย ↩ -
Variable
์ด๋ผ๋ ํด๋์ค๊ฐ ์ธ๊ธ๋๋ค. ๊ทธ๋ฐ๋ฐVariable
ํด๋์ค๋ ์ง์์ด ์ค๋จ๋ ํด๋์ค๋ก 2020๋ 9์ ๊ธฐ์ค์ผ๋ก๋ ๋์ด์ ์ฌ์ฉ๋์ง ์๋๋ค.linkVariable
์Tensor
ํด๋์ค๋ก ์นํํ์ฌ ์ดํดํ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ๋ค.ย ↩