배우기 · 4
학습
기울기를 지우고, 순방향, 손실, 역방향, 한 걸음. torch 에 없는 것은
scope() 하나이고, 그것이 없으면 장치가 몇 초 만에 찬다.
구역이 왜 있는가
한 스텝이 중간 버퍼를 수천 개 만든다. 자바스크립트의 쓰레기 수집은 GPU 메모리를
제때 안 놓아준다 — 작은 객체가 큰 할당을 쥐고 있다는 것을 모르기 때문이다.
scope() 는 그 안에서 만든 것을 나갈 때 놓고,
keepAlive() 가 살아남을 것을 표시한다. TF.js 의 tidy 와
같은 자리다.
이 블록을 돌려 수를 보고, scope 를 지운 뒤 다시 돌려 보라.
zeroGrad() 가 구역의 첫 줄인 것도 그냥 습관이 아니다. 지난 스텝의
기울기는 지난 구역에서 만들어졌고, 그 구역이 닫힌 뒤에 거기 더하려 하면 이미 남에게
넘어간 버퍼를 읽는다. borch 는 그 자리에서 멈춘다 — 지금 그 메모리에 무엇이 들어
있든 그것을 답으로 주지 않는다.
루프
정답이 있는 데이터로 보는 것이 정직하다. y = 3x + 2 를 못 찾는 루프가
내놓는 다른 수는 아무 뜻도 없다.
이 블록은 같은 고리를 두 벌 담고 있다. javascript 로 돌린 뒤 python 을 눌러 다시 돌려 보면 손실이 마지막 자리까지 같다 — 두 표면이 같은 WGSL 로 내려가기 때문이다. 파이썬 길에 대해 이 사이트가 하는 주장이 그것이고, 믿는 것보다 눌러 보는 편이 싸다.
옵티마이저와 스케줄
SGD·Adam·RMSprop 을 비롯해 열 몇 가지가 있고
학습률 스케줄러도 있다. 파라미터 그룹도 torch 처럼 돈다 — 그룹별 학습률, 그리고
치우침에는 weight decay 를 빼는 것.
손실이 떨어지는 것 보기
학습 루프는 매번 같은 네 줄이다: 기울기 0, forward, backward, step. 작은 직선 맞추기에 돌리고 손실을 그려라 — 떨어진다. 그것이 배움의 모습이다.
기억할 것
- 루프:
zeroGrad→ forward → loss →backward()→step(), 반복. - 옵티마이저(
SGD·Adam)가 기울기를 갱신으로; 스케줄러가 학습률을 조절. - 각 스텝을
scope()로 감싸 중간 텐서를 해제한다. - 손실이 떨어지면 배우는 중; 평평하거나 오르면 버그(버그 고쳐 보기 참고).
[1,2,3,4] 가 9,9,9,9 로 돌아왔다. 지금은 쓰는 그 자리에서
예외가 난다. 조용한 것보다 시끄러운 편이 낫다.