์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
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 |
- ์๊ณ ๋ฆฌ์ฆ
- dropout
- ๊ฐ๋์_๋ง๋ก
- 2023
- back propagation
- ๊ฐ๋์ ๋ง๋ก
- BFS
- ํ๋ก์ด๋ ์์ฌ
- ํฌ๋ฃจ์ค์นผ
- DP
- ์ธ๊ทธ๋จผํธ ํธ๋ฆฌ
- ๋ฌธ์์ด
- ๋๋น ์ฐ์ ํ์
- tensorflow
- lazy propagation
- c++
- dfs
- object detection
- ๋ถํ ์ ๋ณต
- ๋ค์ต์คํธ๋ผ
- NEXT
- ์๋ฐ์คํฌ๋ฆฝํธ
- ํ๊ณ ๋ก
- ๋ฐฑํธ๋ํน
- ์ฐ์ ์์ ํ
- ์กฐํฉ๋ก
- pytorch
- ๋ฏธ๋๋_ํ์ฌ์_๊ณผ๊ฑฐ๋ก
- ์ด๋ถ ํ์
- Overfitting
- Today
- Total
Doby's Lab
backward()๋ ์ญ์ ํ๋ฅผ ์ด๋ป๊ฒ ํ ๊น? (Autograd์ Node) ๋ณธ๋ฌธ
backward()๋ ์ญ์ ํ๋ฅผ ์ด๋ป๊ฒ ํ ๊น? (Autograd์ Node)
๋๋น(Doby) 2023. 11. 19. 15:13๐ค Problem
PyTorch์ Tensor๋ requires_grad๊ฐ True๋ก ๋์ด์์ ๋, ๋ณํ๋์ ๋ํ ์ฐ์ฐ์ ์ถ์ ์ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค.
์ฆ, ๊ฐ Tensor์ ๋ํด์ .grad ์์ฑ๊ณผ .grad_fn ์์ฑ์ด ์๊น๋๋ค.
.grad๋ ํ์ฌ Tensor์ ๋ํด ๋ชฉ์ ํจ์๊ฐ ์ผ๋งํผ ๋ณํ๋์ ๋ํ ๋ณํ๋์ ๊ฐ, ์ฆ ๋ฏธ๋ถ ๊ฐ์ ๋ด๊ณ ์์ผ๋ฉฐ,
.grad_fn์ ์ด์ Tensor์ ๋ํด์ ํ์ฌ Tensor๋ฅผ ๋ฏธ๋ถํด ์ค ๋, ์ด๋ ํ ์ฐ์ฐ์ ๋ํ ๋ฏธ๋ถ์ ํด์ฃผ์ด์ผ ํ๋์ง ํน์ ์ฐ์ฐ์ ๋ํ ๋ฏธ๋ถ ํจ์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์์ต๋๋ค. (๊ฐ์ด ์๋ ํจ์ ์ ๋ณด์์ ์ ์) ์๋ฅผ ๋ค์ด, b = a + 2๋ผ๋ฉด, b์๋ a์ ๋ํด ๋ฏธ๋ถ์ ํ ๋, ๋ํ๊ธฐ ์ฐ์ฐ์ ํตํด ์์ฑ์ด ๋์์ผ๋ ๋ํ๊ธฐ ์ฐ์ฐ์ผ๋ก ๋ง๋ค์ด์ก๋ค๋ ๊ฒ์ ์๊ณ ์๋ค๋ ๋ป์ ๋๋ค.
์ฌ๊ธฐ์ ์ ๊ฐ ๊ถ๊ธํ ์ ์ด์ ์ด๋ฒ ํฌ์คํ ์ ์ฃผ์ ๋ 'backward()๋ฅผ ํธ์ถํ์ ๋, ๋๋์ฒด ์ด๋ป๊ฒ .grad๋ฅผ ๊ฐฑ์ ํ๋๊ฐ?'์ ๋๋ค. ๋๋ฌด ๋น์ฐํ๊ฒ๋ ์ด๋ก ์ ์ผ๋ก๋ ์ญ์ ํ๋ฅผ ์ํํ๋๋ก ํ๋ฉด, .grad์๋ ๋ณํ๋์ ๋ํ ์ ๋ณด๊ฐ ๋ค์ด๊ฐ๋ ๊ฒ์ด ๋ง์ง๋ง, ํ์ฌ ์ ๊ฐ ๊ฐ์ง๊ณ ์๋ ์ ๋ณด๋ก๋ ๊ทธ๊ฑด ๋ถ๊ฐ๋ฅํ๋ค๊ณ ํ๋จํ๊ธฐ ๋๋ฌธ์ ๋๋ค.
์ด๋ ๊ฒ ํ๋จํ ๊ทผ๊ฑฐ์๋ Tensor์์ .grad์ .grad_fn๊ณผ ๊ฐ์ ์์ฑ, ํน์ ๋ค๋ฅธ ์์ฑ๋ค์์๋ ํ์ฌ Tensor์์๋ ์ด์ Tensor์ ๋ํ ์์น ์ ๋ณด(์์ฑ)๋ฅผ ์ฐพ์ ์ ์์๊ธฐ ๋๋ฌธ์ ๋๋ค.
์๋ํ๋ฉด, ํ์ฌ Tensor๋ ์ด ์์น ์ ๋ณด๋ฅผ ์๊ณ ์์ด์ผ ์ด ์์น์๊ฒ ์ด๋ค ์ ๋ณด๋ ๋๊ฒจ์ค ์ ์๊ธฐ ๋๋ฌธ์ ์ญ์ ํ๋ฅผ ํ๊ธฐ ์ํด์๋ 'ํ์ฌ Tensor๋ ์ด๋ ํ Tensor๋ก๋ถํฐ ๋์๋์ง' ๋ฌด์กฐ๊ฑด ์๊ณ ์์ด์ผ ํฉ๋๋ค.
์ด๋ฒ ํฌ์คํ ์ ๋ด์ฉ์ ๋ค์ ํผ์ก์ค๋ฌ์ธ ์ ์๊ธฐ ๋๋ฌธ์ ๋งจ ํ๋จ์ Summary๋ฅผ ๊ผญ ์ฝ์ด์ฃผ์๊ฑฐ๋ ๋๊ธ์ ๋จ๊ฒจ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค :)
๐ง Computational Graph (์ฐ์ฐ ๊ทธ๋ํ)
์ด ๋ฌธ์ ์ ๊ด๋ จํด์ ์ ์ผ ๋ฐ์ ํ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ ํค์๋๋ Computational Graph์ ๋๋ค. ์ด์ ๋ํ ์ ๋ณด๋ PyTorch ํ๊ตญ ์ฌ์ฉ์ ๋ชจ์์์๋ ์ด๋ฏธ ์ ๊ณต์ ํ๊ณ ์์ต๋๋ค.
Forward Propagation์ ํตํด์ ๊ตฌ์ถ์ด ๋๋ Computational Graph๋ ๋์ ์ผ๋ก ๊ตฌ์ถ์ด ๋ฉ๋๋ค. ๋์ ์ผ๋ก ๊ตฌ์ถ์ด ๋๋ ์ด์ ๋ ์ด๋ค์์ ์ด๋ ํ Forward๊ฐ ๋ฐ์ํ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ์ ์ ์ผ๋ก ๊ด๋ฆฌ๋์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค.
๊ทธ๋์ Computational Graph์์๋ ํ์ฌ Tensor์ ์ด์ Tensor๋ ๋ฌด์์ธ์ง์ ๊ฐ์ ์ ๋ณด๋ฅผ ๊ด๋ฆฌํ์ง๋ ์์ต๋๋ค.
๐ Solution: Autograd์ Node
ํ์ง๋ง, ์์์ ๋งํ Computational Graph๋ PyTorch์ ๋ํ ์ค๋ช ์ด์์ ๋ฟ, ์ ์ด์ ๋ฏธ๋ถ์ ์๋์ํค๊ณ ์๋ Autograd์์๋ Computational Graph์ ๋ํด ๋ ๊น์ด ๋ค๋ฃจ๊ณ ์์ ๊ฑฐ๋ผ๋ ์๊ฐ์ด ๋ค์๊ณ , ์ด์ ๊ธฐ๋ฐํ์ฌ Autograd์ ๊ณต์ ๋ฌธ์๋ฅผ ์ฐพ์๋ณด์์ต๋๋ค.
https://autograd.readthedocs.io/en/latest/implementation.html
ํด๋น ๊ณต์ ๋ฌธ์์์๋ Autograd๊ฐ ์ด๋ป๊ฒ ๊ตฌ์ฑ์ด ๋์ด์๋์ง๋ฅผ ๋ํ๋ด๋ฉฐ, ํฌ๊ฒ Variable, Block, Node๋ก ์ ๋ฆฌํ ์ ์์์ต๋๋ค. ๋ค๋ง, ์ด 3๊ฐ์ง์์ ๊ด๋ฆฌํ๊ณ ์ ํ๋ ๊ฒ๋ค์ด ์กฐ๊ธ์ฉ ๋ค๋ฅด๊ณ , ํท๊ฐ๋ฆด ์ ์๋ ๋ชจํธ์ฑ์ด ์๊ธฐ ๋๋ฌธ์ ์ํ๋ ์ ๋ณด๊ฐ ์๋ Node์ ๋ํด์๋ง ์ด์ผ๊ธฐํ๊ฒ ์ต๋๋ค.
Node๋ Autograd์์ ๊ด๋ฆฌํ๋ Data Structure๋ก y = f(x)์ ๊ฐ์ ํ๋์ ํจ์๋ฅผ ๊ณ์ฐํ๋ ๊ณผ์ ์ ๋ํด ์ฐ์ฐ ๊ทธ๋ํ๋ฅผ ์์ฑํ๋ฉฐ, ํจ์ ๋ด๋ถ์ ๊ฐ ์ฐ์ฐ์ ๋ํ ๊ด๊ณ์ Gradient๋ฅผ Node๋ก ๊ด๋ฆฌํฉ๋๋ค. y = g(f(x))๋ ๊ฒฐ๊ตญ ํผ์ณ๋ณด์์ ๋, ํ๋์ ํจ์๊ฐ ์ฌ๋ฌ ๊ฐ์ ์ฐ์ฐ์ผ๋ก ์ฎ์ธ ๊ฒ๊ณผ ๊ฐ๊ธฐ ๋๋ฌธ์ Node๋ฅผ ํ๋์ Tensor๋ผ ๋ณด๊ณ ์ดํดํด๋ ๋ฌด๋ฐฉํฉ๋๋ค.
Forward๊ฐ ์ผ์ด๋๋ ๊ฒฝ์ฐ, PyTorch๊ฐ ์๋ PyTorch ๋ด๋ถ์ Autograd์์๋ Computational Graph๋ฅผ ๊ตฌ์ถํฉ๋๋ค. ์ด๋ฌํ ๊ทธ๋ํ์ ์ ๋ณด๊ฐ ๋ด๊ธด ๊ฒ์ด Autograd์ Node์ ๋๋ค. ๋ง์ง๋ง Node์ธ Loss๋ฅผ Root๋ก ์ก๊ณ , ์ฐ์ฐ์ ์๋ฐฉํฅ๊ณผ ๋ฐ๋์ธ ์ญ๋ฐฉํฅ์ผ๋ก ํธ๋ฆฌ๋ฅผ ํ์ฑํฉ๋๋ค. ์ ๊ทธ๋ฆผ์์ ํ์ดํ๋ฅผ ๋ฐ๋๋ก ๋ฐ๊พผ ๊ฒ๊ณผ ๊ฐ์ต๋๋ค.
๐ง Node
Node์๋ ํฌ๊ฒ 2๊ฐ์ง ์์ฑ์ด ์์ต๋๋ค.
1. children
2. gradient
์ฌ์ค, ์ด๋ฏธ childrens๋ผ๋ ์์ฑ์ ๊ฐ์ง ๊ฒ๋ถํฐ '์ ์ด์ Tensor์ ๋ํ ์์น ์ ๋ณด๋ Autograd์ Node์์ ๊ด๋ฆฌ๊ฐ ๋๊ฒ ๊ตฌ๋'๋ผ๋ ๊ฑธ ์ง์ํ ์ ์์ต๋๋ค. children์์ ๊ด๋ฆฌํ๋ ๊ฒ์ ํ์ฌ Node์ Child Node๊ฐ ๋ฌด์์ธ์ง, ๊ทธ๋ฆฌ๊ณ Child Node์ ์ด๋ ํ ๋ฏธ๋ถ ๊ฐ(Gradient)์ ๊ฐ๋์ง์ ๋ํด Jacobian Matrix ํํ๋ก ๊ฐ์ง๊ณ ์์ต๋๋ค.
x=Variable(2)
y=sin(x)
y.node.childrens=[{'node':x.node, 'jacobian':cos(x.data)}]
๊ทธ๋ฆฌ๊ณ , gradient์์๋ ํ์ฌ Node์ ๋ํ root(๋ชฉ์ ํจ์)์ ๋ฏธ๋ถ ๊ฐ์ ๊ด๋ฆฌํฉ๋๋ค.
๊ณต์ ๋ฌธ์์์ ์ ๊ณตํ๋ child์ gradient(์ด์ Tensor์ .grad)๊ฐ ๊ฐฑ์ ์ด ๋์ด๊ฐ๋ ๊ณผ์ ์ ๋ํ๋ด๋ ์ฝ๋๋ฅผ ๊ฐ์ ธ์์ต๋๋ค.
for child in self.childrens:
node,jacobian=child['node'], child['jacobian']
new_grad = np.dot(self.gradient, jacobian)
node.update_gradient(new_grad)
์ด ์ฝ๋์์ ์ ์ ์๋ ๊ฑด self(= ํ์ฌ Node)์์ child(= ์ด์ Tensor)์ ์ ๊ทผ์ ํ์ฌ ํ์ฌ Node์ ๋ํ ๋ชฉ์ ํจ์์ Gradient์ child Node์ ๋ํด ํ์ฌ Node๋ฅผ ๋ฏธ๋ถํ ๊ฐ์ ๊ณฑํ์ฌ child Node์ gradient(์ด์ Tensor์ .grad)๊ฐ ๊ฐฑ์ ์ด ๋๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค. ๋จ์ํ ๊ณฑํ๋ ๊ฒ์ผ๋ก ๋ฏธ๋ถ ๊ฐ์ด ๊ตฌํด์ง๋ ๊ฒ์ ๋ฏธ๋ถ์ ์ฐ์ ๋ฒ์น์ ์ํด์ ๊ฐ๋ฅํ ๊ฒ์ด๋ฉฐ ์ด ๋ง์ ์์์ผ๋ก ๋ํ๋์ ๋๋ ์๋์ ๊ฐ์ต๋๋ค.
https://draw-code-boy.tistory.com/517
$$ \begin{align}
\text{self.gradient} = \frac{\delta Loss}{\delta Now} \\ \\
\text{child[`jacobian`]} = \frac{\delta Now}{\delta child} \\ \\
\frac{\delta Loss}{\delta child} = \frac{\delta Loss}{\delta Now}\cdot\frac{\delta Now}{\delta child}
\end{align} $$
๋ฌผ๋ก , Autograd์์๋ Computational Graph๋ ์ด๋ ํ ๋ค๋ฅธ Forward๊ฐ ๋ฐ์ํ ์ง ๋ชจ๋ฅด๊ธฐ ๋๋ฌธ์ ๋์ ์ผ๋ก ๊ด๋ฆฌ๊ฐ ๋ฉ๋๋ค.
โ Summary
์ด๋ฒ ๋ด์ฉ์ด ๋ณต์กํ๋ ๋งํผ ์ ๊ฐ ์ฐพ์๋ณด๊ณ ์ ํ๋ ์ ๋ณด์ ๋ํด์ ๊ฐ๋จํ๊ฒ ์ ๋ฆฌ๋ฅผ ํ์๋ฉด, PyTorch์์ Back Propagation์ด ์ผ์ด๋ ๋ ํ์ฌ Tensor์์ ์ด์ Tensor์๊ฒ Gradient์ ๊ฐ์ ์ ๋ณด๋ค์ ๋๊ธธ ๋, ์ด์ Tensor์ ์์น๋ฅผ ์ด๋ป๊ฒ ์๊ณ ์๋๊ฐ์ ๋ํ ์๋ฌธ์ ํ์์์ต๋๋ค.
์ด์ ๋ํด์๋ Autograd์ Computational Graph๋ฅผ ํตํด์ ํ์ฌ Node์ Child Node ์ ๋ณด๋ก ๊ด๋ฆฌ๊ฐ ๋๊ณ ์๋ค๋ ์ฌ์ค์ ๊ณต์ ๋ฌธ์๋ฅผ ํตํด ํ์ธํ์ต๋๋ค.