서론

저번엔 Model을 만들기 위한 기틀을 닦았다.

이번엔 직접적으로 구현해보자.

근사하게

어떤 param들을 가지고 있는지 굳이 명시하지 않아도 된다는건 근사하다.

어떻게 하면 ‘이런 이런 파라미터들이 있어요’라는걸 굳이 명시하지 않아도 코드가 알아서 찾을 수 있게 만들 수 있을까.

구조

먼저 이런 구조로 만들어보자.

__call__ (실제로 호출되는 부분, final) -> _apply (전체 구현, final) -> apply (프로그래머가 구현하는 부분, abstract)

__call__에서는 _apply를 부르고 _applyapply를 부르는데, _apply에 로직이 살짝 더 추가된다.

Model은 내부에 어떤 파라미터들을 가지고 있는지 알아야 하는데, 이걸 _apply가 처음 불릴 때 한번 초기화해준다.

초기화는 파이썬의 dirgetattr, 그리고 := 오퍼레이터를 이용해서 만들어주자.

지금까지 :=을 써본 적이 없는데, 잘 쓰면 코드를 깔끔하게 만들 수 있을 것 같다.

테스트

일단 layer들을 구현하기 전에, playground에서 테스트를 해보자.

Optimizer 수정

그 전에, Optimizer를 수정해야 할 부분이 있다.

지금은 loss의 텐서를 받는데… 이게 모델을 받을 수 있게 하자.

방법은 크게 두가지다.

  1. __init__이 Tensor와 Model을 받을 수 있게 바꾸기
  2. from_model같은 메서드를 만들기

1번 방법으로 가겠다.

또 그러고 보니까 이러면 zero_grad를 수동으로 불러줘야 하는데… zero_grad만은 자동으로 하고 싶다.

PyTorch와의 차이점 뭐 그런 느낌으로.

CalcGraph를 조금 건드려서, trainable이 아니라면 grad 정보를 날려주게 만들어주겠다.

이것 저것 건드리고 했는데, 잘 되는 것 같다.

Layer

모델이 잘 작동하는걸 확인했으면 이제 Layer들을 만들 차례다.

Layer는 따로 layer 파일을 만들어서 해주자.

레이어 클래스는 뭐가 필요할까?

Backward는 알아서 계산그래프가 잘 처리해줄꺼다.

그렇다면 역시 매 층마다 계산해야 하는 것을 알고 있어야 할 것이다. 이걸 __call__로 부르고.

함수 명은 어떻게 할까? apply? forward?

Apply가 나을 것 같다.

Linear Layer의 초기화는 그냥 표준정규분포로 해주자.

또 Keras식으로 Layer에 activation을 받을 수 있게 해주자. 물론 Activation도 Layer로 구현하는게 정신건강상 편할 것 같다.

아, 맞다. Bias. Bias도 Layer 안에 넣어줘야한다.

또 init에서 바로 Tensor를 만드는게 아니라 따로 Tensor를 만드는 부분을 만들어주는게 더 근사할 것 같다.

shape와 관련된 부분을 처리하기엔 그 편이 좋을 것 같다. _layer_init 함수를 만들어주자.

잠시 시간이 지난 후

좋다. 이제 잘 작동한다.

다만 코드가 조금 더러우니까 (특히 ‘근사하게’ 만드는 부분의 코드가 좀 더럽다)

다음엔 그 부분을 손봐주자.

그래도 playground의 코드는 믿을 수 없을 정도로 깔끔해졌다.