GitHub 트렌딩 딥다이브 · 2026-06-24

Mukul-svg/graddy 딥다이브
— 99줄로 읽는 backprop(역전파), 그리고 학습된 신경망을 '눈으로' 보기

Mukul-svg/graddy는 순수 파이썬으로 짠 아주 작은 autograd(자동 미분) 엔진 + 신경망 라이브러리입니다. Andrej Karpathy의 micrograd 계열 교육용 프로젝트로, 숫자 하나하나에 직접 사칙연산을 하면 계산 그래프가 쌓이고, .backward() 한 번에 미분(기울기)이 거꾸로 흘러내리는 과정을 99줄짜리 engine.py에 다 담았습니다. 여기에 micrograd엔 없는 '학습된 신경망을 matplotlib으로 그리는' 시각화가 더해진 게 차별점입니다. (저장소: Mukul-svg/graddy · 언어 Python 100% · ★ 신생(거의 0) · 라이선스 MIT · 2026-06-23 생성)

목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석 (forward로 그래프를 짓고, backward로 기울기를 흘린다)
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

"PyTorch의 loss.backward()가 안에서 무슨 일을 하는지, 99줄로 직접 열어 보는 프로젝트."

한 줄로

graddy는 '미분을 자동으로 해 주는 기계'를 가장 작게 만들어, backprop이 실제로 어떻게 도는지 손으로 따라 읽게 해 주는 교본이다.

딥러닝을 배우면 누구나 loss.backward()를 칩니다. 하지만 그 한 줄 안에서 무슨 일이 벌어지는지는 PyTorch라는 거대한 블랙박스 뒤에 숨어 있습니다. graddy는 그 블랙박스를 99줄로 줄여 열어 줍니다 — 숫자를 Value라는 객체로 감싸고, 그 객체들끼리 +·*를 하면 계산 그래프(DAG)가 저절로 그려지고, 마지막 결과에서 .backward()를 부르면 연쇄법칙(chain rule)으로 기울기가 거꾸로 흘러 각 숫자의 .grad에 쌓입니다.

용어
autograd / 역전파(backpropagation)
autograd는 'automatic gradient', 즉 미분(기울기)을 자동으로 계산해 주는 기능입니다. 신경망 학습은 "출력의 오차를 줄이려면 각 가중치를 어느 방향으로 조금 바꿔야 하나?"를 알아야 하는데, 그 '어느 방향'이 바로 미분값(gradient)입니다. 역전파는 그 미분을 출력에서 입력 쪽으로 거꾸로 연쇄법칙을 적용해 한 번에 구하는 알고리즘입니다. 사람이 일일이 미분 공식을 쓰지 않아도, 연산마다 '국소 미분 규칙'만 정의해 두면 기계가 알아서 이어 붙입니다.
용어
계산 그래프(computational graph) · 정의-즉-실행(define-by-run)
계산 그래프는 "이 값은 저 값과 저 값을 더해서/곱해서 나왔다"는 유래의 지도입니다(노드=값, 화살표=연산). graddy는 이 지도를 미리 짜 두는 게 아니라, 순전파(forward) 계산을 실제로 하는 그 순간에 한 줄씩 그립니다 — 이를 '정의-즉-실행(define-by-run)' 또는 동적 그래프라 부릅니다. PyTorch가 쓰는 방식과 같습니다. 별도의 '컴파일' 단계가 없어 디버깅이 쉽고 직관적입니다.

핵심 사용법은 micrograd와 똑같이 단순합니다 — Value(-4.0) 같은 숫자를 만들고, 평범하게 수식을 쓰고, y.backward()를 부른 뒤 x.grad를 읽으면 됩니다. 이 문서는 그 안의 설계 — "연산자 오버로딩으로 그래프를 어떻게 짓나", "backward()의 위상정렬은 왜 필요한가", "기울기를 왜 =가 아니라 +=로 쌓나", 그리고 "학습된 신경망을 어떻게 그림으로 보여 주나"를 파고듭니다.

2왜 주목받는가

"backprop을 '소스로' 배우는 micrograd 계보. graddy의 한 끗은 '학습 결과를 눈으로 보는' 시각화다."

함정
먼저 정직하게 — 이 레포는 갓 태어났다

graddy는 2026년 6월 23일에 만들어진 신생 저장소로, 분석 시점 기준 커밋 1개·별 0개입니다. '트렌딩'에 잡힌 건 인지도가 아니라 신선함 + micrograd라는 사랑받는 장르 + 좋은 GitHub 토픽 덕입니다. 즉, 검증된 라이브러리가 아니라 잘 만든 '학습용 개인 프로젝트'로 보는 게 맞습니다. (그래서 이 문서도 '쓰는 도구'가 아니라 '읽고 배우는 교본'으로 다룹니다.)

그럼에도 학습 가치가 큰 이유 — micrograd 계보와 비교

backprop을 코드로 배우는 길에서 micrograd는 이미 고전입니다. graddy는 그 계보 위에 두 가지를 더합니다 — 엔진에 exp()·tanh() 활성함수를 추가했고(micrograd 엔진은 relu만), 무엇보다 '학습이 끝난 신경망'을 그림으로 그리는 시각화를 넣었습니다.

관점graddymicrograd (Karpathy)
입자 단위스칼라(Value=숫자 하나)스칼라(동일)
활성함수relu·exp·tanh엔진은 relu 중심
시각화학습된 '망 구조'를 matplotlib으로
(가중치=색·굵기, 편향=주석)
Graphviz로 '계산 그래프'
검증PyTorch와 기울기 대조 테스트데모·sklearn moons
차별점
'계산 그래프'가 아니라 '학습된 망'을 그린다

micrograd의 유명한 draw_dot은 모든 연산 노드를 그린 계산 그래프입니다. graddy의 draw_neural_network()는 다릅니다 — 학습이 끝난 신경망의 뉴런과 가중치 자체를 그립니다. 가중치 부호는 색(양수 초록·음수 빨강), 크기는 선의 굵기·투명도로, 각 뉴런의 편향(bias)은 아래에 숫자로. 그래서 "훈련이 가중치를 어떻게 바꿨나"를 한눈에 볼 수 있습니다. backprop 입문자에게 특히 직관적입니다.

다만 솔직히 짚으면, README는 '텐서 지원'·'신경망 라이브러리'라며 다소 부풀려 말하지만 현재는 철저히 스칼라입니다(가중치 곱 하나하나가 파이썬 float 연산이라 느림). 학습 도구로는 그게 오히려 장점입니다 — 모든 게 느리지만 모든 게 들여다보입니다.

3기술 스택 전체 지도

"코어는 의존성 0 — 파이썬 표준 math/random뿐. 외부 라이브러리는 데모·테스트·그림용으로만 등장한다."

graddy의 무게중심은 딱 두 파일engine.py(autograd 스칼라)와 nn.py(그 위에 올린 신경망)입니다. 이 둘은 외부 패키지 없이 파이썬 표준 라이브러리만 씁니다. 나머지(numpy·matplotlib·sklearn·torch)는 데모와 테스트, 그림에만 쓰입니다.

① 코어 (의존성 없음)

기술역할한 줄 설명
Python 3.6+전체 언어f-string 정도만 쓰는 평범한 파이썬. 별도 빌드 도구 없음.
표준 mathengine.pyexp 등 — 활성함수 계산에만. autograd 자체엔 외부 의존성 0.
표준 randomnn.py가중치 초기화(uniform(-1,1)).
용어
연산자 오버로딩(operator overloading)
파이썬에서 a + b를 쓰면 내부적으로 a.__add__(b)가 불립니다. 연산자 오버로딩은 그 __add__ 같은 함수를 내 클래스에 맞게 새로 정의하는 것입니다. graddy는 Value 클래스의 __add__·__mul__·__pow__를 재정의해, "값끼리 더하면 새 그래프 노드가 생기고 미분 규칙이 따라붙도록" 만듭니다. 즉, 평범한 수식을 쓰는 행위가 곧 그래프를 짓는 행위가 됩니다.

② 데모 · 테스트 · 시각화 (선택 의존성)

기술역할
torch (PyTorch)test/test.py에서만 — graddy의 forward·grad가 PyTorch와 같은지 대조(골든 레퍼런스 테스트).
numpy좌표 계산(linspace·meshgrid) — 시각화·결정경계 그림용.
matplotlib시각화 백엔드. graphviz 불필요(micrograd와 달리 그림이 순수 matplotlib).
scikit-learnmake_moons 장난감 데이터셋(이진 분류 데모).

주의할 점 — 저장소에 setup.py·pyproject.toml·requirements.txt가 전혀 없습니다. 즉 pip install로 깔리는 패키지가 아니라, 클론해서 저장소 안에서 실행하거나 sys.path에 경로를 넣어 쓰는 구조입니다. 패키지 __init__.py도 비어 있어 from graddy.engine import Value처럼 모듈을 콕 집어 임포트합니다.

4아키텍처 심화 분석 (forward로 그래프를 짓고, backward로 기울기를 흘린다)

"핵심은 두 가지 — 연산할 때 그래프가 저절로 그려지고, backward는 그 그래프를 거꾸로 한 번 훑는다."

전체 그림 — Value 노드 하나의 구조

모든 숫자는 Value(data, _children, _op) 객체입니다. 각 노드는 값(data)·기울기(grad)·부모로 가는 화살표(_prev)·연산 이름(_op), 그리고 결정적으로 자기 기울기를 자식에게 밀어 넣는 함수 _backward를 들고 있습니다.

forward (정의-즉-실행: 연산 한 번에 노드 1개 + _backward 1개가 생김) a = Value(-4.0) b = Value(2.0) \ / \ / + ── 연산 '+' ─► out = Value(-2.0, _prev={a,b}, _op='+') ├ data : -2.0 (forward 결과) ├ grad : 0.0 (backward 전엔 0) ├ _prev : {a, b} (부모로 가는 화살표) ├ _op : '+' └ _backward : () => { a.grad += out.grad b.grad += out.grad } ▲ 이 노드의 '국소 미분 규칙'

backward — 위상정렬 후 거꾸로 한 번 훑기

backward()는 깊이우선탐색으로 그래프를 위상정렬(자식이 부모보다 먼저 오도록 줄세우기)한 뒤, 출력의 기울기를 1.0으로 두고 역순으로 각 노드의 _backward()를 부릅니다. 모든 국소 규칙이 +=로 더하기 때문에, 한 값이 여러 곳에 쓰여도 기울기가 올바르게 합산됩니다.

# engine.py — backward의 전부
def backward(self):
    topo = []; visited = set()
    def build_topo(v):
        if v not in visited:
            visited.add(v)
            for child in v._prev:
                build_topo(child)
            topo.append(v)          # 후위순회 → 자식이 부모보다 앞에
    build_topo(self)
    self.grad = 1.0                 # 출력의 기울기를 1로 씨앗
    for node in reversed(topo):     # 부모 → 자식 순으로
        node._backward()            # 연쇄법칙을 += 로 흘린다
backward y.backward(): 1. build_topo(y) → _prev 따라 후위 DFS → topo(자식→부모) 줄세움 2. y.grad = 1.0 (씨앗) 3. for node in reversed(topo): node._backward() # 연쇄법칙, += y.grad=1 ─► 각 _backward가 자식 grad에 더한다 │ 한 값이 여러 곳에 쓰였으면(z 재사용) grad가 SUM 으로 누적 ▼ x.grad, w.grad … 입력단까지 기울기가 흘러내림

신경망은 어떻게 쌓이나 — Neuron → Layer → MLP

Neuron은 가중치들(Value)과 편향 하나를 들고 Σ wᵢ·xᵢ + b를 계산한 뒤(이 계산 자체가 그래프를 늘림) relu를 씌웁니다. Layer는 뉴런들의 묶음, MLP는 층들의 연결입니다. 영리하게도 마지막 층만 활성함수를 빼(nonlin = i != 마지막) 출력이 relu에 눌리지 않게 합니다.

# nn.py — 순전파가 곧 그래프를 늘리는 행위
def __call__(self, x):
    act = sum((wi*xi for wi,xi in zip(self.w, x)), self.b)  # Σ wᵢxᵢ + b
    return act.relu() if self.nonlin else act               # 마지막 층은 선형
용어
옵티마이저가 따로 없다 — 손으로 쓴 경사하강(SGD)
graddy엔 Optimizer 클래스가 없습니다. 각 데모가 직접 기울기 반대 방향으로 가중치를 조금 옮기는 코드를 씁니다: p.data -= lr * p.grad. 이게 경사하강법(gradient descent)의 알맹이입니다 — "오차를 줄이는 방향(=기울기의 반대)으로 한 걸음씩". 일부 데모는 여기에 학습률 감소·L2 정규화·hinge 손실을 더합니다. 옵티마이저가 없다는 건 결함이 아니라, 가장 중요한 한 줄을 숨기지 않고 보여 주는 교육적 선택입니다.

훈련 한 바퀴 — 이 네 줄이 전부다

model.zero_grad()          # 지난 기울기 0으로
loss.backward()            # 역전파로 모든 grad 채움
for p in model.parameters():
    p.data -= learning_rate * p.grad   # 한 걸음 갱신(SGD)

5디렉토리 구조 해부

"전부 합쳐 ~517줄. autograd는 engine.py, 신경망은 nn.py, 나머지는 데모·그림·테스트."

graddy/ (저장소 루트) ├── graddy/ ← 실제 패키지 │ ├── __init__.py ← 비어 있음(공개 재노출 없음) │ ├── engine.py (99줄) ⭐ Value: autograd 스칼라, 모든 연산, backward() │ └── nn.py (59줄) ⭐ Module·Neuron·Layer·MLP (Value 위에) ├── test/ │ └── test.py (100줄) forward+grad를 PyTorch와 대조하는 3개 테스트 ├── demo.py (52줄) MLP(3,[8,8,1]) 학습, MSE + SGD ├── moons_demo.py (80줄) sklearn moons, hinge 손실, L2, 결정경계 그림 ├── plot_nn.py (127줄) ★ 학습 후 draw_neural_network() 시각화 ├── README.md · LICENSE(MIT) ├── nn_architecture.png 시각화 결과 샘플 └── moons_decision_boundary.png 결정경계 결과 샘플
파일역할
engine.py핵심 중의 핵심. Value 클래스 하나에 그래프 구축·backward가 다 들어 있다(99줄).
nn.pyValue를 레고처럼 쌓아 만든 Neuron/Layer/MLP. parameters()·zero_grad() 제공.
plot_nn.py이 레포의 차별점. 학습된 망을 색·굵기·편향 주석으로 그린다.
test/test.py"내 autograd가 PyTorch와 같은 답을 내는가"를 확인하는 골든 테스트.

6학습 포인트 (기술별)

"backprop을 '소스로' 이해하기에 거의 완벽한 재료. 연산별 미분 공식이 코드에 그대로 있다."

연산별 국소 미분 규칙 (engine.py에 구현된 그대로)

연산_backward (국소미분 × 상류 grad)수학
+ (덧셈)self.grad += out.grad∂/∂a = 1
* (곱셈)self.grad += other.data * out.grad∂/∂a = b
** (거듭제곱)self.grad += (n*a**(n-1)) * out.gradn·aⁿ⁻¹
reluself.grad += (out.data>0) * out.grada>0이면 1, 아니면 0
expself.grad += out.data * out.gradd(eˣ)=eˣ(=out.data)
tanhself.grad += (1 - t**2) * out.grad1 − tanh²(x)
학습 1 · 역전파의 심장

위상정렬 + 연쇄법칙을 ~30줄로

backward()와 각 연산의 _backward 클로저만 읽으면, 역전파의 전부를 이해할 수 있습니다. 특히 왜 위상정렬이 필요한지(한 노드의 기울기는 그걸 쓰는 모든 곳에서 다 모인 뒤에야 자식으로 흘러야 함)를 코드로 체감하는 게 핵심입니다.

학습 2 · += 의 이유

왜 grad는 '대입'이 아니라 '누적'인가

한 값이 여러 갈래로 쓰이면(fan-out), 각 갈래에서 온 기울기를 더해야 맞습니다. 그래서 모든 _backward=가 아니라 +=를 씁니다. graddy의 테스트는 일부러 z를 두 번 재사용해 이 누적이 맞는지 확인합니다. 미분의 '덧셈 법칙'이 코드 한 글자에 녹아 있는 셈입니다.

학습 3 · 시각화

학습된 가중치를 색·굵기로 그리기

plot_nn.py의 그리기 함수는 matplotlib 기본 도형만으로 뉴런(원)과 가중치(선)를 그립니다. 부호는 색, 크기는 굵기·투명도로 인코딩해 "이 망이 무엇을 학습했나"를 눈으로 보게 합니다. 데이터 시각화 입문으로도 훌륭합니다.

# plot_nn.py — 가중치를 색/굵기로 인코딩 (차별점)
color = '#2E7D32' if w > 0 else '#C62828'   # 양수 초록 / 음수 빨강
alpha = max(0.1, min(0.85, abs(w) / max_w)) # 투명도 = |가중치|
linewidth = 0.5 + 2.5 * (abs(w) / max_w)    # 굵기 = |가중치|
학습 4 · 검증의 자세

내 구현을 PyTorch로 '채점'하기

같은 수식을 graddy와 PyTorch로 각각 돌려 forward 값과 grad가 일치하는지 assert로 확인합니다. 직접 만든 수치 코드를 신뢰할 수 있는 기준과 대조하는 '골든 레퍼런스 테스트' 패턴 — 모든 수치 구현에 적용할 좋은 습관입니다.

7시스템 요구사항

"코어는 파이썬만 있으면 된다. GPU도, 무거운 의존성도 없다."

항목요구사항
언어Python 3.6+ (f-string 정도만 사용). 패키징 파일 없음 → pip 설치가 아니라 클론 후 실행.
코어(engine·nn)외부 의존성 0(표준 math·random만).
테스트pip install torch (기울기 대조용).
시각화·데모pip install numpy matplotlib scikit-learn (graphviz 불필요).
하드웨어CPU만으로 충분. 스칼라 연산이라 느리지만 데이터가 수백 점 규모라 문제없다.

8직접 해볼 수 있는 실습 과제

"손으로 grad 계산 검산 → 작은 MLP 학습 → 새 연산 추가 → 시각화 확장 순으로."

실습 A 난이도 ★☆☆ 입문

forward·backward 한 번 돌려 손으로 검산

README 예제(y = h + q + q*x …)를 실행해 y.data·x.grad를 출력하고, 같은 식을 종이에 미분해 손 계산과 일치하는지 확인합니다. 일치하는 순간 backprop이 '마법'이 아니라 연쇄법칙임이 손에 잡힙니다.

실습 B 난이도 ★★☆ 중급

작은 MLP를 학습시키고 손실이 주는 걸 보기

demo.py를 돌려 100스텝 동안 손실이 줄어드는 걸 관찰하고, 학습률을 0.01→0.1→0.5로 바꿔 가며 발산·진동을 직접 만들어 봅니다. 경사하강의 감각을 몸으로 익히는 실습입니다.

실습 C 난이도 ★★★ 고급

새 연산 추가: sigmoid를 직접 구현

engine.pysigmoid를 추가하세요 — forward는 1/(1+e⁻ˣ), _backwards*(1-s). 그런 뒤 test/test.py처럼 PyTorch와 grad를 대조해 내 미분 규칙이 맞는지 검증합니다. autograd 엔진을 '확장'해 보는 핵심 실습입니다.

실습 D 난이도 ★★★ 고급

시각화 확장 + (도전) 텐서화 맛보기

plot_nn.py의 그리기에 '활성값 히트맵'이나 '에지 위 가중치 숫자'를 더해 봅니다. 더 나아가, 스칼라 Value를 numpy 배열로 바꾸는 '미니 텐서화'를 시도하면 micrograd→tinygrad로 가는 길이 보입니다.

9관련 기술 심화 학습 로드맵

"미분 기초 → autograd 원리 → 신경망 → 텐서화/프레임워크 순으로 쌓으면 단단하다."

주차주제학습 자료 / 키워드
1주차미분·연쇄법칙 복습편미분, chain rule, 경사(gradient)의 의미
2주차역전파 원리graddy engine.py, Karpathy "micrograd" 강의(YouTube)
3주차계산 그래프·define-by-run위상정렬, 동적 그래프, PyTorch autograd 개념
4주차신경망 기초퍼셉트론→MLP, 활성함수(relu/tanh/sigmoid), 손실함수(MSE/hinge)
5주차학습 동역학SGD, 학습률, L2 정규화, 과적합/결정경계
6주차텐서화·프레임워크tinygrad 읽기, numpy 벡터화, PyTorch로 같은 망 재현

10핵심 키워드 사전

"문서에 나온 용어를 한자리에."

용어의미
autograd미분(기울기)을 자동 계산하는 기능. 연산마다 국소 미분 규칙만 정의해 두면 기계가 연쇄.
역전파(backprop)출력에서 입력으로 거꾸로 연쇄법칙을 적용해 모든 기울기를 한 번에 구하는 알고리즘.
계산 그래프값(노드)이 어떤 연산으로 만들어졌는지의 지도(DAG). graddy는 forward 때 즉석에서 그림.
연산자 오버로딩+·* 같은 연산을 내 클래스에 맞게 재정의. 수식 쓰기 = 그래프 짓기.
위상정렬의존 순서대로 줄세우기. backward에서 자식이 부모보다 먼저 오게 한다.
경사하강(SGD)기울기 반대 방향으로 가중치를 조금씩 옮겨 손실을 줄이는 학습법.
활성함수뉴런 출력에 비선형성을 더하는 함수(relu·tanh·sigmoid 등). 없으면 층을 쌓아도 선형.
MLPMulti-Layer Perceptron. 여러 층의 뉴런으로 이뤄진 가장 기본적인 신경망.

11참고 링크