3P by GN⁺ 18시간전 | ★ favorite | 댓글 1개
  • 역전파(backpropagation) 는 신경망 학습의 핵심이지만, 내부 작동 원리를 이해하지 않으면 예상치 못한 오류가 발생하는 ‘누수되는 추상화(leaky abstraction)’ 구조
  • 시그모이드(sigmoid)tanh 활성화 함수는 가중치 초기화가 잘못되면 기울기 소실(vanishing gradient) 로 학습이 멈추는 문제 발생
  • ReLU는 입력이 0 이하일 때 뉴런이 영구적으로 비활성화되는 죽은 ReLU(dead ReLU) 현상 유발 가능
  • RNN에서는 반복된 행렬 곱셈으로 인해 기울기 폭발(exploding gradient) 이 일어나며, 이를 방지하기 위해 gradient clipping이나 LSTM 사용 필요
  • 역전파의 작동 원리를 이해하지 않으면 프레임워크가 자동으로 처리하더라도 디버깅과 모델 개선 능력이 크게 떨어짐

역전파 이해의 필요성

  • Stanford의 CS231n 강의에서는 학생들에게 순전파와 역전파를 직접 구현하도록 과제를 설계
    • 일부 학생들은 TensorFlow 같은 프레임워크가 자동으로 역전파를 계산하므로 불필요하다고 불만 제기
  • 그러나 역전파는 완전한 추상화가 아닌 누수되는 추상화로, 내부 작동을 모르면 학습 실패 원인을 파악하기 어려움
  • 단순히 “프레임워크가 알아서 해준다”는 태도는 모델 설계와 디버깅 능력 저하로 이어짐

시그모이드에서의 기울기 소실

  • 시그모이드tanh 비선형 함수는 입력 값이 크면 출력이 0 또는 1에 가까워져 포화(saturation) 상태 발생
    • 이때 지역 기울기 z(1-z)* 가 0이 되어 역전파 시 기울기 전파가 차단
  • 시그모이드의 최대 기울기는 0.25로, 매번 통과할 때마다 신호가 1/4 이하로 감소
  • 결과적으로 하위 계층의 학습 속도가 상위 계층보다 현저히 느려짐
  • 따라서 시그모이드 계층을 사용할 경우 가중치 초기화와 데이터 전처리에 각별한 주의 필요

죽은 ReLU 문제

  • ReLU는 입력이 0 이하일 때 출력을 0으로 만드는 함수
    • 순전파에서 뉴런 출력이 0이면 역전파 시 기울기 또한 0이 되어 해당 뉴런이 영구적으로 비활성화
  • 학습 중 큰 가중치 업데이트나 높은 학습률로 인해 뉴런이 ‘죽은 상태’ 로 고정될 수 있음
  • 학습 후 전체 뉴런 중 상당수가 0을 출력하는 경우도 존재
  • 따라서 ReLU를 사용할 때는 학습률 조정초기화 전략이 중요

RNN의 기울기 폭발

  • 단순 RNN에서는 시간 단계마다 동일한 은닉 상태 행렬(Whh) 이 반복적으로 곱해짐
    • 역전파 시 이 행렬의 고유값(eigenvalue) 크기에 따라 기울기가 0으로 수렴하거나 무한히 커짐
  • |b| < 1이면 기울기 소실, |b| > 1이면 기울기 폭발 발생
  • 이를 방지하기 위해 gradient clipping을 적용하거나 LSTM 구조를 사용하는 것이 일반적

DQN 코드에서의 잘못된 클리핑 사례

  • TensorFlow 기반 DQN 구현에서 tf.clip_by_valuedelta(Q 오차) 를 직접 클리핑한 코드 발견
    • 이 방식은 delta가 범위를 벗어나면 기울기가 0이 되어 학습이 멈춤
  • 의도한 것은 기울기 클리핑이므로, 대신 Huber loss를 사용해야 함
    • 예시 코드에서는 조건부로 tf.squaretf.abs를 조합해 Huber 손실 구현
  • 이 문제는 GitHub 이슈로 보고되어 즉시 수정됨

결론

  • 역전파는 단순한 자동화 도구가 아닌, 신용 할당(credit assignment) 체계로서 복잡한 결과를 초래
  • 내부 작동을 이해하지 않으면 모델 불안정성, 학습 실패, 디버깅 한계에 직면
  • 역전파는 수학적으로 어렵지 않으며, CS231n 강의와 과제를 통해 직관적으로 학습 가능
  • 역전파를 이해하면 신경망 설계와 문제 해결 능력이 크게 향상됨
  • 프레임워크의 자동 미분 기능에 의존하기보다 역전파의 실제 흐름을 숙지하는 것이 중요
Hacker News 의견
  • 여기서 backpropagation이 부당하게 나쁜 평판을 얻고 있는 것 같음
    사실 이 논의는 역전파 자체보다는 gradient와 gradient descent 변형들이 최적화 과정에서 얼마나 불완전한 추상화인지에 대한 이야기임
    역전파는 단지 합성함수의 미분을 계산하는 알고리즘일 뿐이고, sigmoid를 여러 번 쌓아 생기는 gradient 소실 같은 문제는 역전파의 문제가 아니라 함수 자체의 특성임
    사람들이 직접 backward pass를 구현하게 하는 이유는, 직접 미분을 계산하면서 지수항이 어떻게 작용하는지 체감하게 하기 위함임

    • 네 말 이해하지만, 이 경우엔 그 ‘사소한 지적’이 별로 유용하지 않다고 생각함
      핵심은 어떤 상황에서는 역전파의 세부사항(gradient 계산 포함)을 추상화할 수 없다는 점임
      특히 gradient descent를 쓸 때는 그렇고, 다른 전역 최적화 알고리즘에서는 문제가 덜할 수도 있음
      지금 현실적으로 딥러닝에서 gradient를 계산하는 유일한 방법이 역전파이기 때문에 이 추상화의 누수는 실제적임
    • 사소한 지적이 아니라, 잘못된 개념적 틀에 대한 정당한 반박이라고 생각함
      Karpathy의 공헌은 존중하지만, 그의 글과 강연은 종종 개념 구분을 흐리게 만들어서 오해를 낳음
      그의 수준이라면 더 높은 정확성을 기대하게 됨
  • Karpathy의 딥러닝 교육 기여도는 정말 엄청남
    짧은 글부터 RNN에 대한 명문까지, 그리고 YouTube 강의와 GitHub 프로젝트까지 모두 훌륭함
    최근 공개된 nanochat도 훌륭한 예시로, 작고 명확한 완전한 예제는 학습자에게 매우 큰 도움이 됨

    • LLM에 깊이 몰입한 동료들에게 Karpathy의 글을 추천했는데, 의외로 관심이 없었음
      나중에 보니 그들은 LLM을 이해하기보다 믿고 활용하는 데 더 관심이 있었음
      실제로는 LLM의 작동 원리보다, “지능형 기계가 모든 일을 하는 사회” 같은 공상적 논의에 더 흥미를 보였음
    • Karpathy의 작업 방식이 흥미로움
      그는 단순히 “ChatGPT에게 물어보는” 대신, 직접 검색하고 코드를 읽으며 버그를 발견함
      이런 탐구적 접근이 진짜 학습임
  • 석사 과정에서 논문을 기반으로 역전파를 직접 구현하는 과제를 했음
    수학적 연산만으로 forward와 backward pass를 짜는 것이었는데, 그 해 최고의 학습 경험이었음
    이런 과제는 스스로는 잘 안 하게 되지만, 강제로 하게 되면 엄청난 도움이 됨

    • 논문만 읽을 때와 직접 코드로 구현할 때의 이해 차이가 엄청남
    • 고등학교 때 Java로 직접 구현했는데, 행렬 곱셈을 직접 짜는 게 제일 어려웠음
      UI를 만들어서 가중치와 편향이 학습 중 어떻게 변하는지도 시각화했음
    • 그 논문이 공개되어 있는지 궁금함
  • 역전파와 optimizer의 관계에 대해 궁금했음
    SGD는 gradient 방향으로 단순히 이동하지만, Adam 같은 고급 optimizer는 gradient를 직접 쓰지 않고 정규화, 모멘텀, 클리핑 등을 적용함
    그렇다면 정확한 gradient 계산이 정말 필요한가, 아니면 대략적인 방향만 알아도 되는가?

    • 실제로는 gradient를 작은 minibatch로 근사하기 때문에, 각 스텝은 noisy하지만 오히려 그 노이즈가 성능 향상에 도움을 줌
      관련 연구로 SGD noise 논문들, 시각화 연구 등이 있음
      하지만 방향을 대충 잡는 건 위험함 — loss 함수의 곡률(Hessian) 이 급격히 변하기 때문임
    • “정확한 gradient보다 방향만 알면 되지 않나?”는 오래된 질문임
      실제로 이런 아이디어에서 stochastic gradient descent가 나왔고, 더 나아가 Direct Feedback Alignment 같은 접근도 있음
      Ben Recht의 최적화와 강화학습의 관계 정리도 흥미로움
    • 역전파는 수치 정밀도 수준에서 정확한 미분 계산을 함
      중요한 건 loss 함수의 값보다 기울기와 곡률의 형태
      Adam 같은 optimizer는 1차 근사로 각 파라미터의 스케일 민감도를 추정해 gradient를 조정함
      더 높은 차수의 최적화는 ReLU 같은 비선형 함수에서는 불가능함
    • gradient를 조정하는 건 ‘fudge’가 아님
      vanishing gradient 문제를 해결하기 위한 필수 조치임
      고차원 공간에서는 작은 오차도 큰 영향을 주기 때문에, 정확한 gradient 계산이 매우 중요함
    • 미적분 자체는 어렵지 않음
      “대략적인 방향”을 어떻게 계산할 건지부터가 문제임
      AdamW 같은 고급 optimizer도 여전히 gradient를 핵심적으로 사용함
  • 2016년 즈음에는 gradient clipping 같은 트릭을 훨씬 자주 썼던 것 같음
    예를 들어 Alex Graves의 2013년 논문 Sequence Generation with RNNs에서도 LSTM의 gradient 폭주를 막기 위해 clipping을 사용했다고 밝힘
    나도 PyTorch autograd만 다루는 전문 강의를 들을 정도로 역전파의 중요성을 느꼈음

    • 예전엔 다양한 네트워크 구조를 실험하느라 이런 트릭이 많았던 것 같음
      지금은 프레임워크에서 clipping을 지원하고, 훈련 문제에 대한 이해도가 높아졌음
      하지만 문제 자체가 사라진 건 아님 — ReLU나 GELU는 여전히 기본 활성화 함수이고, LLM 학습은 여전히 ‘블랙아트’ 에 가까움
      Hugging Face의 Smol Training Playbook이 그 증거임
  • 장기적으로는 활성화 함수의 다양성에 강인한 모델을 훈련하는 게 유리할 수도 있다고 생각함
    예를 들어 ReLU, Swish, GELU 등을 무작위로 바꿔가며 학습시키면 dropout처럼 일종의 regularization 효과를 얻을 수 있음
    이렇게 하면 추론 시엔 계산이 가장 저렴한 함수로 바꿔 쓸 수도 있음

  • 원래 제목 “Yes you should understand backprop”이 훨씬 명확하고 좋음

    • 역전파가 누수되는 추상화이기 때문에, 직접 손으로 계산해보며 직관을 쌓는 게 중요함
      너무 많은 부분을 코드가 대신하면 ‘마법처럼 작동한다’는 착각에 빠지기 쉬움
      대학원 때 직접 손으로 convolution과 역전파를 계산했던 경험이 큰 도움이 됨
  • “프레임워크가 자동으로 backward pass를 계산해주는데 왜 직접 써야 하나?”라는 질문은
    “계산기가 있는데 왜 덧셈을 배워야 하나?”와 같은 논리라서 걱정스러움

    • 반론도 있음
      컴파일러나 정렬 알고리즘, 트랜지스터 동작을 이해하는 게 유용하듯, 역전파를 배우는 것도 가치가 있음
      다만 학습 시간은 한정적이므로, 이걸 배우는 게 다른 주제보다 더 유익한가가 핵심임
      역전파는 내부 동작을 모르면 숨은 실패 모드를 인식하기 어렵다는 점에서 배울 가치가 있음
      나도 여러 번 직접 구현해봤는데, 새로운 언어를 평가하기에 딱 좋은 복잡도임
  • 처음 딥러닝을 배울 때는 역전파가 마치 마법처럼 느껴졌음
    하지만 직접 구현해보니 단순한 계산의 연속이었고, 덕분에 디버깅이나 loss 정체 원인을 찾을 때 훨씬 자신감이 생겼음
    딥러닝을 배우는 사람이라면 한 번쯤은 직접 손으로 구현해보길 권함

  • 반대 입장도 있음
    학생들이 굳이 NumPy로 역전파를 구현할 필요는 없다고 생각함
    BackProp의 누수 문제는 연구자들이 새로운 optimizer로 해결하고, 개발자는 그저 좋은 하이퍼파라미터를 찾으면 됨

    • 하지만 대학에서는 학생들을 연구자로 양성하는 것이 목적임
    • “좋은 optimizer만 고르면 된다”는 건 오해임
      문제의 일부는 모델 설계나 학습 루프에서 발생함
      예를 들어 gradient clipping은 대부분의 프레임워크에서 기본값이 아님
      이 글은 연구자나 학문적 관점의 독자를 대상으로 함
    • 문제는 optimizer가 아니라 활성화 함수의 미분 특성
      Sigmoid나 ReLU 같은 함수의 gradient 동작을 이해하지 못하면, 폭주나 소실 문제를 해결할 수 없음
    • Stanford의 CS 수업이라면 기초 원리를 직접 구현하는 게 당연함
      새로운 모델 구조를 만들려면 역전파의 동작을 이해해야 하고, 그렇지 않으면 학습이 실패하거나 성능이 저하됨
    • “모르는 걸 모른 채로 남겨두는” 게 문제임
      추상화를 뚫고 들어가야 비로소 진짜 모르는 영역(unknown unknowns) 을 발견할 수 있음