[Neural Network 10] 다층 퍼셉트론 구현 실습

admin | | 조회 5


[주요 목차]

다층 퍼셉트론 클래스 정의

순전파와 손실 계산 구현

역전파로 XOR 문제 해결하기


단층 퍼셉트론으로는 절대 풀 수 없었던 XOR 문제를 실제 코드로 해결해 보고 싶으신가요? 이번 글에서는 다층 퍼셉트론 구현 실습을 통해 역전파 알고리즘을 처음부터 끝까지 직접 만들어 봅니다. 비개발자도 따라올 수 있게 단계별로 설명했으니, 주피터 노트북만 있으면 바로 실습 가능해요. 실습을 마치면 단순한 3층 신경망이라도 XOR 게이트를 90% 이상 정확도로 학습시키는 걸 직접 확인할 수 있습니다. 시간을 절약하고 싶다면 미리 정의된 클래스 구조와 초기 가중치 고정 팁을 참고하세요. 이 글을 끝까지 읽으면 다층 퍼셉트론 구현의 전체 흐름이 머릿속에 정리될 거예요.


[Neural Network 10] 다층 퍼셉트론 구현 실습 - 본문 이미지 1 - 다층퍼셉트론[Neural Network 10] 다층 퍼셉트론 구현 실습 · 본문 이미지 1

다층 퍼셉트론 클래스 정의

클래스 하나로 모든 기능을 담는 방식이 실무에서 가장 편합니다. 먼저 입력 노드 2개, 은닉 노드 2개, 출력 노드 1개로 가장 단순한 3층 구조를 정하고, __init__에서 가중치 w1~w6를 미리 고정값으로 선언해요.

랜덤 초기화 대신 고정값을 쓰면 학습 초반 로스가 빠르게 줄어 100번 만에 0.1 아래로 떨어지는 걸 볼 수 있어요. 변수명은 w1234, w56처럼 과거 영상과 연결해 기억하기 쉽게 했습니다.

시그모이드 함수도 클래스 안에 넣어 두면 forward, backward에서 매번 불러오기 편해요. 이렇게 큰 클래스 안에 forward, loss, backward, train까지 모두 넣으면 한눈에 전체 구조가 파악돼 유지보수도 쉬워집니다.

[Neural Network 10] 다층 퍼셉트론 구현 실습 - 주요 포인트 2 - 다층퍼셉트론[Neural Network 10] 다층 퍼셉트론 구현 실습 · 주요 포인트 2

순전파와 손실 계산 구현

순전파는 입력 → 은닉 → 출력 순으로 행렬 곱을 차례대로 수행하는 과정이에요. x1, x2에 w1~w4를 곱해 z1, z2를 만들고 시그모이드로 h1, h2를 얻은 뒤, 다시 w5, w6을 곱해 최종 출력 ŷ를 계산합니다.

코드로는 np.dot을 두 번 쓰면 끝이라서 초보자도 10줄 안에 구현할 수 있어요. 손실은 MSE로 계산하는데, (y - ŷ)²의 평균을 구하는 방식입니다.

출력 노드가 하나라서 공식이 간단하고, 미분할 때도 -2*(y-ŷ)만 기억하면 됩니다. 실전에서는 이 손실 값을 100번마다 print해서 학습이 제대로 되고 있는지 바로 확인하세요.

[Neural Network 10] 다층 퍼셉트론 구현 실습 - 본문 이미지 3 - 다층퍼셉트론[Neural Network 10] 다층 퍼셉트론 구현 실습 · 본문 이미지 3

역전파로 XOR 문제 해결하기

역전파는 출력층부터 거꾸로 가중치를 업데이트하는 단계예요. δ3을 먼저 구하고, δ3 × h1으로 w5의 기울기를 얻은 뒤 learning rate 0.1을 곱해 빼주는 방식으로 진행합니다.

행렬 연산이라 transpose가 필요하지만, 개념은 단순히 ‘체인룰로 미분을 연결한다’는 점만 이해하면 돼요. 100개의 XOR 학습 데이터를 만들어 1000번 반복 학습시키면, 0 0 입력에는 0.01, 1 0 입력에는 0.96처럼 명확한 결과가 나옵니다.

실무 팁: 처음엔 100번마다 로스를 출력하고, 로스가 0.05 이하로 떨어지면 학습을 멈추는 early stopping을 추가하면 시간을 크게 절약할 수 있어요. 다음 단계로는 PyTorch로 넘어가 더 복잡한 문제를 풀어보는 걸 추천합니다.


[자주 묻는 질문]

다층 퍼셉트론으로 XOR 문제를 풀 때 은닉층 노드 수는 몇 개가 적당한가요?

가장 간단한 경우 은닉 노드 2개로도 충분히 해결됩니다. 실제 실습에서도 2개로 90% 이상 정확도를 얻었어요. 노드를 4~8개로 늘리면 학습 속도가 조금 빨라지지만, 과적합 위험이 생기니 처음엔 2개로 시작해서 점차 늘려보세요. 데이터가 100개 정도라면 2개가 가장 균형 잡힌 선택입니다.

초기 가중치를 고정하는 대신 랜덤으로 설정해도 되나요?

가능합니다. 다만 실습 영상처럼 고정값을 쓰면 처음부터 로스가 낮게 시작해 100번 안에 결과를 확인할 수 있어요. 랜덤으로 할 경우 seed를 고정하거나 500~1000번 정도 더 학습해야 비슷한 성능이 나옵니다. 실무 프로젝트에서는 Xavier나 He 초기화를 사용하는 게 일반적입니다.

앞으로 PyTorch로 넘어가려면 지금 코드에서 어떤 부분을 바꿔야 하나요?

가장 큰 차이는 자동 미분과 GPU 연산입니다. 지금처럼 직접 backward를 구현할 필요 없이 loss.backward() 한 줄로 끝나요. 대신 DataLoader, nn.Module, optimizer를 새로 익혀야 합니다. 현재 클래스를 PyTorch 버전으로 포팅해 보면 전이 학습이 훨씬 수월해집니다.

목록
글쓰기
한국 서버호스팅
전체보기 →

댓글 0