인지야공

인지야공/딥러닝 기초 정리/36번째 글

ReLU가 공간을 접는다 — 표현력의 기하

실행: python NN_37_relu_folding.py (검증 환경: torch 2.8.0+cu129, RTX 5080) 이 글의 수치는 전부 그 스크립트를 돌려 얻은 것이다.


“신경망은 아무 함수나 근사할 수 있다”는 말을 자주 듣는다. 그런데 어떻게 근사하는지를 그려 보면 생각보다 훨씬 단순하다. ReLU 망이 하는 일은 직선을 몇 군데에서 꺾는 것뿐이다.


1. 한 유닛이 하는 일 — 그림으로 먼저

ReLU는 max⁡(0,wx+b)\max(0, wx+b)다. 입력이 문턱을 넘기 전에는 0이고, 넘으면 직선이 된다. 즉 꺾임 하나다. 이것들을 더하면 꺾임이 여러 개인 조각 선형 함수가 되고, 쌓으면 앞 층의 꺾임이 뒤 층에서 다시 꺾인다 — 종이를 접었다가 또 접는 것과 같다.

ReLU 가 꺾임을 만드는 세 단계 ① ReLU 한 개는 문턱 전에는 0, 넘으면 직선이라 꺾임이 하나다. ② 여러 개를 더하면 꺾임이 그 수만큼 늘어 조각 선형 함수가 된다. ③ 층을 쌓으면 앞에서 만든 꺾임이 뒤에서 다시 꺾여 수가 곱해진다. ① 한 개 = 꺾임 하나 ② 더하면 = 꺾임이 늘어난다 ③ 쌓으면 = 꺾임이 곱해진다 max(0, wx+b) 은닉 k개 → 꺾임 약 k개 앞의 꺾임이 뒤에서 또 꺾인다 문턱

빨간 점이 꺾임이다. ①에서 하나였던 것이 ②에서 유닛 수만큼 늘고, ③에서는 층을 지날 때마다 곱해진다. 이 세 장면이 이 글에서 잴 것의 전부다.


2. 직접 재 보기 A — 폭은 꺾임을 더한다

은닉층 하나짜리 ReLU 망으로 sin⁡(4x)\sin(4x)를 근사시키고, 결과 곡선의 기울기가 바뀌는 지점을 세었다.

ReLU 접힘

은닉 유닛 수248163264
실제 꺾임 수468204076
근사 오차0.29230.01420.00400.00080.000040.00006

꺾임 수가 유닛 수를 그대로 따라간다(32개 → 40개). 그리고 유닛 2개짜리는 사실상 꺾인 직선 두어 개라 sin을 못 흉내 내지만(오차 0.29), 32개면 오차가 0.00004다. 눈으로는 매끄러운 곡선처럼 보이는 것이 실은 40조각짜리 직선인 셈이다.

“신경망이 아무 함수나 근사한다”는 정리(범용 근사)의 실체가 이것이다. 마법이 아니라 조각을 충분히 많이 쓰면 된다는 이야기이고, 그래서 얼마나 많은 조각이 필요한가가 진짜 질문이 된다.


3. 직접 재 보기 B — 깊이는 꺾임을 곱한다, 그런데

조각이 많이 필요하다면 깊이가 유리하다. 층을 지날 때마다 앞의 꺾임이 다시 꺾이기 때문이다(1절 ③). 이론적으로 깊이 LL이면 꺾임이 지수적으로 는다. 확인해 봤다 — 파라미터 수를 817개로 맞추고 깊게(6층×12) 대 얕게(1층×272) 톱니 함수를 근사시켰다.

톱니 수481632
깊게 — 꺾임4896141151
얕게 — 꺾임21476159
깊게 — 오차0.00000.05780.04610.0808
얕게 — 오차0.00000.00010.04370.0783

꺾임 쪽은 이론대로다. 같은 파라미터로 깊은 망이 2.5배 많은 꺾임(151개 대 59개)을 만들었다.

그런데 오차는 더 낫지 않았다. 톱니 8개에서 얕은 망은 0.0001인데 깊은 망은 0.0578 — 578배 나쁘다. 꺾임을 훨씬 많이 만들어 놓고도 그것을 목표에 맞추지 못한 것이다.

이건 예상과 반대라 한 번 더 짚어 둔다. 표현할 수 있다는 것과 경사하강이 찾아낸다는 것은 다른 얘기다. 깊은 망의 표현력은 “이런 함수를 적어 낼 수 있다”는 존재 증명이고, 학습은 그 해를 찾아가야 하는 별개의 문제다(한 번에 풀기의 벽 노트에서 만난 것과 같은 구분이다). 실제 깊은 망이 잘 되는 데에 정규화와 잔차 편가 필요했던 이유이기도 하다 — 표현력이 아니라 학습 가능성을 고치는 장치들이었다.


4. 직접 재 보기 C — 2차원에서 접히는 것을 보기

1차원에서 “꺾임”이었던 것이 2차원에서는 직선으로 자른 영역이 된다. 층을 지날수록 그 조각들이 겹치고 접혀 복잡한 경계가 만들어진다. 나선 두 갈래를 가르는 과정을 그대로 찍었다.

결정 경계가 만들어지는 과정

학습 스텝0601503006008,000
정확도49.7%60.3%74.1%97.2%99.7%99.9%

처음에는 거의 직선 하나로 평면을 가른다(정확도 49.7%, 찍는 수준). 그다음 조각이 하나씩 붙으면서 경계가 꺾이기 시작하고, 300스텝쯤에서 나선을 따라 감기는 모양이 갑자기 잡힌다. 경계가 매끄러운 곡선처럼 보이지만 확대해 보면 직선 조각들이다 — 2절에서 본 그것이다.


5. 흔한 오해와 한계

  1. “신경망은 곡선을 배운다” — ReLU 망이 만드는 것은 조각 선형 함수다. 매끄러워 보이는 것은 조각이 촘촘해서다.
  2. “범용 근사 정리가 있으니 무엇이든 된다” — 그 정리는 얼마나 많은 유닛이 필요한지를 말해 주지 않는다. 2절에서 유닛 2개로는 sin조차 못 따라갔다.
  3. “깊을수록 강하다” — 표현력은 그렇지만 학습은 아니었다(3절). 깊이의 이점은 구조(잔차·정규화)와 함께 와야 실현된다.
  4. “꺾임이 많을수록 좋다” — 아니다. 3절의 깊은 망은 꺾임 151개를 만들고도 오차가 더 컸다. 꺾임을 어디에 두느냐가 문제다.
  5. 이 글의 실험 — 1차원 회귀와 2차원 분류라는 장난감이다. 40개·151개 같은 수는 이 설정의 값이고, 요점은 근사는 접는 일이고, 폭은 꺾임을 더하고 깊이는 곱하지만, 만든 꺾임을 쓸 수 있느냐는 별개라는 구조다.

6. 한 문단 요약

ReLU 망은 곡선을 그리지 않는다 — 직선을 꺾는다. 은닉 유닛 하나가 꺾임 하나를 만들고, 32개가 만든 40개의 꺾임만으로 sin을 오차 0.00004까지 따라갔다. 층을 쌓으면 앞의 꺾임이 뒤에서 다시 꺾여 수가 곱해지고, 실제로 같은 파라미터에서 깊은 망이 2.5배 많은 꺾임(151개 대 59개)을 만들었다. 그런데 오차는 오히려 얕은 망이 나았다(톱니 8개에서 0.0001 대 0.0578) — 표현할 수 있는 것과 경사하강이 찾아내는 것은 다르다. 2차원에서도 같은 일이 벌어진다. 처음에는 직선 하나로 평면을 가르다가, 조각이 쌓이며 300스텝쯤에서 나선을 감싸는 경계가 갑자기 잡힌다. 매끄러워 보이는 그 경계도 확대하면 직선 조각들이다.


참고

표시는 이 브라우저에만 남는다. 서버로 가는 것은 없다.