어디에서 문제가 생기는지를 (문서 밖에서) 확인했다. 확인한 문제는 다음과 같다.
이게 유일한 문제인지는 모르겠지만, 확실한 문제가 있다.
‘학습하면 안 되는 것’과 ‘학습해도 되는 것’의 구분이 없기 때문에, y값을 학습해버린 것이다.
왜 이게 빠른 수렴이 아니라 엄청 발산으로 이어졌는지는 잘 모르겠지만 (아마 다른 문제도 있지 않을까 싶어지는 대목이다.) 적어도 이런 문제가 있다는 것 만큼은 확실하다.
이런 저런 프레임워크마다 이름은 다르겠지만 여기서는 trainable
이라는 이름을 쓰겠다.
단순하다.
계산그래프에 학습 가능한 인자들은 <T>
가 붙어 나오게 해서 계산 그래프를 출력해봤다.
원하는 곳에 학습 가능이 붙어있는 것을 확인할 수 있다.
생각해볼 만한 것은 계산 ‘중간’의 결과들을 학습시킬까인데… 사실 얘들은 임시 변수이기 때문에 큰 영향이 없다.
어짜피 한번 쓰고 버려지는 애들이기도 하고, 학습을 시키는지 시키지 않는지는 그 step의 gradient에 영향을 미치지 않기 때문에 상관이 없다.
(나중에 더 고-급 기술을 쓸 때는 조금 성가실 수도 있겠지만, 그 때 가서 생각하자.)
그리고 이제 학습될 변수 (즉 세 레이어의 변수)에 trainable을 True로 주고, 돌려보자.
느낌이 좋지 않다…
뭐랄까, 이것만이 유일한 문제는 확실히 아닌 것 같은 기분이다. 학습이 잘 되지 않는다.
이전과 똑같이 저 하늘 어딘가로 발산하고 있다.
zero_grad
를 Optimizer 안에서 수행하는 대신 매뉴얼하게 수행해주는 모드로 바꾸고, 학습 과정에서 gradient를 출력해 보았다.
알아낸 사실이 있다면, Gradient가 전혀 바뀌지 않는다는 것이다.
하지만 out값이 계속 바뀌고, 각 값도 계속 바뀌는 것 역시 확인했다.
즉, 어떤 상황에서도 Gradient는 그 값을 계속 유지하기 때문에, 한쪽 방향으로 움직이기 시작하면 그 쪽으로 계속 움직이게 된다… 그런 상황이다.
어디에서 문제가 생겼을까.
당장 가장 의심 되는 곳은 계산그래프이다.
원본의 값은 바뀌었지만, 계산그래프 내에 저장되는 값은 바뀌지 않아 그라디언트 값이 계속 똑같은 값으로 계산되는게 아닐까?
그냥 ‘그렇지 않을까’하고 끙끙대기만 하지 말고 직접 확인해보자.
직접 현재 값과 계산 그래프 상에 저장된 값을 비교해보면 될 것이다.
어떤 면에선 다행이게도, 어떤 면에선 불행이게도 예측이 틀렸다.
심지어 ID도 계속 같은 것을 공유하는 것을 확인했다.
그렇게 짜두었으니까 어찌 보면 당연한 일이지만… 왜 이런 결과가 나오는지를 다시 고찰해 봐야 할 것이다.
아마도 진짜 문제로 의심되는 곳을 발견했다.
계산 속도를 빠르게 하기 위해 사용한 value caching… 이라고 해야 하나? 아무튼 저장해둔 CalcGraph.value
말이다.
이게 전혀 업데이트가 되지 않는 것 같다.
value
를 cache
나 뭐 그런 이름으로 바꿔주고, use_cached
같은 새로운 함수를 만드는 식으로 대응해주면 될 것 같다.
사실 새로운 함수를 만들 필요도 없는 것 같다. 그냥 .cache
를 바로 불러주면 되니까.
이게 문제를 해결해줄 수 있으면 좋겠다…
단박에 문제가 해결되거나 하진 않는다. 역시나.
무언가 아직 해결하지 않은 부분이 있는게 아닐까.
그래서 cache를 사용하는 부분을 없애봤다…
이젠 모든게 nan이 되버렸다.
여기서 많이 해맸다.
이것 저것 해매다가, 첫번째로 nan이 생기는 곳을 찾아보기로 했다.
좀 더 여기저기 해매다가, 어느 정도 단서를 알아냈다.
nan이 생기는 곳은 어디인가?
np.exp
에서 inf
가 생겨나고, 그게 0과 곱해지며 nan
이 된다.
일단 (임시 방편으로?) np.exp
에서 생겨나는 nan
을 0으로 처리했다.
이전보단 나아진 것 같지만… 여전히 뭔가 문제가 있는 기분이다.
(최소한 nan으로 날아가는 현상은 해결됐다.)
여전히 남아 있는 문제가 분명히 있다.
학습이 이전처럼 fly me to the moon은 아니지만 (즉 어딘가에서 수렴 비스무레한 걸 하지만)
그 수렴 지점이 그래프하고 한참 떨어진 어딘가라는 것이 첫 문제고
그게 실제 loss상으로도 그렇다는게 두번째 문제다.
즉, loss가 뭔가 잘못 작동하는 기분이다.
그 쪽을 더 살펴보자.